@cursor/july 0.1.6 → 0.1.8

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.
Files changed (179) hide show
  1. package/dist/bin/agent-serve.js +73 -19
  2. package/dist/channels/slack/channel-watch.d.ts +6 -1
  3. package/dist/channels/slack/channel-watch.d.ts.map +1 -1
  4. package/dist/channels/slack/channel-watch.js +22 -1
  5. package/dist/channels/slack/cursor-account.d.ts +4 -0
  6. package/dist/channels/slack/cursor-account.d.ts.map +1 -1
  7. package/dist/channels/slack/cursor-account.js +12 -2
  8. package/dist/channels/slack/defaults.d.ts +10 -5
  9. package/dist/channels/slack/defaults.d.ts.map +1 -1
  10. package/dist/channels/slack/defaults.js +39 -17
  11. package/dist/channels/slack/dispatch.d.ts +18 -0
  12. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  13. package/dist/channels/slack/dispatch.js +141 -38
  14. package/dist/channels/slack/inbound.d.ts +13 -3
  15. package/dist/channels/slack/inbound.d.ts.map +1 -1
  16. package/dist/channels/slack/inbound.js +17 -9
  17. package/dist/channels/slack/index.d.ts +4 -0
  18. package/dist/channels/slack/index.d.ts.map +1 -1
  19. package/dist/channels/slack/index.js +4 -0
  20. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  21. package/dist/channels/slack/live-delivery.js +1 -0
  22. package/dist/channels/slack/manifest.d.ts.map +1 -1
  23. package/dist/channels/slack/manifest.js +3 -0
  24. package/dist/channels/slack/nudge-carrier.d.ts +19 -0
  25. package/dist/channels/slack/nudge-carrier.d.ts.map +1 -0
  26. package/dist/channels/slack/nudge-carrier.js +166 -0
  27. package/dist/channels/slack/nudge-store.d.ts +61 -0
  28. package/dist/channels/slack/nudge-store.d.ts.map +1 -0
  29. package/dist/channels/slack/nudge-store.js +266 -0
  30. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  31. package/dist/channels/slack/slack-channel.js +74 -25
  32. package/dist/channels/slack/stop.d.ts +14 -0
  33. package/dist/channels/slack/stop.d.ts.map +1 -0
  34. package/dist/channels/slack/stop.js +22 -0
  35. package/dist/channels/slack/thread-context.d.ts +81 -0
  36. package/dist/channels/slack/thread-context.d.ts.map +1 -0
  37. package/dist/channels/slack/thread-context.js +470 -0
  38. package/dist/channels/slack/types.d.ts +27 -0
  39. package/dist/channels/slack/types.d.ts.map +1 -1
  40. package/dist/docs/404.html +2 -2
  41. package/dist/docs/ab.html +4 -4
  42. package/dist/docs/assets/{app.DMboGKUD.js → app.BP8mAVMW.js} +1 -1
  43. package/dist/docs/assets/chunks/@localSearchIndexroot.DevOabKJ.js +1 -0
  44. package/dist/docs/assets/chunks/{VPLocalSearchBox.DkEqEnJU.js → VPLocalSearchBox.1FXIZbz8.js} +1 -1
  45. package/dist/docs/assets/chunks/{theme.ASugdMNm.js → theme.Dm1R02v9.js} +2 -2
  46. package/dist/docs/assets/example-agents_index.md.CwtWu5ix.js +2 -0
  47. package/dist/docs/assets/{example-agents_index.md.CRqJlnIf.lean.js → example-agents_index.md.CwtWu5ix.lean.js} +1 -1
  48. package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +10 -0
  49. package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.lean.js +1 -0
  50. package/dist/docs/assets/{guides_slack.md.CCwqHvSV.js → guides_slack.md.FWale6Ip.js} +4 -3
  51. package/dist/docs/assets/{guides_slack.md.CCwqHvSV.lean.js → guides_slack.md.FWale6Ip.lean.js} +1 -1
  52. package/dist/docs/assets/{reference_sessions.md.DdjWabnN.js → reference_sessions.md.DLd6mvbv.js} +2 -2
  53. package/dist/docs/assets/{reference_sessions.md.DdjWabnN.lean.js → reference_sessions.md.DLd6mvbv.lean.js} +1 -1
  54. package/dist/docs/assets/{storage.md.CVnInNiN.js → storage.md.Cu3MwM2a.js} +3 -2
  55. package/dist/docs/assets/{storage.md.CVnInNiN.lean.js → storage.md.Cu3MwM2a.lean.js} +1 -1
  56. package/dist/docs/building-with-agents.html +4 -4
  57. package/dist/docs/concepts.html +4 -4
  58. package/dist/docs/deployment.html +4 -4
  59. package/dist/docs/evals.html +4 -4
  60. package/dist/docs/example-agents/approval-buddy.html +4 -4
  61. package/dist/docs/example-agents/benny.html +5 -5
  62. package/dist/docs/example-agents/bugbot.html +5 -5
  63. package/dist/docs/example-agents/codebase-wiki.html +4 -4
  64. package/dist/docs/example-agents/codeowners-review.html +4 -4
  65. package/dist/docs/example-agents/concierge.html +4 -4
  66. package/dist/docs/example-agents/fsd.html +4 -4
  67. package/dist/docs/example-agents/index.html +6 -6
  68. package/dist/docs/example-agents/knowledge-base.html +4 -4
  69. package/dist/docs/example-agents/oncall.html +34 -0
  70. package/dist/docs/example-agents/security-reviewer.html +4 -4
  71. package/dist/docs/example-agents/slack-agent.html +4 -4
  72. package/dist/docs/example-agents/weather-agent.html +4 -4
  73. package/dist/docs/guides/agent-to-agent.html +4 -4
  74. package/dist/docs/guides/cloud-runtime.html +4 -4
  75. package/dist/docs/guides/github.html +4 -4
  76. package/dist/docs/guides/human-in-the-loop.html +4 -4
  77. package/dist/docs/guides/slack.html +7 -6
  78. package/dist/docs/guides/webhooks.html +4 -4
  79. package/dist/docs/hashmap.json +1 -1
  80. package/dist/docs/hillclimbing.html +4 -4
  81. package/dist/docs/index.html +4 -4
  82. package/dist/docs/quickstart.html +4 -4
  83. package/dist/docs/reference/agent-config.html +4 -4
  84. package/dist/docs/reference/channels.html +4 -4
  85. package/dist/docs/reference/cli.html +4 -4
  86. package/dist/docs/reference/connections.html +4 -4
  87. package/dist/docs/reference/hooks.html +4 -4
  88. package/dist/docs/reference/http-api.html +4 -4
  89. package/dist/docs/reference/instructions.html +4 -4
  90. package/dist/docs/reference/playground.html +4 -4
  91. package/dist/docs/reference/project-layout.html +4 -4
  92. package/dist/docs/reference/schedules.html +4 -4
  93. package/dist/docs/reference/sessions.html +5 -5
  94. package/dist/docs/reference/skills.html +4 -4
  95. package/dist/docs/reference/subagents.html +4 -4
  96. package/dist/docs/reference/tools.html +4 -4
  97. package/dist/docs/scaffolding-agents.html +4 -4
  98. package/dist/docs/storage.html +7 -6
  99. package/dist/docs/troubleshooting.html +4 -4
  100. package/dist/evals.d.ts +2 -2
  101. package/dist/internal/cli-ax.d.ts +23 -10
  102. package/dist/internal/cli-ax.d.ts.map +1 -1
  103. package/dist/internal/cli-ax.js +358 -55
  104. package/dist/internal/cli-mcp.d.ts +64 -0
  105. package/dist/internal/cli-mcp.d.ts.map +1 -0
  106. package/dist/internal/cli-mcp.js +570 -0
  107. package/dist/internal/distribution.d.ts.map +1 -1
  108. package/dist/internal/distribution.js +2 -0
  109. package/dist/internal/eval-run-store.d.ts +2 -0
  110. package/dist/internal/eval-run-store.d.ts.map +1 -1
  111. package/dist/internal/eval-run-store.js +4 -4
  112. package/dist/internal/evals-client.d.ts +96 -0
  113. package/dist/internal/evals-client.d.ts.map +1 -0
  114. package/dist/internal/evals-client.js +262 -0
  115. package/dist/internal/host-kv.d.ts +17 -0
  116. package/dist/internal/host-kv.d.ts.map +1 -0
  117. package/dist/internal/host-kv.js +77 -0
  118. package/dist/internal/init-project.js +3 -3
  119. package/dist/internal/server.d.ts.map +1 -1
  120. package/dist/internal/server.js +19 -2
  121. package/dist/internal/session-engine.d.ts +42 -7
  122. package/dist/internal/session-engine.d.ts.map +1 -1
  123. package/dist/internal/session-engine.js +247 -51
  124. package/dist/internal/storage-coordinator.d.ts +18 -1
  125. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  126. package/dist/internal/storage-coordinator.js +43 -0
  127. package/dist/playground/assets/index-Bpr4Th4M.js +319 -0
  128. package/dist/playground/index.html +1 -1
  129. package/dist/storage-backends/file-kv.d.ts +42 -0
  130. package/dist/storage-backends/file-kv.d.ts.map +1 -0
  131. package/dist/storage-backends/file-kv.js +190 -0
  132. package/dist/storage-backends/postgres-kv.d.ts +77 -0
  133. package/dist/storage-backends/postgres-kv.d.ts.map +1 -0
  134. package/dist/storage-backends/postgres-kv.js +180 -0
  135. package/dist/storage.d.ts +10 -1
  136. package/dist/storage.d.ts.map +1 -1
  137. package/dist/storage.js +10 -1
  138. package/dist/types.d.ts +79 -0
  139. package/dist/types.d.ts.map +1 -1
  140. package/docs/example-agents/index.md +14 -9
  141. package/docs/example-agents/oncall.md +216 -0
  142. package/docs/guides/slack.md +11 -2
  143. package/docs/reference/sessions.md +13 -4
  144. package/docs/storage.md +27 -0
  145. package/package.json +15 -1
  146. package/skills/framework-map/SKILL.md +6 -4
  147. package/src/bin/agent-serve.ts +79 -18
  148. package/src/channels/slack/channel-watch.ts +28 -1
  149. package/src/channels/slack/cursor-account.ts +20 -0
  150. package/src/channels/slack/defaults.ts +51 -20
  151. package/src/channels/slack/dispatch.ts +215 -40
  152. package/src/channels/slack/inbound.ts +30 -10
  153. package/src/channels/slack/index.ts +4 -0
  154. package/src/channels/slack/live-delivery.ts +1 -0
  155. package/src/channels/slack/manifest.ts +3 -0
  156. package/src/channels/slack/nudge-carrier.ts +182 -0
  157. package/src/channels/slack/nudge-store.ts +308 -0
  158. package/src/channels/slack/slack-channel.ts +106 -31
  159. package/src/channels/slack/stop.ts +25 -0
  160. package/src/channels/slack/thread-context.ts +572 -0
  161. package/src/channels/slack/types.ts +27 -0
  162. package/src/evals.ts +2 -2
  163. package/src/internal/cli-ax.ts +466 -75
  164. package/src/internal/cli-mcp.ts +708 -0
  165. package/src/internal/distribution.ts +2 -0
  166. package/src/internal/eval-run-store.ts +5 -0
  167. package/src/internal/evals-client.ts +431 -0
  168. package/src/internal/host-kv.ts +85 -0
  169. package/src/internal/init-project.ts +3 -3
  170. package/src/internal/server.ts +43 -0
  171. package/src/internal/session-engine.ts +351 -50
  172. package/src/internal/storage-coordinator.ts +41 -0
  173. package/src/storage-backends/file-kv.ts +221 -0
  174. package/src/storage-backends/postgres-kv.ts +248 -0
  175. package/src/storage.ts +11 -1
  176. package/src/types.ts +83 -0
  177. package/dist/docs/assets/chunks/@localSearchIndexroot.O6eP7QZr.js +0 -1
  178. package/dist/docs/assets/example-agents_index.md.CRqJlnIf.js +0 -2
  179. package/dist/playground/assets/index-mux9aj5P.js +0 -319
