Skip to content
46 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Chat and workspace agents: channels, DMs and named agents you talk to1import { test } from "node:test";
2import assert from "node:assert/strict";
3
Workspace agents are told where they are and who is in the conversation every turn, and hand work to a colleague with a hand_off tool instead of an @mention: the brief is posted where the colleague already is, or in a group message of the person who asked, the agent and the colleague with a card linking to it; an agent's messages no longer wake other agents, its mentions of anyone outside the conversation show as plain names, and the agents and chat guides and the workspace plan say how.4import { mentionedHandles, mentions, mentionsColumn, plainOutside } from "./mentions.ts";
Chat and workspace agents: channels, DMs and named agents you talk to5
6test("mentions are found once each, lowercased, in order", () => {
7 assert.deepEqual(mentionedHandles("@Ship can you cut it? cc @syntaqx and @ship"), ["ship", "syntaqx"]);
8 assert.deepEqual(mentionedHandles("(@review-bot) @a_b, @x."), ["review-bot", "a_b", "x"]);
9 assert.deepEqual(mentionedHandles("@ship\n@docs"), ["ship", "docs"]);
10});
11
12test("an email address or a stray @ is not a mention", () => {
13 assert.deepEqual(mentionedHandles("mail me@example.com"), []);
14 assert.deepEqual(mentionedHandles("@ alone, @@double, @-dash"), []);
15 assert.deepEqual(mentionedHandles(""), []);
16});
17
18test("a kept mention matches its whole handle only", () => {
19 const column = mentionsColumn(mentionedHandles("hey @bobby and @ship"));
20 assert.equal(column, " bobby ship ");
21 assert.equal(mentions(column, "bobby"), true);
22 assert.equal(mentions(column, "Ship"), true);
23 assert.equal(mentions(column, "bob"), false);
24 assert.equal(mentions(mentionsColumn([]), "bob"), false);
25 assert.equal(mentions(null, "bob"), false);
26});
Workspace agents are told where they are and who is in the conversation every turn, and hand work to a colleague with a hand_off tool instead of an @mention: the brief is posted where the colleague already is, or in a group message of the person who asked, the agent and the colleague with a card linking to it; an agent's messages no longer wake other agents, its mentions of anyone outside the conversation show as plain names, and the agents and chat guides and the workspace plan say how.27
28test("an agent's mention of someone outside the conversation becomes a plain name", () => {
29 const members = new Set(["syntaqx", "g1t"]);
30 assert.equal(
31 plainOutside("Ask @mike to help @syntaqx. @Triage, @bruno and @david know too; I'm @g1t.", members),
32 "Ask mike to help @syntaqx. Triage, bruno and david know too; I'm @g1t.",
33 );
34 // Matching is by whole handle, whatever its case.
35 assert.equal(plainOutside("@SYNTAQX and @syntaqxx", members), "@SYNTAQX and syntaqxx");
36});
37
38test("code, addresses and team mentions are left as written", () => {
39 const none = new Set<string>();
40 assert.equal(
41 plainOutside("Use `@mike` or\n```py\n@property\ndef x(): ...\n```\nthen @mike", none),
42 "Use `@mike` or\n```py\n@property\ndef x(): ...\n```\nthen mike",
43 );
44 assert.equal(plainOutside("mail me@example.com, ping @acme/web", none), "mail me@example.com, ping @acme/web");
45 assert.equal(plainOutside("```\n@open fence", none), "```\n@open fence");
46});