@aexol/spectral 0.9.231 → 0.9.240
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/README.md +47 -0
- package/dist/agent/index.d.ts +32 -5
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +209 -36
- package/dist/backend/generated-images.d.ts +1 -1
- package/dist/backend/generated-images.d.ts.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +18 -4
- package/dist/commands/desktop.d.ts +167 -0
- package/dist/commands/desktop.d.ts.map +1 -0
- package/dist/commands/desktop.js +540 -0
- package/dist/commands/serve.d.ts +9 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +90 -2
- package/dist/commands/update.d.ts +85 -5
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +288 -58
- package/dist/extensions/desktop-control/macos.d.ts.map +1 -1
- package/dist/extensions/desktop-control/macos.js +2 -2
- package/dist/extensions/logic-trace.d.ts +1 -1
- package/dist/extensions/logic-trace.d.ts.map +1 -1
- package/dist/extensions/logic-trace.js +199 -70
- package/dist/extensions/video-generation/index.d.ts +3 -0
- package/dist/extensions/video-generation/index.d.ts.map +1 -0
- package/dist/extensions/video-generation/index.js +299 -0
- package/dist/generated/zeus/const.d.ts.map +1 -1
- package/dist/generated/zeus/const.js +30 -0
- package/dist/generated/zeus/index.d.ts +140 -0
- package/dist/generated/zeus/index.d.ts.map +1 -1
- package/dist/generated/zeus/index.js +5 -0
- package/dist/mcp/server-manager.d.ts.map +1 -1
- package/dist/mcp/server-manager.js +6 -0
- package/dist/memory/tools/receive-agent-observations.d.ts.map +1 -1
- package/dist/memory/tools/receive-agent-observations.js +12 -2
- package/dist/relay/dispatcher.d.ts +13 -1
- package/dist/relay/dispatcher.d.ts.map +1 -1
- package/dist/relay/dispatcher.js +41 -2
- package/dist/sdk/agent-core/agent-loop.js +13 -3
- package/dist/sdk/agent-core/agent.d.ts +11 -4
- package/dist/sdk/agent-core/agent.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent.js +16 -4
- package/dist/sdk/agent-core/tool-call-registry.d.ts +75 -0
- package/dist/sdk/agent-core/tool-call-registry.d.ts.map +1 -0
- package/dist/sdk/agent-core/tool-call-registry.js +131 -0
- package/dist/sdk/agent-core/tool-execution.d.ts.map +1 -1
- package/dist/sdk/agent-core/tool-execution.js +103 -4
- package/dist/sdk/agent-core/types.d.ts +15 -4
- package/dist/sdk/agent-core/types.d.ts.map +1 -1
- package/dist/sdk/ai/index.d.ts +3 -0
- package/dist/sdk/ai/index.d.ts.map +1 -1
- package/dist/sdk/ai/index.js +3 -0
- package/dist/sdk/ai/providers/faux.d.ts.map +1 -1
- package/dist/sdk/ai/providers/faux.js +3 -0
- package/dist/sdk/ai/providers/leaked-tool-call-parser.d.ts +39 -6
- package/dist/sdk/ai/providers/leaked-tool-call-parser.d.ts.map +1 -1
- package/dist/sdk/ai/providers/leaked-tool-call-parser.js +159 -18
- package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openai-completions.js +22 -8
- package/dist/sdk/ai/providers/openrouter-videos.d.ts +3 -0
- package/dist/sdk/ai/providers/openrouter-videos.d.ts.map +1 -0
- package/dist/sdk/ai/providers/openrouter-videos.js +412 -0
- package/dist/sdk/ai/providers/register-builtins.d.ts.map +1 -1
- package/dist/sdk/ai/providers/register-builtins.js +6 -0
- package/dist/sdk/ai/providers/simple-options.d.ts +1 -6
- package/dist/sdk/ai/providers/simple-options.d.ts.map +1 -1
- package/dist/sdk/ai/providers/simple-options.js +0 -22
- package/dist/sdk/ai/providers/transform-messages.d.ts.map +1 -1
- package/dist/sdk/ai/providers/transform-messages.js +52 -1
- package/dist/sdk/ai/types.d.ts +91 -10
- package/dist/sdk/ai/types.d.ts.map +1 -1
- package/dist/sdk/ai/video-models.d.ts +10 -0
- package/dist/sdk/ai/video-models.d.ts.map +1 -0
- package/dist/sdk/ai/video-models.generated.d.ts +440 -0
- package/dist/sdk/ai/video-models.generated.d.ts.map +1 -0
- package/dist/sdk/ai/video-models.generated.js +441 -0
- package/dist/sdk/ai/video-models.js +22 -0
- package/dist/sdk/ai/videos-api-registry.d.ts +14 -0
- package/dist/sdk/ai/videos-api-registry.d.ts.map +1 -0
- package/dist/sdk/ai/videos-api-registry.js +21 -0
- package/dist/sdk/ai/videos.d.ts +4 -0
- package/dist/sdk/ai/videos.d.ts.map +1 -0
- package/dist/sdk/ai/videos.js +13 -0
- package/dist/sdk/coding-agent/core/agent-session.d.ts +8 -0
- package/dist/sdk/coding-agent/core/agent-session.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/agent-session.js +11 -0
- package/dist/sdk/coding-agent/core/extensions/loader.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/loader.js +14 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts +26 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/native-extensions.js +23 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts +2 -2
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/types.d.ts +12 -2
- package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/messages.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/messages.js +42 -2
- package/dist/sdk/coding-agent/core/resource-loader.d.ts +11 -0
- package/dist/sdk/coding-agent/core/resource-loader.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/resource-loader.js +23 -6
- package/dist/sdk/coding-agent/core/sdk.d.ts +24 -2
- package/dist/sdk/coding-agent/core/sdk.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/sdk.js +15 -3
- package/dist/sdk/coding-agent/core/settings-manager.d.ts +0 -8
- package/dist/sdk/coding-agent/core/settings-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/settings-manager.js +3 -3
- package/dist/sdk/coding-agent/core/system-prompt.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/system-prompt.js +5 -0
- package/dist/sdk/coding-agent/index.d.ts +2 -2
- package/dist/sdk/coding-agent/index.d.ts.map +1 -1
- package/dist/sdk/coding-agent/index.js +1 -1
- package/dist/sdk-public.d.ts +96 -0
- package/dist/sdk-public.d.ts.map +1 -0
- package/dist/sdk-public.js +109 -0
- package/dist/server/agent-bridge/rehydrate.d.ts +2 -2
- package/dist/server/agent-bridge/rehydrate.d.ts.map +1 -1
- package/dist/server/agent-bridge/rehydrate.js +14 -0
- package/dist/server/agent-bridge/tps-metrics.d.ts +34 -0
- package/dist/server/agent-bridge/tps-metrics.d.ts.map +1 -1
- package/dist/server/agent-bridge/tps-metrics.js +22 -0
- package/dist/server/agent-bridge.d.ts +17 -2
- package/dist/server/agent-bridge.d.ts.map +1 -1
- package/dist/server/agent-bridge.js +108 -5
- package/dist/server/handlers/paths-list.d.ts +1 -1
- package/dist/server/handlers/paths-list.js +1 -1
- package/dist/server/inter-agent-broker.d.ts +12 -0
- package/dist/server/inter-agent-broker.d.ts.map +1 -1
- package/dist/server/inter-agent-broker.js +1 -0
- package/dist/server/preset-chain.d.ts +151 -0
- package/dist/server/preset-chain.d.ts.map +1 -0
- package/dist/server/preset-chain.js +250 -0
- package/dist/server/session-stream.d.ts +74 -1
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +238 -24
- package/dist/server/storage/rows.d.ts +2 -0
- package/dist/server/storage/rows.d.ts.map +1 -1
- package/dist/server/storage/schema.d.ts +2 -2
- package/dist/server/storage/schema.d.ts.map +1 -1
- package/dist/server/storage/schema.js +2 -1
- package/dist/server/storage.d.ts +7 -0
- package/dist/server/storage.d.ts.map +1 -1
- package/dist/server/storage.js +142 -9
- package/dist/server/wire.d.ts +84 -0
- package/dist/server/wire.d.ts.map +1 -1
- package/dist/utils/augment-path.d.ts +51 -0
- package/dist/utils/augment-path.d.ts.map +1 -0
- package/dist/utils/augment-path.js +234 -0
- package/dist/utils/open-browser.d.ts +55 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +163 -0
- package/dist/utils/serve-state.d.ts +264 -0
- package/dist/utils/serve-state.d.ts.map +1 -0
- package/dist/utils/serve-state.js +563 -0
- package/dist/utils/standalone.d.ts +14 -0
- package/dist/utils/standalone.d.ts.map +1 -0
- package/dist/utils/standalone.js +23 -0
- package/package.json +7 -3
|
@@ -698,6 +698,11 @@ export var PresetSource;
|
|
|
698
698
|
PresetSource["SYSTEM"] = "SYSTEM";
|
|
699
699
|
PresetSource["USER"] = "USER";
|
|
700
700
|
})(PresetSource || (PresetSource = {}));
|
|
701
|
+
export var FollowUpMode;
|
|
702
|
+
(function (FollowUpMode) {
|
|
703
|
+
FollowUpMode["INJECT"] = "INJECT";
|
|
704
|
+
FollowUpMode["QUEUE"] = "QUEUE";
|
|
705
|
+
})(FollowUpMode || (FollowUpMode = {}));
|
|
701
706
|
export var AgentMode;
|
|
702
707
|
(function (AgentMode) {
|
|
703
708
|
AgentMode["SUBAGENT"] = "SUBAGENT";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/server-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAKnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,mCAAmC,EACnC,SAAS,EACV,MAAM,YAAY,CAAC;AAMpB,OAAO,EAA2B,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../../src/mcp/server-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAKnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,mCAAmC,EACnC,SAAS,EACV,MAAM,YAAY,CAAC;AAMpB,OAAO,EAA2B,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAI3F,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,YAAY,CAAC;CAC/C;AAED,KAAK,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,mCAAmC,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;AAElH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,eAAe,CAAgD;IACvE,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,cAAc,CAAmC;IAEzD,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,GAAG,IAAI;IAI3D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAyBtE,gBAAgB;IAmF9B,OAAO,CAAC,YAAY;YAWN,mBAAmB;YAyEnB,aAAa;YAab,iBAAiB;IAkB/B,OAAO,CAAC,iCAAiC;IAQzC,wBAAwB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAI/E,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAI3C,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgBpE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAelC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIzD,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIlD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOzB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOrC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOrC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;CAMjD"}
|
|
@@ -10,6 +10,7 @@ import { McpOAuthProvider } from "./mcp-oauth-provider.js";
|
|
|
10
10
|
import { supportsOAuth } from "./mcp-auth-flow.js";
|
|
11
11
|
import { registerSamplingHandler } from "./sampling-handler.js";
|
|
12
12
|
import { interpolateEnvRecord, resolveBearerToken, resolveConfigPath } from "./utils.js";
|
|
13
|
+
import { augmentPath, getPathEnvKey } from "../utils/augment-path.js";
|
|
13
14
|
export class McpServerManager {
|
|
14
15
|
connections = new Map();
|
|
15
16
|
connectPromises = new Map();
|
|
@@ -293,6 +294,11 @@ function resolveEnv(env) {
|
|
|
293
294
|
resolved[key] = value;
|
|
294
295
|
}
|
|
295
296
|
}
|
|
297
|
+
// MCP stdio servers are spawned by name (`npx -y pkg`, `node server.js`), so
|
|
298
|
+
// they live or die by PATH. When spectral itself was launched from a GUI
|
|
299
|
+
// context that PATH has no node/npm in it — augment it for the child only,
|
|
300
|
+
// leaving our own process env untouched.
|
|
301
|
+
resolved[getPathEnvKey(resolved)] = augmentPath(resolved[getPathEnvKey(resolved)]);
|
|
296
302
|
if (!env)
|
|
297
303
|
return resolved;
|
|
298
304
|
const overrides = interpolateEnvRecord(env);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"receive-agent-observations.d.ts","sourceRoot":"","sources":["../../../src/memory/tools/receive-agent-observations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAIhF,eAAO,MAAM,oCAAoC,+BAA+B,CAAC;AAEjF,MAAM,WAAW,uBAAuB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,aAAa,GAAG,YAAY,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,4BAA4B;;;
|
|
1
|
+
{"version":3,"file":"receive-agent-observations.d.ts","sourceRoot":"","sources":["../../../src/memory/tools/receive-agent-observations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAIhF,eAAO,MAAM,oCAAoC,+BAA+B,CAAC;AAEjF,MAAM,WAAW,uBAAuB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,aAAa,GAAG,YAAY,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,4BAA4B;;;iFAkFvC,CAAC;AAEH,wBAAgB,oCAAoC,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAE5E"}
|
|
@@ -8,7 +8,8 @@ export const receiveAgentObservationsTool = defineTool({
|
|
|
8
8
|
label: "Receive observations from other agents",
|
|
9
9
|
description: "Poll for observations shared by other active sessions on this machine working in the " +
|
|
10
10
|
"same directory (same-machine, same-cwd; no cross-machine or team relay). " +
|
|
11
|
-
"Call this before starting work or when you suspect another agent has shared context."
|
|
11
|
+
"Call this before starting work or when you suspect another agent has shared context. " +
|
|
12
|
+
"Delivery is per-recipient: each session polls its own inbox, and you never see your own messages.",
|
|
12
13
|
promptSnippet: "Use receive_agent_observations() to pull shared observations from other active sessions on this machine.",
|
|
13
14
|
promptGuidelines: [
|
|
14
15
|
"Messages are same-machine + same-cwd only; there is no cross-machine or team fan-out.",
|
|
@@ -29,7 +30,13 @@ export const receiveAgentObservationsTool = defineTool({
|
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
const projectId = store.getProjectByCwd(ctx.cwd);
|
|
32
|
-
|
|
33
|
+
// Subagents receive a DISTINCT derived observation session id on the
|
|
34
|
+
// SubagentToolContext so they poll their own inbox; primary sessions
|
|
35
|
+
// fall back to the session manager's id. Never the bare parent id for
|
|
36
|
+
// subagents — per-recipient delivery would let a subagent consume the
|
|
37
|
+
// parent's broadcast observations.
|
|
38
|
+
const subCtx = ctx;
|
|
39
|
+
const sessionId = subCtx.observationSessionId ?? subCtx.sessionManager?.getSessionId?.();
|
|
33
40
|
if (!projectId || !sessionId) {
|
|
34
41
|
return {
|
|
35
42
|
content: [{ type: "text", text: "No project/session context." }],
|
|
@@ -40,6 +47,9 @@ export const receiveAgentObservationsTool = defineTool({
|
|
|
40
47
|
projectId,
|
|
41
48
|
channel: "memory",
|
|
42
49
|
recipientSessionId: sessionId,
|
|
50
|
+
// Self-filtering: never surface the requesting session's own
|
|
51
|
+
// observations back to it (live subscribe already does this).
|
|
52
|
+
excludeSenderSessionId: sessionId,
|
|
43
53
|
since: params.since,
|
|
44
54
|
limit: params.limit ?? 20,
|
|
45
55
|
markDelivered: true,
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
* re-exported below so existing imports from `relay/dispatcher.js` keep
|
|
44
44
|
* working.
|
|
45
45
|
*/
|
|
46
|
-
import type { AutoOptimizeFrame, AutoResearchFrame, CancelTurnFrame, ClientMessageFrame, SubscribeFrame } from "@aexol/relay-protocol";
|
|
46
|
+
import type { AutoOptimizeFrame, AutoResearchFrame, CancelTurnFrame, ClientMessageFrame, SubscribeFrame, StopToolCallFrame } from "@aexol/relay-protocol";
|
|
47
47
|
import type { SessionStreamManager, Subscriber } from "../server/session-stream.js";
|
|
48
48
|
import type { SessionStore } from "../server/storage.js";
|
|
49
49
|
import { coerceImages, hasImages, MAX_INLINE_IMAGE_BASE64_CHARS } from "../server/image-attachments.js";
|
|
@@ -124,6 +124,18 @@ export declare function handleCancelTurn(frame: CancelTurnFrame, deps: {
|
|
|
124
124
|
error: (...args: unknown[]) => void;
|
|
125
125
|
};
|
|
126
126
|
}): void;
|
|
127
|
+
export type { StopToolCallFrame };
|
|
128
|
+
/**
|
|
129
|
+
* Dispatch a `stop_tool_call` frame. Stops ONE hung/long-running tool call
|
|
130
|
+
* for the session — that call is aborted, the agent receives a synthesized
|
|
131
|
+
* user-stop tool result, and the turn continues (unlike `cancel_turn`).
|
|
132
|
+
*
|
|
133
|
+
* Guarded: unknown toolCallId → no crash, the manager broadcasts a
|
|
134
|
+
* best-effort `tool_stop_result` info frame.
|
|
135
|
+
*/
|
|
136
|
+
export declare function handleStopToolCall(frame: StopToolCallFrame, deps: {
|
|
137
|
+
manager: SessionStreamManager;
|
|
138
|
+
}): Promise<void>;
|
|
127
139
|
/**
|
|
128
140
|
* Detach every subscriber the dispatcher has attached. Called by
|
|
129
141
|
* `serve.ts` on relay disconnect / shutdown so the underlying spectral
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/relay/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,cAAc,
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/relay/dispatcher.ts"],"names":[],"mappings":"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"}
|
package/dist/relay/dispatcher.js
CHANGED
|
@@ -291,7 +291,11 @@ export async function handleClientMessage(frame, deps) {
|
|
|
291
291
|
// Set autonomous iterative loop state before firing the prompt.
|
|
292
292
|
// loop:true → start/renew loop with the current content as original prompt;
|
|
293
293
|
// loop:false → stop any active loop.
|
|
294
|
-
|
|
294
|
+
// Arm loop state BEFORE any await: for non-reference prompts this is
|
|
295
|
+
// synchronous, preserving the client_message/subscribe interleave below.
|
|
296
|
+
// For "@preset:<name>" prompts this returns a promise that we await just
|
|
297
|
+
// before firing the turn, so the loop replays the EXPANDED prompt.
|
|
298
|
+
const armed = manager.setLoopActive(sessionId, isLoop, content, loopMaxIterations, loopGoal);
|
|
295
299
|
// 2. Attach (idempotent). On first attach we capture the replay payload
|
|
296
300
|
// and synthesize a `session_ready` ws_event so the browser sees the
|
|
297
301
|
// same first frame it would have on a direct WS connection.
|
|
@@ -350,6 +354,30 @@ export async function handleClientMessage(frame, deps) {
|
|
|
350
354
|
});
|
|
351
355
|
}
|
|
352
356
|
}
|
|
357
|
+
// "@preset:<name>" loop prompts: resolve the preset before the turn fires
|
|
358
|
+
// (undefined = already armed synchronously — no yield, no reordering).
|
|
359
|
+
// The arm path resolves to the EXPANDED prompt; `null` means it failed or
|
|
360
|
+
// was aborted (loop state changed mid-resolution) — fall back to the raw
|
|
361
|
+
// content in those cases. The promise is caught, not just awaited: serve
|
|
362
|
+
// calls this handler fire-and-forget, so a rejection (e.g. a sync throw
|
|
363
|
+
// from teamIdForSession inside the manager) would otherwise surface as an
|
|
364
|
+
// unhandled rejection instead of a visible error event.
|
|
365
|
+
let expandedLoopPrompt = null;
|
|
366
|
+
if (armed instanceof Promise) {
|
|
367
|
+
try {
|
|
368
|
+
expandedLoopPrompt = await armed;
|
|
369
|
+
}
|
|
370
|
+
catch (err) {
|
|
371
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
372
|
+
logger.error?.(`[dispatcher] loop arming failed for ${sessionId}:`, err);
|
|
373
|
+
relay.send({
|
|
374
|
+
kind: "ws_event",
|
|
375
|
+
sessionId,
|
|
376
|
+
event: { type: "error", message: humanizeProviderError(msg) },
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
const promptContent = expandedLoopPrompt ?? content;
|
|
353
381
|
// 3. Fire the prompt. `prompt()` resolves on `agent_end`; errors are
|
|
354
382
|
// converted to `error` events by the manager itself, so we just log.
|
|
355
383
|
// `modelId` (Phase 3 — Available Models whitelist) is forwarded as
|
|
@@ -359,7 +387,7 @@ export async function handleClientMessage(frame, deps) {
|
|
|
359
387
|
//
|
|
360
388
|
// When `loop: true`, loop state is set before prompting; the normal
|
|
361
389
|
// model is used — loop replay is handled by session-stream on agent_end.
|
|
362
|
-
manager.prompt(sessionId,
|
|
390
|
+
manager.prompt(sessionId, promptContent, modelId, validImages, reasoningEffort).catch((err) => {
|
|
363
391
|
logger.error?.(`[dispatcher] manager.prompt failed for ${sessionId}:`, err);
|
|
364
392
|
});
|
|
365
393
|
// Arm the interval scheduler after the first (immediate) launch.
|
|
@@ -440,6 +468,17 @@ export async function handleSubscribe(frame, deps) {
|
|
|
440
468
|
export function handleCancelTurn(frame, deps) {
|
|
441
469
|
deps.manager.cancelTurn(frame.sessionId);
|
|
442
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* Dispatch a `stop_tool_call` frame. Stops ONE hung/long-running tool call
|
|
473
|
+
* for the session — that call is aborted, the agent receives a synthesized
|
|
474
|
+
* user-stop tool result, and the turn continues (unlike `cancel_turn`).
|
|
475
|
+
*
|
|
476
|
+
* Guarded: unknown toolCallId → no crash, the manager broadcasts a
|
|
477
|
+
* best-effort `tool_stop_result` info frame.
|
|
478
|
+
*/
|
|
479
|
+
export async function handleStopToolCall(frame, deps) {
|
|
480
|
+
await deps.manager.stopToolCall(frame.sessionId, frame.toolCallId, frame.reason);
|
|
481
|
+
}
|
|
443
482
|
/**
|
|
444
483
|
* Detach every subscriber the dispatcher has attached. Called by
|
|
445
484
|
* `serve.ts` on relay disconnect / shutdown so the underlying spectral
|
|
@@ -267,13 +267,21 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
267
267
|
newMessages.push(result);
|
|
268
268
|
}
|
|
269
269
|
// Fix 1: Track consecutive tool call errors; terminate after threshold.
|
|
270
|
-
|
|
270
|
+
// User-stopped results (`stoppedByUser`) are deliberate user actions,
|
|
271
|
+
// not tool failures — they must not count toward the threshold, or a
|
|
272
|
+
// run where the user stops every tool call dies as "10 consecutive
|
|
273
|
+
// tool call errors" (defeating the per-call stop feature). A batch of
|
|
274
|
+
// only user-stopped results leaves the counter unchanged; normal
|
|
275
|
+
// results still reset it.
|
|
276
|
+
const turnHasError = toolResults.some((r) => r.isError && !r.stoppedByUser);
|
|
277
|
+
const batchAllUserStopped = toolResults.length > 0 &&
|
|
278
|
+
toolResults.every((r) => r.isError && r.stoppedByUser === true);
|
|
271
279
|
if (turnHasError) {
|
|
272
280
|
consecutiveToolErrors++;
|
|
273
281
|
if (consecutiveToolErrors >= MAX_CONSECUTIVE_TOOL_ERRORS) {
|
|
274
282
|
const lastErrorResult = [...toolResults]
|
|
275
283
|
.reverse()
|
|
276
|
-
.find((r) => r.isError);
|
|
284
|
+
.find((r) => r.isError && !r.stoppedByUser);
|
|
277
285
|
const lastErrorMsg = lastErrorResult?.content.find((c) => c.type === "text")?.text ||
|
|
278
286
|
"Unknown tool error";
|
|
279
287
|
const finalMessage = {
|
|
@@ -303,7 +311,9 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
303
311
|
return;
|
|
304
312
|
}
|
|
305
313
|
}
|
|
306
|
-
else {
|
|
314
|
+
else if (!batchAllUserStopped) {
|
|
315
|
+
// Pure success/normal batch: reset as today. An all-user-stopped
|
|
316
|
+
// batch is neither a real error nor a success — counter unchanged.
|
|
307
317
|
consecutiveToolErrors = 0;
|
|
308
318
|
}
|
|
309
319
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ImageContent, type Message, type SimpleStreamOptions, type
|
|
1
|
+
import { type ImageContent, type Message, type SimpleStreamOptions, type Transport } from "../ai/index.js";
|
|
2
2
|
import type { AfterToolCallContext, AfterToolCallResult, AgentEvent, AgentLoopTurnUpdate, AgentMessage, AgentState, BeforeToolCallContext, BeforeToolCallResult, QueueMode, StreamFn, ToolExecutionMode } from "./types.js";
|
|
3
3
|
export type { QueueMode } from "./types.js";
|
|
4
4
|
/** Options for constructing an {@link Agent}. */
|
|
@@ -16,7 +16,6 @@ export interface AgentOptions {
|
|
|
16
16
|
steeringMode?: QueueMode;
|
|
17
17
|
followUpMode?: QueueMode;
|
|
18
18
|
sessionId?: string;
|
|
19
|
-
thinkingBudgets?: ThinkingBudgets;
|
|
20
19
|
transport?: Transport;
|
|
21
20
|
maxRetryDelayMs?: number;
|
|
22
21
|
toolExecution?: ToolExecutionMode;
|
|
@@ -32,6 +31,7 @@ export declare class Agent {
|
|
|
32
31
|
private readonly listeners;
|
|
33
32
|
private readonly steeringQueue;
|
|
34
33
|
private readonly followUpQueue;
|
|
34
|
+
private readonly toolCallRegistry;
|
|
35
35
|
convertToLlm: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;
|
|
36
36
|
transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
|
|
37
37
|
streamFn: StreamFn;
|
|
@@ -44,8 +44,6 @@ export declare class Agent {
|
|
|
44
44
|
private activeRun?;
|
|
45
45
|
/** Session identifier forwarded to providers for cache-aware backends. */
|
|
46
46
|
sessionId?: string;
|
|
47
|
-
/** Optional per-level thinking token budgets forwarded to the stream function. */
|
|
48
|
-
thinkingBudgets?: ThinkingBudgets;
|
|
49
47
|
/** Preferred transport forwarded to the stream function. */
|
|
50
48
|
transport: Transport;
|
|
51
49
|
/** Optional cap for provider-requested retry delays. */
|
|
@@ -92,6 +90,15 @@ export declare class Agent {
|
|
|
92
90
|
get signal(): AbortSignal | undefined;
|
|
93
91
|
/** Abort the current run, if one is active. */
|
|
94
92
|
abort(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Stop a single in-flight tool call (user-initiated per-call stop).
|
|
95
|
+
*
|
|
96
|
+
* Aborts only the targeted call's execution — siblings keep running and the
|
|
97
|
+
* agent loop CONTINUES the turn with a synthesized user-stop tool result
|
|
98
|
+
* ("Tool call stopped by user (was running too long)"). Returns false for
|
|
99
|
+
* unknown/finished toolCallIds (no-op).
|
|
100
|
+
*/
|
|
101
|
+
stopToolCall(toolCallId: string, reason?: string): Promise<boolean>;
|
|
95
102
|
/**
|
|
96
103
|
* Resolve when the current run and all awaited event listeners have finished.
|
|
97
104
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,OAAO,EAEZ,KAAK,mBAAmB,EAGxB,KAAK,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { streamSimple, } from "../ai/index.js";
|
|
2
2
|
import { runAgentLoop, runAgentLoopContinue } from "./agent-loop.js";
|
|
3
|
+
import { ToolCallRegistry } from "./tool-call-registry.js";
|
|
3
4
|
function defaultConvertToLlm(messages) {
|
|
4
5
|
return messages.filter((message) => message.role === "user" || message.role === "assistant" || message.role === "toolResult");
|
|
5
6
|
}
|
|
@@ -88,6 +89,7 @@ export class Agent {
|
|
|
88
89
|
listeners = new Set();
|
|
89
90
|
steeringQueue;
|
|
90
91
|
followUpQueue;
|
|
92
|
+
toolCallRegistry = new ToolCallRegistry();
|
|
91
93
|
convertToLlm;
|
|
92
94
|
transformContext;
|
|
93
95
|
streamFn;
|
|
@@ -100,8 +102,6 @@ export class Agent {
|
|
|
100
102
|
activeRun;
|
|
101
103
|
/** Session identifier forwarded to providers for cache-aware backends. */
|
|
102
104
|
sessionId;
|
|
103
|
-
/** Optional per-level thinking token budgets forwarded to the stream function. */
|
|
104
|
-
thinkingBudgets;
|
|
105
105
|
/** Preferred transport forwarded to the stream function. */
|
|
106
106
|
transport;
|
|
107
107
|
/** Optional cap for provider-requested retry delays. */
|
|
@@ -122,7 +122,6 @@ export class Agent {
|
|
|
122
122
|
this.steeringQueue = new PendingMessageQueue(options.steeringMode ?? "one-at-a-time");
|
|
123
123
|
this.followUpQueue = new PendingMessageQueue(options.followUpMode ?? "one-at-a-time");
|
|
124
124
|
this.sessionId = options.sessionId;
|
|
125
|
-
this.thinkingBudgets = options.thinkingBudgets;
|
|
126
125
|
this.transport = options.transport ?? "auto";
|
|
127
126
|
this.maxRetryDelayMs = options.maxRetryDelayMs;
|
|
128
127
|
this.toolExecution = options.toolExecution ?? "parallel";
|
|
@@ -196,6 +195,17 @@ export class Agent {
|
|
|
196
195
|
abort() {
|
|
197
196
|
this.activeRun?.abortController.abort();
|
|
198
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Stop a single in-flight tool call (user-initiated per-call stop).
|
|
200
|
+
*
|
|
201
|
+
* Aborts only the targeted call's execution — siblings keep running and the
|
|
202
|
+
* agent loop CONTINUES the turn with a synthesized user-stop tool result
|
|
203
|
+
* ("Tool call stopped by user (was running too long)"). Returns false for
|
|
204
|
+
* unknown/finished toolCallIds (no-op).
|
|
205
|
+
*/
|
|
206
|
+
async stopToolCall(toolCallId, reason) {
|
|
207
|
+
return this.toolCallRegistry.stop(toolCallId, reason);
|
|
208
|
+
}
|
|
199
209
|
/**
|
|
200
210
|
* Resolve when the current run and all awaited event listeners have finished.
|
|
201
211
|
*
|
|
@@ -211,6 +221,7 @@ export class Agent {
|
|
|
211
221
|
this._state.streamingMessage = undefined;
|
|
212
222
|
this._state.pendingToolCalls = new Set();
|
|
213
223
|
this._state.errorMessage = undefined;
|
|
224
|
+
this.toolCallRegistry.clear();
|
|
214
225
|
this.clearFollowUpQueue();
|
|
215
226
|
this.clearSteeringQueue();
|
|
216
227
|
}
|
|
@@ -284,7 +295,6 @@ export class Agent {
|
|
|
284
295
|
onPayload: this.onPayload,
|
|
285
296
|
onResponse: this.onResponse,
|
|
286
297
|
transport: this.transport,
|
|
287
|
-
thinkingBudgets: this.thinkingBudgets,
|
|
288
298
|
maxRetryDelayMs: this.maxRetryDelayMs,
|
|
289
299
|
toolExecution: this.toolExecution,
|
|
290
300
|
beforeToolCall: this.beforeToolCall,
|
|
@@ -301,6 +311,7 @@ export class Agent {
|
|
|
301
311
|
return this.steeringQueue.drain();
|
|
302
312
|
},
|
|
303
313
|
getFollowUpMessages: async () => this.followUpQueue.drain(),
|
|
314
|
+
toolCallRegistry: this.toolCallRegistry,
|
|
304
315
|
};
|
|
305
316
|
}
|
|
306
317
|
async runWithLifecycle(executor) {
|
|
@@ -316,6 +327,7 @@ export class Agent {
|
|
|
316
327
|
this._state.isStreaming = true;
|
|
317
328
|
this._state.streamingMessage = undefined;
|
|
318
329
|
this._state.errorMessage = undefined;
|
|
330
|
+
this.toolCallRegistry.clear();
|
|
319
331
|
try {
|
|
320
332
|
await executor(abortController.signal);
|
|
321
333
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Killable registry of in-flight tool executions for one agent run.
|
|
3
|
+
*
|
|
4
|
+
* The agent loop hands every `tool.execute()` a run-level abort signal, which
|
|
5
|
+
* makes whole-turn cancellation the only kill path. This registry adds a
|
|
6
|
+
* per-call controller chained from the run signal so a single hung/long-running
|
|
7
|
+
* tool call can be aborted on its own (`stopToolCall`) while its siblings keep
|
|
8
|
+
* running and the agent loop continues the turn.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle:
|
|
11
|
+
* - `register()` is called by the tool executor right before execution and
|
|
12
|
+
* returns a handle carrying the per-call abort signal.
|
|
13
|
+
* - `settle()` is called by the executor when the call finishes (success or
|
|
14
|
+
* error) — it removes the entry and resolves the handle's `settled` promise,
|
|
15
|
+
* which is what `stop()` awaits.
|
|
16
|
+
* - `stop()` marks a user-initiated stop (so the caught abort error is
|
|
17
|
+
* replaced by the synthesized user-stop tool result), aborts only the
|
|
18
|
+
* targeted call's controller, and resolves once the call settles.
|
|
19
|
+
*
|
|
20
|
+
* Chaining: when the run-level signal aborts (turn cancel), every per-call
|
|
21
|
+
* controller aborts too, so existing whole-turn cancel behavior is preserved.
|
|
22
|
+
*/
|
|
23
|
+
/** Default reason recorded on the handle when the caller passes none. */
|
|
24
|
+
export declare const DEFAULT_USER_STOP_REASON = "stopped by user";
|
|
25
|
+
/**
|
|
26
|
+
* Exactly-matching synthesized toolResult content per the `stop_tool_call`
|
|
27
|
+
* wire contract. The wire tool_result frame carries `stoppedByUser: true`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const USER_STOP_TOOL_RESULT_TEXT = "Tool call stopped by user (was running too long)";
|
|
30
|
+
/** Handle for one in-flight tool call execution. */
|
|
31
|
+
export interface InFlightToolCallHandle {
|
|
32
|
+
readonly toolCallId: string;
|
|
33
|
+
readonly toolName: string;
|
|
34
|
+
/** Per-call abort signal source. `controller.signal` is what tools receive. */
|
|
35
|
+
readonly controller: AbortController;
|
|
36
|
+
/** Resolves when the executor settles this call (success or error). */
|
|
37
|
+
readonly settled: Promise<void>;
|
|
38
|
+
/** Set true when a user-initiated stop targets this call. */
|
|
39
|
+
userStopRequested: boolean;
|
|
40
|
+
/** Reason supplied by the caller of `stop()` (defaults to "stopped by user"). */
|
|
41
|
+
userStopReason?: string;
|
|
42
|
+
/** Resolve the `settled` promise. Called by the executor, not by callers. */
|
|
43
|
+
settle(): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Per-run killable registry of in-flight tool executions.
|
|
47
|
+
* Keyed by toolCallId; one Agent owns one registry per run.
|
|
48
|
+
*/
|
|
49
|
+
export declare class ToolCallRegistry {
|
|
50
|
+
private readonly calls;
|
|
51
|
+
/**
|
|
52
|
+
* Register an in-flight call and return its handle. The returned
|
|
53
|
+
* controller's signal aborts when this call is stopped individually OR
|
|
54
|
+
* when the run-level signal aborts (turn cancel propagates).
|
|
55
|
+
*/
|
|
56
|
+
register(toolCallId: string, toolName: string, runSignal?: AbortSignal): InFlightToolCallHandle;
|
|
57
|
+
/** Look up an in-flight call by id. Undefined for unknown/finished ids. */
|
|
58
|
+
get(toolCallId: string): InFlightToolCallHandle | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Mark a user-initiated stop and abort only this call's controller.
|
|
61
|
+
* Returns false for unknown/finished ids (no-op). Idempotent: a second
|
|
62
|
+
* stop for the same id keeps the first marker and reason.
|
|
63
|
+
*/
|
|
64
|
+
markUserStop(toolCallId: string, reason?: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Abort only the targeted call and resolve once it settles.
|
|
67
|
+
* Returns false for unknown/finished ids (no-op).
|
|
68
|
+
*/
|
|
69
|
+
stop(toolCallId: string, reason?: string): Promise<boolean>;
|
|
70
|
+
/** Settle an in-flight call. Called by the executor when execution ends. */
|
|
71
|
+
settle(toolCallId: string): void;
|
|
72
|
+
/** Settle and drop every tracked call. Called when a run starts/ends. */
|
|
73
|
+
clear(): void;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=tool-call-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-registry.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/tool-call-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,0BAA0B,qDACY,CAAC;AAEpD,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,6DAA6D;IAC7D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,MAAM,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IAEnE;;;;OAIG;IACH,QAAQ,CACP,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,WAAW,GACrB,sBAAsB;IA+CzB,2EAA2E;IAC3E,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAI3D;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IAe1D;;;OAGG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMjE,4EAA4E;IAC5E,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhC,yEAAyE;IACzE,KAAK,IAAI,IAAI;CAIb"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Killable registry of in-flight tool executions for one agent run.
|
|
3
|
+
*
|
|
4
|
+
* The agent loop hands every `tool.execute()` a run-level abort signal, which
|
|
5
|
+
* makes whole-turn cancellation the only kill path. This registry adds a
|
|
6
|
+
* per-call controller chained from the run signal so a single hung/long-running
|
|
7
|
+
* tool call can be aborted on its own (`stopToolCall`) while its siblings keep
|
|
8
|
+
* running and the agent loop continues the turn.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle:
|
|
11
|
+
* - `register()` is called by the tool executor right before execution and
|
|
12
|
+
* returns a handle carrying the per-call abort signal.
|
|
13
|
+
* - `settle()` is called by the executor when the call finishes (success or
|
|
14
|
+
* error) — it removes the entry and resolves the handle's `settled` promise,
|
|
15
|
+
* which is what `stop()` awaits.
|
|
16
|
+
* - `stop()` marks a user-initiated stop (so the caught abort error is
|
|
17
|
+
* replaced by the synthesized user-stop tool result), aborts only the
|
|
18
|
+
* targeted call's controller, and resolves once the call settles.
|
|
19
|
+
*
|
|
20
|
+
* Chaining: when the run-level signal aborts (turn cancel), every per-call
|
|
21
|
+
* controller aborts too, so existing whole-turn cancel behavior is preserved.
|
|
22
|
+
*/
|
|
23
|
+
/** Default reason recorded on the handle when the caller passes none. */
|
|
24
|
+
export const DEFAULT_USER_STOP_REASON = "stopped by user";
|
|
25
|
+
/**
|
|
26
|
+
* Exactly-matching synthesized toolResult content per the `stop_tool_call`
|
|
27
|
+
* wire contract. The wire tool_result frame carries `stoppedByUser: true`.
|
|
28
|
+
*/
|
|
29
|
+
export const USER_STOP_TOOL_RESULT_TEXT = "Tool call stopped by user (was running too long)";
|
|
30
|
+
/**
|
|
31
|
+
* Per-run killable registry of in-flight tool executions.
|
|
32
|
+
* Keyed by toolCallId; one Agent owns one registry per run.
|
|
33
|
+
*/
|
|
34
|
+
export class ToolCallRegistry {
|
|
35
|
+
calls = new Map();
|
|
36
|
+
/**
|
|
37
|
+
* Register an in-flight call and return its handle. The returned
|
|
38
|
+
* controller's signal aborts when this call is stopped individually OR
|
|
39
|
+
* when the run-level signal aborts (turn cancel propagates).
|
|
40
|
+
*/
|
|
41
|
+
register(toolCallId, toolName, runSignal) {
|
|
42
|
+
const existing = this.calls.get(toolCallId);
|
|
43
|
+
if (existing)
|
|
44
|
+
return existing;
|
|
45
|
+
const controller = new AbortController();
|
|
46
|
+
let settle = () => { };
|
|
47
|
+
const settled = new Promise((resolve) => {
|
|
48
|
+
settle = resolve;
|
|
49
|
+
});
|
|
50
|
+
const handle = {
|
|
51
|
+
toolCallId,
|
|
52
|
+
toolName,
|
|
53
|
+
controller,
|
|
54
|
+
settled,
|
|
55
|
+
userStopRequested: false,
|
|
56
|
+
settle: () => {
|
|
57
|
+
this.calls.delete(toolCallId);
|
|
58
|
+
settle();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
if (runSignal) {
|
|
62
|
+
if (runSignal.aborted) {
|
|
63
|
+
try {
|
|
64
|
+
controller.abort();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// ignore — abort must never throw into the executor
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const onRunAbort = () => {
|
|
72
|
+
try {
|
|
73
|
+
controller.abort();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// ignore
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
runSignal.addEventListener("abort", onRunAbort, { once: true });
|
|
80
|
+
void settled.then(() => runSignal.removeEventListener("abort", onRunAbort));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this.calls.set(toolCallId, handle);
|
|
84
|
+
return handle;
|
|
85
|
+
}
|
|
86
|
+
/** Look up an in-flight call by id. Undefined for unknown/finished ids. */
|
|
87
|
+
get(toolCallId) {
|
|
88
|
+
return this.calls.get(toolCallId);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Mark a user-initiated stop and abort only this call's controller.
|
|
92
|
+
* Returns false for unknown/finished ids (no-op). Idempotent: a second
|
|
93
|
+
* stop for the same id keeps the first marker and reason.
|
|
94
|
+
*/
|
|
95
|
+
markUserStop(toolCallId, reason) {
|
|
96
|
+
const handle = this.calls.get(toolCallId);
|
|
97
|
+
if (!handle)
|
|
98
|
+
return false;
|
|
99
|
+
if (!handle.userStopRequested) {
|
|
100
|
+
handle.userStopRequested = true;
|
|
101
|
+
handle.userStopReason = reason ?? DEFAULT_USER_STOP_REASON;
|
|
102
|
+
try {
|
|
103
|
+
handle.controller.abort();
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// ignore — abort must never throw into the caller
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Abort only the targeted call and resolve once it settles.
|
|
113
|
+
* Returns false for unknown/finished ids (no-op).
|
|
114
|
+
*/
|
|
115
|
+
async stop(toolCallId, reason) {
|
|
116
|
+
if (!this.markUserStop(toolCallId, reason))
|
|
117
|
+
return false;
|
|
118
|
+
await this.calls.get(toolCallId)?.settled;
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/** Settle an in-flight call. Called by the executor when execution ends. */
|
|
122
|
+
settle(toolCallId) {
|
|
123
|
+
this.calls.get(toolCallId)?.settle();
|
|
124
|
+
}
|
|
125
|
+
/** Settle and drop every tracked call. Called when a run starts/ends. */
|
|
126
|
+
clear() {
|
|
127
|
+
for (const handle of this.calls.values())
|
|
128
|
+
handle.settle();
|
|
129
|
+
this.calls.clear();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/tool-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/tool-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,aAAa,EAEb,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOtD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,YAAY,EAC5B,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,qBAAqB,CAAC,CA2BhC;AAED,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AA0fF;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAYlG"}
|