@@ -0,0 +1,96 @@
1
+ /**
2
+ * HTTP client for playground eval batches (`/v1/dev/evals/runs`).
3
+ *
4
+ * Used by `agentkit eval --prod` (or `--url`) so the batch runs on the serve
5
+ * process and is mirrored to `defineStorage` when an `evals` table is
6
+ * configured. Without those flags, eval keeps the in-process ephemeral path
7
+ * in `cli-ax.ts`.
8
+ */
9
+ import type { EvalRunSnapshot } from "../evals.js";
10
+ import type { EvalRunResult } from "./eval-runner.js";
11
+ import { type RequestAuth } from "./request-headers.js";
12
+ export type RemoteEvalErrorCode = "no_matching_evals" | "eval_run_in_progress" | "unknown_eval_run" | "start_failed" | "poll_failed" | "aborted";
13
+ export declare class RemoteEvalError extends Error {
14
+ readonly status?: number | undefined;
15
+ readonly code?: RemoteEvalErrorCode | undefined;
16
+ readonly activeRunId?: string | undefined;
17
+ constructor(message: string, status?: number | undefined, code?: RemoteEvalErrorCode | undefined, activeRunId?: string | undefined);
18
+ }
19
+ export interface RemoteEvalListItem {
20
+ id: string;
21
+ fileId: string;
22
+ description?: string;
23
+ tags?: string[];
24
+ }
25
+ export interface RunRemoteEvalsOptions extends RequestAuth {
26
+ baseUrl: string;
27
+ filterIds?: string[];
28
+ tags?: string[];
29
+ /** Per-case timeout override forwarded to the serve process. */
30
+ timeoutMs?: number;
31
+ /** Ask the serve harness to emit verbose case logs (server-side). */
32
+ verbose?: boolean;
33
+ fetchImpl?: typeof fetch;
34
+ /** Poll interval while the batch is `running`. */
35
+ pollMs?: number;
36
+ /** Abort the wait (not the remote batch). */
37
+ signal?: AbortSignal;
38
+ /** Called each time the polled snapshot changes. */
39
+ onSnapshot?: (snap: EvalRunSnapshot) => void;
40
+ }
41
+ /**
42
+ * Start a batch on the target serve via `POST /v1/dev/evals/runs`, poll until
43
+ * terminal, and return CLI-shaped case results.
44
+ */
45
+ export declare function runRemoteEvals(options: RunRemoteEvalsOptions): Promise<{
46
+ snapshot: EvalRunSnapshot;
47
+ results: EvalRunResult[];
48
+ }>;
49
+ /** List datapoints from `GET /v1/dev/evals` (same surface a remote run uses). */
50
+ export declare function listRemoteEvals(args: {
51
+ baseUrl: string;
52
+ auth?: RequestAuth;
53
+ fetchImpl?: typeof fetch;
54
+ filterIds?: string[];
55
+ tags?: string[];
56
+ signal?: AbortSignal;
57
+ }): Promise<RemoteEvalListItem[]>;
58
+ export declare function startRemoteEvalRun(args: {
59
+ baseUrl: string;
60
+ auth?: RequestAuth;
61
+ fetchImpl?: typeof fetch;
62
+ filterIds?: string[];
63
+ tags?: string[];
64
+ timeoutMs?: number;
65
+ verbose?: boolean;
66
+ signal?: AbortSignal;
67
+ }): Promise<EvalRunSnapshot>;
68
+ /** One-shot `GET /v1/dev/evals/runs/:runId` (no polling). */
69
+ export declare function getRemoteEvalRun(args: {
70
+ baseUrl: string;
71
+ runId: string;
72
+ auth?: RequestAuth;
73
+ fetchImpl?: typeof fetch;
74
+ signal?: AbortSignal;
75
+ }): Promise<EvalRunSnapshot>;
76
+ /** Recent batches from `GET /v1/dev/evals/runs`. */
77
+ export declare function listRemoteEvalRuns(args: {
78
+ baseUrl: string;
79
+ auth?: RequestAuth;
80
+ fetchImpl?: typeof fetch;
81
+ signal?: AbortSignal;
82
+ }): Promise<{
83
+ runs: EvalRunSnapshot[];
84
+ activeRunId?: string;
85
+ }>;
86
+ export declare function pollRemoteEvalRun(args: {
87
+ baseUrl: string;
88
+ runId: string;
89
+ auth?: RequestAuth;
90
+ fetchImpl?: typeof fetch;
91
+ pollMs?: number;
92
+ signal?: AbortSignal;
93
+ onSnapshot?: (snap: EvalRunSnapshot) => void;
94
+ }): Promise<EvalRunSnapshot>;
95
+ export declare function snapshotToEvalRunResults(snapshot: EvalRunSnapshot): EvalRunResult[];
96
+ //# sourceMappingURL=evals-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evals-client.d.ts","sourceRoot":"","sources":["../../src/internal/evals-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,262 @@
1
+ /**
2
+ * HTTP client for playground eval batches (`/v1/dev/evals/runs`).
3
+ *
4
+ * Used by `agentkit eval --prod` (or `--url`) so the batch runs on the serve
5
+ * process and is mirrored to `defineStorage` when an `evals` table is
6
+ * configured. Without those flags, eval keeps the in-process ephemeral path
7
+ * in `cli-ax.ts`.
8
+ */
9
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
10
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
11
+ return new (P || (P = Promise))(function (resolve, reject) {
12
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
13
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
14
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
15
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
16
+ });
17
+ };
18
+ import { matchesEvalIdFilter } from "../evals.js";
19
+ import { mergeRequestHeaders } from "./request-headers.js";
20
+ const DEFAULT_POLL_MS = 1000;
21
+ export class RemoteEvalError extends Error {
22
+ constructor(message, status, code, activeRunId) {
23
+ super(message);
24
+ this.status = status;
25
+ this.code = code;
26
+ this.activeRunId = activeRunId;
27
+ this.name = "RemoteEvalError";
28
+ }
29
+ }
30
+ /**
31
+ * Start a batch on the target serve via `POST /v1/dev/evals/runs`, poll until
32
+ * terminal, and return CLI-shaped case results.
33
+ */
34
+ export function runRemoteEvals(options) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ var _a;
37
+ var _b, _c;
38
+ const baseUrl = options.baseUrl.replace(/\/$/, "");
39
+ const fetchImpl = (_b = options.fetchImpl) !== null && _b !== void 0 ? _b : fetch;
40
+ const auth = {
41
+ bearerToken: options.bearerToken,
42
+ headers: options.headers,
43
+ };
44
+ const started = yield startRemoteEvalRun({
45
+ baseUrl,
46
+ auth,
47
+ fetchImpl,
48
+ filterIds: options.filterIds,
49
+ tags: options.tags,
50
+ timeoutMs: options.timeoutMs,
51
+ verbose: options.verbose,
52
+ signal: options.signal,
53
+ });
54
+ (_a = options.onSnapshot) === null || _a === void 0 ? void 0 : _a.call(options, started);
55
+ const snapshot = yield pollRemoteEvalRun({
56
+ baseUrl,
57
+ runId: started.runId,
58
+ auth,
59
+ fetchImpl,
60
+ pollMs: (_c = options.pollMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_MS,
61
+ signal: options.signal,
62
+ onSnapshot: options.onSnapshot,
63
+ });
64
+ return { snapshot, results: snapshotToEvalRunResults(snapshot) };
65
+ });
66
+ }
67
+ /** List datapoints from `GET /v1/dev/evals` (same surface a remote run uses). */
68
+ export function listRemoteEvals(args) {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ var _a, _b;
71
+ const baseUrl = args.baseUrl.replace(/\/$/, "");
72
+ const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
73
+ let resp;
74
+ try {
75
+ resp = yield fetchImpl(`${baseUrl}/v1/dev/evals`, {
76
+ headers: mergeRequestHeaders(args.auth),
77
+ signal: args.signal,
78
+ });
79
+ }
80
+ catch (error) {
81
+ throw new RemoteEvalError(error instanceof Error ? error.message : "Could not list evals.", undefined, "start_failed");
82
+ }
83
+ if (!resp.ok) {
84
+ throw new RemoteEvalError(`Could not list evals (HTTP ${resp.status}).`, resp.status, "start_failed");
85
+ }
86
+ const body = (yield resp.json());
87
+ const listed = [];
88
+ for (const row of (_b = body.evals) !== null && _b !== void 0 ? _b : []) {
89
+ if (typeof row.id !== "string" || row.id === "") {
90
+ continue;
91
+ }
92
+ if (typeof row.fileId !== "string" || row.fileId === "") {
93
+ continue;
94
+ }
95
+ const tags = Array.isArray(row.tags)
96
+ ? row.tags.filter((t) => typeof t === "string")
97
+ : undefined;
98
+ listed.push(Object.assign(Object.assign({ id: row.id, fileId: row.fileId }, (typeof row.description === "string"
99
+ ? { description: row.description }
100
+ : {})), (tags === undefined || tags.length === 0 ? {} : { tags })));
101
+ }
102
+ let selected = listed;
103
+ if (args.filterIds !== undefined && args.filterIds.length > 0) {
104
+ selected = selected.filter((e) => args.filterIds.some((f) => matchesEvalIdFilter(e.id, f)));
105
+ }
106
+ if (args.tags !== undefined && args.tags.length > 0) {
107
+ selected = selected.filter((e) => { var _a; return ((_a = e.tags) !== null && _a !== void 0 ? _a : []).some((t) => args.tags.includes(t)); });
108
+ }
109
+ return selected;
110
+ });
111
+ }
112
+ export function startRemoteEvalRun(args) {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ var _a;
115
+ const baseUrl = args.baseUrl.replace(/\/$/, "");
116
+ const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
117
+ const body = {};
118
+ if (args.filterIds !== undefined && args.filterIds.length > 0) {
119
+ body.filterIds = args.filterIds;
120
+ }
121
+ if (args.tags !== undefined && args.tags.length > 0) {
122
+ body.tags = args.tags;
123
+ }
124
+ if (args.timeoutMs !== undefined) {
125
+ body.timeoutMs = args.timeoutMs;
126
+ }
127
+ if (args.verbose === true) {
128
+ body.verbose = true;
129
+ }
130
+ let resp;
131
+ try {
132
+ resp = yield fetchImpl(`${baseUrl}/v1/dev/evals/runs`, {
133
+ method: "POST",
134
+ headers: Object.assign({ "content-type": "application/json" }, mergeRequestHeaders(args.auth)),
135
+ body: JSON.stringify(body),
136
+ signal: args.signal,
137
+ });
138
+ }
139
+ catch (error) {
140
+ throw new RemoteEvalError(error instanceof Error ? error.message : "Could not start eval run.", undefined, "start_failed");
141
+ }
142
+ const json = (yield resp.json().catch(() => ({})));
143
+ if (json.error === "no_matching_evals") {
144
+ throw new RemoteEvalError("No matching evals found.", 404, "no_matching_evals");
145
+ }
146
+ if (resp.status === 409 || json.error === "eval_run_in_progress") {
147
+ throw new RemoteEvalError(json.activeRunId !== undefined && json.activeRunId !== ""
148
+ ? `An eval run is already in progress (${json.activeRunId}).`
149
+ : "An eval run is already in progress.", 409, "eval_run_in_progress", typeof json.activeRunId === "string" ? json.activeRunId : undefined);
150
+ }
151
+ if (!resp.ok) {
152
+ const detail = typeof json.message === "string" && json.message !== ""
153
+ ? json.message
154
+ : typeof json.error === "string" && json.error !== ""
155
+ ? json.error
156
+ : `HTTP ${resp.status}`;
157
+ throw new RemoteEvalError(`Could not start eval run: ${detail}`, resp.status, "start_failed");
158
+ }
159
+ if (typeof json.runId !== "string" || json.runId === "") {
160
+ throw new RemoteEvalError("Eval start response missing runId.", undefined, "start_failed");
161
+ }
162
+ return json;
163
+ });
164
+ }
165
+ /** One-shot `GET /v1/dev/evals/runs/:runId` (no polling). */
166
+ export function getRemoteEvalRun(args) {
167
+ return __awaiter(this, void 0, void 0, function* () {
168
+ var _a;
169
+ const baseUrl = args.baseUrl.replace(/\/$/, "");
170
+ const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
171
+ let resp;
172
+ try {
173
+ resp = yield fetchImpl(`${baseUrl}/v1/dev/evals/runs/${encodeURIComponent(args.runId)}`, {
174
+ headers: mergeRequestHeaders(args.auth),
175
+ signal: args.signal,
176
+ });
177
+ }
178
+ catch (error) {
179
+ throw new RemoteEvalError(error instanceof Error ? error.message : "Could not fetch eval run.", undefined, "poll_failed");
180
+ }
181
+ if (resp.status === 404) {
182
+ throw new RemoteEvalError(`Unknown eval run ${args.runId}.`, 404, "unknown_eval_run");
183
+ }
184
+ if (!resp.ok) {
185
+ throw new RemoteEvalError(`Could not fetch eval run (HTTP ${resp.status}).`, resp.status, "poll_failed");
186
+ }
187
+ return (yield resp.json());
188
+ });
189
+ }
190
+ /** Recent batches from `GET /v1/dev/evals/runs`. */
191
+ export function listRemoteEvalRuns(args) {
192
+ return __awaiter(this, void 0, void 0, function* () {
193
+ var _a;
194
+ const baseUrl = args.baseUrl.replace(/\/$/, "");
195
+ const fetchImpl = (_a = args.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
196
+ let resp;
197
+ try {
198
+ resp = yield fetchImpl(`${baseUrl}/v1/dev/evals/runs`, {
199
+ headers: mergeRequestHeaders(args.auth),
200
+ signal: args.signal,
201
+ });
202
+ }
203
+ catch (error) {
204
+ throw new RemoteEvalError(error instanceof Error ? error.message : "Could not list eval runs.", undefined, "poll_failed");
205
+ }
206
+ if (!resp.ok) {
207
+ throw new RemoteEvalError(`Could not list eval runs (HTTP ${resp.status}).`, resp.status, "poll_failed");
208
+ }
209
+ const body = (yield resp.json());
210
+ const runs = Array.isArray(body.runs)
211
+ ? body.runs.filter((r) => r !== null &&
212
+ typeof r === "object" &&
213
+ typeof r.runId === "string")
214
+ : [];
215
+ return Object.assign({ runs }, (typeof body.activeRunId === "string" && body.activeRunId !== ""
216
+ ? { activeRunId: body.activeRunId }
217
+ : {}));
218
+ });
219
+ }
220
+ export function pollRemoteEvalRun(args) {
221
+ return __awaiter(this, void 0, void 0, function* () {
222
+ var _a, _b;
223
+ var _c;
224
+ const pollMs = (_c = args.pollMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_MS;
225
+ let lastJson = "";
226
+ for (;;) {
227
+ if (((_a = args.signal) === null || _a === void 0 ? void 0 : _a.aborted) === true) {
228
+ throw new RemoteEvalError("Eval wait aborted.", undefined, "aborted");
229
+ }
230
+ const snap = yield getRemoteEvalRun(args);
231
+ const serialized = JSON.stringify(snap);
232
+ if (serialized !== lastJson) {
233
+ lastJson = serialized;
234
+ (_b = args.onSnapshot) === null || _b === void 0 ? void 0 : _b.call(args, snap);
235
+ }
236
+ if (snap.status !== "running") {
237
+ return snap;
238
+ }
239
+ yield sleep(pollMs, args.signal);
240
+ }
241
+ });
242
+ }
243
+ export function snapshotToEvalRunResults(snapshot) {
244
+ return snapshot.cases.map((c) => { var _a, _b, _c, _d; return (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ id: c.id, path: c.fileId }, (c.description === undefined ? {} : { description: c.description })), { ok: c.ok === true, assertions: (_a = c.assertions) !== null && _a !== void 0 ? _a : [] }), (c.sessionId === undefined ? {} : { sessionId: c.sessionId })), { inputs: (_b = c.inputs) !== null && _b !== void 0 ? _b : [] }), (c.finalText === undefined ? {} : { finalText: c.finalText })), (c.tools === undefined ? {} : { tools: c.tools })), (c.toolCalls === undefined ? {} : { toolCalls: c.toolCalls })), (c.error === undefined ? {} : { error: c.error })), { logs: (_c = c.logs) !== null && _c !== void 0 ? _c : [], durationMs: (_d = c.durationMs) !== null && _d !== void 0 ? _d : 0 })); });
245
+ }
246
+ function sleep(ms, signal) {
247
+ return new Promise((resolve, reject) => {
248
+ if ((signal === null || signal === void 0 ? void 0 : signal.aborted) === true) {
249
+ reject(new RemoteEvalError("Eval wait aborted.", undefined, "aborted"));
250
+ return;
251
+ }
252
+ const timer = setTimeout(() => {
253
+ signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", onAbort);
254
+ resolve();
255
+ }, ms);
256
+ const onAbort = () => {
257
+ clearTimeout(timer);
258
+ reject(new RemoteEvalError("Eval wait aborted.", undefined, "aborted"));
259
+ };
260
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
261
+ });
262
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Author-facing durable JSON KV for {@link HostContext.kv}.
3
+ *
4
+ * When `defineStorage` is authored and exposes `get`, values live in that
5
+ * sink under {@link storageKeys.kv}. Otherwise they land as one JSON file
6
+ * per key under `--state-root/kv` (local dogfood / no durable plug-in).
7
+ */
8
+ import type { HostKvApi } from "../types.js";
9
+ import type { StorageCoordinator } from "./storage-coordinator.js";
10
+ export interface CreateHostKvApiOptions {
11
+ agentName: string;
12
+ stateRoot: string;
13
+ storage?: StorageCoordinator;
14
+ }
15
+ /** Build the host KV API for one agent process. */
16
+ export declare function createHostKvApi(options: CreateHostKvApiOptions): HostKvApi;
17
+ //# sourceMappingURL=host-kv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-kv.d.ts","sourceRoot":"","sources":["../../src/internal/host-kv.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAa1E"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Author-facing durable JSON KV for {@link HostContext.kv}.
3
+ *
4
+ * When `defineStorage` is authored and exposes `get`, values live in that
5
+ * sink under {@link storageKeys.kv}. Otherwise they land as one JSON file
6
+ * per key under `--state-root/kv` (local dogfood / no durable plug-in).
7
+ */
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ import { randomUUID } from "node:crypto";
18
+ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
19
+ import { join } from "node:path";
20
+ import { storageKeys } from "../storage.js";
21
+ /** Build the host KV API for one agent process. */
22
+ export function createHostKvApi(options) {
23
+ const storage = options.storage;
24
+ if ((storage === null || storage === void 0 ? void 0 : storage.supportsAuthorKv) === true) {
25
+ return {
26
+ get: (key) => storage.kvGet(normalizeAuthorKey(key)),
27
+ put: (key, value) => storage.kvPut(normalizeAuthorKey(key), value),
28
+ delete: (key) => storage.kvDelete(normalizeAuthorKey(key)),
29
+ };
30
+ }
31
+ return createFilesystemKvApi({
32
+ agentName: options.agentName,
33
+ stateRoot: options.stateRoot,
34
+ });
35
+ }
36
+ function createFilesystemKvApi(options) {
37
+ const dir = join(options.stateRoot, "kv");
38
+ const filePath = (authorKey) => join(dir, `${encodeURIComponent(storageKeys.kv(options.agentName, authorKey))}.json`);
39
+ return {
40
+ get(key) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ const authorKey = normalizeAuthorKey(key);
43
+ try {
44
+ return JSON.parse(yield readFile(filePath(authorKey), "utf8"));
45
+ }
46
+ catch (error) {
47
+ if (error.code === "ENOENT") {
48
+ return undefined;
49
+ }
50
+ throw error;
51
+ }
52
+ });
53
+ },
54
+ put(key, value) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const authorKey = normalizeAuthorKey(key);
57
+ yield mkdir(dir, { recursive: true });
58
+ const target = filePath(authorKey);
59
+ const tmp = join(dir, `.tmp-${randomUUID()}`);
60
+ yield writeFile(tmp, JSON.stringify(value), "utf8");
61
+ yield rename(tmp, target);
62
+ });
63
+ },
64
+ delete(key) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ const authorKey = normalizeAuthorKey(key);
67
+ yield rm(filePath(authorKey), { force: true });
68
+ });
69
+ },
70
+ };
71
+ }
72
+ function normalizeAuthorKey(key) {
73
+ if (typeof key !== "string" || key.trim() === "") {
74
+ throw new Error("host.kv key must be a non-empty string");
75
+ }
76
+ return key;
77
+ }
@@ -301,15 +301,15 @@ Recommended loop once the project exists:
301
301
  1. Edit agent/ + tools under agent/tools/
