openhorse 0.2.18 → 0.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/coordinator.d.ts.map +1 -1
- package/dist/agents/fork.d.ts.map +1 -1
- package/dist/agents/fork.js +0 -1
- package/dist/agents/fork.js.map +1 -1
- package/dist/agents/worker-pool.d.ts.map +1 -1
- package/dist/agents/worker-pool.js +3 -1
- package/dist/agents/worker-pool.js.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +13 -28
- package/dist/commands/index.js.map +1 -1
- package/dist/core/checkpoint.d.ts.map +1 -1
- package/dist/core/checkpoint.js +3 -0
- package/dist/core/checkpoint.js.map +1 -1
- package/dist/framework/prompt.d.ts.map +1 -1
- package/dist/framework/prompt.js +16 -0
- package/dist/framework/prompt.js.map +1 -1
- package/dist/framework/query.d.ts.map +1 -1
- package/dist/framework/query.js +0 -7
- package/dist/framework/query.js.map +1 -1
- package/dist/harness/context-harness.d.ts.map +1 -1
- package/dist/harness/context-harness.js +6 -1
- package/dist/harness/context-harness.js.map +1 -1
- package/dist/harness/ledger.d.ts +1 -0
- package/dist/harness/ledger.d.ts.map +1 -1
- package/dist/harness/ledger.js +8 -0
- package/dist/harness/ledger.js.map +1 -1
- package/dist/harness/safety.d.ts +2 -0
- package/dist/harness/safety.d.ts.map +1 -1
- package/dist/harness/safety.js +27 -3
- package/dist/harness/safety.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +1 -1
- package/dist/init.js.map +1 -1
- package/dist/ink-ui/components/Markdown.d.ts +1 -1
- package/dist/ink-ui/components/Markdown.d.ts.map +1 -1
- package/dist/ink-ui/components/Markdown.js +1 -1
- package/dist/ink-ui/components/Markdown.js.map +1 -1
- package/dist/ink-ui/runtime/grapheme.d.ts +9 -8
- package/dist/ink-ui/runtime/grapheme.d.ts.map +1 -1
- package/dist/ink-ui/runtime/grapheme.js +14 -60
- package/dist/ink-ui/runtime/grapheme.js.map +1 -1
- package/dist/ink-ui/runtime/input-buffer.d.ts +9 -31
- package/dist/ink-ui/runtime/input-buffer.d.ts.map +1 -1
- package/dist/ink-ui/runtime/input-buffer.js +15 -162
- package/dist/ink-ui/runtime/input-buffer.js.map +1 -1
- package/dist/ink-ui/runtime/native-cursor.js +0 -25
- package/dist/ink-ui/runtime/native-cursor.js.map +1 -1
- package/dist/ink-ui/runtime/prompt-layout.d.ts +9 -29
- package/dist/ink-ui/runtime/prompt-layout.d.ts.map +1 -1
- package/dist/ink-ui/runtime/prompt-layout.js +18 -166
- package/dist/ink-ui/runtime/prompt-layout.js.map +1 -1
- package/dist/ink-ui/runtime/transcript-state.d.ts.map +1 -1
- package/dist/ink-ui/runtime/transcript-state.js +2 -0
- package/dist/ink-ui/runtime/transcript-state.js.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.js +11 -0
- package/dist/ink-ui/screens/ReplScreen.js.map +1 -1
- package/dist/memory/entrypoint.js +1 -1
- package/dist/memory/entrypoint.js.map +1 -1
- package/dist/memory/storage.js +1 -1
- package/dist/memory/storage.js.map +1 -1
- package/dist/memory/store.d.ts +1 -0
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +9 -0
- package/dist/memory/store.js.map +1 -1
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +15 -0
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-protocol.d.ts +4 -1
- package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-protocol.js +6 -0
- package/dist/runtime/agent-runtime-protocol.js.map +1 -1
- package/dist/runtime/chat-controller.d.ts +27 -0
- package/dist/runtime/chat-controller.d.ts.map +1 -1
- package/dist/runtime/chat-controller.js +148 -5
- package/dist/runtime/chat-controller.js.map +1 -1
- package/dist/runtime/composer/buffer.d.ts +43 -0
- package/dist/runtime/composer/buffer.d.ts.map +1 -0
- package/dist/runtime/composer/buffer.js +176 -0
- package/dist/runtime/composer/buffer.js.map +1 -0
- package/dist/runtime/composer/grapheme.d.ts +19 -0
- package/dist/runtime/composer/grapheme.d.ts.map +1 -0
- package/dist/runtime/composer/grapheme.js +73 -0
- package/dist/runtime/composer/grapheme.js.map +1 -0
- package/dist/runtime/composer/history.d.ts +39 -0
- package/dist/runtime/composer/history.d.ts.map +1 -0
- package/dist/runtime/composer/history.js +91 -0
- package/dist/runtime/composer/history.js.map +1 -0
- package/dist/runtime/composer/layout.d.ts +40 -0
- package/dist/runtime/composer/layout.d.ts.map +1 -0
- package/dist/runtime/composer/layout.js +174 -0
- package/dist/runtime/composer/layout.js.map +1 -0
- package/dist/runtime/rich-text/ansi-parser.d.ts +31 -0
- package/dist/runtime/rich-text/ansi-parser.d.ts.map +1 -0
- package/dist/runtime/rich-text/ansi-parser.js +272 -0
- package/dist/runtime/rich-text/ansi-parser.js.map +1 -0
- package/dist/runtime/rich-text/layout.d.ts +21 -0
- package/dist/runtime/rich-text/layout.d.ts.map +1 -0
- package/dist/runtime/rich-text/layout.js +327 -0
- package/dist/runtime/rich-text/layout.js.map +1 -0
- package/dist/runtime/rich-text/markdown-parser.d.ts +17 -0
- package/dist/runtime/rich-text/markdown-parser.d.ts.map +1 -0
- package/dist/runtime/rich-text/markdown-parser.js +211 -0
- package/dist/runtime/rich-text/markdown-parser.js.map +1 -0
- package/dist/runtime/rich-text/sanitizer.d.ts +18 -0
- package/dist/runtime/rich-text/sanitizer.d.ts.map +1 -0
- package/dist/runtime/rich-text/sanitizer.js +32 -0
- package/dist/runtime/rich-text/sanitizer.js.map +1 -0
- package/dist/runtime/rich-text/types.d.ts +59 -0
- package/dist/runtime/rich-text/types.d.ts.map +1 -0
- package/dist/runtime/rich-text/types.js +17 -0
- package/dist/runtime/rich-text/types.js.map +1 -0
- package/dist/runtime/subagents/budget.d.ts +118 -0
- package/dist/runtime/subagents/budget.d.ts.map +1 -0
- package/dist/runtime/subagents/budget.js +173 -0
- package/dist/runtime/subagents/budget.js.map +1 -0
- package/dist/runtime/subagents/child-executor-guard.d.ts +60 -0
- package/dist/runtime/subagents/child-executor-guard.d.ts.map +1 -0
- package/dist/runtime/subagents/child-executor-guard.js +219 -0
- package/dist/runtime/subagents/child-executor-guard.js.map +1 -0
- package/dist/runtime/subagents/context-builder.d.ts +34 -0
- package/dist/runtime/subagents/context-builder.d.ts.map +1 -0
- package/dist/runtime/subagents/context-builder.js +99 -0
- package/dist/runtime/subagents/context-builder.js.map +1 -0
- package/dist/runtime/subagents/index.d.ts +21 -0
- package/dist/runtime/subagents/index.d.ts.map +1 -0
- package/dist/runtime/subagents/index.js +62 -0
- package/dist/runtime/subagents/index.js.map +1 -0
- package/dist/runtime/subagents/policy.d.ts +68 -0
- package/dist/runtime/subagents/policy.d.ts.map +1 -0
- package/dist/runtime/subagents/policy.js +230 -0
- package/dist/runtime/subagents/policy.js.map +1 -0
- package/dist/runtime/subagents/presets.d.ts +44 -0
- package/dist/runtime/subagents/presets.d.ts.map +1 -0
- package/dist/runtime/subagents/presets.js +148 -0
- package/dist/runtime/subagents/presets.js.map +1 -0
- package/dist/runtime/subagents/production.d.ts +44 -0
- package/dist/runtime/subagents/production.d.ts.map +1 -0
- package/dist/runtime/subagents/production.js +118 -0
- package/dist/runtime/subagents/production.js.map +1 -0
- package/dist/runtime/subagents/provider-gate.d.ts +99 -0
- package/dist/runtime/subagents/provider-gate.d.ts.map +1 -0
- package/dist/runtime/subagents/provider-gate.js +186 -0
- package/dist/runtime/subagents/provider-gate.js.map +1 -0
- package/dist/runtime/subagents/result-parser.d.ts +40 -0
- package/dist/runtime/subagents/result-parser.d.ts.map +1 -0
- package/dist/runtime/subagents/result-parser.js +226 -0
- package/dist/runtime/subagents/result-parser.js.map +1 -0
- package/dist/runtime/subagents/runner.d.ts +53 -0
- package/dist/runtime/subagents/runner.d.ts.map +1 -0
- package/dist/runtime/subagents/runner.js +172 -0
- package/dist/runtime/subagents/runner.js.map +1 -0
- package/dist/runtime/subagents/runtime-integration.d.ts +73 -0
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -0
- package/dist/runtime/subagents/runtime-integration.js +148 -0
- package/dist/runtime/subagents/runtime-integration.js.map +1 -0
- package/dist/runtime/subagents/supervisor.d.ts +79 -0
- package/dist/runtime/subagents/supervisor.d.ts.map +1 -0
- package/dist/runtime/subagents/supervisor.js +301 -0
- package/dist/runtime/subagents/supervisor.js.map +1 -0
- package/dist/runtime/subagents/tool.d.ts +38 -0
- package/dist/runtime/subagents/tool.d.ts.map +1 -0
- package/dist/runtime/subagents/tool.js +171 -0
- package/dist/runtime/subagents/tool.js.map +1 -0
- package/dist/runtime/subagents/types.d.ts +150 -0
- package/dist/runtime/subagents/types.d.ts.map +1 -0
- package/dist/runtime/subagents/types.js +52 -0
- package/dist/runtime/subagents/types.js.map +1 -0
- package/dist/runtime/ui-events.d.ts +5 -0
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/runtime/ui-view-model.d.ts +35 -1
- package/dist/runtime/ui-view-model.d.ts.map +1 -1
- package/dist/runtime/ui-view-model.js +32 -1
- package/dist/runtime/ui-view-model.js.map +1 -1
- package/dist/sdk/query.d.ts.map +1 -1
- package/dist/sdk/query.js +0 -1
- package/dist/sdk/query.js.map +1 -1
- package/dist/services/auto-fix/autoFixHook.d.ts.map +1 -1
- package/dist/services/auto-fix/autoFixHook.js +3 -2
- package/dist/services/auto-fix/autoFixHook.js.map +1 -1
- package/dist/services/auto-fix/autoFixRunner.d.ts +2 -2
- package/dist/services/auto-fix/autoFixRunner.d.ts.map +1 -1
- package/dist/services/auto-fix/autoFixRunner.js +2 -2
- package/dist/services/auto-fix/autoFixRunner.js.map +1 -1
- package/dist/services/compact/auto-compact.js +3 -3
- package/dist/services/compact/auto-compact.js.map +1 -1
- package/dist/services/compact/summary-generator.d.ts.map +1 -1
- package/dist/services/compact/summary-generator.js +0 -1
- package/dist/services/compact/summary-generator.js.map +1 -1
- package/dist/services/concurrent-sessions.d.ts.map +1 -1
- package/dist/services/concurrent-sessions.js +3 -0
- package/dist/services/concurrent-sessions.js.map +1 -1
- package/dist/services/config.d.ts +11 -4
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +45 -4
- package/dist/services/config.js.map +1 -1
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +1 -1
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/global-config.d.ts +23 -1
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/global-config.js +3 -0
- package/dist/services/global-config.js.map +1 -1
- package/dist/services/llm.d.ts.map +1 -1
- package/dist/services/llm.js +9 -1
- package/dist/services/llm.js.map +1 -1
- package/dist/services/mcp/transports.d.ts +2 -0
- package/dist/services/mcp/transports.d.ts.map +1 -1
- package/dist/services/mcp/transports.js +23 -2
- package/dist/services/mcp/transports.js.map +1 -1
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js.map +1 -1
- package/dist/services/model-context.d.ts.map +1 -1
- package/dist/services/model-context.js +7 -1
- package/dist/services/model-context.js.map +1 -1
- package/dist/services/session-memory/sessionMemory.js +1 -1
- package/dist/services/session-memory/sessionMemory.js.map +1 -1
- package/dist/services/session-storage.d.ts +1 -1
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +49 -5
- package/dist/services/session-storage.js.map +1 -1
- package/dist/services/task-manager.d.ts +2 -0
- package/dist/services/task-manager.d.ts.map +1 -1
- package/dist/services/task-manager.js +13 -0
- package/dist/services/task-manager.js.map +1 -1
- package/dist/services/usage-state.d.ts.map +1 -1
- package/dist/services/usage-state.js +3 -0
- package/dist/services/usage-state.js.map +1 -1
- package/dist/skills/loader.d.ts +1 -1
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +1 -1
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/registry.d.ts +1 -1
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +1 -1
- package/dist/skills/registry.js.map +1 -1
- package/dist/terminal-ui/launch.d.ts +18 -3
- package/dist/terminal-ui/launch.d.ts.map +1 -1
- package/dist/terminal-ui/launch.js +21 -4
- package/dist/terminal-ui/launch.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lsp.js.map +1 -1
- package/dist/tools/mcp.d.ts +1 -0
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mcp.js +19 -4
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/web.js +3 -3
- package/dist/tools/web.js.map +1 -1
- package/dist/tui-core/frame.d.ts +13 -1
- package/dist/tui-core/frame.d.ts.map +1 -1
- package/dist/tui-core/frame.js +61 -8
- package/dist/tui-core/frame.js.map +1 -1
- package/dist/tui-core/style.d.ts +87 -0
- package/dist/tui-core/style.d.ts.map +1 -0
- package/dist/tui-core/style.js +248 -0
- package/dist/tui-core/style.js.map +1 -0
- package/dist/tui-core/terminal-writer.d.ts.map +1 -1
- package/dist/tui-core/terminal-writer.js +16 -3
- package/dist/tui-core/terminal-writer.js.map +1 -1
- package/dist/tui-ui/inline-surface.d.ts +134 -0
- package/dist/tui-ui/inline-surface.d.ts.map +1 -0
- package/dist/tui-ui/inline-surface.js +364 -0
- package/dist/tui-ui/inline-surface.js.map +1 -0
- package/dist/tui-ui/launch.d.ts.map +1 -1
- package/dist/tui-ui/launch.js +251 -64
- package/dist/tui-ui/launch.js.map +1 -1
- package/dist/tui-ui/layout.js +31 -2
- package/dist/tui-ui/layout.js.map +1 -1
- package/dist/tui-ui/render-scheduler.d.ts +37 -0
- package/dist/tui-ui/render-scheduler.d.ts.map +1 -0
- package/dist/tui-ui/render-scheduler.js +118 -0
- package/dist/tui-ui/render-scheduler.js.map +1 -0
- package/dist/tui-ui/runner.d.ts +13 -0
- package/dist/tui-ui/runner.d.ts.map +1 -1
- package/dist/tui-ui/runner.js +60 -11
- package/dist/tui-ui/runner.js.map +1 -1
- package/dist/tui-ui/state.d.ts +33 -3
- package/dist/tui-ui/state.d.ts.map +1 -1
- package/dist/tui-ui/state.js +138 -25
- package/dist/tui-ui/state.js.map +1 -1
- package/dist/tui-ui/transcript-cache.d.ts +33 -0
- package/dist/tui-ui/transcript-cache.d.ts.map +1 -0
- package/dist/tui-ui/transcript-cache.js +67 -0
- package/dist/tui-ui/transcript-cache.js.map +1 -0
- package/dist/ui/box.d.ts.map +1 -1
- package/dist/ui/box.js +0 -11
- package/dist/ui/box.js.map +1 -1
- package/dist/ui/command-panel.d.ts.map +1 -1
- package/dist/ui/command-panel.js +1 -3
- package/dist/ui/command-panel.js.map +1 -1
- package/dist/ui/file-completion.js +1 -1
- package/dist/ui/file-completion.js.map +1 -1
- package/dist/ui/markdown.d.ts.map +1 -1
- package/dist/ui/markdown.js +1 -2
- package/dist/ui/markdown.js.map +1 -1
- package/dist/ui/multiline-input.d.ts.map +1 -1
- package/dist/ui/multiline-input.js +1 -2
- package/dist/ui/multiline-input.js.map +1 -1
- package/dist/ui/progress.d.ts.map +1 -1
- package/dist/ui/progress.js +0 -3
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/status-bar.d.ts.map +1 -1
- package/dist/ui/status-bar.js +0 -1
- package/dist/ui/status-bar.js.map +1 -1
- package/dist/ui/stream-markdown.d.ts +3 -0
- package/dist/ui/stream-markdown.d.ts.map +1 -1
- package/dist/ui/stream-markdown.js +0 -6
- package/dist/ui/stream-markdown.js.map +1 -1
- package/dist/ui/tool-preview.d.ts.map +1 -1
- package/dist/ui/tool-preview.js +0 -1
- package/dist/ui/tool-preview.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli-dbg.js +0 -717
- package/dist/cli-debug.d.ts +0 -7
- package/dist/cli-debug.d.ts.map +0 -1
- package/dist/cli-debug.js +0 -717
- package/dist/cli-debug.js.map +0 -1
- package/dist/cli-debug2.d.ts +0 -7
- package/dist/cli-debug2.d.ts.map +0 -1
- package/dist/cli-debug2.js +0 -717
- package/dist/cli-debug2.js.map +0 -1
- package/dist/cli-debug3.d.ts +0 -7
- package/dist/cli-debug3.d.ts.map +0 -1
- package/dist/cli-debug3.js +0 -719
- package/dist/cli-debug3.js.map +0 -1
- package/dist/cli-ink.d.ts +0 -8
- package/dist/cli-ink.d.ts.map +0 -1
- package/dist/cli-ink.js +0 -32
- package/dist/cli-ink.js.map +0 -1
- package/dist/cli-patch.js +0 -716
- package/dist/cli-test.js +0 -726
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Production binding for {@link ExecuteChildQuery}.
|
|
4
|
+
*
|
|
5
|
+
* Bridges the Supervisor (which is LLM-agnostic) to the real `query()` loop.
|
|
6
|
+
* Each child gets its own {@link LLMService} so mutable per-request state
|
|
7
|
+
* (`consecutive529Errors`, `usingFallback`, `lastRequestDiagnostics`) is not
|
|
8
|
+
* shared across concurrent children. All children still flow through the shared
|
|
9
|
+
* {@link SubagentProviderGate} for concurrency bounding and cooldown.
|
|
10
|
+
*
|
|
11
|
+
* `createLlm` and `runQuery` are injectable so the binding is unit-testable
|
|
12
|
+
* without a live provider; production wires them to `new LLMService(...)` and
|
|
13
|
+
* `query()`.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.createChildLlmConfig = createChildLlmConfig;
|
|
17
|
+
exports.createProductionExecuteQuery = createProductionExecuteQuery;
|
|
18
|
+
const llm_1 = require("../../services/llm");
|
|
19
|
+
const query_1 = require("../../framework/query");
|
|
20
|
+
const types_1 = require("./types");
|
|
21
|
+
/**
|
|
22
|
+
* Create a per-child LLMService. Children share the provider account but not
|
|
23
|
+
* the mutable request state, so one child's fallback/retry does not reshape
|
|
24
|
+
* another child's model choice or diagnostics.
|
|
25
|
+
*/
|
|
26
|
+
function createChildLlmConfig(rootConfig) {
|
|
27
|
+
return {
|
|
28
|
+
apiKey: rootConfig.apiKey,
|
|
29
|
+
baseUrl: rootConfig.baseUrl,
|
|
30
|
+
model: rootConfig.model,
|
|
31
|
+
fallbackModel: rootConfig.fallbackModel,
|
|
32
|
+
timeout: 60000,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the production {@link ExecuteChildQuery}. The returned function runs one
|
|
37
|
+
* child to completion: it creates an isolated LLMService, drives `query()` with
|
|
38
|
+
* the child messages + filtered tools, and returns the final assistant text and
|
|
39
|
+
* observed usage. Never throws - provider errors surface as an empty result so
|
|
40
|
+
* the runner normalizes them into a `failed` SubtaskResult.
|
|
41
|
+
*/
|
|
42
|
+
function createProductionExecuteQuery(deps) {
|
|
43
|
+
const createLlm = deps.createLlm ?? ((config) => new llm_1.LLMService(config));
|
|
44
|
+
const runQuery = deps.runQuery ?? ((params) => (0, query_1.query)(params));
|
|
45
|
+
return async (messages, toolSet, abortSignal) => {
|
|
46
|
+
const llm = createLlm(createChildLlmConfig(deps.rootConfig));
|
|
47
|
+
let finalContent = '';
|
|
48
|
+
let usage = { ...types_1.EMPTY_SUBTASK_USAGE };
|
|
49
|
+
let modelRequests = 0;
|
|
50
|
+
try {
|
|
51
|
+
const params = {
|
|
52
|
+
messages: messages,
|
|
53
|
+
tools: toolSet.tools,
|
|
54
|
+
toolExecutor: toolSet.toolExecutor,
|
|
55
|
+
llm,
|
|
56
|
+
maxTurns: deps.maxTurnsPerTask,
|
|
57
|
+
abortSignal,
|
|
58
|
+
// Children stream nothing to stdout; the root only sees the structured result.
|
|
59
|
+
streamCallbacks: { onChunk: () => undefined },
|
|
60
|
+
};
|
|
61
|
+
for await (const event of runQuery(params)) {
|
|
62
|
+
if (event.type === 'message' && event.role === 'assistant') {
|
|
63
|
+
finalContent = event.content;
|
|
64
|
+
}
|
|
65
|
+
else if (event.type === 'complete') {
|
|
66
|
+
finalContent = event.content;
|
|
67
|
+
usage = loopStatsToUsage(event.stats, modelRequests, event.usage?.promptTokens, event.usage?.completionTokens);
|
|
68
|
+
}
|
|
69
|
+
else if (event.type === 'assistant_tool_calls') {
|
|
70
|
+
modelRequests += 1;
|
|
71
|
+
finalContent = event.content;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
// A 429 with retry-after should pause siblings; surface the cooldown.
|
|
77
|
+
if (isRateLimitError(err)) {
|
|
78
|
+
const retryAfter = extractRetryAfterMs(err);
|
|
79
|
+
deps.providerGate.enterCooldown(retryAfter);
|
|
80
|
+
}
|
|
81
|
+
// Re-throw so the runner normalizes into failed/cancelled. The runner
|
|
82
|
+
// never lets this propagate to the root loop.
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
usage.modelRequests = Math.max(usage.modelRequests, modelRequests);
|
|
86
|
+
return { content: finalContent, usage };
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function loopStatsToUsage(stats, modelRequests, promptTokens, completionTokens) {
|
|
90
|
+
return {
|
|
91
|
+
modelRequests: Math.max(modelRequests, stats?.llmRequests ?? modelRequests, 1),
|
|
92
|
+
toolCalls: stats?.toolCalls ?? 0,
|
|
93
|
+
promptTokens: promptTokens ?? 0,
|
|
94
|
+
completionTokens: completionTokens ?? 0,
|
|
95
|
+
durationMs: 0,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function isRateLimitError(err) {
|
|
99
|
+
if (!err || typeof err !== 'object')
|
|
100
|
+
return false;
|
|
101
|
+
const e = err;
|
|
102
|
+
const status = e.status ?? e.statusCode;
|
|
103
|
+
return status === 429 || /rate.?limit|429|too many requests/i.test(String(e.message ?? ''));
|
|
104
|
+
}
|
|
105
|
+
function extractRetryAfterMs(err) {
|
|
106
|
+
if (!err || typeof err !== 'object')
|
|
107
|
+
return 5000;
|
|
108
|
+
const e = err;
|
|
109
|
+
const headers = e.headers;
|
|
110
|
+
const retryAfter = headers?.['retry-after'];
|
|
111
|
+
if (retryAfter) {
|
|
112
|
+
const seconds = Number.parseFloat(retryAfter);
|
|
113
|
+
if (Number.isFinite(seconds))
|
|
114
|
+
return seconds * 1000;
|
|
115
|
+
}
|
|
116
|
+
return 5000; // conservative default cooldown
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=production.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"production.js","sourceRoot":"","sources":["../../../src/runtime/subagents/production.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubagentProviderGate: shared concurrency + cooldown for child LLM requests.
|
|
3
|
+
*
|
|
4
|
+
* Each child runs its own loop, but all children draw model requests from the
|
|
5
|
+
* same provider account. The gate bounds concurrent in-flight child execution
|
|
6
|
+
* and shares cooldown state so that one child's 429/retry-after pauses new
|
|
7
|
+
* children rather than letting each independently retry into a storm.
|
|
8
|
+
*
|
|
9
|
+
* The gate does NOT own per-request diagnostics or fallback model state - those
|
|
10
|
+
* live in the child's own LLMService. The gate only owns the shared go/no-go.
|
|
11
|
+
*
|
|
12
|
+
* R4 semantics:
|
|
13
|
+
* - `canReserve(count)` only reports whether the provider is in an
|
|
14
|
+
* unrecoverable state (cooldown). Normal concurrency saturation is NOT a
|
|
15
|
+
* reason to reject - the policy should let batches queue and let the FIFO
|
|
16
|
+
* semaphore bound actual peak concurrency.
|
|
17
|
+
* - `acquire(signal?)` queues when slots are full; resolves in FIFO order.
|
|
18
|
+
* An abort signal atomically removes the waiter and rejects, with no leaked
|
|
19
|
+
* active slot or listener.
|
|
20
|
+
* - cooldown has a single wake timer that re-arms on extension; when it
|
|
21
|
+
* fires it drains queued waiters so they do not hang after the last
|
|
22
|
+
* release during cooldown.
|
|
23
|
+
*/
|
|
24
|
+
export interface ProviderGateOptions {
|
|
25
|
+
/** Maximum children running concurrently. */
|
|
26
|
+
maxConcurrent: number;
|
|
27
|
+
/** Optional clock, injectable for deterministic tests. */
|
|
28
|
+
now?: () => number;
|
|
29
|
+
/** Optional timer scheduler (defaults to setTimeout). Injectable for tests. */
|
|
30
|
+
scheduleTimer?: (fn: () => void, ms: number) => {
|
|
31
|
+
clear(): void;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Thrown when an acquire is aborted via its signal. */
|
|
35
|
+
export declare class AcquireAbortedError extends Error {
|
|
36
|
+
constructor();
|
|
37
|
+
}
|
|
38
|
+
export declare class SubagentProviderGate {
|
|
39
|
+
private readonly maxConcurrent;
|
|
40
|
+
private readonly now;
|
|
41
|
+
private readonly scheduleTimer;
|
|
42
|
+
private active;
|
|
43
|
+
private cooldownUntil;
|
|
44
|
+
private waiters;
|
|
45
|
+
private cooldownTimer;
|
|
46
|
+
constructor(options: ProviderGateOptions);
|
|
47
|
+
/** Whether the provider is currently in a cooldown window. */
|
|
48
|
+
isInCooldown(): boolean;
|
|
49
|
+
/** Remaining ms in the current cooldown, or 0. */
|
|
50
|
+
cooldownRemainingMs(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Enter a cooldown after a rate-limit response. New acquires will wait until
|
|
53
|
+
* the window expires. A longer requested cooldown extends; a shorter one is
|
|
54
|
+
* ignored if an active cooldown is longer. Re-arms the wake timer so queued
|
|
55
|
+
* waiters are drained when the cooldown expires (R4: no permanent hang).
|
|
56
|
+
*/
|
|
57
|
+
enterCooldown(retryAfterMs: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* R4: whether the provider can accept new children. Returns false ONLY during
|
|
60
|
+
* cooldown — normal concurrency saturation is not a rejection reason, because
|
|
61
|
+
* the FIFO semaphore queues excess tasks and bounds actual peak concurrency
|
|
62
|
+
* at acquire time.
|
|
63
|
+
*
|
|
64
|
+
* NOTE: the `count` parameter is currently unused. It is reserved for future
|
|
65
|
+
* per-slot reservation checks. Today, policy only needs to know whether the
|
|
66
|
+
* provider is in an unrecoverable state (cooldown).
|
|
67
|
+
*/
|
|
68
|
+
canReserve(_count: number): boolean;
|
|
69
|
+
/** Number of children currently holding a slot. */
|
|
70
|
+
activeCount(): number;
|
|
71
|
+
/**
|
|
72
|
+
* Acquire a slot. Resolves once a slot is free and the provider is not in
|
|
73
|
+
* cooldown. The caller MUST call `release()` when the child finishes.
|
|
74
|
+
*
|
|
75
|
+
* R4: if `signal` is provided and aborts while queued, the waiter is removed
|
|
76
|
+
* atomically and the promise rejects with {@link AcquireAbortedError}. No
|
|
77
|
+
* active slot is leaked and the abort listener is removed.
|
|
78
|
+
*
|
|
79
|
+
* The slot is claimed synchronously before the waiter's microtask runs, so
|
|
80
|
+
* `drainWaiters` never over-allocates beyond `maxConcurrent`.
|
|
81
|
+
*/
|
|
82
|
+
acquire(signal?: AbortSignal): Promise<void>;
|
|
83
|
+
/** Release a slot and wake the next waiter (if not in cooldown). */
|
|
84
|
+
release(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Wake waiters in FIFO order. For each waiter, the slot is claimed
|
|
87
|
+
* synchronously (active += 1) BEFORE the promise is resolved, so the
|
|
88
|
+
* next iteration of the while-loop sees the updated count and won't
|
|
89
|
+
* over-allocate.
|
|
90
|
+
*/
|
|
91
|
+
private drainWaiters;
|
|
92
|
+
/**
|
|
93
|
+
* Arm (or re-arm) a single timer that fires when the current cooldown
|
|
94
|
+
* expires, then drains queued waiters. Re-arming on extension keeps a
|
|
95
|
+
* single pending timer at all times.
|
|
96
|
+
*/
|
|
97
|
+
private armCooldownTimer;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=provider-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-gate.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/provider-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK;QAAE,KAAK,IAAI,IAAI,CAAA;KAAE,CAAC;CACnE;AAED,wDAAwD;AACxD,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAUD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoD;IAClF,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,aAAa,CAAkC;gBAE3C,OAAO,EAAE,mBAAmB;IAUxC,8DAA8D;IAC9D,YAAY,IAAI,OAAO;IAIvB,kDAAkD;IAClD,mBAAmB,IAAI,MAAM;IAI7B;;;;;OAKG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAQzC;;;;;;;;;OASG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC,mDAAmD;IACnD,WAAW,IAAI,MAAM;IAIrB;;;;;;;;;;OAUG;IACG,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgClD,oEAAoE;IACpE,OAAO,IAAI,IAAI;IAKf;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAapB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CAgBzB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SubagentProviderGate: shared concurrency + cooldown for child LLM requests.
|
|
4
|
+
*
|
|
5
|
+
* Each child runs its own loop, but all children draw model requests from the
|
|
6
|
+
* same provider account. The gate bounds concurrent in-flight child execution
|
|
7
|
+
* and shares cooldown state so that one child's 429/retry-after pauses new
|
|
8
|
+
* children rather than letting each independently retry into a storm.
|
|
9
|
+
*
|
|
10
|
+
* The gate does NOT own per-request diagnostics or fallback model state - those
|
|
11
|
+
* live in the child's own LLMService. The gate only owns the shared go/no-go.
|
|
12
|
+
*
|
|
13
|
+
* R4 semantics:
|
|
14
|
+
* - `canReserve(count)` only reports whether the provider is in an
|
|
15
|
+
* unrecoverable state (cooldown). Normal concurrency saturation is NOT a
|
|
16
|
+
* reason to reject - the policy should let batches queue and let the FIFO
|
|
17
|
+
* semaphore bound actual peak concurrency.
|
|
18
|
+
* - `acquire(signal?)` queues when slots are full; resolves in FIFO order.
|
|
19
|
+
* An abort signal atomically removes the waiter and rejects, with no leaked
|
|
20
|
+
* active slot or listener.
|
|
21
|
+
* - cooldown has a single wake timer that re-arms on extension; when it
|
|
22
|
+
* fires it drains queued waiters so they do not hang after the last
|
|
23
|
+
* release during cooldown.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.SubagentProviderGate = exports.AcquireAbortedError = void 0;
|
|
27
|
+
/** Thrown when an acquire is aborted via its signal. */
|
|
28
|
+
class AcquireAbortedError extends Error {
|
|
29
|
+
constructor() {
|
|
30
|
+
super('Subagent provider gate acquire was aborted');
|
|
31
|
+
this.name = 'AcquireAbortedError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.AcquireAbortedError = AcquireAbortedError;
|
|
35
|
+
class SubagentProviderGate {
|
|
36
|
+
constructor(options) {
|
|
37
|
+
this.active = 0;
|
|
38
|
+
this.cooldownUntil = 0;
|
|
39
|
+
this.waiters = [];
|
|
40
|
+
this.cooldownTimer = null;
|
|
41
|
+
const maxConcurrent = Number(options.maxConcurrent);
|
|
42
|
+
// N12: guard against NaN/undefined/negative — clamp to 1 as safe minimum.
|
|
43
|
+
this.maxConcurrent = Number.isFinite(maxConcurrent) && maxConcurrent >= 1
|
|
44
|
+
? Math.floor(maxConcurrent)
|
|
45
|
+
: 1;
|
|
46
|
+
this.now = options.now ?? (() => Date.now());
|
|
47
|
+
this.scheduleTimer = options.scheduleTimer ?? defaultScheduleTimer;
|
|
48
|
+
}
|
|
49
|
+
/** Whether the provider is currently in a cooldown window. */
|
|
50
|
+
isInCooldown() {
|
|
51
|
+
return this.now() < this.cooldownUntil;
|
|
52
|
+
}
|
|
53
|
+
/** Remaining ms in the current cooldown, or 0. */
|
|
54
|
+
cooldownRemainingMs() {
|
|
55
|
+
return Math.max(0, this.cooldownUntil - this.now());
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Enter a cooldown after a rate-limit response. New acquires will wait until
|
|
59
|
+
* the window expires. A longer requested cooldown extends; a shorter one is
|
|
60
|
+
* ignored if an active cooldown is longer. Re-arms the wake timer so queued
|
|
61
|
+
* waiters are drained when the cooldown expires (R4: no permanent hang).
|
|
62
|
+
*/
|
|
63
|
+
enterCooldown(retryAfterMs) {
|
|
64
|
+
const until = this.now() + Math.max(0, retryAfterMs);
|
|
65
|
+
if (until > this.cooldownUntil) {
|
|
66
|
+
this.cooldownUntil = until;
|
|
67
|
+
this.armCooldownTimer();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* R4: whether the provider can accept new children. Returns false ONLY during
|
|
72
|
+
* cooldown — normal concurrency saturation is not a rejection reason, because
|
|
73
|
+
* the FIFO semaphore queues excess tasks and bounds actual peak concurrency
|
|
74
|
+
* at acquire time.
|
|
75
|
+
*
|
|
76
|
+
* NOTE: the `count` parameter is currently unused. It is reserved for future
|
|
77
|
+
* per-slot reservation checks. Today, policy only needs to know whether the
|
|
78
|
+
* provider is in an unrecoverable state (cooldown).
|
|
79
|
+
*/
|
|
80
|
+
canReserve(_count) {
|
|
81
|
+
return !this.isInCooldown();
|
|
82
|
+
}
|
|
83
|
+
/** Number of children currently holding a slot. */
|
|
84
|
+
activeCount() {
|
|
85
|
+
return this.active;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Acquire a slot. Resolves once a slot is free and the provider is not in
|
|
89
|
+
* cooldown. The caller MUST call `release()` when the child finishes.
|
|
90
|
+
*
|
|
91
|
+
* R4: if `signal` is provided and aborts while queued, the waiter is removed
|
|
92
|
+
* atomically and the promise rejects with {@link AcquireAbortedError}. No
|
|
93
|
+
* active slot is leaked and the abort listener is removed.
|
|
94
|
+
*
|
|
95
|
+
* The slot is claimed synchronously before the waiter's microtask runs, so
|
|
96
|
+
* `drainWaiters` never over-allocates beyond `maxConcurrent`.
|
|
97
|
+
*/
|
|
98
|
+
async acquire(signal) {
|
|
99
|
+
// Already aborted before we even start.
|
|
100
|
+
if (signal?.aborted)
|
|
101
|
+
throw new AcquireAbortedError();
|
|
102
|
+
if (this.canReserve(1) && this.active < this.maxConcurrent) {
|
|
103
|
+
this.active += 1;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
await new Promise((resolve, reject) => {
|
|
107
|
+
const waiter = { resolve, reject, signal };
|
|
108
|
+
this.waiters.push(waiter);
|
|
109
|
+
if (signal) {
|
|
110
|
+
const onAbort = () => {
|
|
111
|
+
// Atomically remove this waiter; if it was already claimed by
|
|
112
|
+
// drainWaiters (no longer in the queue), the abort is a no-op.
|
|
113
|
+
const idx = this.waiters.indexOf(waiter);
|
|
114
|
+
if (idx >= 0) {
|
|
115
|
+
this.waiters.splice(idx, 1);
|
|
116
|
+
reject(new AcquireAbortedError());
|
|
117
|
+
}
|
|
118
|
+
signal.removeEventListener('abort', onAbort);
|
|
119
|
+
};
|
|
120
|
+
waiter.onAbort = onAbort;
|
|
121
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// NOTE: `this.active` was already incremented by drainWaiters when the
|
|
125
|
+
// slot was claimed synchronously, so we do NOT increment here.
|
|
126
|
+
}
|
|
127
|
+
/** Release a slot and wake the next waiter (if not in cooldown). */
|
|
128
|
+
release() {
|
|
129
|
+
this.active = Math.max(0, this.active - 1);
|
|
130
|
+
this.drainWaiters();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Wake waiters in FIFO order. For each waiter, the slot is claimed
|
|
134
|
+
* synchronously (active += 1) BEFORE the promise is resolved, so the
|
|
135
|
+
* next iteration of the while-loop sees the updated count and won't
|
|
136
|
+
* over-allocate.
|
|
137
|
+
*/
|
|
138
|
+
drainWaiters() {
|
|
139
|
+
while (this.waiters.length > 0 && !this.isInCooldown() && this.active < this.maxConcurrent) {
|
|
140
|
+
const next = this.waiters.shift();
|
|
141
|
+
if (!next)
|
|
142
|
+
continue;
|
|
143
|
+
this.active += 1; // claim synchronously before resolving
|
|
144
|
+
// Remove the abort listener (if any) - the waiter is being fulfilled.
|
|
145
|
+
if (next.signal && next.onAbort) {
|
|
146
|
+
next.signal.removeEventListener('abort', next.onAbort);
|
|
147
|
+
}
|
|
148
|
+
next.resolve();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Arm (or re-arm) a single timer that fires when the current cooldown
|
|
153
|
+
* expires, then drains queued waiters. Re-arming on extension keeps a
|
|
154
|
+
* single pending timer at all times.
|
|
155
|
+
*/
|
|
156
|
+
armCooldownTimer() {
|
|
157
|
+
if (this.cooldownTimer) {
|
|
158
|
+
this.cooldownTimer.clear();
|
|
159
|
+
this.cooldownTimer = null;
|
|
160
|
+
}
|
|
161
|
+
const remaining = this.cooldownRemainingMs();
|
|
162
|
+
if (remaining <= 0) {
|
|
163
|
+
// Cooldown already over - drain immediately.
|
|
164
|
+
this.drainWaiters();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.cooldownTimer = this.scheduleTimer(() => {
|
|
168
|
+
this.cooldownTimer = null;
|
|
169
|
+
this.drainWaiters();
|
|
170
|
+
}, remaining);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.SubagentProviderGate = SubagentProviderGate;
|
|
174
|
+
function defaultScheduleTimer(fn, ms) {
|
|
175
|
+
const handle = setTimeout(fn, ms);
|
|
176
|
+
// Don't keep the event loop alive solely for a cooldown wake.
|
|
177
|
+
if (typeof handle === 'object' && handle && 'unref' in handle && typeof handle.unref === 'function') {
|
|
178
|
+
handle.unref();
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
clear() {
|
|
182
|
+
clearTimeout(handle);
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=provider-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-gate.js","sourceRoot":"","sources":["../../../src/runtime/subagents/provider-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubagentResultParser: normalize a child's final text into a fixed schema.
|
|
3
|
+
*
|
|
4
|
+
* Children are instructed to emit a single JSON object. In practice they may
|
|
5
|
+
* wrap it in prose, emit invalid JSON, or omit fields. This parser is the
|
|
6
|
+
* single chokepoint that produces a well-typed {@link SubtaskResult} regardless
|
|
7
|
+
* of provider quirks, so the root Agent only ever sees structured data.
|
|
8
|
+
*/
|
|
9
|
+
import type { SubagentRole, SubtaskResult, SubtaskResultStatus } from './types';
|
|
10
|
+
export interface ParsedSubtaskPayload {
|
|
11
|
+
summary?: unknown;
|
|
12
|
+
findings?: unknown;
|
|
13
|
+
files?: unknown;
|
|
14
|
+
commands?: unknown;
|
|
15
|
+
verification?: unknown;
|
|
16
|
+
risks?: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract the first balanced JSON object from text that may contain prose
|
|
20
|
+
* around it. Returns the parsed object or null if none is found / invalid.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractJsonObject(text: string): unknown;
|
|
23
|
+
/**
|
|
24
|
+
* Parse a child's final text into a {@link SubtaskResult}.
|
|
25
|
+
*
|
|
26
|
+
* @param id Runtime-generated task id.
|
|
27
|
+
* @param role The role the child ran as.
|
|
28
|
+
* @param content The child's final assistant text (may contain prose + JSON).
|
|
29
|
+
* @param status Terminal status. `completed` requires parseable JSON;
|
|
30
|
+
* otherwise the summary records the failure mode.
|
|
31
|
+
* @param usage Observed usage; defaults to empty.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseSubtaskResult(args: {
|
|
34
|
+
id: string;
|
|
35
|
+
role: SubagentRole;
|
|
36
|
+
content: string;
|
|
37
|
+
status: SubtaskResultStatus;
|
|
38
|
+
usage?: SubtaskResult['usage'];
|
|
39
|
+
}): SubtaskResult;
|
|
40
|
+
//# sourceMappingURL=result-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-parser.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/result-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,YAAY,EAEZ,aAAa,EACb,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAUjB,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAqCvD;AAgED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAChC,GAAG,aAAa,CAgEhB"}
|