@cursor/july 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agent-serve.js +0 -0
- package/dist/channels/github/instrument.d.ts +20 -0
- package/dist/channels/github/instrument.d.ts.map +1 -0
- package/dist/channels/slack/api.d.ts +2 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +3 -0
- package/dist/channels/slack/bot-mentions.d.ts +106 -0
- package/dist/channels/slack/bot-mentions.d.ts.map +1 -0
- package/dist/channels/slack/bot-mentions.js +243 -0
- package/dist/channels/slack/dispatch.d.ts +6 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +24 -3
- package/dist/channels/slack/inbound.d.ts +10 -1
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +12 -4
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +61 -22
- package/dist/channels/slack/types.d.ts +58 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +1 -1
- package/dist/docs/ab.html +2 -2
- package/dist/docs/assets/{app.T-5ImnM3.js → app.jDxLzWv4.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DoJHJjqF.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.OMGMWH6H.js → VPLocalSearchBox.Y6bDR1-a.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DLg4yB4D.js → theme.CLazCWlJ.js} +2 -2
- package/dist/docs/building-with-agents.html +2 -2
- package/dist/docs/concepts.html +2 -2
- package/dist/docs/deployment.html +2 -2
- package/dist/docs/evals.html +2 -2
- package/dist/docs/example-agents/approval-buddy.html +2 -2
- package/dist/docs/example-agents/benny.html +2 -2
- package/dist/docs/example-agents/bugbot.html +2 -2
- package/dist/docs/example-agents/codebase-wiki.html +2 -2
- package/dist/docs/example-agents/codeowners-review.html +2 -2
- package/dist/docs/example-agents/concierge.html +2 -2
- package/dist/docs/example-agents/fsd.html +2 -2
- package/dist/docs/example-agents/index.html +2 -2
- package/dist/docs/example-agents/knowledge-base.html +2 -2
- package/dist/docs/example-agents/oncall.html +2 -2
- package/dist/docs/example-agents/security-reviewer.html +2 -2
- package/dist/docs/example-agents/slack-agent.html +2 -2
- package/dist/docs/example-agents/weather-agent.html +2 -2
- package/dist/docs/guides/agent-to-agent.html +2 -2
- package/dist/docs/guides/cloud-runtime.html +2 -2
- package/dist/docs/guides/github.html +2 -2
- package/dist/docs/guides/human-in-the-loop.html +2 -2
- package/dist/docs/guides/mcp-oauth.html +2 -2
- package/dist/docs/guides/slack.html +2 -2
- package/dist/docs/guides/webhooks.html +2 -2
- package/dist/docs/hillclimbing.html +2 -2
- package/dist/docs/index.html +2 -2
- package/dist/docs/quickstart.html +2 -2
- package/dist/docs/reference/agent-config.html +2 -2
- package/dist/docs/reference/channels.html +2 -2
- package/dist/docs/reference/cli.html +2 -2
- package/dist/docs/reference/connections.html +2 -2
- package/dist/docs/reference/hooks.html +2 -2
- package/dist/docs/reference/http-api.html +2 -2
- package/dist/docs/reference/instructions.html +2 -2
- package/dist/docs/reference/playground.html +2 -2
- package/dist/docs/reference/project-layout.html +2 -2
- package/dist/docs/reference/prompt.html +2 -2
- package/dist/docs/reference/schedules.html +2 -2
- package/dist/docs/reference/sessions.html +2 -2
- package/dist/docs/reference/skills.html +2 -2
- package/dist/docs/reference/subagents.html +2 -2
- package/dist/docs/reference/tools.html +2 -2
- package/dist/docs/scaffolding-agents.html +2 -2
- package/dist/docs/storage.html +2 -2
- package/dist/docs/troubleshooting.html +2 -2
- package/dist/internal/json-dir-store.d.ts +32 -0
- package/dist/internal/json-dir-store.d.ts.map +1 -0
- package/dist/internal/json-dir-store.js +100 -0
- package/dist/internal/resolved-connections.d.ts +1 -1
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +10 -0
- package/dist/internal/session-engine.d.ts +4 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +13 -2
- package/dist/playground/assets/index-CjOQ4hN9.css +1 -0
- package/dist/playground/assets/index-dshZQJCp.js +85 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/package.json +24 -24
- package/src/bin/agent-serve.version.test.ts +62 -0
- package/src/channels/github/api.test.ts +64 -0
- package/src/channels/github/auth.test.ts +105 -0
- package/src/channels/github/cursor-account.test.ts +204 -0
- package/src/channels/github/forward.test.ts +457 -0
- package/src/channels/github/github.test.ts +937 -0
- package/src/channels/github/replay.test.ts +179 -0
- package/src/channels/slack/api.post-message.test.ts +148 -0
- package/src/channels/slack/api.ts +5 -0
- package/src/channels/slack/approvals.test.ts +328 -0
- package/src/channels/slack/block-actions.test.ts +452 -0
- package/src/channels/slack/bot-mentions.test.ts +217 -0
- package/src/channels/slack/bot-mentions.ts +315 -0
- package/src/channels/slack/channel-watch.test.ts +363 -0
- package/src/channels/slack/cursor-account.test.ts +253 -0
- package/src/channels/slack/defaults.final-post.test.ts +182 -0
- package/src/channels/slack/dispatch.test.ts +795 -0
- package/src/channels/slack/dispatch.ts +27 -1
- package/src/channels/slack/eval-directive.test.ts +273 -0
- package/src/channels/slack/inbound.ts +25 -4
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/message-body.test.ts +54 -0
- package/src/channels/slack/nudge-store.test.ts +143 -0
- package/src/channels/slack/slack-channel.ts +66 -8
- package/src/channels/slack/slack.test.ts +391 -0
- package/src/channels/slack/stop.test.ts +23 -0
- package/src/channels/slack/thread-context.test.ts +202 -0
- package/src/channels/slack/types.ts +60 -0
- package/src/evals/assertions.test.ts +580 -0
- package/src/evals/expect.test.ts +144 -0
- package/src/evals/judge.test.ts +181 -0
- package/src/evals/loaders.test.ts +132 -0
- package/src/evals/matchers.test.ts +95 -0
- package/src/evals/reporters.test.ts +303 -0
- package/src/evals/run-facts.test.ts +259 -0
- package/src/internal/ab-snapshot.test.ts +325 -0
- package/src/internal/approval-gate.test.ts +49 -0
- package/src/internal/approvals.integration.test.ts +383 -0
- package/src/internal/authored-loaders.test.ts +31 -0
- package/src/internal/builtin-tools/reminders.test.ts +201 -0
- package/src/internal/channel-route-schema.test.ts +294 -0
- package/src/internal/chat-attach.test.ts +262 -0
- package/src/internal/cli-deploy.test.ts +1991 -0
- package/src/internal/cli-mcp.test.ts +789 -0
- package/src/internal/cli-skills.test.ts +133 -0
- package/src/internal/cli-slack.test.ts +1647 -0
- package/src/internal/cloud-merge.test.ts +74 -0
- package/src/internal/cron.test.ts +22 -0
- package/src/internal/cursor/account-mcp.test.ts +807 -0
- package/src/internal/cursor/backend-client.test.ts +591 -0
- package/src/internal/cursor/credentials.test.ts +351 -0
- package/src/internal/cursor/github-credentials.test.ts +136 -0
- package/src/internal/cursor-account-mcp-auth.test.ts +310 -0
- package/src/internal/cursor-account.integration.test.ts +441 -0
- package/src/internal/cursor-event-relay.test.ts +746 -0
- package/src/internal/cursor-github-credentials.integration.test.ts +271 -0
- package/src/internal/cursor-slack-relay.test.ts +525 -0
- package/src/internal/deploy-source.test.ts +111 -0
- package/src/internal/discovery.builtin-tools.test.ts +94 -0
- package/src/internal/discovery.concurrency.test.ts +60 -0
- package/src/internal/discovery.cursor-account.test.ts +133 -0
- package/src/internal/discovery.cwd.test.ts +83 -0
- package/src/internal/discovery.hosting.test.ts +80 -0
- package/src/internal/discovery.identity.test.ts +44 -0
- package/src/internal/docs-site.test.ts +66 -0
- package/src/internal/duration.test.ts +29 -0
- package/src/internal/eval-judge-model.test.ts +187 -0
- package/src/internal/eval-run-store.cancel.test.ts +142 -0
- package/src/internal/eval-run-store.storage.test.ts +211 -0
- package/src/internal/eval-runner.http.test.ts +403 -0
- package/src/internal/eval-runner.run.test.ts +928 -0
- package/src/internal/evals-client.test.ts +307 -0
- package/src/internal/event-mapper.test.ts +243 -0
- package/src/internal/github-fanout.test.ts +213 -0
- package/src/internal/handleAgentServeTrigger.test.ts +179 -0
- package/src/internal/host-kv.test.ts +82 -0
- package/src/internal/host-platforms.test.ts +126 -0
- package/src/internal/http-channel.test.ts +402 -0
- package/src/internal/init-project.test.ts +269 -0
- package/src/internal/install-cursor-skills.test.ts +262 -0
- package/src/internal/local-env.test.ts +100 -0
- package/src/internal/log-ring.test.ts +31 -0
- package/src/internal/logs-client.test.ts +350 -0
- package/src/internal/mcp-endpoint.test.ts +436 -0
- package/src/internal/mcp-host.test.ts +298 -0
- package/src/internal/mcp-oauth.test.ts +148 -0
- package/src/internal/net.test.ts +17 -0
- package/src/internal/peer-connections.test.ts +128 -0
- package/src/internal/peer-mcp.integration.test.ts +289 -0
- package/src/internal/playground/toolchain.test.ts +53 -0
- package/src/internal/playground-cli.test.ts +187 -0
- package/src/internal/playground-proxy.test.ts +376 -0
- package/src/internal/prompt-context.integration.test.ts +232 -0
- package/src/internal/prompt-context.test.ts +127 -0
- package/src/internal/reminder-runner.test.ts +390 -0
- package/src/internal/reminder-store.test.ts +53 -0
- package/src/internal/request-headers.test.ts +27 -0
- package/src/internal/resolve-prod-target.test.ts +787 -0
- package/src/internal/resolved-connections.test.ts +295 -0
- package/src/internal/resolved-connections.ts +18 -1
- package/src/internal/router.test.ts +57 -0
- package/src/internal/sdk-runner.test.ts +290 -0
- package/src/internal/session-engine.coalesce.test.ts +169 -0
- package/src/internal/session-engine.concurrency.test.ts +250 -0
- package/src/internal/session-engine.host-oauth-mcp.test.ts +110 -0
- package/src/internal/session-engine.interrupt.test.ts +577 -0
- package/src/internal/session-engine.storage.test.ts +547 -0
- package/src/internal/session-engine.ts +15 -1
- package/src/internal/session-urls.test.ts +28 -0
- package/src/internal/sessions-client.test.ts +518 -0
- package/src/internal/storage-coordinator.test.ts +517 -0
- package/src/internal/tool-call.test.ts +458 -0
- package/src/internal/tool-result.test.ts +52 -0
- package/src/internal/trajectory.approvals.test.ts +83 -0
- package/src/internal/trajectory.subagents.test.ts +198 -0
- package/src/internal/turn-governor.test.ts +137 -0
- package/src/internal/update-check.test.ts +485 -0
- package/src/internal/workspace.test.ts +81 -0
- package/src/storage-backends/cursor-hosted.test.ts +121 -0
- package/src/types.ts +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.CvejISXF.js +0 -1
- package/dist/playground/assets/index-CidizGZv.css +0 -1
- package/dist/playground/assets/index-CuiAKZaP.js +0 -85
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import * as slackApi from "./api.js";
|
|
3
|
+
import {
|
|
4
|
+
findLastBotMessageTs,
|
|
5
|
+
formatSlackThreadContextBlock,
|
|
6
|
+
formatSlackThreadDeltaBlock,
|
|
7
|
+
loadSlackThreadContextBlock,
|
|
8
|
+
mergeThreadMessagesByTs,
|
|
9
|
+
selectThreadDeltaMessages,
|
|
10
|
+
trimThreadMessagesForPrompt,
|
|
11
|
+
} from "./thread-context.js";
|
|
12
|
+
|
|
13
|
+
describe("formatSlackThreadContextBlock", () => {
|
|
14
|
+
it("formats parent then replies and excludes the triggering message", () => {
|
|
15
|
+
const block = formatSlackThreadContextBlock(
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
ts: "1.0",
|
|
19
|
+
bot_id: "B1",
|
|
20
|
+
username: "Datadog",
|
|
21
|
+
text: "parent alert",
|
|
22
|
+
},
|
|
23
|
+
{ ts: "2.0", user: "U1", text: "looking" },
|
|
24
|
+
{ ts: "3.0", user: "U2", text: "@jenny what happened?" },
|
|
25
|
+
],
|
|
26
|
+
{ excludeTs: "3.0" }
|
|
27
|
+
);
|
|
28
|
+
expect(block).toContain("<slack_thread>");
|
|
29
|
+
expect(block).toContain("[parent] bot:B1 (Datadog) @ 1.0:");
|
|
30
|
+
expect(block).toContain("parent alert");
|
|
31
|
+
expect(block).toContain("[reply] U1 @ 2.0:");
|
|
32
|
+
expect(block).not.toContain("what happened?");
|
|
33
|
+
expect(block).toContain("</slack_thread>");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("labels parent by thread ts even when earlier rows are filtered", () => {
|
|
37
|
+
const block = formatSlackThreadContextBlock(
|
|
38
|
+
[
|
|
39
|
+
{ ts: "1.0", user: "U1", text: "" },
|
|
40
|
+
{ ts: "2.0", user: "U2", text: "actual parent" },
|
|
41
|
+
{ ts: "3.0", user: "U3", text: "reply" },
|
|
42
|
+
],
|
|
43
|
+
{ threadTs: "2.0", excludeTs: "3.0" }
|
|
44
|
+
);
|
|
45
|
+
expect(block).toContain("[parent] U2 @ 2.0:");
|
|
46
|
+
expect(block).not.toContain("[reply] U3 @ 3.0:");
|
|
47
|
+
expect(block).not.toContain("[parent] U3");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("keeps the thread root plus the newest replies when over the limit", () => {
|
|
51
|
+
const messages = [{ ts: "1.0", user: "U0", text: "root" }];
|
|
52
|
+
for (let i = 2; i <= 60; i++) {
|
|
53
|
+
messages.push({ ts: `${i}.0`, user: "U1", text: `reply ${i}` });
|
|
54
|
+
}
|
|
55
|
+
const trimmed = trimThreadMessagesForPrompt(messages, {
|
|
56
|
+
threadTs: "1.0",
|
|
57
|
+
limit: 50,
|
|
58
|
+
});
|
|
59
|
+
expect(trimmed[0]).toMatchObject({ ts: "1.0" });
|
|
60
|
+
expect(trimmed.at(-1)).toMatchObject({ ts: "60.0" });
|
|
61
|
+
expect(trimmed).toHaveLength(50);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("returns undefined when nothing usable remains", () => {
|
|
65
|
+
expect(
|
|
66
|
+
formatSlackThreadContextBlock([{ ts: "1.0", text: "only me" }], {
|
|
67
|
+
excludeTs: "1.0",
|
|
68
|
+
})
|
|
69
|
+
).toBeUndefined();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("truncates oversized blocks", () => {
|
|
73
|
+
const block = formatSlackThreadContextBlock(
|
|
74
|
+
[
|
|
75
|
+
{
|
|
76
|
+
ts: "1.0",
|
|
77
|
+
user: "U1",
|
|
78
|
+
text: "x".repeat(500),
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
{ maxChars: 120 }
|
|
82
|
+
);
|
|
83
|
+
expect(block).toBeDefined();
|
|
84
|
+
expect(block!.length).toBeLessThanOrEqual(200);
|
|
85
|
+
expect(block).toContain("truncated");
|
|
86
|
+
expect(block).toContain("</slack_thread>");
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("thread delta helpers", () => {
|
|
91
|
+
it("finds the latest bot message ts", () => {
|
|
92
|
+
expect(
|
|
93
|
+
findLastBotMessageTs([
|
|
94
|
+
{ ts: "1.0", user: "U1", text: "human" },
|
|
95
|
+
{ ts: "1.5", bot_id: "B1", text: "bot a" },
|
|
96
|
+
{ ts: "2.0", user: "U2", text: "human 2" },
|
|
97
|
+
{ ts: "2.5", bot_id: "B1", text: "bot b" },
|
|
98
|
+
])
|
|
99
|
+
).toBe("2.5");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("restricts watermark to the agent bot when identity is provided", () => {
|
|
103
|
+
expect(
|
|
104
|
+
findLastBotMessageTs(
|
|
105
|
+
[
|
|
106
|
+
{ ts: "1.0", bot_id: "BDD", text: "datadog" },
|
|
107
|
+
{ ts: "1.5", bot_id: "BJENNY", text: "jenny" },
|
|
108
|
+
{ ts: "2.0", user: "U1", text: "human" },
|
|
109
|
+
{ ts: "2.5", bot_id: "BDD", text: "datadog again" },
|
|
110
|
+
],
|
|
111
|
+
{ botId: "BJENNY" }
|
|
112
|
+
)
|
|
113
|
+
).toBe("1.5");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("merges missing triggering ask by ts", () => {
|
|
117
|
+
const merged = mergeThreadMessagesByTs(
|
|
118
|
+
[{ ts: "1.0", user: "U0", text: "root" }],
|
|
119
|
+
[{ ts: "2.0", user: "U1", text: "lagging ask" }]
|
|
120
|
+
);
|
|
121
|
+
expect(merged.map((m) => m.ts)).toEqual(["1.0", "2.0"]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("formats slack_thread_delta after watermark", () => {
|
|
125
|
+
const delta = selectThreadDeltaMessages(
|
|
126
|
+
[
|
|
127
|
+
{ ts: "1.0", bot_id: "B1", text: "bot" },
|
|
128
|
+
{ ts: "2.0", user: "U1", text: "ask" },
|
|
129
|
+
],
|
|
130
|
+
{ afterTs: "1.0", excludeTs: "2.0" }
|
|
131
|
+
);
|
|
132
|
+
expect(delta).toHaveLength(0);
|
|
133
|
+
const block = formatSlackThreadDeltaBlock(
|
|
134
|
+
[
|
|
135
|
+
{ ts: "1.0", bot_id: "B1", text: "bot" },
|
|
136
|
+
{ ts: "2.0", user: "U1", text: "ask" },
|
|
137
|
+
{ ts: "3.0", user: "U2", text: "more" },
|
|
138
|
+
],
|
|
139
|
+
{ afterTs: "1.0", excludeTs: "2.0" }
|
|
140
|
+
);
|
|
141
|
+
expect(block).toContain("<slack_thread_delta>");
|
|
142
|
+
expect(block).toContain("more");
|
|
143
|
+
expect(block).not.toContain("ask");
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("loadSlackThreadContextBlock", () => {
|
|
148
|
+
it("soft-fails without a bot token", async () => {
|
|
149
|
+
await expect(
|
|
150
|
+
loadSlackThreadContextBlock({
|
|
151
|
+
botToken: undefined,
|
|
152
|
+
channelId: "C1",
|
|
153
|
+
threadTs: "1.0",
|
|
154
|
+
})
|
|
155
|
+
).resolves.toBeUndefined();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("calls conversations.replies and formats the result", async () => {
|
|
159
|
+
const spy = vi.spyOn(slackApi, "callSlackApiSoft").mockResolvedValue({
|
|
160
|
+
ok: true,
|
|
161
|
+
messages: [
|
|
162
|
+
{ ts: "1.0", user: "Ubot", text: "alert body" },
|
|
163
|
+
{ ts: "2.0", user: "U1", text: "mention" },
|
|
164
|
+
],
|
|
165
|
+
has_more: false,
|
|
166
|
+
});
|
|
167
|
+
const block = await loadSlackThreadContextBlock({
|
|
168
|
+
botToken: "xoxb-test",
|
|
169
|
+
channelId: "C1",
|
|
170
|
+
threadTs: "1.0",
|
|
171
|
+
excludeTs: "2.0",
|
|
172
|
+
});
|
|
173
|
+
expect(spy).toHaveBeenCalledWith(
|
|
174
|
+
expect.objectContaining({
|
|
175
|
+
operation: "conversations.replies",
|
|
176
|
+
body: expect.objectContaining({
|
|
177
|
+
channel: "C1",
|
|
178
|
+
ts: "1.0",
|
|
179
|
+
inclusive: true,
|
|
180
|
+
}),
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
expect(block).toContain("alert body");
|
|
184
|
+
expect(block).not.toContain("mention");
|
|
185
|
+
spy.mockRestore();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("soft-fails when Slack returns not-ok", async () => {
|
|
189
|
+
const spy = vi.spyOn(slackApi, "callSlackApiSoft").mockResolvedValue({
|
|
190
|
+
ok: false,
|
|
191
|
+
error: "channel_not_found",
|
|
192
|
+
});
|
|
193
|
+
await expect(
|
|
194
|
+
loadSlackThreadContextBlock({
|
|
195
|
+
botToken: "xoxb-test",
|
|
196
|
+
channelId: "C1",
|
|
197
|
+
threadTs: "1.0",
|
|
198
|
+
})
|
|
199
|
+
).resolves.toBeUndefined();
|
|
200
|
+
spy.mockRestore();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
@@ -88,6 +88,21 @@ export interface SlackAuthor {
|
|
|
88
88
|
botId?: string;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Delegation metadata carried on bot-to-bot mention posts (Slack message
|
|
93
|
+
* `metadata`, event type {@link SLACK_DELEGATION_METADATA_EVENT_TYPE}).
|
|
94
|
+
* Absent on posts from bots that don't speak the protocol — the gate then
|
|
95
|
+
* treats the mention as depth 1.
|
|
96
|
+
*/
|
|
97
|
+
export interface SlackDelegationInfo {
|
|
98
|
+
/** Delegation hop count. A dispatcher woken by a human posts depth 1. */
|
|
99
|
+
depth: number;
|
|
100
|
+
/** Mount slug / display name of the delegating agent. */
|
|
101
|
+
fromAgent?: string;
|
|
102
|
+
/** Session id on the delegating agent, for cross-agent tracing. */
|
|
103
|
+
originSessionId?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
91
106
|
export interface SlackMessage {
|
|
92
107
|
/** Raw top-level `text` exactly as Slack sent it. Often empty on bot posts. */
|
|
93
108
|
text: string;
|
|
@@ -105,6 +120,8 @@ export interface SlackMessage {
|
|
|
105
120
|
channelId: string;
|
|
106
121
|
teamId?: string;
|
|
107
122
|
author?: SlackAuthor;
|
|
123
|
+
/** Parsed delegation metadata when the post carried it (bot mentions). */
|
|
124
|
+
delegation?: SlackDelegationInfo;
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
export interface SlackDispatchDecision {
|
|
@@ -298,6 +315,44 @@ export interface SlackChannelPostsOptions {
|
|
|
298
315
|
includeBotPosts?: boolean;
|
|
299
316
|
}
|
|
300
317
|
|
|
318
|
+
/**
|
|
319
|
+
* Opt-in bot-to-bot mention wake: allow @mentions authored by explicitly
|
|
320
|
+
* trusted bots (e.g. a dispatcher agent) to dispatch like human mentions.
|
|
321
|
+
* Default off — bot-authored mentions are dropped (loop safety). There is
|
|
322
|
+
* deliberately no "any bot" wildcard; trusting a bot is a per-bot decision.
|
|
323
|
+
*
|
|
324
|
+
* Loop protection is layered: this allowlist, the always-on own-post
|
|
325
|
+
* filter, a delegation-depth budget (Slack message metadata), and a
|
|
326
|
+
* per-thread wake budget.
|
|
327
|
+
*/
|
|
328
|
+
export interface SlackBotMentionsOptions {
|
|
329
|
+
/**
|
|
330
|
+
* Bots whose mentions may wake this agent: `bot_id`s (`B…`) and/or bot
|
|
331
|
+
* *user* ids (`U…`). Must be non-empty (empty is a definition error).
|
|
332
|
+
*/
|
|
333
|
+
allowFrom: string[];
|
|
334
|
+
/**
|
|
335
|
+
* Maximum delegation depth admitted (from the mention's delegation
|
|
336
|
+
* metadata; mentions without metadata count as depth 1). Defaults to 2 —
|
|
337
|
+
* human → dispatcher → specialist, no deeper chains.
|
|
338
|
+
*/
|
|
339
|
+
maxDepth?: number;
|
|
340
|
+
/**
|
|
341
|
+
* Maximum bot-initiated wakes per thread per hour (sliding window).
|
|
342
|
+
* Defaults to 5. Rate-limits ping-pong between bots that carry no
|
|
343
|
+
* delegation metadata; termination comes from {@link maxPerThreadTotal}.
|
|
344
|
+
*/
|
|
345
|
+
maxPerThreadPerHour?: number;
|
|
346
|
+
/**
|
|
347
|
+
* Lifetime cap on bot-initiated wakes per thread (resets only after the
|
|
348
|
+
* thread has been idle for 24h). Defaults to 20. This is the terminating
|
|
349
|
+
* backstop: a sliding window alone refills, so two mutually-allowlisted
|
|
350
|
+
* bots could ping-pong forever at the rate cap. Avoid mutual allowlists
|
|
351
|
+
* regardless — keep the delegation graph a DAG.
|
|
352
|
+
*/
|
|
353
|
+
maxPerThreadTotal?: number;
|
|
354
|
+
}
|
|
355
|
+
|
|
301
356
|
/**
|
|
302
357
|
* How the agent engages over Slack. Omitted entirely = mentions + DMs,
|
|
303
358
|
* which is also the default for each flag — summoned, never proactive.
|
|
@@ -313,6 +368,11 @@ export interface SlackEngagementOptions {
|
|
|
313
368
|
* (`slack init --channel-posts`, or add the events to an existing app).
|
|
314
369
|
*/
|
|
315
370
|
channelPosts?: SlackChannelPostsOptions;
|
|
371
|
+
/**
|
|
372
|
+
* Opt-in bot-to-bot mention wake (see {@link SlackBotMentionsOptions}).
|
|
373
|
+
* Socket Mode only — rejected on `cursorAccount: true`.
|
|
374
|
+
*/
|
|
375
|
+
botMentions?: SlackBotMentionsOptions;
|
|
316
376
|
}
|
|
317
377
|
|
|
318
378
|
/**
|