302
302
  2. ${CLI_COMMAND_NAME} info --dir . --json
303
303
  3. ${CLI_COMMAND_NAME} run --dir . --message "..."
304
- 4. ${CLI_COMMAND_NAME} eval --local --dir .
304
+ 4. ${CLI_COMMAND_NAME} eval --dir .
305
305
 
306
306
  Evals:
307
307
  Create evals/**/*.eval.ts using defineEval from ${PACKAGE_NAME}/evals
308
308
  Case id is the path: evals/weather/nyc.eval.ts → weather/nyc
309
309
  Required: evals/evals.config.ts with defineEvalConfig({ maxConcurrency })
310
310
  (hard-capped at 200 due to model provider request limits)
311
- Run: ${CLI_COMMAND_NAME} eval --local [--json] [evalId...]
312
- (omit --local to run against the hosted deployment)
311
+ Run: ${CLI_COMMAND_NAME} eval [--json] [evalId...]
312
+ (pass --prod to run against the hosted deployment)
313
313
 
314
314
  See AGENTS.md in the ${PACKAGE_NAME} package for the full loop.
315
315
  `);
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAoFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CA2lB3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAoFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAsmB3B"}
@@ -272,6 +272,10 @@ export function startServer(mounts_1) {
272
272
  engine.trackBackground(promise);
273
273
  },
274
274
  resolveApproval: (sessionId, callId, decision, auth) => engine.resolveApproval(sessionId, callId, decision, auth),
275
+ hasContinuationSession: (continuationToken) => engine.hasContinuationSession(channel.id, continuationToken),
276
+ isContinuationBusy: (continuationToken) => engine.isContinuationBusy(channel.id, continuationToken),
277
+ getContinuationLastBotMessageTs: (continuationToken) => engine.getContinuationLastBotMessageTs(channel.id, continuationToken),
278
+ interruptContinuation: (continuationToken) => engine.interruptContinuation(channel.id, continuationToken),
275
279
  logger,
276
280
  };
277
281
  try {
@@ -846,14 +850,16 @@ function mountAgentRoutes(router, runtime, args) {
846
850
  const body = yield readJsonObject(request);
847
851
  const filterIds = asStringArray(body === null || body === void 0 ? void 0 : body.filterIds);
848
852
  const tags = asStringArray(body === null || body === void 0 ? void 0 : body.tags);
853
+ const timeoutMs = asPositiveInt(body === null || body === void 0 ? void 0 : body.timeoutMs);
854
+ const verbose = (body === null || body === void 0 ? void 0 : body.verbose) === true;
849
855
  const authHeader = request.headers.get("authorization");
850
856
  const bearerToken = (authHeader === null || authHeader === void 0 ? void 0 : authHeader.toLowerCase().startsWith("bearer "))
851
857
  ? authHeader.slice("bearer ".length).trim()
852
858
  : undefined;
853
859
  try {
854
- const snap = yield runtime.evalRuns.start(Object.assign(Object.assign(Object.assign({}, (filterIds === undefined ? {} : { filterIds })), (tags === undefined ? {} : { tags })), (bearerToken === undefined || bearerToken === ""
860
+ const snap = yield runtime.evalRuns.start(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (filterIds === undefined ? {} : { filterIds })), (tags === undefined ? {} : { tags })), (bearerToken === undefined || bearerToken === ""
855
861
  ? {}
856
- : { bearerToken })));
862
+ : { bearerToken })), (timeoutMs === undefined ? {} : { timeoutMs })), (verbose ? { verbose: true } : {})));
857
863
  return jsonResponse(snap, { status: 202 });
858
864
  }
859
865
  catch (error) {
@@ -1252,6 +1258,10 @@ function startCursorSlackRelay(input) {
1252
1258
  envelope,
1253
1259
  send: args.send,
1254
1260
  host: args.host,
1261
+ hasContinuationSession: (continuationToken) => target.runtime.engine.hasContinuationSession(target.channelId, continuationToken),
1262
+ isContinuationBusy: (continuationToken) => target.runtime.engine.isContinuationBusy(target.channelId, continuationToken),
1263
+ getContinuationLastBotMessageTs: (continuationToken) => target.runtime.engine.getContinuationLastBotMessageTs(target.channelId, continuationToken),
1264
+ interruptContinuation: (continuationToken) => target.runtime.engine.interruptContinuation(target.channelId, continuationToken),
1255
1265
  });
1256
1266
  }),
1257
1267
  });
@@ -1488,6 +1498,13 @@ function asStringArray(value) {
1488
1498
  }
1489
1499
  return out.length === 0 ? undefined : out;
1490
1500
  }
1501
+ function asPositiveInt(value) {
1502
+ if (typeof value !== "number" || !Number.isFinite(value)) {
1503
+ return undefined;
1504
+ }
1505
+ const n = Math.floor(value);
1506
+ return n > 0 ? n : undefined;
1507
+ }
1491
1508
  function assertReminderReadable(input) {
1492
1509
  return __awaiter(this, void 0, void 0, function* () {
1493
1510
  const existing = yield input.engine.sessions.findByContinuation(input.reminder.channelId, input.reminder.continuationToken);
@@ -6,6 +6,7 @@
6
6
  * are mapped onto the channel event vocabulary and dispatched to channel
7
7
  * event handlers and hooks.
8
8
  */
9
+ import { SlackAskDedupeStore, SlackNudgeStore } from "../channels/slack/nudge-store.js";
9
10
  import { type AgentProject, type ApprovalDecision, type AuthContext, type CallToolOptions, type ChannelDefinition, type ChannelSession, type HostContext, type HttpChannelDefinition, type PendingApproval, type ReceiveInput, type SendMessageOptions, type SessionEvent, type SessionInfo, type SessionRecord, type SessionSummary, type ToolCallOutcome, type TurnOutcome } from "../types.js";
10
11
  import { type ABSnapshot } from "./ab-snapshot.js";
11
12
  import { type HostPlatforms } from "./host-platforms.js";
@@ -83,6 +84,10 @@ export declare class SessionEngine {
83
84
  readonly project: AgentProject;
84
85
  readonly stateRoot: string;
85
86
  readonly sessions: SessionStore;
87
+ /** Durable Slack mid-turn nudges under `<stateRoot>/slack-nudges`. */
88
+ readonly nudgeStore: SlackNudgeStore;
89
+ /** Durable `channelId:ts` ask claims under `<stateRoot>/slack-asks`. */
90
+ readonly askDedupe: SlackAskDedupeStore;
86
91
  /**
87
92
  * Runtime for `agent/storage.ts` (`defineStorage`), when
88
93
  * authored. All durable state changes funnel through it (session
@@ -105,6 +110,16 @@ export declare class SessionEngine {
105
110
  private readonly turnAborts;
106
111
  /** Serializes turn admission per session (latest follow-up wins). */
107
112
  private readonly admissionChains;
113
+ /**
114
+ * Per-session coalesce queue for `admission: "coalesce"` (Slack). Drained
115
+ * into one follow-up turn when the active turn finishes without interrupt.
116
+ */
117
+ private readonly coalesceQueues;
118
+ /**
119
+ * Sessions whose turn lifecycle is draining coalesced follow-ups. Counts as
120
+ * busy so inbound coalesce admits enqueue instead of racing `clearCoalesced`.
121
+ */
122
+ private readonly coalesceDrains;
108
123
  private readonly lastOutcomes;
109
124
  private readonly updateChains;
110
125
  private readonly dispatchChains;
@@ -114,6 +129,7 @@ export declare class SessionEngine {
114
129
  private readonly approvals;
115
130
  private readonly abCollector;
116
131
  private reminderApi;
132
+ private readonly kvApi;
117
133
  /** Serve-time resolved connections (see {@link setResolvedConnections}). */
118
134
  private resolvedConnections;
119
135
  constructor(options: SessionEngineOptions);
@@ -124,8 +140,9 @@ export declare class SessionEngine {
124
140
  * (`ctx.host.mcp`, always loopback).
125
141
  */
126
142
  setResolvedConnections(connections: EngineResolvedConnection[]): void;
127
- /** Shared host services (MCP / GitHub / Slack / reminders). */
143
+ /** Shared host services (MCP / GitHub / Slack / reminders / kv / Slack nudges). */
128
144
  get host(): HostContext;
145
+ private slackNudgeHostApi;
129
146
  /** Attach the serve-host reminder API (called from startServer). */
130
147
  setReminders(api: HostContext["reminders"]): void;
131
148
  /**
@@ -134,6 +151,8 @@ export declare class SessionEngine {
134
151
  * session is created (keyed by the provided token, or a fresh one).
135
152
  */
136
153
  send(channelId: string, message: string, options?: EngineSendOptions): Promise<ChannelSession>;
154
+ /** Whether a continuation token already maps to a session on this channel. */
155
+ hasContinuationSession(channelId: string, continuationToken: string): Promise<boolean>;
137
156
  /**
138
157
  * Sticky A/B enrollment at session creation — before the first turn, so
139
158
  * variants are in the durable stream (and on {@link SessionRecord.abs})
@@ -167,13 +186,21 @@ export declare class SessionEngine {
167
186
  done: Promise<TurnOutcome>;
168
187
  }>;
169
188
  /**
170
- * Admit a turn for `sessionId`. A follow-up that arrives while a turn is in
171
- * flight preempts it: the running turn is cancelled and its SDK run marked
172
- * terminal before the new turn starts. Admissions are serialized per session
173
- * so a burst of follow-ups can't race two runs onto the same SDK agent — the
174
- * last message wins. Resolves once the new turn has started (not finished).
189
+ * Admit a turn for `sessionId`.
190
+ *
191
+ * Default (`preempt`): a follow-up cancels the running turn and starts
192
+ * immediately (HTTP / MCP). With `admission: "coalesce"` (Slack), a busy
193
+ * session enqueues the message and returns without interrupting; the queue
194
+ * drains into one follow-up when the active turn finishes.
195
+ *
196
+ * Resolves to `true` when the message was coalesced (enqueued), `false`
197
+ * when a turn was started.
175
198
  */
176
199
  private startTurn;
200
+ private enqueueCoalesced;
201
+ private clearCoalesced;
202
+ private formatCoalescedFollowups;
203
+ private drainCoalescedFollowups;
177
204
  private admitTurn;
178
205
  /**
179
206
  * Cancel the turn in flight for `sessionId` (if any) and wait for it to
@@ -183,9 +210,17 @@ export declare class SessionEngine {
183
210
  private interruptActiveTurn;
184
211
  /**
185
212
  * Abort the in-flight turn without starting a follow-up. Returns whether
186
- * a turn was active (or pending abort) when called.
213
+ * a turn was active (or pending abort) when called. Also clears any
214
+ * coalesced follow-ups queued behind the session.
187
215
  */
188
216
  interrupt(sessionId: string): Promise<boolean>;
217
+ isContinuationBusy(channelId: string, continuationToken: string): Promise<boolean>;
218
+ /**
219
+ * Last agent-posted Slack message ts for warm `<slack_thread_delta>`, from
220
+ * the session's channel state when present.
221
+ */
222
+ getContinuationLastBotMessageTs(channelId: string, continuationToken: string): Promise<string | undefined>;
223
+ interruptContinuation(channelId: string, continuationToken: string): Promise<boolean>;
189
224
  /**
190
225
  * Local harness cwd for a session: per-send override, else
191
226
  * `<agent.local.cwd>/<sessionId>`, else the durable session workspace.