@aexol/spectral 0.9.109 → 0.9.113
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/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +57 -3
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +6 -0
- package/dist/extensions/image-generation/index.d.ts.map +1 -1
- package/dist/extensions/image-generation/index.js +42 -5
- package/dist/extensions/spectral-vision-fallback.d.ts.map +1 -1
- package/dist/extensions/spectral-vision-fallback.js +5 -0
- package/dist/memory/hooks/inter-agent-receiver.d.ts.map +1 -1
- package/dist/memory/hooks/inter-agent-receiver.js +13 -2
- package/dist/sdk/agent-core/agent-loop.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent-loop.js +27 -7
- package/dist/sdk/ai/providers/openrouter-images.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openrouter-images.js +45 -8
- package/dist/sdk/ai/types.d.ts +2 -0
- package/dist/sdk/ai/types.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/tools/find.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/tools/find.js +63 -2
- package/dist/server/agent-bridge.d.ts +12 -0
- package/dist/server/agent-bridge.d.ts.map +1 -1
- package/dist/server/agent-bridge.js +94 -11
- package/dist/server/session-stream.d.ts +8 -0
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +146 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAIX,SAAS,EAET,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,KAAK,WAAW,EAAmC,MAAM,aAAa,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD,OAAO,KAAK,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAIX,SAAS,EAET,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,KAAK,WAAW,EAAmC,MAAM,aAAa,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOrD,OAAO,KAAK,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AA4F7G,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CASpG;AAED,wBAAgB,yBAAyB,CACxC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAAC,GAC/C,MAAM,CAKR;AAiHD;;;GAGG;AACH,wBAAgB,oCAAoC,CACnD,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAChD,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC,CAK3D;AAED,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,EAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,gBAAgB,GACnB,SAAS,EAAE,CAqCb;AAuaD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACxC,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;CAAE,GACpF,IAAI,CAgZN"}
|
package/dist/agent/index.js
CHANGED
|
@@ -47,6 +47,14 @@ const MAX_PARALLEL_TASKS = 8;
|
|
|
47
47
|
const MAX_CONCURRENCY = 4;
|
|
48
48
|
const PRIMARY_AGENT_PROMPT_HEADER = "# Primary Agent:";
|
|
49
49
|
const PRIMARY_AGENT_PROMPT_DELIMITER = "\n\n---\n\n";
|
|
50
|
+
/**
|
|
51
|
+
* Per-subagent timeout. Each subagent invocation (single, parallel, chain)
|
|
52
|
+
* gets its own independent deadline so that no single subagent can
|
|
53
|
+
* exhaust the parent prompt's entire timeout budget.
|
|
54
|
+
*
|
|
55
|
+
* Defaults to 4 hours. Override via SPECTRAL_SUBAGENT_TIMEOUT_MS env var.
|
|
56
|
+
*/
|
|
57
|
+
const SUBAGENT_TIMEOUT_MS = Number(process.env.SPECTRAL_SUBAGENT_TIMEOUT_MS) || 4 * 60 * 60 * 1000;
|
|
50
58
|
// ---------------------------------------------------------------------------
|
|
51
59
|
// Helpers — formatting
|
|
52
60
|
// ---------------------------------------------------------------------------
|
|
@@ -248,6 +256,52 @@ async function mapWithConcurrencyLimit(items, concurrency, fn) {
|
|
|
248
256
|
await Promise.all(workers);
|
|
249
257
|
return results;
|
|
250
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Wraps `runSingleAgent` with an independent per-subagent timeout.
|
|
261
|
+
*
|
|
262
|
+
* Combines the parent's abort signal with a fresh timeout AbortController so
|
|
263
|
+
* that no single subagent can exhaust the parent prompt's full timeout budget.
|
|
264
|
+
* On timeout, returns a clear error result instead of throwing so the parent
|
|
265
|
+
* agent can continue (e.g. stop a chain, or surface the error as the tool
|
|
266
|
+
* result for parallel/single modes).
|
|
267
|
+
*/
|
|
268
|
+
async function runSingleAgentWithTimeout(defaultCwd, agents, agentName, task, cwd, step, signal, onUpdate, makeDetails, parentToolCallId, onInternalEvent, ext, ctx) {
|
|
269
|
+
const timeoutMs = SUBAGENT_TIMEOUT_MS;
|
|
270
|
+
const timeoutSeconds = timeoutMs / 1000;
|
|
271
|
+
const controller = new AbortController();
|
|
272
|
+
const timeoutId = setTimeout(() => controller.abort(new Error(`Subagent timeout (${timeoutSeconds}s)`)), timeoutMs);
|
|
273
|
+
// Propagate parent abort into the combined controller.
|
|
274
|
+
const onParentAbort = () => controller.abort(signal.reason);
|
|
275
|
+
if (signal) {
|
|
276
|
+
if (signal.aborted)
|
|
277
|
+
onParentAbort();
|
|
278
|
+
else
|
|
279
|
+
signal.addEventListener("abort", onParentAbort, { once: true });
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
const result = await runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, controller.signal, onUpdate, makeDetails, parentToolCallId, onInternalEvent, ext, ctx);
|
|
283
|
+
// If the timeout fired (and parent signal did not), surface a clean
|
|
284
|
+
// timeout error result rather than a bare "aborted" result.
|
|
285
|
+
if (controller.signal.aborted &&
|
|
286
|
+
!signal?.aborted &&
|
|
287
|
+
result.stopReason === "aborted") {
|
|
288
|
+
const message = `Subagent "${agentName}" timed out after ${timeoutSeconds}s`;
|
|
289
|
+
return {
|
|
290
|
+
...result,
|
|
291
|
+
exitCode: 1,
|
|
292
|
+
stopReason: "aborted",
|
|
293
|
+
errorMessage: message,
|
|
294
|
+
stderr: result.stderr || message,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
finally {
|
|
300
|
+
if (signal)
|
|
301
|
+
signal.removeEventListener("abort", onParentAbort);
|
|
302
|
+
clearTimeout(timeoutId);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
251
305
|
// ---------------------------------------------------------------------------
|
|
252
306
|
// Core — run a single subagent in-process via agentLoop
|
|
253
307
|
// ---------------------------------------------------------------------------
|
|
@@ -683,7 +737,7 @@ export default function subagentExtension(ext, opts) {
|
|
|
683
737
|
}
|
|
684
738
|
}
|
|
685
739
|
: undefined;
|
|
686
|
-
const result = await
|
|
740
|
+
const result = await runSingleAgentWithTimeout(ctx.cwd, agents, step.agent, taskWithContext, step.cwd, i + 1, signal, chainUpdate, makeDetails("chain"), _toolCallId, emitSubagentToolProgress, ext, ctx);
|
|
687
741
|
results.push(result);
|
|
688
742
|
const isError = result.exitCode !== 0 ||
|
|
689
743
|
result.stopReason === "error" ||
|
|
@@ -756,7 +810,7 @@ export default function subagentExtension(ext, opts) {
|
|
|
756
810
|
}
|
|
757
811
|
};
|
|
758
812
|
const results = await mapWithConcurrencyLimit(params.tasks, MAX_CONCURRENCY, async (t, index) => {
|
|
759
|
-
const result = await
|
|
813
|
+
const result = await runSingleAgentWithTimeout(ctx.cwd, agents, t.agent, t.task, t.cwd, undefined, signal, (partial) => {
|
|
760
814
|
if (partial.details?.results[0]) {
|
|
761
815
|
allResults[index] = partial.details.results[0];
|
|
762
816
|
emitParallelUpdate();
|
|
@@ -784,7 +838,7 @@ export default function subagentExtension(ext, opts) {
|
|
|
784
838
|
}
|
|
785
839
|
// ── Single mode ─────────────────────────────────────────────
|
|
786
840
|
if (params.agent && params.task) {
|
|
787
|
-
const result = await
|
|
841
|
+
const result = await runSingleAgentWithTimeout(ctx.cwd, agents, params.agent, params.task, params.cwd, undefined, signal, onUpdate, makeDetails("single"), _toolCallId, emitSubagentToolProgress, ext, ctx);
|
|
788
842
|
const isError = result.exitCode !== 0 ||
|
|
789
843
|
result.stopReason === "error" ||
|
|
790
844
|
result.stopReason === "aborted";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAyBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAWlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAsBrE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAyBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAWlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAsBrE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAgelF;AA+DD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAa5E"}
|
package/dist/commands/serve.js
CHANGED
|
@@ -185,12 +185,18 @@ export async function runServe(opts = {}) {
|
|
|
185
185
|
// Stream manager owns per-session spectral processes. Batch 3 will subscribe
|
|
186
186
|
// it to relay frames; for now it's just here so the handles match the
|
|
187
187
|
// shape Batch 3 expects.
|
|
188
|
+
const closeBrowser = async () => {
|
|
189
|
+
const { BrowserService } = await import("../extensions/browser/browser-service.js");
|
|
190
|
+
await BrowserService.closeAll();
|
|
191
|
+
};
|
|
188
192
|
const manager = new SessionStreamManager({
|
|
189
193
|
store,
|
|
190
194
|
cwd,
|
|
191
195
|
backendUrl,
|
|
192
196
|
machineJwt: registration.record.machineJwt,
|
|
193
197
|
bridgeFactory: opts.bridgeFactory,
|
|
198
|
+
onTurnEnd: closeBrowser,
|
|
199
|
+
onDispose: closeBrowser,
|
|
194
200
|
});
|
|
195
201
|
if (!silent) {
|
|
196
202
|
const action = registration.reused ? "Reusing" : "Registered";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/image-generation/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,YAAY,EAAkB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/image-generation/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,YAAY,EAAkB,MAAM,iCAAiC,CAAC;AAmErG,wBAA8B,wBAAwB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDvF"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { generateImages, getImageModel, getImageModels } from "../../sdk/ai/index.js";
|
|
3
|
+
// App-layer routing helpers (mirror kanban-bridge.ts): obtain backendUrl +
|
|
4
|
+
// machineJwt the same way agent-bridge.ts gets them for text models, so image
|
|
5
|
+
// generation routes through the backend proxy (POST /image/generation) using
|
|
6
|
+
// the backend's own OPENROUTER_API_KEY instead of a local env key.
|
|
7
|
+
import { getApiUrl, readConfig } from "../../config.js";
|
|
8
|
+
import { loadMachine } from "../../relay/machine-store.js";
|
|
9
|
+
import { isJwtExpired } from "../../relay/registration.js";
|
|
3
10
|
const imageGenerateSchema = Type.Object({
|
|
4
11
|
prompt: Type.String({ description: "Text prompt describing the image to generate." }),
|
|
5
12
|
model: Type.Optional(Type.String({ default: "google/gemini-3.1-flash-lite-image", description: "OpenRouter image model id." })),
|
|
@@ -23,12 +30,33 @@ function imageModel(modelId) {
|
|
|
23
30
|
return exact;
|
|
24
31
|
return getImageModels("openrouter").find((model) => model.id === modelId);
|
|
25
32
|
}
|
|
26
|
-
function resultText(count, model,
|
|
33
|
+
function resultText(count, model, credits) {
|
|
27
34
|
const lines = [`✓ Generated ${count} image${count === 1 ? "" : "s"}`, `Model: ${model}`];
|
|
28
|
-
|
|
29
|
-
lines.push(`Cost: $${usageCost.toFixed(6)}`);
|
|
35
|
+
lines.push(`Cost: ${credits ?? 0} credits`);
|
|
30
36
|
return lines.join("\n");
|
|
31
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve backend routing for image generation, mirroring how agent-bridge.ts
|
|
40
|
+
* obtains `backendUrl` + `machineJwt` for text models. The machine JWT is the
|
|
41
|
+
* same token the CLI registers with (see serve.ts → registration.record), so
|
|
42
|
+
* this is exactly equivalent to `AgentBridgeOptions.machineJwt`.
|
|
43
|
+
*
|
|
44
|
+
* Returns `null` when routing cannot be resolved (e.g. not logged in); the
|
|
45
|
+
* caller then falls back to the SDK's local-key path.
|
|
46
|
+
*/
|
|
47
|
+
async function resolveBackendRouting() {
|
|
48
|
+
const cfg = await readConfig();
|
|
49
|
+
if (!cfg)
|
|
50
|
+
return null;
|
|
51
|
+
const machine = await loadMachine();
|
|
52
|
+
if (machine?.machineJwt && !isJwtExpired(machine.machineJwt)) {
|
|
53
|
+
const backendUrl = process.env.SPECTRAL_BACKEND_URL ||
|
|
54
|
+
getApiUrl(cfg.apiUrl).replace(/\/mcp\/?$/, "");
|
|
55
|
+
return { backendUrl, machineJwt: machine.machineJwt };
|
|
56
|
+
}
|
|
57
|
+
// No usable machine JWT — let the SDK fall back to local OPENROUTER_API_KEY.
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
32
60
|
export default async function imageGenerationExtension(ext) {
|
|
33
61
|
const tool = {
|
|
34
62
|
name: "image_generate",
|
|
@@ -56,7 +84,16 @@ export default async function imageGenerationExtension(ext) {
|
|
|
56
84
|
})),
|
|
57
85
|
],
|
|
58
86
|
};
|
|
59
|
-
|
|
87
|
+
// Route through the backend image proxy (POST /image/generation) using
|
|
88
|
+
// the machine JWT, mirroring how text models route through
|
|
89
|
+
// `${backendUrl}/v1` in agent-bridge.ts. Falls back to the SDK's local
|
|
90
|
+
// OPENROUTER_API_KEY path when routing cannot be resolved.
|
|
91
|
+
const routing = await resolveBackendRouting();
|
|
92
|
+
const response = await generateImages(model, context, {
|
|
93
|
+
...input,
|
|
94
|
+
signal,
|
|
95
|
+
...(routing ? { backendUrl: routing.backendUrl, apiKey: routing.machineJwt } : {}),
|
|
96
|
+
});
|
|
60
97
|
if (response.stopReason !== "stop") {
|
|
61
98
|
const message = response.errorMessage ?? "Image generation failed";
|
|
62
99
|
return {
|
|
@@ -67,7 +104,7 @@ export default async function imageGenerationExtension(ext) {
|
|
|
67
104
|
const images = response.output.filter((item) => item.type === "image");
|
|
68
105
|
return {
|
|
69
106
|
content: [
|
|
70
|
-
{ type: "text", text: resultText(images.length, response.model, response.usage?.
|
|
107
|
+
{ type: "text", text: resultText(images.length, response.model, response.usage?.credits) },
|
|
71
108
|
...response.output,
|
|
72
109
|
],
|
|
73
110
|
details: { isError: false, model: response.model, count: images.length, usage: response.usage },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spectral-vision-fallback.d.ts","sourceRoot":"","sources":["../../src/extensions/spectral-vision-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"spectral-vision-fallback.d.ts","sourceRoot":"","sources":["../../src/extensions/spectral-vision-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AA+YjE,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CA6DvE"}
|
|
@@ -111,7 +111,12 @@ function countImages(msg) {
|
|
|
111
111
|
return 0;
|
|
112
112
|
return msg.content.filter((c) => c.type === "image").length;
|
|
113
113
|
}
|
|
114
|
+
function isImageGenerateResult(msg) {
|
|
115
|
+
return msg.role === "toolResult" && msg.toolName === "image_generate";
|
|
116
|
+
}
|
|
114
117
|
function isProcessableImageMessage(msg) {
|
|
118
|
+
if (isImageGenerateResult(msg))
|
|
119
|
+
return false;
|
|
115
120
|
return (msg.role === "user" || msg.role === "toolResult") && Array.isArray(msg.content) && hasImageContent(msg.content);
|
|
116
121
|
}
|
|
117
122
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inter-agent-receiver.d.ts","sourceRoot":"","sources":["../../../src/memory/hooks/inter-agent-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAoFpE,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"inter-agent-receiver.d.ts","sourceRoot":"","sources":["../../../src/memory/hooks/inter-agent-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAoFpE,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CA0IlE"}
|
|
@@ -137,8 +137,19 @@ export function registerInterAgentReceiver(ext) {
|
|
|
137
137
|
return;
|
|
138
138
|
state.pending.push(obs);
|
|
139
139
|
state.deliveredIds.add(obs.memoryId);
|
|
140
|
-
|
|
141
|
-
ctx.
|
|
140
|
+
try {
|
|
141
|
+
if (ctx.hasUI && ctx.ui) {
|
|
142
|
+
ctx.ui.notify(`Shared observation from ${msg.senderName ?? msg.senderSessionId}: ${obs.content.slice(0, 120)}`, "info");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
147
|
+
if (message.includes("stale after session replacement")) {
|
|
148
|
+
state.unsubscribe?.();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Re-throw unexpected errors so the broker surfaces them.
|
|
152
|
+
throw err;
|
|
142
153
|
}
|
|
143
154
|
},
|
|
144
155
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,WAAW,EAIZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAIZ,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAsBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CA6BzC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB"}
|
|
@@ -11,8 +11,13 @@ export function agentLoop(prompts, context, config, signal, streamFn) {
|
|
|
11
11
|
const stream = createAgentStream();
|
|
12
12
|
void runAgentLoop(prompts, context, config, async (event) => {
|
|
13
13
|
stream.push(event);
|
|
14
|
-
}, signal, streamFn)
|
|
14
|
+
}, signal, streamFn)
|
|
15
|
+
.then((messages) => {
|
|
15
16
|
stream.end(messages);
|
|
17
|
+
})
|
|
18
|
+
.catch(() => {
|
|
19
|
+
stream.push({ type: "agent_end", messages: [] });
|
|
20
|
+
stream.end([]);
|
|
16
21
|
});
|
|
17
22
|
return stream;
|
|
18
23
|
}
|
|
@@ -34,8 +39,13 @@ export function agentLoopContinue(context, config, signal, streamFn) {
|
|
|
34
39
|
const stream = createAgentStream();
|
|
35
40
|
void runAgentLoopContinue(context, config, async (event) => {
|
|
36
41
|
stream.push(event);
|
|
37
|
-
}, signal, streamFn)
|
|
42
|
+
}, signal, streamFn)
|
|
43
|
+
.then((messages) => {
|
|
38
44
|
stream.end(messages);
|
|
45
|
+
})
|
|
46
|
+
.catch(() => {
|
|
47
|
+
stream.push({ type: "agent_end", messages: [] });
|
|
48
|
+
stream.end([]);
|
|
39
49
|
});
|
|
40
50
|
return stream;
|
|
41
51
|
}
|
|
@@ -116,7 +126,13 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
116
126
|
if (toolCalls.length > 0) {
|
|
117
127
|
const executedToolBatch = await executeToolCalls(currentContext, message, config, signal, emit);
|
|
118
128
|
toolResults.push(...executedToolBatch.messages);
|
|
119
|
-
|
|
129
|
+
// Only continue the loop when the provider explicitly asked for
|
|
130
|
+
// tool use. Some providers emit a tool call alongside a terminal
|
|
131
|
+
// `stopReason: "stop"`; treating that as a continuation triggers
|
|
132
|
+
// a spurious second LLM call that hangs the agent and leaves the
|
|
133
|
+
// landing UI stuck in "streaming" until the 15-min hang timeout.
|
|
134
|
+
hasMoreToolCalls =
|
|
135
|
+
message.stopReason === "toolUse" && !executedToolBatch.terminate;
|
|
120
136
|
for (const result of toolResults) {
|
|
121
137
|
currentContext.messages.push(result);
|
|
122
138
|
newMessages.push(result);
|
|
@@ -185,7 +201,9 @@ async function streamAssistantResponse(context, config, signal, emit, streamFn)
|
|
|
185
201
|
};
|
|
186
202
|
const streamFunction = streamFn || streamSimple;
|
|
187
203
|
// Resolve API key (important for expiring tokens)
|
|
188
|
-
const resolvedApiKey = (config.getApiKey
|
|
204
|
+
const resolvedApiKey = (config.getApiKey
|
|
205
|
+
? await config.getApiKey(config.model.provider)
|
|
206
|
+
: undefined) || config.apiKey;
|
|
189
207
|
const response = await streamFunction(config.model, llmContext, {
|
|
190
208
|
...config,
|
|
191
209
|
apiKey: resolvedApiKey,
|
|
@@ -253,7 +271,8 @@ async function streamAssistantResponse(context, config, signal, emit, streamFn)
|
|
|
253
271
|
*/
|
|
254
272
|
async function executeToolCalls(currentContext, assistantMessage, config, signal, emit) {
|
|
255
273
|
const toolCalls = assistantMessage.content.filter((c) => c.type === "toolCall");
|
|
256
|
-
const hasSequentialToolCall = toolCalls.some((tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode ===
|
|
274
|
+
const hasSequentialToolCall = toolCalls.some((tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode ===
|
|
275
|
+
"sequential");
|
|
257
276
|
if (config.toolExecution === "sequential" || hasSequentialToolCall) {
|
|
258
277
|
return executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);
|
|
259
278
|
}
|
|
@@ -329,7 +348,7 @@ async function executeToolCallsParallel(currentContext, assistantMessage, toolCa
|
|
|
329
348
|
break;
|
|
330
349
|
}
|
|
331
350
|
}
|
|
332
|
-
const orderedFinalizedCalls = await Promise.all(finalizedCalls.map((entry) =>
|
|
351
|
+
const orderedFinalizedCalls = await Promise.all(finalizedCalls.map((entry) => typeof entry === "function" ? entry() : Promise.resolve(entry)));
|
|
333
352
|
const messages = [];
|
|
334
353
|
for (const finalized of orderedFinalizedCalls) {
|
|
335
354
|
const toolResultMessage = createToolResultMessage(finalized);
|
|
@@ -342,7 +361,8 @@ async function executeToolCallsParallel(currentContext, assistantMessage, toolCa
|
|
|
342
361
|
};
|
|
343
362
|
}
|
|
344
363
|
function shouldTerminateToolBatch(finalizedCalls) {
|
|
345
|
-
return finalizedCalls.length > 0 &&
|
|
364
|
+
return (finalizedCalls.length > 0 &&
|
|
365
|
+
finalizedCalls.every((finalized) => finalized.result.terminate === true));
|
|
346
366
|
}
|
|
347
367
|
function prepareToolCallArguments(tool, toolCall) {
|
|
348
368
|
if (!tool.prepareArguments) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter-images.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openrouter-images.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EAEf,aAAa,EACb,WAAW,EACX,qBAAqB,EAGrB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"openrouter-images.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openrouter-images.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,eAAe,EAEf,aAAa,EACb,WAAW,EACX,qBAAqB,EAGrB,MAAM,aAAa,CAAC;AA6ErB,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,EACvC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,eAAe,CAAC,CAwG1B"}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import { getEnvApiKey } from "../env-api-keys.js";
|
|
2
|
+
/**
|
|
3
|
+
* Image generation routing.
|
|
4
|
+
*
|
|
5
|
+
* PRIMARY PATH (mirrors how text models route through `${backendUrl}/v1` in
|
|
6
|
+
* agent-bridge.ts): when `options.backendUrl` and `options.apiKey` (the
|
|
7
|
+
* machine JWT) are provided, requests are sent to the backend proxy at
|
|
8
|
+
* `${backendUrl}/image/generation`. The backend authenticates via the
|
|
9
|
+
* machine JWT and uses ITS OWN `OPENROUTER_API_KEY`, so the CLI never needs
|
|
10
|
+
* a local OpenRouter key for normal operation.
|
|
11
|
+
*
|
|
12
|
+
* FALLBACK PATH: when no backend routing is configured (e.g. standalone
|
|
13
|
+
* SDK use outside the Spectral CLI), we fall back to calling OpenRouter
|
|
14
|
+
* directly with a local `OPENROUTER_API_KEY` env var. This keeps the SDK
|
|
15
|
+
* usable in isolation, but is NOT the path used by `image_generate`.
|
|
16
|
+
*/
|
|
2
17
|
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
3
18
|
const PASSTHROUGH_KEYS = [
|
|
4
19
|
"n",
|
|
@@ -45,6 +60,7 @@ function usageFromOpenRouter(raw) {
|
|
|
45
60
|
cacheWrite: Number(usage.cache_write_tokens ?? 0) || 0,
|
|
46
61
|
totalTokens,
|
|
47
62
|
cost: { input: 0, output: totalCost, cacheRead: 0, cacheWrite: 0, total: totalCost },
|
|
63
|
+
credits: Number(usage.credits ?? 0) || undefined,
|
|
48
64
|
};
|
|
49
65
|
}
|
|
50
66
|
function mediaTypeFor(item, outputFormat) {
|
|
@@ -57,9 +73,16 @@ function mediaTypeFor(item, outputFormat) {
|
|
|
57
73
|
return "image/png";
|
|
58
74
|
}
|
|
59
75
|
export async function generateOpenRouterImages(model, context, options = {}) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
76
|
+
// Backend-routed path: when the caller (extension) supplies a backendUrl
|
|
77
|
+
// and the machine JWT as apiKey, route through the backend image proxy —
|
|
78
|
+
// the same pattern text models use for `${backendUrl}/v1`.
|
|
79
|
+
const backendUrl = typeof options.backendUrl === "string" ? options.backendUrl : undefined;
|
|
80
|
+
const machineJwt = options.apiKey;
|
|
81
|
+
const routeThroughBackend = Boolean(backendUrl && machineJwt);
|
|
82
|
+
// Local-key fallback for standalone SDK use (NOT the image_generate path).
|
|
83
|
+
const localApiKey = !routeThroughBackend ? getEnvApiKey("openrouter") : undefined;
|
|
84
|
+
if (!routeThroughBackend && !localApiKey) {
|
|
85
|
+
throw new Error("Missing OPENROUTER_API_KEY for OpenRouter image generation (no backend routing configured)");
|
|
63
86
|
}
|
|
64
87
|
const prompt = textFromContext(context);
|
|
65
88
|
if (!prompt)
|
|
@@ -88,14 +111,28 @@ export async function generateOpenRouterImages(model, context, options = {}) {
|
|
|
88
111
|
options.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
89
112
|
}
|
|
90
113
|
try {
|
|
91
|
-
|
|
114
|
+
// Backend proxy endpoint (POST /image/generation) accepts the same
|
|
115
|
+
// body shape the OpenRouter Images API expects and returns the
|
|
116
|
+
// upstream OpenRouter response verbatim, so request/response handling
|
|
117
|
+
// is identical on both paths. Only the URL + auth differ.
|
|
118
|
+
const url = routeThroughBackend
|
|
119
|
+
? `${backendUrl.replace(/\/$/, "")}/image/generation`
|
|
120
|
+
: `${model.baseUrl.replace(/\/$/, "")}/images`;
|
|
121
|
+
const bearer = routeThroughBackend ? machineJwt : localApiKey;
|
|
122
|
+
const response = await fetch(url, {
|
|
92
123
|
method: "POST",
|
|
93
124
|
headers: {
|
|
94
125
|
"Content-Type": "application/json",
|
|
95
|
-
Authorization: `Bearer ${
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
126
|
+
Authorization: `Bearer ${bearer}`,
|
|
127
|
+
// OpenRouter attribution headers are only meaningful on the
|
|
128
|
+
// direct path; the backend proxy sets its own when forwarding.
|
|
129
|
+
...(routeThroughBackend
|
|
130
|
+
? {}
|
|
131
|
+
: {
|
|
132
|
+
"HTTP-Referer": "https://aexol.ai",
|
|
133
|
+
"X-OpenRouter-Title": "Aexol.ai",
|
|
134
|
+
"X-OpenRouter-Categories": "cli-agent",
|
|
135
|
+
}),
|
|
99
136
|
...(options.headers ?? {}),
|
|
100
137
|
},
|
|
101
138
|
body: JSON.stringify(body),
|
package/dist/sdk/ai/types.d.ts
CHANGED
|
@@ -180,6 +180,8 @@ export interface Usage {
|
|
|
180
180
|
cacheWrite: number;
|
|
181
181
|
total: number;
|
|
182
182
|
};
|
|
183
|
+
/** Credits deducted by the backend, when routed through backend image generation. */
|
|
184
|
+
credits?: number;
|
|
183
185
|
}
|
|
184
186
|
export type StopReason = "stop" | "length" | "toolUse" | "error" | "aborted";
|
|
185
187
|
export interface UserMessage {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sdk/ai/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE3E,YAAY,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE3E,MAAM,MAAM,QAAQ,GACjB,oBAAoB,GACpB,uBAAuB,GACvB,kBAAkB,GAClB,wBAAwB,GACxB,wBAAwB,GACxB,oBAAoB,GACpB,yBAAyB,GACzB,sBAAsB,GACtB,eAAe,CAAC;AAEnB,MAAM,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAEjD,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEvD,MAAM,MAAM,aAAa,GACtB,gBAAgB,GAChB,WAAW,GACX,QAAQ,GACR,eAAe,GACf,QAAQ,GACR,wBAAwB,GACxB,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,KAAK,GACL,MAAM,GACN,UAAU,GACV,YAAY,GACZ,mBAAmB,GACnB,KAAK,GACL,SAAS,GACT,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,aAAa,GACb,WAAW,GACX,UAAU,GACV,UAAU,GACV,aAAa,GACb,aAAa,GACb,uBAAuB,GACvB,uBAAuB,GACvB,QAAQ,GACR,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,CAAC;AAC3B,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;AAE9C,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAC5E,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,aAAa,CAAC;AACvD,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AAElF,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,WAAW,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACxG;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5E,MAAM,WAAW,aAAa;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,KAAK,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACpH;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjG;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAG5E,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACzD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,4EAA4E;IAC5E,eAAe,CAAC,EAAE,eAAe,CAAC;CAClC;AAUD,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,GAAG,GAAG,GAAG,EAAE,QAAQ,SAAS,aAAa,GAAG,aAAa,IAAI,CACpG,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,QAAQ,KACd,2BAA2B,CAAC;AAEjC,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,SAAS,GAAG,SAAS,EAAE,QAAQ,SAAS,aAAa,GAAG,aAAa,IAAI,CAChH,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,EACxB,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,QAAQ,KACd,OAAO,CAAC,eAAe,CAAC,CAAC;AAE9B,MAAM,WAAW,eAAe;IAC/B,CAAC,EAAE,CAAC,CAAC;IACL,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C;;gDAE4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,KAAK;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACd,CAAC;CACF;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,CAAC,WAAW,GAAG,eAAe,GAAG,QAAQ,CAAC,EAAE,CAAC;IACtD,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,GAAG;IAChD,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAEzE,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,YAAY,CAAC;AAC5D,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,YAAY,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,EAAE,gBAAgB,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,WAAW,IAAI,CAAC,WAAW,SAAS,OAAO,GAAG,OAAO;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACtF;IACD,IAAI,EAAE,gBAAgB,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,GACC;IACD,IAAI,EAAE,gBAAgB,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,GACC;IACD,IAAI,EAAE,cAAc,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,GACC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC1F;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GAC7F;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAEhG;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACvC,wFAAwF;IACxF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yGAAyG;IACzG,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yFAAyF;IACzF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,qIAAqI;IACrI,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,uBAAuB,GAAG,YAAY,CAAC;IACxD,sFAAsF;IACtF,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,2HAA2H;IAC3H,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAC3C,4HAA4H;IAC5H,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,wJAAwJ;IACxJ,2CAA2C,CAAC,EAAE,OAAO,CAAC;IACtD,qbAAqb;IACrb,cAAc,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,oBAAoB,CAAC;IAC3G,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,iGAAiG;IACjG,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,0GAA0G;IAC1G,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2FAA2F;IAC3F,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iMAAiM;IACjM,kBAAkB,CAAC,EAAE,WAAW,CAAC;IACjC,0QAA0Q;IAC1Q,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,oLAAoL;IACpL,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,wDAAwD;AACxD,MAAM,WAAW,qBAAqB;IACrC,qIAAqI;IACrI,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oFAAoF;IACpF,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,qEAAqE;AACrE,MAAM,WAAW,uBAAuB;IACvC;;;;;;OAMG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAC1C,+GAA+G;IAC/G,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;OAMG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4GAA4G;IAC5G,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,yJAAyJ;IACzJ,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,+EAA+E;IAC/E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+EAA+E;IAC/E,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2GAA2G;IAC3G,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kIAAkI;IAClI,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,yHAAyH;IACzH,IAAI,CAAC,EACF,MAAM,GACN;QACA,4DAA4D;QAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,0DAA0D;QAC1D,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACL,8CAA8C;IAC9C,SAAS,CAAC,EAAE;QACX,uCAAuC;QACvC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACzB,2CAA2C;QAC3C,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC7B,uBAAuB;QACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,4BAA4B;QAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,yBAAyB;QACzB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KAC1B,CAAC;IACF,oIAAoI;IACpI,wBAAwB,CAAC,EACtB,MAAM,GACN;QACA,oDAAoD;QACpD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,oDAAoD;QACpD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,oDAAoD;QACpD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,oDAAoD;QACpD,GAAG,CAAC,EAAE,MAAM,CAAC;KACZ,CAAC;IACL,2HAA2H;IAC3H,qBAAqB,CAAC,EACnB,MAAM,GACN;QACA,yDAAyD;QACzD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,yDAAyD;QACzD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,yDAAyD;QACzD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,yDAAyD;QACzD,GAAG,CAAC,EAAE,MAAM,CAAC;KACZ,CAAC;CACL;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,MAAM,WAAW,KAAK,CAAC,IAAI,SAAS,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,KAAK,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kGAAkG;IAClG,MAAM,CAAC,EAAE,IAAI,SAAS,oBAAoB,GACvC,uBAAuB,GACvB,IAAI,SAAS,kBAAkB,GAC9B,qBAAqB,GACrB,IAAI,SAAS,oBAAoB,GAChC,uBAAuB,GACvB,KAAK,CAAC;CACX;AAED,MAAM,WAAW,WAAW,CAAC,IAAI,SAAS,SAAS,CAClD,SAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,WAAW,GAAG,eAAe,GAAG,WAAW,GAAG,QAAQ,CAAC;IACrG,GAAG,EAAE,IAAI,CAAC;IACV,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC7B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sdk/ai/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/tools/find.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAMnG,QAAA,MAAM,UAAU;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../../../src/sdk/coding-agent/core/tools/find.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAMnG,QAAA,MAAM,UAAU;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAiDtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,2BAA2B;IAC3B,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC7D,4EAA4E;IAC5E,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CACnH;AAQD,MAAM,WAAW,eAAe;IAC/B,oEAAoE;IACpE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAmDD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CA0QhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
|
|
@@ -19,6 +19,48 @@ const findSchema = Type.Object({
|
|
|
19
19
|
limit: Type.Optional(Type.Number({ description: "Maximum number of results (default: 1000)" })),
|
|
20
20
|
});
|
|
21
21
|
const DEFAULT_LIMIT = 1000;
|
|
22
|
+
// Hard cap on how long a single fd invocation may run. Prevents the find tool
|
|
23
|
+
// from hanging indefinitely when the search root contains large/irrelevant
|
|
24
|
+
// trees (node_modules, .git, .next, build artifacts, project temp folders).
|
|
25
|
+
const FD_TIMEOUT_MS = 20_000;
|
|
26
|
+
// Directories and patterns excluded from fd searches regardless of .gitignore.
|
|
27
|
+
// These are a safety net for trees that have no/incomplete .gitignore, and they
|
|
28
|
+
// also catch project-specific temp folders the agent itself creates.
|
|
29
|
+
const FD_EXCLUDE_PATTERNS = [
|
|
30
|
+
"node_modules",
|
|
31
|
+
".git",
|
|
32
|
+
".next",
|
|
33
|
+
"dist",
|
|
34
|
+
"build",
|
|
35
|
+
".turbo",
|
|
36
|
+
".cache",
|
|
37
|
+
".tmp",
|
|
38
|
+
"tmp",
|
|
39
|
+
".spectral",
|
|
40
|
+
".agent-cache",
|
|
41
|
+
".visual-agent-output",
|
|
42
|
+
"coverage",
|
|
43
|
+
".deno-cache",
|
|
44
|
+
"*.log",
|
|
45
|
+
];
|
|
46
|
+
// Glob equivalents of FD_EXCLUDE_PATTERNS, used by the custom glob branch.
|
|
47
|
+
const GLOB_IGNORE_PATTERNS = [
|
|
48
|
+
"**/node_modules/**",
|
|
49
|
+
"**/.git/**",
|
|
50
|
+
"**/.next/**",
|
|
51
|
+
"**/dist/**",
|
|
52
|
+
"**/build/**",
|
|
53
|
+
"**/.turbo/**",
|
|
54
|
+
"**/.cache/**",
|
|
55
|
+
"**/.tmp/**",
|
|
56
|
+
"**/tmp/**",
|
|
57
|
+
"**/.spectral/**",
|
|
58
|
+
"**/.agent-cache/**",
|
|
59
|
+
"**/.visual-agent-output/**",
|
|
60
|
+
"**/coverage/**",
|
|
61
|
+
"**/.deno-cache/**",
|
|
62
|
+
"**/*.log",
|
|
63
|
+
];
|
|
22
64
|
const defaultFindOperations = {
|
|
23
65
|
exists: existsSync,
|
|
24
66
|
// This is a placeholder. Actual fd execution happens in execute() when no custom glob is provided.
|
|
@@ -106,7 +148,7 @@ export function createFindToolDefinition(cwd, options) {
|
|
|
106
148
|
return;
|
|
107
149
|
}
|
|
108
150
|
const results = await ops.glob(pattern, searchPath, {
|
|
109
|
-
ignore: [
|
|
151
|
+
ignore: [...GLOB_IGNORE_PATTERNS],
|
|
110
152
|
limit: effectiveLimit,
|
|
111
153
|
});
|
|
112
154
|
if (signal?.aborted) {
|
|
@@ -162,14 +204,20 @@ export function createFindToolDefinition(cwd, options) {
|
|
|
162
204
|
// Build fd arguments. --no-require-git makes fd apply hierarchical .gitignore
|
|
163
205
|
// semantics whether or not the search path is inside a git repository, without
|
|
164
206
|
// leaking sibling-directory rules the way --ignore-file (a global source) would.
|
|
207
|
+
// --hidden is intentionally omitted: it caused fd to descend into .git/ and
|
|
208
|
+
// .next/, which is the #1 cause of the find tool hanging on large trees.
|
|
165
209
|
const args = [
|
|
166
210
|
"--glob",
|
|
167
211
|
"--color=never",
|
|
168
|
-
"--hidden",
|
|
169
212
|
"--no-require-git",
|
|
170
213
|
"--max-results",
|
|
171
214
|
String(effectiveLimit),
|
|
172
215
|
];
|
|
216
|
+
// Safety net excludes independent of .gitignore (handles trees with no or
|
|
217
|
+
// incomplete .gitignore). fd accepts repeated --exclude args.
|
|
218
|
+
for (const pattern of FD_EXCLUDE_PATTERNS) {
|
|
219
|
+
args.push("--exclude", pattern);
|
|
220
|
+
}
|
|
173
221
|
// fd --glob matches against the basename unless --full-path is set; in --full-path
|
|
174
222
|
// mode it matches against the absolute candidate path, so a path-containing
|
|
175
223
|
// pattern like 'src/**/*.spec.ts' needs a leading '**/' to match anything.
|
|
@@ -185,12 +233,21 @@ export function createFindToolDefinition(cwd, options) {
|
|
|
185
233
|
const rl = createInterface({ input: child.stdout });
|
|
186
234
|
let stderr = "";
|
|
187
235
|
const lines = [];
|
|
236
|
+
// Kill fd if it runs longer than FD_TIMEOUT_MS. Without this, a search
|
|
237
|
+
// rooted at a large tree can hang the find tool indefinitely.
|
|
238
|
+
let timedOut = false;
|
|
239
|
+
const timeoutHandle = setTimeout(() => {
|
|
240
|
+
timedOut = true;
|
|
241
|
+
child.kill("SIGTERM");
|
|
242
|
+
}, FD_TIMEOUT_MS);
|
|
243
|
+
const clearTimer = () => clearTimeout(timeoutHandle);
|
|
188
244
|
stopChild = () => {
|
|
189
245
|
if (!child.killed) {
|
|
190
246
|
child.kill();
|
|
191
247
|
}
|
|
192
248
|
};
|
|
193
249
|
const cleanup = () => {
|
|
250
|
+
clearTimer();
|
|
194
251
|
rl.close();
|
|
195
252
|
};
|
|
196
253
|
child.stderr?.on("data", (chunk) => {
|
|
@@ -205,6 +262,10 @@ export function createFindToolDefinition(cwd, options) {
|
|
|
205
262
|
});
|
|
206
263
|
child.on("close", (code) => {
|
|
207
264
|
cleanup();
|
|
265
|
+
if (timedOut) {
|
|
266
|
+
settle(() => reject(new Error(`Search timed out after ${FD_TIMEOUT_MS / 1000}s — the search scope was too large. Try narrowing the path or pattern.`)));
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
208
269
|
if (signal?.aborted) {
|
|
209
270
|
settle(() => reject(new Error("Operation aborted")));
|
|
210
271
|
return;
|
|
@@ -139,6 +139,8 @@ export interface AgentBridgeOptions {
|
|
|
139
139
|
}
|
|
140
140
|
export declare class AgentBridge {
|
|
141
141
|
private session?;
|
|
142
|
+
private suppressNextAgentEndForGeneration;
|
|
143
|
+
private turnGeneration;
|
|
142
144
|
private sessionManager?;
|
|
143
145
|
private unsubscribe?;
|
|
144
146
|
private pending?;
|
|
@@ -164,6 +166,8 @@ export declare class AgentBridge {
|
|
|
164
166
|
* envelopes carrying the same modelId don't churn spectral's internal state.
|
|
165
167
|
*/
|
|
166
168
|
private lastAppliedModelId?;
|
|
169
|
+
private promptActivityTimer?;
|
|
170
|
+
private promptReject?;
|
|
167
171
|
/** Current model's credit rates (from availableAgentModels), used for token_usage. */
|
|
168
172
|
private activeCreditRates;
|
|
169
173
|
private memoryPhase;
|
|
@@ -326,6 +330,14 @@ export declare class AgentBridge {
|
|
|
326
330
|
* `customInstructions` forwards guidance to compaction hooks so memory
|
|
327
331
|
* observations can stay relevant to the current task.
|
|
328
332
|
*/
|
|
333
|
+
private withPromptTimeout;
|
|
334
|
+
/**
|
|
335
|
+
* Reset the inactivity watchdog. Called from `handleEvent` on EVERY session
|
|
336
|
+
* event so a long-running prompt that is actively streaming / calling tools
|
|
337
|
+
* is never killed by the inactivity timeout.
|
|
338
|
+
*/
|
|
339
|
+
private bumpPromptActivity;
|
|
340
|
+
private clearPromptTimers;
|
|
329
341
|
compact(options?: string | AgentBridgeCompactionOptions): Promise<CompactionResult>;
|
|
330
342
|
dispose(): void;
|
|
331
343
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-bridge.d.ts","sourceRoot":"","sources":["../../src/server/agent-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAaH,OAAO,EAQL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EAEtB,MAAM,8BAA8B,CAAC;AAYtC,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAatC,OAAO,EACL,kBAAkB,IAAI,yBAAyB,EAEhD,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3E,UAAU,4BAA4B;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CACpC;AAkBD,sEAAsE;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,yBAAyB,CAAC;AAmCpE,MAAM,WAAW,kBAAkB;IACjC,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,0BAA0B,EAAE,CAAC,GAAG,EAAE;QAChC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,6EAA6E;QAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX;;;OAGG;IACH,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC9C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"agent-bridge.d.ts","sourceRoot":"","sources":["../../src/server/agent-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAaH,OAAO,EAQL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EAEtB,MAAM,8BAA8B,CAAC;AAYtC,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAatC,OAAO,EACL,kBAAkB,IAAI,yBAAyB,EAEhD,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3E,UAAU,4BAA4B;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CACpC;AAkBD,sEAAsE;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,yBAAyB,CAAC;AAmCpE,MAAM,WAAW,kBAAkB;IACjC,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,0BAA0B,EAAE,CAAC,GAAG,EAAE;QAChC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,6EAA6E;QAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX;;;OAGG;IACH,yBAAyB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC9C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAkjBD,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAC,CAAe;IAC/B,OAAO,CAAC,iCAAiC,CAAqB;IAC9D,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,WAAW,CAAC,CAAa;IACjC,OAAO,CAAC,OAAO,CAAC,CAA0B;IAC1C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C;;;;;OAKG;IACH,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB,CAAC,CAAS;IAEpC,OAAO,CAAC,mBAAmB,CAAC,CAAgC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAuB;IAC5C,sFAAsF;IACtF,OAAO,CAAC,iBAAiB,CAMT;IAChB,OAAO,CAAC,WAAW,CACuD;IAC1E,OAAO,CAAC,mBAAmB,CAA+B;IAC1D;;;;OAIG;IACH,OAAO,CAAC,cAAc,CAAuB;gBAEjC,IAAI,EAAE,kBAAkB;IAIpC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiV5B,OAAO,CAAC,4BAA4B;IAWpC;;;;;OAKG;YACW,qBAAqB;IAcnC;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;YAI7B,oBAAoB;IAoBlC;;;;;;;;;;;;OAYG;IACH;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,0BAA0B;IA+GlC;;;;;;;;;;;;;;;OAeG;IACH;;;;;;;;OAQG;IACH,wBAAwB,IAAI,MAAM,GAAG,SAAS;IAI9C;;;;OAIG;IACH,eAAe,IACX;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GACxE,SAAS;IAIb,gBAAgB,IAAI,KAAK,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IAgBF,iBAAiB,IAAI;QACnB,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;QACtE,QAAQ,EAAE;YACR,QAAQ,EAAE,OAAO,CAAC;YAClB,UAAU,EAAE,OAAO,CAAC;YACpB,UAAU,EAAE,OAAO,CAAC;YACpB,MAAM,EAAE,OAAO,CAAC;SACjB,CAAC;KACH;IAYD,OAAO,CAAC,iBAAiB;IAmCnB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IA2DpE;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iCAAiC;IAkBzC;;;;;;OAMG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAoBpD;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CrE;;;;;;;;OAQG;YACW,iBAAiB;IAsB/B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,iBAAiB;IAOnB,OAAO,CACX,OAAO,CAAC,EAAE,MAAM,GAAG,4BAA4B,GAC9C,OAAO,CAAC,gBAAgB,CAAC;IAY5B,OAAO,IAAI,IAAI;IA2Bf;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,sBAAsB;IAuD9B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI;CAydzC"}
|
|
@@ -486,18 +486,14 @@ function parseWireToolEvents(eventsJsonl) {
|
|
|
486
486
|
/**
|
|
487
487
|
* Safety clean-up for content blocks rehydrated from persisted wire events.
|
|
488
488
|
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
* they can trigger 400 API errors (unsupported image content in tool results)
|
|
493
|
-
* or context-window overflow — both surface as "skipping empty intermediate
|
|
494
|
-
* message" / hung sessions after reconnect.
|
|
489
|
+
* Rehydrated tool-result content is bounded for the model-facing context,
|
|
490
|
+
* while the original wire event remains available to the UI for rendering
|
|
491
|
+
* images and other rich results.
|
|
495
492
|
*/
|
|
496
493
|
const MAX_REHYDRATED_TEXT = 100_000;
|
|
497
494
|
function sanitizeRehydratedBlock(block) {
|
|
498
|
-
//
|
|
499
|
-
//
|
|
500
|
-
// models often only accept images in user-turn content).
|
|
495
|
+
// Tool-result image blocks are not accepted by every provider; the raw
|
|
496
|
+
// result remains in events_jsonl for the UI, while the model gets a compact reference.
|
|
501
497
|
if (block.type === "image") {
|
|
502
498
|
const sizeBytes = typeof block.data === "string" ? block.data.length : 0;
|
|
503
499
|
return {
|
|
@@ -537,8 +533,22 @@ function toRestoredMemorySnapshot(snapshot) {
|
|
|
537
533
|
details: normalizeSnapshotDetails(snapshot.details),
|
|
538
534
|
};
|
|
539
535
|
}
|
|
536
|
+
/**
|
|
537
|
+
* Inactivity-based prompt hang watchdog. Unlike a fixed wall-clock deadline,
|
|
538
|
+
* this only fires when the agent session has emitted NO events (text deltas,
|
|
539
|
+
* tool calls, tool results, thinking, message boundaries) for the configured
|
|
540
|
+
* window. Long-running but active prompts (multi-turn tool use, builds,
|
|
541
|
+
* subagents, streaming) are NOT killed — only truly stuck sessions are.
|
|
542
|
+
*
|
|
543
|
+
* Reset on every `AgentSessionEvent` seen by `handleEvent`. Default 120s of
|
|
544
|
+
* total silence. Hard ceiling removed — working agents (including
|
|
545
|
+
* subagents) must never be killed by a wall-clock timeout.
|
|
546
|
+
*/
|
|
547
|
+
const PROMPT_INACTIVITY_TIMEOUT_MS = Number(process.env.SPECTRAL_PROMPT_INACTIVITY_MS) || 2 * 60 * 1000;
|
|
540
548
|
export class AgentBridge {
|
|
541
549
|
session;
|
|
550
|
+
suppressNextAgentEndForGeneration;
|
|
551
|
+
turnGeneration = 0;
|
|
542
552
|
sessionManager;
|
|
543
553
|
unsubscribe;
|
|
544
554
|
pending;
|
|
@@ -564,6 +574,8 @@ export class AgentBridge {
|
|
|
564
574
|
* envelopes carrying the same modelId don't churn spectral's internal state.
|
|
565
575
|
*/
|
|
566
576
|
lastAppliedModelId;
|
|
577
|
+
promptActivityTimer;
|
|
578
|
+
promptReject;
|
|
567
579
|
/** Current model's credit rates (from availableAgentModels), used for token_usage. */
|
|
568
580
|
activeCreditRates = null;
|
|
569
581
|
memoryPhase = "idle";
|
|
@@ -1268,16 +1280,37 @@ export class AgentBridge {
|
|
|
1268
1280
|
data: img.data,
|
|
1269
1281
|
mimeType: img.mimeType,
|
|
1270
1282
|
}));
|
|
1271
|
-
await this.session.prompt(text, { images: imageContents });
|
|
1283
|
+
await this.withPromptTimeout(this.session.prompt(text, { images: imageContents }));
|
|
1272
1284
|
}
|
|
1273
1285
|
else {
|
|
1274
|
-
await this.session.prompt(text);
|
|
1286
|
+
await this.withPromptTimeout(this.session.prompt(text));
|
|
1275
1287
|
}
|
|
1276
1288
|
}
|
|
1277
1289
|
catch (err) {
|
|
1278
1290
|
const e = err instanceof Error ? err : new Error(String(err));
|
|
1279
1291
|
this.opts.onError?.(e);
|
|
1292
|
+
// The prompt promise may never resolve after a timeout, so the upstream
|
|
1293
|
+
// agent_end is not a reliable persistence boundary. Preserve the
|
|
1294
|
+
// partial assistant/tool turn before closing it synthetically; the
|
|
1295
|
+
// subsequent upstream agent_end is suppressed below.
|
|
1296
|
+
this.finalizePendingMessage();
|
|
1297
|
+
this.pending = undefined;
|
|
1298
|
+
this.suppressNextAgentEndForGeneration = this.turnGeneration;
|
|
1299
|
+
// Root-cause fix: when the prompt times out (or any prompt rejection
|
|
1300
|
+
// fires), the SDK session is still running because Promise.race does
|
|
1301
|
+
// not cancel the underlying `session.prompt()` call. The SDK keeps
|
|
1302
|
+
// emitting events (notably `message_start`), which would re-arm
|
|
1303
|
+
// `currentTurn` downstream and leave the session stuck in "streaming"
|
|
1304
|
+
// forever. Abort the SDK session best-effort so it stops emitting; a
|
|
1305
|
+
// failure here must not mask the original error.
|
|
1306
|
+
try {
|
|
1307
|
+
await this.session?.abort();
|
|
1308
|
+
}
|
|
1309
|
+
catch {
|
|
1310
|
+
// best-effort: abort failure must not propagate out of error handler
|
|
1311
|
+
}
|
|
1280
1312
|
this.opts.emit({ type: "error", message: e.message });
|
|
1313
|
+
this.opts.emit({ type: "agent_end" });
|
|
1281
1314
|
}
|
|
1282
1315
|
}
|
|
1283
1316
|
/**
|
|
@@ -1289,6 +1322,44 @@ export class AgentBridge {
|
|
|
1289
1322
|
* `customInstructions` forwards guidance to compaction hooks so memory
|
|
1290
1323
|
* observations can stay relevant to the current task.
|
|
1291
1324
|
*/
|
|
1325
|
+
async withPromptTimeout(prompt) {
|
|
1326
|
+
// Activity-based watchdog: reset on every session event via
|
|
1327
|
+
// `bumpPromptActivity()`. Only triggers on total silence, NOT on long
|
|
1328
|
+
// active prompts. Hard ceiling removed — working agents (including
|
|
1329
|
+
// subagents) must never be killed by a wall-clock timeout.
|
|
1330
|
+
const inactivityPromise = new Promise((_, reject) => {
|
|
1331
|
+
this.promptReject = reject;
|
|
1332
|
+
this.promptActivityTimer = setTimeout(() => {
|
|
1333
|
+
reject(new Error(`Agent prompt inactive for ${PROMPT_INACTIVITY_TIMEOUT_MS / 1000}s`));
|
|
1334
|
+
}, PROMPT_INACTIVITY_TIMEOUT_MS);
|
|
1335
|
+
});
|
|
1336
|
+
try {
|
|
1337
|
+
await Promise.race([prompt, inactivityPromise]);
|
|
1338
|
+
}
|
|
1339
|
+
finally {
|
|
1340
|
+
this.clearPromptTimers();
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Reset the inactivity watchdog. Called from `handleEvent` on EVERY session
|
|
1345
|
+
* event so a long-running prompt that is actively streaming / calling tools
|
|
1346
|
+
* is never killed by the inactivity timeout.
|
|
1347
|
+
*/
|
|
1348
|
+
bumpPromptActivity() {
|
|
1349
|
+
if (!this.promptActivityTimer)
|
|
1350
|
+
return;
|
|
1351
|
+
clearTimeout(this.promptActivityTimer);
|
|
1352
|
+
this.promptActivityTimer = setTimeout(() => {
|
|
1353
|
+
this.promptReject?.(new Error(`Agent prompt inactive for ${PROMPT_INACTIVITY_TIMEOUT_MS / 1000}s`));
|
|
1354
|
+
}, PROMPT_INACTIVITY_TIMEOUT_MS);
|
|
1355
|
+
}
|
|
1356
|
+
clearPromptTimers() {
|
|
1357
|
+
if (this.promptActivityTimer) {
|
|
1358
|
+
clearTimeout(this.promptActivityTimer);
|
|
1359
|
+
this.promptActivityTimer = undefined;
|
|
1360
|
+
}
|
|
1361
|
+
this.promptReject = undefined;
|
|
1362
|
+
}
|
|
1292
1363
|
async compact(options) {
|
|
1293
1364
|
if (!this.session)
|
|
1294
1365
|
throw new Error("AgentBridge.start() not called");
|
|
@@ -1325,6 +1396,7 @@ export class AgentBridge {
|
|
|
1325
1396
|
this.session = undefined;
|
|
1326
1397
|
this.unsubscribe = undefined;
|
|
1327
1398
|
this.pending = undefined;
|
|
1399
|
+
this.clearPromptTimers();
|
|
1328
1400
|
}
|
|
1329
1401
|
// --- internals -----------------------------------------------------------
|
|
1330
1402
|
/**
|
|
@@ -1412,12 +1484,16 @@ export class AgentBridge {
|
|
|
1412
1484
|
handleEvent(ev) {
|
|
1413
1485
|
if (this.disposed)
|
|
1414
1486
|
return;
|
|
1487
|
+
// Reset inactivity watchdog on every session event so long active
|
|
1488
|
+
// prompts (multi-tool, streaming, subagents) are not killed.
|
|
1489
|
+
this.bumpPromptActivity();
|
|
1415
1490
|
switch (ev.type) {
|
|
1416
1491
|
case "message_start": {
|
|
1417
1492
|
// Only assistant messages get our message_start frame on the wire.
|
|
1418
1493
|
// User messages are persisted separately by the routes layer.
|
|
1419
1494
|
if (ev.message.role !== "assistant")
|
|
1420
1495
|
return;
|
|
1496
|
+
this.turnGeneration += 1;
|
|
1421
1497
|
// Finalize the previous pending message (if any) before starting a
|
|
1422
1498
|
// new one. This captures tool events that arrived after the previous
|
|
1423
1499
|
// `message_end` but before this `message_start`. Deferred persistence
|
|
@@ -1710,6 +1786,13 @@ export class AgentBridge {
|
|
|
1710
1786
|
return;
|
|
1711
1787
|
}
|
|
1712
1788
|
case "agent_end": {
|
|
1789
|
+
if (this.suppressNextAgentEndForGeneration !== undefined) {
|
|
1790
|
+
const isSameTurn = this.suppressNextAgentEndForGeneration === this.turnGeneration;
|
|
1791
|
+
this.suppressNextAgentEndForGeneration = undefined;
|
|
1792
|
+
if (isSameTurn)
|
|
1793
|
+
return;
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1713
1796
|
// Finalize the last pending message before closing the turn. After
|
|
1714
1797
|
// `agent_end`, no more tool events will arrive, so this is the final
|
|
1715
1798
|
// persistence opportunity for the current message.
|
|
@@ -227,6 +227,8 @@ export interface SessionStreamManagerOptions {
|
|
|
227
227
|
machineJwt: string;
|
|
228
228
|
bridgeFactory?: BridgeFactory;
|
|
229
229
|
agentDir?: string;
|
|
230
|
+
onTurnEnd?: () => void | Promise<void>;
|
|
231
|
+
onDispose?: () => void | Promise<void>;
|
|
230
232
|
}
|
|
231
233
|
export declare class SessionStreamManager {
|
|
232
234
|
private readonly store;
|
|
@@ -235,6 +237,8 @@ export declare class SessionStreamManager {
|
|
|
235
237
|
private readonly machineJwt;
|
|
236
238
|
private readonly bridgeFactory;
|
|
237
239
|
private readonly agentDir;
|
|
240
|
+
private readonly onTurnEnd;
|
|
241
|
+
private readonly onDispose;
|
|
238
242
|
private readonly broker;
|
|
239
243
|
private readonly streams;
|
|
240
244
|
private readonly managerCompactions;
|
|
@@ -380,6 +384,9 @@ export declare class SessionStreamManager {
|
|
|
380
384
|
private getIntervalEventSnapshot;
|
|
381
385
|
private scheduleIntervalTick;
|
|
382
386
|
private clearIntervalTimer;
|
|
387
|
+
private clearCurrentTurnSilenceTimer;
|
|
388
|
+
private armCurrentTurnSilenceTimer;
|
|
389
|
+
private handleCurrentTurnSilenceTimeout;
|
|
383
390
|
private intervalTick;
|
|
384
391
|
/**
|
|
385
392
|
* Fork & Compact: trigger compaction after the first assistant turn of a
|
|
@@ -396,6 +403,7 @@ export declare class SessionStreamManager {
|
|
|
396
403
|
private sendNextLoopIteration;
|
|
397
404
|
private createStream;
|
|
398
405
|
private handleBridgeEvent;
|
|
406
|
+
private runTurnCleanup;
|
|
399
407
|
/**
|
|
400
408
|
* Flush the current in-flight turn's events to SQLite for crash recovery.
|
|
401
409
|
* Only the events accumulated since the last flush are written — we append
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-stream.d.ts","sourceRoot":"","sources":["../../src/server/session-stream.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"session-stream.d.ts","sourceRoot":"","sources":["../../src/server/session-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,6 +51,32 @@ import { reflectionContent, reflectionId } from "../memory/types.js";
|
|
|
51
51
|
const DEFAULT_BRIDGE_FACTORY = (args) => new AgentBridge(args);
|
|
52
52
|
/** Safety limit for autonomous loop iterations per session. */
|
|
53
53
|
const MAX_LOOP_ITERATIONS = 100;
|
|
54
|
+
// Fix E: safety-net for stale `currentTurn`. When an agent hangs, crashes,
|
|
55
|
+
// or the WS drops during sleep, `agent_end` may never arrive and
|
|
56
|
+
// `stream.currentTurn` stays non-null forever. On reconnect, `session_ready`
|
|
57
|
+
// then reports `currentTurn != null`, so landing shows a phantom "streaming"
|
|
58
|
+
// status. This timer clears the stale turn and emits a synthetic `agent_end`
|
|
59
|
+
// after 5 minutes of silence on streaming-meaningful events.
|
|
60
|
+
const CURRENT_TURN_SILENCE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
61
|
+
// Streaming-meaningful events that reset the silence timer while a turn is
|
|
62
|
+
// active. Mirrors Fix C on the landing side, but EXCLUDES `token_usage`
|
|
63
|
+
// (arrives post-turn) and excludes terminal/control events handled by their
|
|
64
|
+
// own branches (`agent_end`, `error`) and non-streaming side channels
|
|
65
|
+
// (`inter_agent_observation`, `agent_notification`, `queue_changed`,
|
|
66
|
+
// `session_renamed`, `interval_*`, `loop_*`, `compaction_*`).
|
|
67
|
+
const STREAMING_MEANINGFUL_EVENT_TYPES = new Set([
|
|
68
|
+
"message_start",
|
|
69
|
+
"text_delta",
|
|
70
|
+
"thinking_start",
|
|
71
|
+
"thinking_delta",
|
|
72
|
+
"thinking_end",
|
|
73
|
+
"tool_call",
|
|
74
|
+
"tool_result",
|
|
75
|
+
"message_end",
|
|
76
|
+
"subagent_start",
|
|
77
|
+
"subagent_progress",
|
|
78
|
+
"subagent_end",
|
|
79
|
+
]);
|
|
54
80
|
/**
|
|
55
81
|
* Defensive cap for fresh-bridge history replay when we already have a
|
|
56
82
|
* persisted observational-memory snapshot. spectral's own compaction keeps a
|
|
@@ -430,6 +456,8 @@ export class SessionStreamManager {
|
|
|
430
456
|
machineJwt;
|
|
431
457
|
bridgeFactory;
|
|
432
458
|
agentDir;
|
|
459
|
+
onTurnEnd;
|
|
460
|
+
onDispose;
|
|
433
461
|
broker;
|
|
434
462
|
streams = new Map();
|
|
435
463
|
managerCompactions = new Map();
|
|
@@ -441,6 +469,8 @@ export class SessionStreamManager {
|
|
|
441
469
|
this.machineJwt = opts.machineJwt;
|
|
442
470
|
this.bridgeFactory = opts.bridgeFactory ?? DEFAULT_BRIDGE_FACTORY;
|
|
443
471
|
this.agentDir = opts.agentDir;
|
|
472
|
+
this.onTurnEnd = opts.onTurnEnd;
|
|
473
|
+
this.onDispose = opts.onDispose;
|
|
444
474
|
// Broker for project-scoped inter-session communication.
|
|
445
475
|
this.broker = new InterAgentBroker({ store: this.store });
|
|
446
476
|
// Wire the project observations store singleton so the memory extension's
|
|
@@ -954,7 +984,12 @@ export class SessionStreamManager {
|
|
|
954
984
|
events: [],
|
|
955
985
|
assistantText: "",
|
|
956
986
|
persistedEventCount: 0,
|
|
987
|
+
cleanupStarted: false,
|
|
957
988
|
};
|
|
989
|
+
// New prompt dispatched — clear the turn-closed fence so legitimate
|
|
990
|
+
// next-turn events (including the upcoming `message_start`) are not
|
|
991
|
+
// rejected. The fence is re-armed if this turn later closes.
|
|
992
|
+
stream.closedTurnGeneration = null;
|
|
958
993
|
// 4. Fire spectral. `prompt` resolves on agent_end; errors inside
|
|
959
994
|
// AgentBridge are caught and emitted as wire errors. Synchronous throws
|
|
960
995
|
// (e.g. disposed bridge, missing session) arrive as a rejected promise
|
|
@@ -980,6 +1015,8 @@ export class SessionStreamManager {
|
|
|
980
1015
|
for (const stream of this.streams.values()) {
|
|
981
1016
|
stream.loopActive = false;
|
|
982
1017
|
this.clearIntervalTimer(stream);
|
|
1018
|
+
// Fix E: drop any in-flight safety-net timers on teardown.
|
|
1019
|
+
this.clearCurrentTurnSilenceTimer(stream);
|
|
983
1020
|
try {
|
|
984
1021
|
stream.bridge.dispose();
|
|
985
1022
|
}
|
|
@@ -989,6 +1026,11 @@ export class SessionStreamManager {
|
|
|
989
1026
|
stream.subscribers.clear();
|
|
990
1027
|
}
|
|
991
1028
|
this.streams.clear();
|
|
1029
|
+
if (this.onDispose) {
|
|
1030
|
+
void Promise.resolve(this.onDispose()).catch((err) => {
|
|
1031
|
+
console.error(`[spectral] error: session cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
992
1034
|
}
|
|
993
1035
|
/** Test/inspection helper: how many streams are currently tracked. */
|
|
994
1036
|
streamCount() {
|
|
@@ -1041,6 +1083,10 @@ export class SessionStreamManager {
|
|
|
1041
1083
|
// through handleBridgeEvent — which clears currentTurn. We must
|
|
1042
1084
|
// broadcast agent_end regardless of what dispose() does to currentTurn.
|
|
1043
1085
|
const hadTurn = stream.currentTurn != null;
|
|
1086
|
+
// Fix E: cancelTurn forces a turn end — clear the safety-net timer so
|
|
1087
|
+
// the synthetic agent_end below isn't later double-emitted by a stale
|
|
1088
|
+
// timer.
|
|
1089
|
+
this.clearCurrentTurnSilenceTimer(stream);
|
|
1044
1090
|
// Dispose the agent bridge immediately — this tears down spectral's session and
|
|
1045
1091
|
// unsubscribe. The bridge's own event handler is detached; no further
|
|
1046
1092
|
// events will flow. We broadcast agent_end ourselves below.
|
|
@@ -1064,8 +1110,11 @@ export class SessionStreamManager {
|
|
|
1064
1110
|
// may have cleared currentTurn via an error event from the torn-down
|
|
1065
1111
|
// spectral session.
|
|
1066
1112
|
if (hadTurn) {
|
|
1113
|
+
const cancelledTurn = stream.currentTurn;
|
|
1067
1114
|
this.broadcast(stream, { type: "agent_end" });
|
|
1115
|
+
this.runTurnCleanup(cancelledTurn);
|
|
1068
1116
|
stream.currentTurn = null;
|
|
1117
|
+
stream.closedTurnGeneration = stream.bridgeTurnGeneration;
|
|
1069
1118
|
this.maybeAutoDequeue(stream);
|
|
1070
1119
|
}
|
|
1071
1120
|
// Don't delete the stream — the subscribers are still attached and the
|
|
@@ -1228,6 +1277,51 @@ export class SessionStreamManager {
|
|
|
1228
1277
|
stream.intervalTimer = null;
|
|
1229
1278
|
}
|
|
1230
1279
|
}
|
|
1280
|
+
// ---- Fix E: currentTurn silence safety-net timer ----
|
|
1281
|
+
clearCurrentTurnSilenceTimer(stream) {
|
|
1282
|
+
if (stream.currentTurnSilenceTimer) {
|
|
1283
|
+
clearTimeout(stream.currentTurnSilenceTimer);
|
|
1284
|
+
stream.currentTurnSilenceTimer = null;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
armCurrentTurnSilenceTimer(stream) {
|
|
1288
|
+
this.clearCurrentTurnSilenceTimer(stream);
|
|
1289
|
+
stream.currentTurnSilenceTimer = setTimeout(() => {
|
|
1290
|
+
this.handleCurrentTurnSilenceTimeout(stream);
|
|
1291
|
+
}, CURRENT_TURN_SILENCE_TIMEOUT_MS);
|
|
1292
|
+
}
|
|
1293
|
+
handleCurrentTurnSilenceTimeout(stream) {
|
|
1294
|
+
stream.currentTurnSilenceTimer = null;
|
|
1295
|
+
// Guard against double-fire: if currentTurn was already cleared
|
|
1296
|
+
// naturally (agent_end / error / cancelTurn) the timer is normally
|
|
1297
|
+
// cancelled, but defend against a race where a natural clear raced the
|
|
1298
|
+
// timer's expiry callback.
|
|
1299
|
+
if (stream.currentTurn == null)
|
|
1300
|
+
return;
|
|
1301
|
+
const sessionId = stream.sessionId;
|
|
1302
|
+
console.warn(`[session-stream] currentTurn silence timeout fired ` +
|
|
1303
|
+
`(${CURRENT_TURN_SILENCE_TIMEOUT_MS / 1000}s without a ` +
|
|
1304
|
+
`streaming-meaningful event), emitting synthetic agent_end ` +
|
|
1305
|
+
`for session ${sessionId}`);
|
|
1306
|
+
const finishedTurn = stream.currentTurn;
|
|
1307
|
+
stream.currentMessageId = null;
|
|
1308
|
+
stream.lastFlushedEventCount = 0;
|
|
1309
|
+
stream.currentTurn = null;
|
|
1310
|
+
stream.closedTurnGeneration = stream.bridgeTurnGeneration;
|
|
1311
|
+
// Reuse the normal broadcast path so relay subscribers (landing
|
|
1312
|
+
// WebSocket clients) receive agent_end and stop showing "streaming".
|
|
1313
|
+
this.broadcast(stream, { type: "agent_end" });
|
|
1314
|
+
this.runTurnCleanup(finishedTurn);
|
|
1315
|
+
if (!this.disposed) {
|
|
1316
|
+
try {
|
|
1317
|
+
this.maybeAutoDequeue(stream);
|
|
1318
|
+
}
|
|
1319
|
+
catch (err) {
|
|
1320
|
+
console.error(`[session-stream] error: failed to auto-dequeue after ` +
|
|
1321
|
+
`synthetic agent_end for ${sessionId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1231
1325
|
intervalTick(stream) {
|
|
1232
1326
|
if (!stream.intervalConfig)
|
|
1233
1327
|
return;
|
|
@@ -1373,6 +1467,9 @@ export class SessionStreamManager {
|
|
|
1373
1467
|
startError: null,
|
|
1374
1468
|
subscribers: new Set(),
|
|
1375
1469
|
currentTurn: null,
|
|
1470
|
+
bridgeTurnGeneration: 0,
|
|
1471
|
+
closedTurnGeneration: null,
|
|
1472
|
+
currentTurnSilenceTimer: null,
|
|
1376
1473
|
currentMessageId: null,
|
|
1377
1474
|
lastFlushedEventCount: 0,
|
|
1378
1475
|
loopActive: false,
|
|
@@ -1528,6 +1625,17 @@ export class SessionStreamManager {
|
|
|
1528
1625
|
// late attachers see the events. The first event in such a case is
|
|
1529
1626
|
// typically `message_start`.
|
|
1530
1627
|
if (isReplayable(event)) {
|
|
1628
|
+
// Defense-in-depth: reject replayable events from a turn that was
|
|
1629
|
+
// already closed (by a timeout-abort, error, agent_end, cancelTurn, or
|
|
1630
|
+
// the silence timer). A stray `message_start` emitted by an aborted
|
|
1631
|
+
// SDK session would otherwise re-arm `currentTurn` and leave the
|
|
1632
|
+
// session stuck in "streaming" forever. `closedTurnGeneration` is
|
|
1633
|
+
// cleared when a new prompt is dispatched, so legitimate next-turn
|
|
1634
|
+
// events are unaffected.
|
|
1635
|
+
if (stream.closedTurnGeneration !== null &&
|
|
1636
|
+
stream.bridgeTurnGeneration <= stream.closedTurnGeneration) {
|
|
1637
|
+
return;
|
|
1638
|
+
}
|
|
1531
1639
|
if (!stream.currentTurn) {
|
|
1532
1640
|
stream.currentTurn = {
|
|
1533
1641
|
turnId: randomUUID(),
|
|
@@ -1535,6 +1643,7 @@ export class SessionStreamManager {
|
|
|
1535
1643
|
events: [],
|
|
1536
1644
|
assistantText: "",
|
|
1537
1645
|
persistedEventCount: 0,
|
|
1646
|
+
cleanupStarted: false,
|
|
1538
1647
|
};
|
|
1539
1648
|
}
|
|
1540
1649
|
stream.currentTurn.events.push(event);
|
|
@@ -1543,6 +1652,11 @@ export class SessionStreamManager {
|
|
|
1543
1652
|
}
|
|
1544
1653
|
// Track message lifecycle for batch persistence.
|
|
1545
1654
|
if (event.type === "message_start") {
|
|
1655
|
+
// Bump to mirror `AgentBridge.turnGeneration`, which is incremented
|
|
1656
|
+
// on every `message_start` (agent-bridge.ts). This lets the
|
|
1657
|
+
// `closedTurnGeneration` fence distinguish events from a closed turn
|
|
1658
|
+
// from events of a fresh turn that follows it.
|
|
1659
|
+
stream.bridgeTurnGeneration += 1;
|
|
1546
1660
|
stream.currentMessageId = event.messageId;
|
|
1547
1661
|
stream.lastFlushedEventCount = 0;
|
|
1548
1662
|
// Stub-insert so the server can recover this message on restart even
|
|
@@ -1568,6 +1682,15 @@ export class SessionStreamManager {
|
|
|
1568
1682
|
stream.currentTurn.events.length - stream.lastFlushedEventCount >= BATCH_FLUSH_INTERVAL) {
|
|
1569
1683
|
this.flushInFlightTurn(stream);
|
|
1570
1684
|
}
|
|
1685
|
+
// Fix E: reset the 5-min silence timer whenever a
|
|
1686
|
+
// streaming-meaningful event arrives while a turn is active. As long
|
|
1687
|
+
// as the LLM keeps streaming (even slowly), the timer keeps resetting.
|
|
1688
|
+
// `token_usage` is intentionally excluded (arrives post-turn and would
|
|
1689
|
+
// prevent cleanup of a hung turn).
|
|
1690
|
+
if (stream.currentTurn &&
|
|
1691
|
+
STREAMING_MEANINGFUL_EVENT_TYPES.has(event.type)) {
|
|
1692
|
+
this.armCurrentTurnSilenceTimer(stream);
|
|
1693
|
+
}
|
|
1571
1694
|
}
|
|
1572
1695
|
// Broadcast first, then maybe close out the turn. agent_end clears the
|
|
1573
1696
|
// buffer because by that point the assistant message is already in
|
|
@@ -1715,6 +1838,10 @@ export class SessionStreamManager {
|
|
|
1715
1838
|
stream.lastFlushedEventCount = 0;
|
|
1716
1839
|
const finishedTurn = stream.currentTurn;
|
|
1717
1840
|
stream.currentTurn = null;
|
|
1841
|
+
stream.closedTurnGeneration = stream.bridgeTurnGeneration;
|
|
1842
|
+
// Fix E: natural agent_end arrived — cancel the safety-net timer so we
|
|
1843
|
+
// don't double-emit.
|
|
1844
|
+
this.clearCurrentTurnSilenceTimer(stream);
|
|
1718
1845
|
// Autonomous iterative loop (Ralph Wiggum pattern).
|
|
1719
1846
|
// When loopActive is set, check for completion marker, then re-send
|
|
1720
1847
|
// the ORIGINAL prompt so the agent sees its prior changes and
|
|
@@ -1793,9 +1920,14 @@ export class SessionStreamManager {
|
|
|
1793
1920
|
// synchronously would throw "Agent is already processing" — the
|
|
1794
1921
|
// agent core rejects all prompt() calls until finishRun() clears
|
|
1795
1922
|
// isStreaming, which happens after this listener returns.
|
|
1923
|
+
if (!stream.loopActive && !stream.loopOriginalPrompt) {
|
|
1924
|
+
this.runTurnCleanup(finishedTurn);
|
|
1925
|
+
}
|
|
1796
1926
|
if (!stream.loopActive || !stream.loopOriginalPrompt) {
|
|
1797
1927
|
if (!stream.compacting) {
|
|
1798
1928
|
setImmediate(() => {
|
|
1929
|
+
if (this.disposed)
|
|
1930
|
+
return;
|
|
1799
1931
|
this.maybeAutoDequeue(stream);
|
|
1800
1932
|
});
|
|
1801
1933
|
}
|
|
@@ -1807,11 +1939,25 @@ export class SessionStreamManager {
|
|
|
1807
1939
|
// client has already shown an error for. The error event itself is
|
|
1808
1940
|
// still broadcast above. Also clear batch-persist tracking so the
|
|
1809
1941
|
// next `message_start` starts a fresh sequence.
|
|
1942
|
+
const failedTurn = stream.currentTurn;
|
|
1810
1943
|
stream.currentMessageId = null;
|
|
1811
1944
|
stream.lastFlushedEventCount = 0;
|
|
1812
1945
|
stream.currentTurn = null;
|
|
1946
|
+
stream.closedTurnGeneration = stream.bridgeTurnGeneration;
|
|
1947
|
+
// Fix E: error terminates the turn — cancel the safety-net timer so we
|
|
1948
|
+
// don't double-emit.
|
|
1949
|
+
this.clearCurrentTurnSilenceTimer(stream);
|
|
1950
|
+
this.runTurnCleanup(failedTurn);
|
|
1813
1951
|
}
|
|
1814
1952
|
}
|
|
1953
|
+
runTurnCleanup(turn) {
|
|
1954
|
+
if (!turn || !this.onTurnEnd || turn.cleanupStarted)
|
|
1955
|
+
return;
|
|
1956
|
+
turn.cleanupStarted = true;
|
|
1957
|
+
void Promise.resolve(this.onTurnEnd()).catch((err) => {
|
|
1958
|
+
console.error(`[spectral] error: turn cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1815
1961
|
/**
|
|
1816
1962
|
* Flush the current in-flight turn's events to SQLite for crash recovery.
|
|
1817
1963
|
* Only the events accumulated since the last flush are written — we append
|