Skip to content
178 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 assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { AgentDelivery } from "@g1t/contracts";
5
6import { g1tSurface } from "./surface.ts";
7
8const delivery: AgentDelivery = {
9 workspace: "acme",
10 workspace_id: "wsp_1",
11 channel_id: "chn_1",
12 channel_kind: "channel",
13 channel_name: "releases",
14 agent_id: "agt_ship",
15 message_id: "msg_1",
16 thread_root: "msg_0",
17 asked_by: "usr_dana",
18 hops: 2,
19 asker: { username: "dana", role: "member", can_write: false },
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)20 chain: ["agt_g1t"],
Chat and workspace agents: channels, DMs and named agents you talk to21 surface: "g1t",
22};
23
24/** A chat binding that records each call and answers `answers[method]`. */
25function fakeChat(answers: Record<string, unknown>) {
26 const calls: { method: string; body: any }[] = [];
27 const binding = {
28 async fetch(url: string, init: { body: string }) {
29 const method = new URL(url).pathname.replace("/rpc/", "");
30 calls.push({ method, body: JSON.parse(init.body) });
31 return Response.json(answers[method] ?? { ok: true, value: null });
32 },
33 };
34 return { binding: binding as any, calls };
35}
36
37test("the g1t adapter posts in the thread, handing on hops, asked_by and the asker's access", async () => {
38 const chat = fakeChat({ post_as_agent: { ok: true, value: { id: "msg_2" } } });
39 const id = await g1tSurface(chat.binding, delivery).post("Tagged 1.4.");
40 assert.equal(id, "msg_2");
41 const [call] = chat.calls;
42 assert.equal(call.method, "post_as_agent");
43 assert.equal(call.body.agent_id, "agt_ship");
44 assert.equal(call.body.channel_id, "chn_1");
45 assert.deepEqual(call.body.message, {
46 body: "Tagged 1.4.",
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)47 card: null,
Chat and workspace agents: channels, DMs and named agents you talk to48 thread_root: "msg_0",
49 hops: 2,
50 asked_by: "usr_dana",
51 asker: { username: "dana", role: "member", can_write: false },
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)52 chain: ["agt_g1t"],
Chat and workspace agents: channels, DMs and named agents you talk to53 });
54});
55
56test("the g1t adapter reads the thread as the agent, and leaves out deleted messages", async () => {
57 const message = (id: string, deleted: string | null) => ({
58 id,
59 channel_id: "chn_1",
60 author: { kind: "user", id: "usr_dana", name: "dana", display_name: "Dana", avatar: null, role: null },
61 kind: "text",
62 body: "hi",
63 card: null,
64 thread_root: "msg_0",
65 reply_count: 0,
66 last_reply_at: null,
67 created_at: "2026-10-08T12:00:00Z",
68 edited_at: null,
69 deleted_at: deleted,
70 });
71 const chat = fakeChat({ history_for_agent: { ok: true, value: [message("msg_0", null), message("msg_1", "2026-10-08T12:01:00Z")] } });
72 const history = await g1tSurface(chat.binding, delivery).history(30);
73 assert.deepEqual(chat.calls[0].body, { workspace: "acme", channel_id: "chn_1", agent_id: "agt_ship", thread_root: "msg_0", limit: 30 });
74 assert.deepEqual(history.map((m) => m.id), ["msg_0"]);
75 assert.equal(history[0].author.name, "dana");
76});
77
78test("a failed post is an error the reply loop records; typing never throws", async () => {
79 const chat = fakeChat({ post_as_agent: { ok: false, error: { code: "forbidden", message: "not a member" } } });
80 await assert.rejects(g1tSurface(chat.binding, delivery).post("x"), /not a member/);
81 const broken = { fetch: async () => new Response("down", { status: 500 }) } as any;
82 await g1tSurface(broken, delivery).typing();
83});
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)84
85test("reactions: in channels and group DMs, never a one-person DM", async () => {
86 const { reactsIn } = await import("./surface.ts");
87 assert.equal(reactsIn("channel", 1), true);
88 assert.equal(reactsIn("dm", 2), true);
89 assert.equal(reactsIn("dm", 1), false);
90});
91
92test("👀 when the desk picks it up, then ✅ when it answered", async () => {
93 const chat = fakeChat({ react_as_agent: { ok: true, value: [] } });
94 const surface = g1tSurface(chat.binding, delivery);
95 await surface.acknowledge();
96 await surface.settle("done");
97 const reacts = chat.calls.filter((c) => c.method === "react_as_agent").map((c) => [c.body.emoji, c.body.remove, c.body.message_id]);
98 assert.deepEqual(reacts, [
99 ["👀", false, "msg_1"],
100 ["👀", true, "msg_1"],
101 ["✅", false, "msg_1"],
102 ]);
103});
104
105test("👀 is taken back after a notice or an apology", async () => {
106 const chat = fakeChat({ react_as_agent: { ok: true, value: [] } });
107 const surface = g1tSurface(chat.binding, delivery);
108 await surface.acknowledge();
109 await surface.settle("withdrawn");
110 assert.deepEqual(chat.calls.map((c) => [c.body.emoji, c.body.remove]), [["👀", false], ["👀", true]]);
111});
112
113test("a one-person DM gets no reactions; a group DM does", async () => {
114 const dm = { ...delivery, channel_kind: "dm" as const, channel_name: null };
115 const alone = fakeChat({ audience: { ok: true, value: { kind: "dm", member_user_ids: ["usr_dana"], member_count: 1 } } });
116 const quiet = g1tSurface(alone.binding, dm);
117 await quiet.acknowledge();
118 await quiet.settle("done");
119 assert.deepEqual(alone.calls.map((c) => c.method), ["audience"]);
120 const group = fakeChat({ audience: { ok: true, value: { kind: "dm", member_user_ids: ["usr_dana", "usr_bo"], member_count: 2 } }, react_as_agent: { ok: true, value: [] } });
121 const loud = g1tSurface(group.binding, dm);
122 await loud.acknowledge();
123 assert.deepEqual(group.calls.map((c) => c.method), ["audience", "react_as_agent"]);
124});
125
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.126const profile = (kind: "user" | "agent", id: string, name: string, display_name: string, title: string | null = null) => ({ kind, id, name, display_name, avatar: null, role: kind === "agent" ? "Does things" : null, title });
127const channel = (kind: "channel" | "dm", isPrivate: boolean, name: string | null) => ({ id: "chn_1", workspace_id: "wsp_1", kind, name, topic: null, private: isPrivate, created_by: { kind: "user", id: "usr_dana" }, created_at: "", archived_at: null, last_message_at: null });
128
129test("the conversation: what kind it is and who is in it, asked as the agent with who asked", async () => {
130 const dm = fakeChat({
131 conversation_for_agent: { ok: true, value: { channel: channel("dm", true, null), members: [profile("agent", "agt_ship", "ship", "Ship"), profile("user", "usr_dana", "dana", "Dana")], people: 1, agents: 1 } },
132 });
133 const one = await g1tSurface(dm.binding, delivery).conversation();
134 assert.deepEqual(dm.calls[0].body, { workspace: "acme", channel_id: "chn_1", agent_id: "agt_ship", asked_by: "usr_dana" });
135 assert.equal(one?.kind, "dm");
136 assert.deepEqual(one?.members.map((m) => [m.kind, m.name, m.title]), [["agent", "ship", "Does things"], ["user", "dana", null]]);
137 const group = fakeChat({ conversation_for_agent: { ok: true, value: { channel: channel("dm", true, null), members: [], people: 1, agents: 2 } } });
138 assert.equal((await g1tSurface(group.binding, delivery).conversation())?.kind, "group_dm");
139 const open = fakeChat({ conversation_for_agent: { ok: true, value: { channel: channel("channel", false, "releases"), members: [], people: 300, agents: 1 } } });
140 assert.deepEqual(await g1tSurface(open.binding, delivery).conversation(), { kind: "public_channel", name: "releases", members: [], people: 300, agents: 1 });
141 const broken = { fetch: async () => new Response("down", { status: 500 }) } as any;
142 assert.equal(await g1tSurface(broken, delivery).conversation(), null, "never throws");
143});
144
145test("a hand-off goes to chat with the delivery's chain, so the colleague works for the same person", async () => {
146 const chat = fakeChat({ hand_off_as_agent: { ok: true, value: { where: "group_dm", channel_id: "chn_9", message_id: "msg_9", opened: true } } });
147 const done = await g1tSurface(chat.binding, delivery).handOff("agt_mike", "@mike draft the role brief.");
148 assert.deepEqual(done, { ok: true, where: "group_dm", opened: true });
149 assert.equal(chat.calls[0].method, "hand_off_as_agent");
150 assert.deepEqual(chat.calls[0].body, {
151 workspace: "acme",
152 channel_id: "chn_1",
153 agent_id: "agt_ship",
154 hand_off: {
155 colleague_id: "agt_mike",
156 brief: "@mike draft the role brief.",
157 thread_root: "msg_0",
158 hops: 2,
159 asked_by: "usr_dana",
160 asker: { username: "dana", role: "member", can_write: false },
161 chain: ["agt_g1t"],
162 },
163 });
164 const refused = fakeChat({ hand_off_as_agent: { ok: false, error: { code: "invalid", message: "too many times" } } });
165 assert.deepEqual(await g1tSurface(refused.binding, delivery).handOff("agt_mike", "x"), { ok: false, message: "too many times" });
166});
167
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)168test("reacting that fails never throws, and nothing is taken back that never went on", async () => {
169 const broken = { fetch: async () => new Response("down", { status: 500 }) } as any;
170 const surface = g1tSurface(broken, delivery);
171 await surface.acknowledge();
172 await surface.settle("done");
173 const refused = fakeChat({ react_as_agent: { ok: false, error: { code: "forbidden", message: "not a member" } } });
174 const s2 = g1tSurface(refused.binding, delivery);
175 await s2.acknowledge();
176 await s2.settle("done");
177 assert.equal(refused.calls.length, 1, "no ✅ or removal after a refused 👀");
178});

This file's history is long; its oldest lines are credited to the oldest commit read.