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,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Subagent runtime public surface.
|
|
4
|
+
*
|
|
5
|
+
* v0.2.20 exposes a read-only subagent runtime. The root Agent may request
|
|
6
|
+
* 1-3 independent investigation packets; a Supervisor runs them as isolated
|
|
7
|
+
* child agents under a unified budget, permission boundary and trace.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
21
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.deriveRootLlmConfig = exports.createSubagentBundleForTurn = exports.createSubagentToolForTurn = exports.createChildLlmConfig = exports.createProductionExecuteQuery = exports.summarizeBatchForModel = exports.coerceSubtaskRequest = exports.createSubtaskTool = exports.runSubtaskBatch = exports.SubagentProviderGate = exports.runSubtask = exports.ScopeHolder = exports.evaluateToolCall = exports.createChildToolExecutorGuard = exports.extractJsonObject = exports.parseSubtaskResult = exports.buildChildMessages = exports.budgetLimitsFromConfig = exports.TurnTaskState = exports.SubagentBudgetLedger = exports.clampSubagentConfig = exports.hasExplicitDelegationIntent = exports.canonicalizeScopePaths = exports.evaluateSubtaskPolicy = void 0;
|
|
25
|
+
__exportStar(require("./types"), exports);
|
|
26
|
+
__exportStar(require("./presets"), exports);
|
|
27
|
+
var policy_1 = require("./policy");
|
|
28
|
+
Object.defineProperty(exports, "evaluateSubtaskPolicy", { enumerable: true, get: function () { return policy_1.evaluateSubtaskPolicy; } });
|
|
29
|
+
Object.defineProperty(exports, "canonicalizeScopePaths", { enumerable: true, get: function () { return policy_1.canonicalizeScopePaths; } });
|
|
30
|
+
Object.defineProperty(exports, "hasExplicitDelegationIntent", { enumerable: true, get: function () { return policy_1.hasExplicitDelegationIntent; } });
|
|
31
|
+
Object.defineProperty(exports, "clampSubagentConfig", { enumerable: true, get: function () { return policy_1.clampSubagentConfig; } });
|
|
32
|
+
var budget_1 = require("./budget");
|
|
33
|
+
Object.defineProperty(exports, "SubagentBudgetLedger", { enumerable: true, get: function () { return budget_1.SubagentBudgetLedger; } });
|
|
34
|
+
Object.defineProperty(exports, "TurnTaskState", { enumerable: true, get: function () { return budget_1.TurnTaskState; } });
|
|
35
|
+
Object.defineProperty(exports, "budgetLimitsFromConfig", { enumerable: true, get: function () { return budget_1.budgetLimitsFromConfig; } });
|
|
36
|
+
var context_builder_1 = require("./context-builder");
|
|
37
|
+
Object.defineProperty(exports, "buildChildMessages", { enumerable: true, get: function () { return context_builder_1.buildChildMessages; } });
|
|
38
|
+
var result_parser_1 = require("./result-parser");
|
|
39
|
+
Object.defineProperty(exports, "parseSubtaskResult", { enumerable: true, get: function () { return result_parser_1.parseSubtaskResult; } });
|
|
40
|
+
Object.defineProperty(exports, "extractJsonObject", { enumerable: true, get: function () { return result_parser_1.extractJsonObject; } });
|
|
41
|
+
var child_executor_guard_1 = require("./child-executor-guard");
|
|
42
|
+
Object.defineProperty(exports, "createChildToolExecutorGuard", { enumerable: true, get: function () { return child_executor_guard_1.createChildToolExecutorGuard; } });
|
|
43
|
+
Object.defineProperty(exports, "evaluateToolCall", { enumerable: true, get: function () { return child_executor_guard_1.evaluateToolCall; } });
|
|
44
|
+
Object.defineProperty(exports, "ScopeHolder", { enumerable: true, get: function () { return child_executor_guard_1.ScopeHolder; } });
|
|
45
|
+
var runner_1 = require("./runner");
|
|
46
|
+
Object.defineProperty(exports, "runSubtask", { enumerable: true, get: function () { return runner_1.runSubtask; } });
|
|
47
|
+
var provider_gate_1 = require("./provider-gate");
|
|
48
|
+
Object.defineProperty(exports, "SubagentProviderGate", { enumerable: true, get: function () { return provider_gate_1.SubagentProviderGate; } });
|
|
49
|
+
var supervisor_1 = require("./supervisor");
|
|
50
|
+
Object.defineProperty(exports, "runSubtaskBatch", { enumerable: true, get: function () { return supervisor_1.runSubtaskBatch; } });
|
|
51
|
+
var tool_1 = require("./tool");
|
|
52
|
+
Object.defineProperty(exports, "createSubtaskTool", { enumerable: true, get: function () { return tool_1.createSubtaskTool; } });
|
|
53
|
+
Object.defineProperty(exports, "coerceSubtaskRequest", { enumerable: true, get: function () { return tool_1.coerceSubtaskRequest; } });
|
|
54
|
+
Object.defineProperty(exports, "summarizeBatchForModel", { enumerable: true, get: function () { return tool_1.summarizeBatchForModel; } });
|
|
55
|
+
var production_1 = require("./production");
|
|
56
|
+
Object.defineProperty(exports, "createProductionExecuteQuery", { enumerable: true, get: function () { return production_1.createProductionExecuteQuery; } });
|
|
57
|
+
Object.defineProperty(exports, "createChildLlmConfig", { enumerable: true, get: function () { return production_1.createChildLlmConfig; } });
|
|
58
|
+
var runtime_integration_1 = require("./runtime-integration");
|
|
59
|
+
Object.defineProperty(exports, "createSubagentToolForTurn", { enumerable: true, get: function () { return runtime_integration_1.createSubagentToolForTurn; } });
|
|
60
|
+
Object.defineProperty(exports, "createSubagentBundleForTurn", { enumerable: true, get: function () { return runtime_integration_1.createSubagentBundleForTurn; } });
|
|
61
|
+
Object.defineProperty(exports, "deriveRootLlmConfig", { enumerable: true, get: function () { return runtime_integration_1.deriveRootLlmConfig; } });
|
|
62
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtime/subagents/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,4CAA0B;AAC1B,mCAQkB;AAPhB,+GAAA,qBAAqB,OAAA;AACrB,gHAAA,sBAAsB,OAAA;AACtB,qHAAA,2BAA2B,OAAA;AAC3B,6GAAA,mBAAmB,OAAA;AAKrB,mCAQkB;AAPhB,8GAAA,oBAAoB,OAAA;AACpB,uGAAA,aAAa,OAAA;AACb,gHAAA,sBAAsB,OAAA;AAMxB,qDAAgF;AAAvE,qHAAA,kBAAkB,OAAA;AAC3B,iDAAmG;AAA1F,mHAAA,kBAAkB,OAAA;AAAE,kHAAA,iBAAiB,OAAA;AAC9C,+DAMgC;AAL9B,oIAAA,4BAA4B,OAAA;AAC5B,wHAAA,gBAAgB,OAAA;AAChB,mHAAA,WAAW,OAAA;AAIb,mCAMkB;AALhB,oGAAA,UAAU,OAAA;AAMZ,iDAGyB;AAFvB,qHAAA,oBAAoB,OAAA;AAGtB,2CAIsB;AAHpB,6GAAA,eAAe,OAAA;AAIjB,+BAIgB;AAHd,yGAAA,iBAAiB,OAAA;AACjB,4GAAA,oBAAoB,OAAA;AACpB,8GAAA,sBAAsB,OAAA;AAExB,2CAIsB;AAHpB,0HAAA,4BAA4B,OAAA;AAC5B,kHAAA,oBAAoB,OAAA;AAGtB,6DAM+B;AAL7B,gIAAA,yBAAyB,OAAA;AACzB,kIAAA,2BAA2B,OAAA;AAC3B,0HAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubagentPolicy: deterministic approval gate for `subtask` requests.
|
|
3
|
+
*
|
|
4
|
+
* The root Agent proposes work packages; the runtime decides whether they may
|
|
5
|
+
* run. Every allow/reject decision is recorded with a reason and a budget
|
|
6
|
+
* snapshot, so the policy is auditable rather than hidden in a classifier.
|
|
7
|
+
*
|
|
8
|
+
* Scope canonicalization lives here too: child paths must stay inside the
|
|
9
|
+
* project root. `../`, absolute escapes and symlink escapes are rejected.
|
|
10
|
+
*/
|
|
11
|
+
import type { SubagentConfig, SubtaskRequest } from './types';
|
|
12
|
+
export type PolicyVerdict = {
|
|
13
|
+
allowed: true;
|
|
14
|
+
canonicalScope: Map<number, string[]>;
|
|
15
|
+
} | {
|
|
16
|
+
allowed: false;
|
|
17
|
+
reason: PolicyRejectReason;
|
|
18
|
+
detail?: string;
|
|
19
|
+
};
|
|
20
|
+
export type PolicyRejectReason = 'mode_off' | 'not_root_depth' | 'explicit_intent_missing' | 'too_many_tasks' | 'role_disabled' | 'objective_unbounded' | 'duplicate_scope' | 'scope_escape' | 'pending_permission' | 'parent_aborted' | 'budget_exhausted' | 'provider_unavailable' | 'concurrency_limit' | 'empty_request' | 'not_eligible_for_delegation';
|
|
21
|
+
export interface PolicyContext {
|
|
22
|
+
/** Current delegation depth. Only depth 0 (root) may delegate. */
|
|
23
|
+
depth: number;
|
|
24
|
+
/** Canonical project root the children operate in. */
|
|
25
|
+
cwd: string;
|
|
26
|
+
/** Active config. */
|
|
27
|
+
config: SubagentConfig;
|
|
28
|
+
/** Root objective text, used to detect explicit delegation intent. */
|
|
29
|
+
rootObjective: string;
|
|
30
|
+
/** Subtasks already started in this root turn. */
|
|
31
|
+
tasksStartedThisTurn: number;
|
|
32
|
+
/** Children currently running. */
|
|
33
|
+
runningChildren: number;
|
|
34
|
+
/** A permission request is awaiting user decision. */
|
|
35
|
+
hasPendingPermission: boolean;
|
|
36
|
+
/** Parent turn abort signal has fired. */
|
|
37
|
+
parentAborted: boolean;
|
|
38
|
+
/** Remaining aggregate model-request budget for the turn. */
|
|
39
|
+
remainingModelRequests: number;
|
|
40
|
+
/** Provider gate can reserve a slot for every task in the batch. */
|
|
41
|
+
providerCanReserve: (count: number) => boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Canonicalize a list of scope paths against the project root.
|
|
45
|
+
*
|
|
46
|
+
* Returns the canonical relative paths for paths that stay inside the root,
|
|
47
|
+
* or `null` if any path escapes (via `..`, absolute outside root, or symlink).
|
|
48
|
+
* Symlink defense only applies to paths that exist on disk: a non-existent
|
|
49
|
+
* path cannot be a symlink escape, and skipping it avoids root/child realpath
|
|
50
|
+
* basis mismatches (e.g. macOS `/tmp` -> `/private/tmp`).
|
|
51
|
+
*/
|
|
52
|
+
export declare function canonicalizeScopePaths(rootCwd: string, paths: readonly string[] | undefined): {
|
|
53
|
+
ok: true;
|
|
54
|
+
paths: string[];
|
|
55
|
+
} | {
|
|
56
|
+
ok: false;
|
|
57
|
+
reason: 'scope_escape';
|
|
58
|
+
path: string;
|
|
59
|
+
};
|
|
60
|
+
export declare function hasExplicitDelegationIntent(rootObjective: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Evaluate a `subtask` request against the policy. This is the single
|
|
63
|
+
* deterministic gate every request must pass before any child is queued.
|
|
64
|
+
*/
|
|
65
|
+
export declare function evaluateSubtaskPolicy(request: SubtaskRequest, ctx: PolicyContext): PolicyVerdict;
|
|
66
|
+
/** Clamp a user-provided config value to the enforced bounds. */
|
|
67
|
+
export declare function clampSubagentConfig(config: SubagentConfig): SubagentConfig;
|
|
68
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EACV,cAAc,EAId,cAAc,EACf,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,GACxD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE,MAAM,MAAM,kBAAkB,GAC1B,UAAU,GACV,gBAAgB,GAChB,yBAAyB,GACzB,gBAAgB,GAChB,eAAe,GACf,qBAAqB,GACrB,iBAAiB,GACjB,cAAc,GACd,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,sBAAsB,GACtB,mBAAmB,GACnB,eAAe,GACf,6BAA6B,CAAC;AAElC,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,oBAAoB,EAAE,OAAO,CAAC;IAC9B,0CAA0C;IAC1C,aAAa,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,sBAAsB,EAAE,MAAM,CAAC;IAC/B,oEAAoE;IACpE,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAChD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACnC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAwBrF;AAmBD,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAE1E;AAcD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,aAAa,GACjB,aAAa,CAuEf;AAMD,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAmB1E"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SubagentPolicy: deterministic approval gate for `subtask` requests.
|
|
4
|
+
*
|
|
5
|
+
* The root Agent proposes work packages; the runtime decides whether they may
|
|
6
|
+
* run. Every allow/reject decision is recorded with a reason and a budget
|
|
7
|
+
* snapshot, so the policy is auditable rather than hidden in a classifier.
|
|
8
|
+
*
|
|
9
|
+
* Scope canonicalization lives here too: child paths must stay inside the
|
|
10
|
+
* project root. `../`, absolute escapes and symlink escapes are rejected.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.canonicalizeScopePaths = canonicalizeScopePaths;
|
|
14
|
+
exports.hasExplicitDelegationIntent = hasExplicitDelegationIntent;
|
|
15
|
+
exports.evaluateSubtaskPolicy = evaluateSubtaskPolicy;
|
|
16
|
+
exports.clampSubagentConfig = clampSubagentConfig;
|
|
17
|
+
const path_1 = require("path");
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const types_1 = require("./types");
|
|
20
|
+
/**
|
|
21
|
+
* Canonicalize a list of scope paths against the project root.
|
|
22
|
+
*
|
|
23
|
+
* Returns the canonical relative paths for paths that stay inside the root,
|
|
24
|
+
* or `null` if any path escapes (via `..`, absolute outside root, or symlink).
|
|
25
|
+
* Symlink defense only applies to paths that exist on disk: a non-existent
|
|
26
|
+
* path cannot be a symlink escape, and skipping it avoids root/child realpath
|
|
27
|
+
* basis mismatches (e.g. macOS `/tmp` -> `/private/tmp`).
|
|
28
|
+
*/
|
|
29
|
+
function canonicalizeScopePaths(rootCwd, paths) {
|
|
30
|
+
if (!paths || paths.length === 0)
|
|
31
|
+
return { ok: true, paths: [] };
|
|
32
|
+
const realRoot = realpathSafe(rootCwd);
|
|
33
|
+
const canonical = [];
|
|
34
|
+
for (const raw of paths) {
|
|
35
|
+
if (typeof raw !== 'string' || raw.trim() === '') {
|
|
36
|
+
return { ok: false, reason: 'scope_escape', path: String(raw) };
|
|
37
|
+
}
|
|
38
|
+
const resolved = (0, path_1.resolve)(rootCwd, raw);
|
|
39
|
+
const rel = (0, path_1.relative)(rootCwd, resolved);
|
|
40
|
+
if (rel.startsWith('..') || (0, path_1.isAbsolute)(rel)) {
|
|
41
|
+
return { ok: false, reason: 'scope_escape', path: raw };
|
|
42
|
+
}
|
|
43
|
+
if ((0, fs_1.existsSync)(resolved)) {
|
|
44
|
+
const realResolved = realpathSafe(resolved);
|
|
45
|
+
const realRel = (0, path_1.relative)(realRoot, realResolved);
|
|
46
|
+
if (realRel.startsWith('..') || (0, path_1.isAbsolute)(realRel)) {
|
|
47
|
+
return { ok: false, reason: 'scope_escape', path: raw };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
canonical.push((0, path_1.normalize)(rel));
|
|
51
|
+
}
|
|
52
|
+
return { ok: true, paths: canonical };
|
|
53
|
+
}
|
|
54
|
+
function realpathSafe(p) {
|
|
55
|
+
try {
|
|
56
|
+
return (0, fs_1.realpathSync)(p);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return p;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const DELEGATION_INTENT_PATTERNS = [
|
|
63
|
+
/\b(parallel|concurrent|separately|independent)\b/i,
|
|
64
|
+
/\b(research|review|investigate|audit)\b/i,
|
|
65
|
+
/\bsub-?agent\b/i,
|
|
66
|
+
/\bsubtask\b/i,
|
|
67
|
+
// CJK patterns: \b word-boundary does not match CJK, so no anchors here.
|
|
68
|
+
/(多个|并行|分别|独立|调研|审查|调查)/,
|
|
69
|
+
];
|
|
70
|
+
function hasExplicitDelegationIntent(rootObjective) {
|
|
71
|
+
return DELEGATION_INTENT_PATTERNS.some(re => re.test(rootObjective));
|
|
72
|
+
}
|
|
73
|
+
const UNBOUNDED_OBJECTIVE_PATTERNS = [
|
|
74
|
+
/^(处理一下|继续看看|看一下|随便|帮个忙)/,
|
|
75
|
+
/^\s*(todo|tbd|fixme)\s*$/i,
|
|
76
|
+
];
|
|
77
|
+
function isObjectiveBounded(objective) {
|
|
78
|
+
const trimmed = objective.trim();
|
|
79
|
+
if (trimmed.length < 4)
|
|
80
|
+
return false;
|
|
81
|
+
if (UNBOUNDED_OBJECTIVE_PATTERNS.some(re => re.test(trimmed)))
|
|
82
|
+
return false;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Evaluate a `subtask` request against the policy. This is the single
|
|
87
|
+
* deterministic gate every request must pass before any child is queued.
|
|
88
|
+
*/
|
|
89
|
+
function evaluateSubtaskPolicy(request, ctx) {
|
|
90
|
+
if (ctx.parentAborted)
|
|
91
|
+
return reject('parent_aborted');
|
|
92
|
+
if (ctx.hasPendingPermission)
|
|
93
|
+
return reject('pending_permission');
|
|
94
|
+
if (ctx.depth !== 0)
|
|
95
|
+
return reject('not_root_depth');
|
|
96
|
+
if (ctx.config.mode === 'off')
|
|
97
|
+
return reject('mode_off');
|
|
98
|
+
const tasks = request.tasks;
|
|
99
|
+
if (!Array.isArray(tasks) || tasks.length === 0)
|
|
100
|
+
return reject('empty_request');
|
|
101
|
+
if (tasks.length > ctx.config.maxTasksPerTurn) {
|
|
102
|
+
return reject('too_many_tasks', `${tasks.length} > ${ctx.config.maxTasksPerTurn}`);
|
|
103
|
+
}
|
|
104
|
+
if (ctx.config.mode === 'explicit' && !hasExplicitDelegationIntent(ctx.rootObjective)) {
|
|
105
|
+
return reject('explicit_intent_missing');
|
|
106
|
+
}
|
|
107
|
+
// R9: for `auto` mode, require at least two independent investigation
|
|
108
|
+
// directions in the root objective OR a review + test-investigate
|
|
109
|
+
// combination. A single-file read or simple Q&A cannot accidentally
|
|
110
|
+
// delegate. `explicit` mode ensures explicit intent manually; this gate
|
|
111
|
+
// only applies when the model proposes delegation unbidden.
|
|
112
|
+
if (ctx.config.mode === 'auto' && tasks.length === 1) {
|
|
113
|
+
if (!meetsAutoEligibility(ctx.rootObjective, tasks)) {
|
|
114
|
+
return reject('not_eligible_for_delegation', 'auto mode requires at least 2 independent investigation directions or a review+test-investigate combination');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const totalTasks = ctx.tasksStartedThisTurn + tasks.length;
|
|
118
|
+
if (totalTasks > ctx.config.maxTasksPerTurn) {
|
|
119
|
+
return reject('too_many_tasks', `turn total ${totalTasks} > ${ctx.config.maxTasksPerTurn}`);
|
|
120
|
+
}
|
|
121
|
+
// Concurrency: a parallel batch must fit within maxParallel alongside running children.
|
|
122
|
+
if (request.execution === 'parallel') {
|
|
123
|
+
if (ctx.runningChildren > 0 && ctx.runningChildren + tasks.length > ctx.config.maxParallel) {
|
|
124
|
+
return reject('concurrency_limit', `${ctx.runningChildren}+${tasks.length} > ${ctx.config.maxParallel}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (ctx.remainingModelRequests < tasks.length) {
|
|
128
|
+
return reject('budget_exhausted', `need >=${tasks.length} requests, have ${ctx.remainingModelRequests}`);
|
|
129
|
+
}
|
|
130
|
+
if (!ctx.providerCanReserve(tasks.length)) {
|
|
131
|
+
return reject('provider_unavailable');
|
|
132
|
+
}
|
|
133
|
+
const canonicalScope = new Map();
|
|
134
|
+
const seenScopes = new Set();
|
|
135
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
136
|
+
const packet = tasks[i];
|
|
137
|
+
if (!ctx.config.roles.includes(packet.role)) {
|
|
138
|
+
return reject('role_disabled', packet.role);
|
|
139
|
+
}
|
|
140
|
+
if (!isObjectiveBounded(packet.objective)) {
|
|
141
|
+
return reject('objective_unbounded', packet.objective.slice(0, 40));
|
|
142
|
+
}
|
|
143
|
+
const scope = canonicalizeScopePaths(ctx.cwd, packet.scope?.paths);
|
|
144
|
+
if (!scope.ok) {
|
|
145
|
+
return reject('scope_escape', scope.path);
|
|
146
|
+
}
|
|
147
|
+
const scopeKey = scope.paths.join(',');
|
|
148
|
+
if (scopeKey && seenScopes.has(scopeKey)) {
|
|
149
|
+
return reject('duplicate_scope', scopeKey);
|
|
150
|
+
}
|
|
151
|
+
if (scopeKey)
|
|
152
|
+
seenScopes.add(scopeKey);
|
|
153
|
+
canonicalScope.set(i, scope.paths);
|
|
154
|
+
}
|
|
155
|
+
return { allowed: true, canonicalScope };
|
|
156
|
+
}
|
|
157
|
+
function reject(reason, detail) {
|
|
158
|
+
return { allowed: false, reason, detail };
|
|
159
|
+
}
|
|
160
|
+
/** Clamp a user-provided config value to the enforced bounds. */
|
|
161
|
+
function clampSubagentConfig(config) {
|
|
162
|
+
const clamp = (value, bounds) => Math.max(bounds.min, Math.min(bounds.max, Math.floor(value) || bounds.min));
|
|
163
|
+
const roles = Array.from(new Set(config.roles)).filter(r => ['research', 'review', 'test-investigate'].includes(r));
|
|
164
|
+
const clampedRoles = roles.length > 0 ? roles : DEFAULT_ROLES;
|
|
165
|
+
const mode = ['off', 'explicit', 'auto'].includes(config.mode) ? config.mode : 'auto';
|
|
166
|
+
return {
|
|
167
|
+
mode,
|
|
168
|
+
maxParallel: clamp(config.maxParallel, types_1.SUBAGENT_LIMITS.maxParallel),
|
|
169
|
+
maxTasksPerTurn: clamp(config.maxTasksPerTurn, types_1.SUBAGENT_LIMITS.maxTasksPerTurn),
|
|
170
|
+
maxTurnsPerTask: clamp(config.maxTurnsPerTask, types_1.SUBAGENT_LIMITS.maxTurnsPerTask),
|
|
171
|
+
maxModelRequestsPerTask: clamp(config.maxModelRequestsPerTask, types_1.SUBAGENT_LIMITS.maxModelRequestsPerTask),
|
|
172
|
+
maxModelRequestsPerTurn: clamp(config.maxModelRequestsPerTurn, types_1.SUBAGENT_LIMITS.maxModelRequestsPerTurn),
|
|
173
|
+
maxToolCallsPerTask: clamp(config.maxToolCallsPerTask, types_1.SUBAGENT_LIMITS.maxToolCallsPerTask),
|
|
174
|
+
timeoutMs: clamp(config.timeoutMs, types_1.SUBAGENT_LIMITS.timeoutMs),
|
|
175
|
+
roles: clampedRoles,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const DEFAULT_ROLES = ['research', 'review', 'test-investigate'];
|
|
179
|
+
/**
|
|
180
|
+
* R9: determine whether a single-task `auto` delegation is eligible.
|
|
181
|
+
*
|
|
182
|
+
* A single-packet delegation is only allowed when the root objective shows
|
|
183
|
+
* two or more independent investigation directions (so the model could have
|
|
184
|
+
* proposed multiple tasks but chose one) OR when the packet requests a review
|
|
185
|
+
* or test-investigation with a well-scoped objective. Simple Q&A, single-file
|
|
186
|
+
* reads, or vague "look at" prompts are never eligible.
|
|
187
|
+
*
|
|
188
|
+
* The check is conservative and explainable. `explicit` mode bypasses this
|
|
189
|
+
* gate entirely (the user said "delegate").
|
|
190
|
+
*
|
|
191
|
+
* @returns true if the task meets the minimum eligibility bar.
|
|
192
|
+
*/
|
|
193
|
+
function meetsAutoEligibility(rootObjective, tasks) {
|
|
194
|
+
if (tasks.length >= 2)
|
|
195
|
+
return true;
|
|
196
|
+
const task = tasks[0];
|
|
197
|
+
const role = task.role;
|
|
198
|
+
const objective = task.objective;
|
|
199
|
+
// review and test-investigate are inherently multi-faceted: they imply a
|
|
200
|
+
// diff/changeset and test coverage analysis respectively. A single review
|
|
201
|
+
// or test-investigate task is eligible when the objective is concrete.
|
|
202
|
+
if (role === 'review' || role === 'test-investigate') {
|
|
203
|
+
return objective.trim().length >= 10;
|
|
204
|
+
}
|
|
205
|
+
// research: require multiple independent investigation signals in either
|
|
206
|
+
// the root objective or the task's scope/packet details.
|
|
207
|
+
const hasMultiDirectionInRoot = hasMultipleInvestigationDirections(rootObjective);
|
|
208
|
+
if (hasMultiDirectionInRoot)
|
|
209
|
+
return true;
|
|
210
|
+
// The packet must show at least two independent aspects.
|
|
211
|
+
const scopeCount = task.scope?.paths?.length ?? 0;
|
|
212
|
+
const hintCount = task.contextHints?.length ?? 0;
|
|
213
|
+
return scopeCount >= 2 || hintCount >= 2;
|
|
214
|
+
}
|
|
215
|
+
/** True if the objective text suggests at least two independent work items. */
|
|
216
|
+
function hasMultipleInvestigationDirections(objective) {
|
|
217
|
+
const lower = objective.toLowerCase();
|
|
218
|
+
// Conjunctions that signal multiple independent directions.
|
|
219
|
+
const multiMarkers = [
|
|
220
|
+
/ and /, /, and /, / or /,
|
|
221
|
+
/ both /, / each /,
|
|
222
|
+
/ parallel/, /separately/, /independently/,
|
|
223
|
+
/ respectively/,
|
|
224
|
+
// CJK: multiple items or separation
|
|
225
|
+
/(和|与|以及|分别|并行|独立|同时)/,
|
|
226
|
+
/(两个|多个|若干|各个|分别)/,
|
|
227
|
+
];
|
|
228
|
+
return multiMarkers.some(re => re.test(lower));
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/runtime/subagents/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in subagent role presets: system prompts and tool allowlists.
|
|
3
|
+
*
|
|
4
|
+
* v0.2.20 ships read-only investigation roles. Every role's allowlist is the
|
|
5
|
+
* intersection of (read-only tools) and (role-appropriate tools). No role
|
|
6
|
+
* receives exec_command, write/edit, memory mutation, or the recursive
|
|
7
|
+
* `subtask` capability - this is enforced structurally, not by prompt alone.
|
|
8
|
+
*/
|
|
9
|
+
import type { SubagentRole } from './types';
|
|
10
|
+
import type { OpenHorseTool } from '../../framework/tool';
|
|
11
|
+
/** Read-only investigation tools available to children in v0.2.20. */
|
|
12
|
+
export declare const READ_ONLY_INVESTIGATION_TOOLS: readonly ["read_file", "list_files", "glob", "grep", "batch_read"];
|
|
13
|
+
/**
|
|
14
|
+
* Tools a child must NEVER receive. Kept as an explicit deny-set so the
|
|
15
|
+
* supervisor can assert that a filtered tool list contains none of these,
|
|
16
|
+
* even if future tools are added upstream.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SUBAGENT_FORBIDDEN_TOOLS: readonly ["exec_command", "edit_file", "write_file", "memory_save", "memory_recall", "memory_forget", "openhorse", "subtask", "mcp_call", "mcp_list", "history_search"];
|
|
19
|
+
export interface RolePreset {
|
|
20
|
+
role: SubagentRole;
|
|
21
|
+
/** Tool names the child may use. */
|
|
22
|
+
tools: readonly string[];
|
|
23
|
+
/** System prompt enforcing the role's contract and JSON output schema. */
|
|
24
|
+
systemPrompt: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const ROLE_PRESETS: Record<SubagentRole, RolePreset>;
|
|
27
|
+
/** Resolve the tool allowlist for a role. Falls back to the read-only set. */
|
|
28
|
+
export declare function toolsForRole(role: SubagentRole): readonly string[];
|
|
29
|
+
/** Resolve the system prompt for a role. */
|
|
30
|
+
export declare function systemPromptForRole(role: SubagentRole): string;
|
|
31
|
+
/**
|
|
32
|
+
* Filter an upstream tool list to a role's allowlist, removing any forbidden
|
|
33
|
+
* tool and the recursive `subtask` capability. Also includes first-class MCP
|
|
34
|
+
* tools (mcp__<server>__<tool>) that declare `readOnlyHint === true` via
|
|
35
|
+
* their `isReadOnly()` method — these are safe for children because they
|
|
36
|
+
* cannot invoke arbitrary MCP actions.
|
|
37
|
+
*
|
|
38
|
+
* Returns the names the child may receive; the caller is responsible for
|
|
39
|
+
* resolving them to tool definitions.
|
|
40
|
+
*/
|
|
41
|
+
export declare function filterToolsForRole(availableToolNames: readonly string[], role: SubagentRole, runtimeTools?: readonly OpenHorseTool[]): string[];
|
|
42
|
+
/** Assert a filtered tool list contains no forbidden tool. Used by the runner. */
|
|
43
|
+
export declare function assertNoForbiddenTools(toolNames: readonly string[]): void;
|
|
44
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,sEAAsE;AACtE,eAAO,MAAM,6BAA6B,oEAYhC,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,yKAgB3B,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,oCAAoC;IACpC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;CACtB;AAqBD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAwBzD,CAAC;AAEF,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,MAAM,EAAE,CAElE;AAED,4CAA4C;AAC5C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAE9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,kBAAkB,EAAE,SAAS,MAAM,EAAE,EACrC,IAAI,EAAE,YAAY,EAClB,YAAY,CAAC,EAAE,SAAS,aAAa,EAAE,GACtC,MAAM,EAAE,CA4BV;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAMzE"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Built-in subagent role presets: system prompts and tool allowlists.
|
|
4
|
+
*
|
|
5
|
+
* v0.2.20 ships read-only investigation roles. Every role's allowlist is the
|
|
6
|
+
* intersection of (read-only tools) and (role-appropriate tools). No role
|
|
7
|
+
* receives exec_command, write/edit, memory mutation, or the recursive
|
|
8
|
+
* `subtask` capability - this is enforced structurally, not by prompt alone.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.ROLE_PRESETS = exports.SUBAGENT_FORBIDDEN_TOOLS = exports.READ_ONLY_INVESTIGATION_TOOLS = void 0;
|
|
12
|
+
exports.toolsForRole = toolsForRole;
|
|
13
|
+
exports.systemPromptForRole = systemPromptForRole;
|
|
14
|
+
exports.filterToolsForRole = filterToolsForRole;
|
|
15
|
+
exports.assertNoForbiddenTools = assertNoForbiddenTools;
|
|
16
|
+
/** Read-only investigation tools available to children in v0.2.20. */
|
|
17
|
+
exports.READ_ONLY_INVESTIGATION_TOOLS = [
|
|
18
|
+
'read_file',
|
|
19
|
+
'list_files',
|
|
20
|
+
'glob',
|
|
21
|
+
'grep',
|
|
22
|
+
'batch_read',
|
|
23
|
+
// NOTE: mcp_call and mcp_list are intentionally EXCLUDED from the child
|
|
24
|
+
// allowlist. mcp_call is a generic escape hatch that can invoke any MCP
|
|
25
|
+
// action (including mutating ones) without going through the root's
|
|
26
|
+
// permission flow. mcp_list leaks server topology. Instead, first-class
|
|
27
|
+
// MCP tools (mcp__<server>__<tool>) with readOnlyHint === true are
|
|
28
|
+
// dynamically included by filterToolsForRole at runtime.
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Tools a child must NEVER receive. Kept as an explicit deny-set so the
|
|
32
|
+
* supervisor can assert that a filtered tool list contains none of these,
|
|
33
|
+
* even if future tools are added upstream.
|
|
34
|
+
*/
|
|
35
|
+
exports.SUBAGENT_FORBIDDEN_TOOLS = [
|
|
36
|
+
'exec_command',
|
|
37
|
+
'edit_file',
|
|
38
|
+
'write_file',
|
|
39
|
+
'memory_save',
|
|
40
|
+
'memory_recall',
|
|
41
|
+
'memory_forget',
|
|
42
|
+
'openhorse',
|
|
43
|
+
'subtask',
|
|
44
|
+
// Generic MCP escape hatches — children must use first-class MCP tools
|
|
45
|
+
// (mcp__<server>__<tool>) with readOnlyHint === true instead.
|
|
46
|
+
'mcp_call',
|
|
47
|
+
'mcp_list',
|
|
48
|
+
// Cross-session information leak: history_search reads transcripts from
|
|
49
|
+
// all projects. Children must never access session history.
|
|
50
|
+
'history_search',
|
|
51
|
+
];
|
|
52
|
+
const JSON_OUTPUT_CONTRACT = `
|
|
53
|
+
You MUST end your investigation by emitting a single JSON object and nothing else after it, matching this schema:
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
"summary": "one concise paragraph of the overall conclusion",
|
|
57
|
+
"findings": [{ "severity": "critical|high|medium|low|info", "title": "short", "evidence": "specific file:line or quoted fact", "file": "optional path", "line": 0 }],
|
|
58
|
+
"files": ["paths you inspected or that are relevant"],
|
|
59
|
+
"commands": [{ "command": "suggested read-only or root-owned command", "purpose": "why" }],
|
|
60
|
+
"verification": ["how the root Agent can verify your conclusion"],
|
|
61
|
+
"risks": ["caveats, unknowns, or things that could invalidate this"]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Rules:
|
|
65
|
+
- Every finding must cite concrete evidence (file path, line, quoted text, or command output you observed). Do not speculate.
|
|
66
|
+
- "commands.executed" is always false; you may only SUGGEST commands for the root Agent to run. Never claim you executed one.
|
|
67
|
+
- You cannot edit, write, delete, commit, push, publish, install dependencies, run tests, or create further subagents.
|
|
68
|
+
- If you cannot reach a confident conclusion, say so in "risks" rather than fabricating evidence.
|
|
69
|
+
- Keep the JSON valid and self-contained. No trailing prose.`;
|
|
70
|
+
exports.ROLE_PRESETS = {
|
|
71
|
+
research: {
|
|
72
|
+
role: 'research',
|
|
73
|
+
tools: exports.READ_ONLY_INVESTIGATION_TOOLS,
|
|
74
|
+
systemPrompt: `You are a read-only research subagent for OpenHorse. Your job is to gather repository facts, official documentation, or API behavior and return a structured conclusion.
|
|
75
|
+
|
|
76
|
+
You may only read files, list/glob/grep, batch read-only steps, and use configured read-only MCP tools (e.g. web search/fetch). You may inspect git state only through read-only means available to you.
|
|
77
|
+
|
|
78
|
+
Focus narrowly on the objective you were given. Do not attempt edits or commands.${JSON_OUTPUT_CONTRACT}`,
|
|
79
|
+
},
|
|
80
|
+
review: {
|
|
81
|
+
role: 'review',
|
|
82
|
+
tools: exports.READ_ONLY_INVESTIGATION_TOOLS,
|
|
83
|
+
systemPrompt: `You are a read-only code review subagent for OpenHorse. Your job is to review a diff, changeset, or code area for risks, regressions, and test gaps, and return a structured conclusion.
|
|
84
|
+
|
|
85
|
+
You may read files, list/glob/grep, batch read-only steps, and use read-only MCP tools. You may NOT fix code, change review scope, execute shell, or commit.${JSON_OUTPUT_CONTRACT}`,
|
|
86
|
+
},
|
|
87
|
+
'test-investigate': {
|
|
88
|
+
role: 'test-investigate',
|
|
89
|
+
tools: exports.READ_ONLY_INVESTIGATION_TOOLS,
|
|
90
|
+
systemPrompt: `You are a read-only test investigation subagent for OpenHorse. You analyze failing test logs, test code, and configuration to identify likely root causes, and return a structured conclusion.
|
|
91
|
+
|
|
92
|
+
You may read files, list/glob/grep, batch read-only steps, and use read-only MCP tools. You may NOT execute tests, install dependencies, update snapshots, write fixtures, or publish. If a command would help diagnose the failure, suggest it in "commands" for the root Agent to run.${JSON_OUTPUT_CONTRACT}`,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
/** Resolve the tool allowlist for a role. Falls back to the read-only set. */
|
|
96
|
+
function toolsForRole(role) {
|
|
97
|
+
return exports.ROLE_PRESETS[role]?.tools ?? exports.READ_ONLY_INVESTIGATION_TOOLS;
|
|
98
|
+
}
|
|
99
|
+
/** Resolve the system prompt for a role. */
|
|
100
|
+
function systemPromptForRole(role) {
|
|
101
|
+
return exports.ROLE_PRESETS[role]?.systemPrompt ?? exports.ROLE_PRESETS.research.systemPrompt;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Filter an upstream tool list to a role's allowlist, removing any forbidden
|
|
105
|
+
* tool and the recursive `subtask` capability. Also includes first-class MCP
|
|
106
|
+
* tools (mcp__<server>__<tool>) that declare `readOnlyHint === true` via
|
|
107
|
+
* their `isReadOnly()` method — these are safe for children because they
|
|
108
|
+
* cannot invoke arbitrary MCP actions.
|
|
109
|
+
*
|
|
110
|
+
* Returns the names the child may receive; the caller is responsible for
|
|
111
|
+
* resolving them to tool definitions.
|
|
112
|
+
*/
|
|
113
|
+
function filterToolsForRole(availableToolNames, role, runtimeTools) {
|
|
114
|
+
const allowed = new Set(toolsForRole(role));
|
|
115
|
+
const denied = new Set(exports.SUBAGENT_FORBIDDEN_TOOLS);
|
|
116
|
+
// Build a map of tool name → tool definition for annotation checks.
|
|
117
|
+
const toolMap = new Map();
|
|
118
|
+
if (runtimeTools) {
|
|
119
|
+
for (const t of runtimeTools) {
|
|
120
|
+
toolMap.set(t.name, t);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return availableToolNames.filter(name => {
|
|
124
|
+
// Explicitly denied tools are never allowed.
|
|
125
|
+
if (denied.has(name))
|
|
126
|
+
return false;
|
|
127
|
+
// First-class MCP tools (mcp__<server>__<tool>) are allowed only if
|
|
128
|
+
// they declare isReadOnly() === true. Unknown or missing annotation
|
|
129
|
+
// means denied — conservative default.
|
|
130
|
+
if (name.startsWith('mcp__')) {
|
|
131
|
+
const tool = toolMap.get(name);
|
|
132
|
+
if (!tool)
|
|
133
|
+
return false;
|
|
134
|
+
return tool.isReadOnly?.({}) === true;
|
|
135
|
+
}
|
|
136
|
+
// Static allowlist covers non-MCP tools.
|
|
137
|
+
return allowed.has(name);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** Assert a filtered tool list contains no forbidden tool. Used by the runner. */
|
|
141
|
+
function assertNoForbiddenTools(toolNames) {
|
|
142
|
+
const denied = new Set(exports.SUBAGENT_FORBIDDEN_TOOLS);
|
|
143
|
+
const found = toolNames.filter(name => denied.has(name));
|
|
144
|
+
if (found.length > 0) {
|
|
145
|
+
throw new Error(`Subagent tool list contains forbidden tools: ${found.join(', ')}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../src/runtime/subagents/presets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production binding for {@link ExecuteChildQuery}.
|
|
3
|
+
*
|
|
4
|
+
* Bridges the Supervisor (which is LLM-agnostic) to the real `query()` loop.
|
|
5
|
+
* Each child gets its own {@link LLMService} so mutable per-request state
|
|
6
|
+
* (`consecutive529Errors`, `usingFallback`, `lastRequestDiagnostics`) is not
|
|
7
|
+
* shared across concurrent children. All children still flow through the shared
|
|
8
|
+
* {@link SubagentProviderGate} for concurrency bounding and cooldown.
|
|
9
|
+
*
|
|
10
|
+
* `createLlm` and `runQuery` are injectable so the binding is unit-testable
|
|
11
|
+
* without a live provider; production wires them to `new LLMService(...)` and
|
|
12
|
+
* `query()`.
|
|
13
|
+
*/
|
|
14
|
+
import { LLMService, type LLMConfig } from '../../services/llm';
|
|
15
|
+
import { type QueryEvent, type QueryParams } from '../../framework/query';
|
|
16
|
+
import type { ExecuteChildQuery } from './runner';
|
|
17
|
+
import type { SubagentProviderGate } from './provider-gate';
|
|
18
|
+
export interface SubagentLlmFactoryDeps {
|
|
19
|
+
/** Root config used to derive each child's LLMConfig. */
|
|
20
|
+
rootConfig: Pick<LLMConfig, 'apiKey' | 'baseUrl' | 'model' | 'fallbackModel'>;
|
|
21
|
+
/** Injectable LLMService factory (production: `new LLMService(config)`). */
|
|
22
|
+
createLlm?: (config: LLMConfig) => LLMService;
|
|
23
|
+
/** Injectable query loop (production: `query`). */
|
|
24
|
+
runQuery?: (params: QueryParams) => AsyncIterable<QueryEvent>;
|
|
25
|
+
/** Shared gate; a child that observes a 429 enters cooldown for siblings. */
|
|
26
|
+
providerGate: SubagentProviderGate;
|
|
27
|
+
/** Per-child turn cap. */
|
|
28
|
+
maxTurnsPerTask: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create a per-child LLMService. Children share the provider account but not
|
|
32
|
+
* the mutable request state, so one child's fallback/retry does not reshape
|
|
33
|
+
* another child's model choice or diagnostics.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createChildLlmConfig(rootConfig: Pick<LLMConfig, 'apiKey' | 'baseUrl' | 'model' | 'fallbackModel'>): LLMConfig;
|
|
36
|
+
/**
|
|
37
|
+
* Build the production {@link ExecuteChildQuery}. The returned function runs one
|
|
38
|
+
* child to completion: it creates an isolated LLMService, drives `query()` with
|
|
39
|
+
* the child messages + filtered tools, and returns the final assistant text and
|
|
40
|
+
* observed usage. Never throws - provider errors surface as an empty result so
|
|
41
|
+
* the runner normalizes them into a `failed` SubtaskResult.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createProductionExecuteQuery(deps: SubagentLlmFactoryDeps): ExecuteChildQuery;
|
|
44
|
+
//# sourceMappingURL=production.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"production.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/production.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAgB,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAS,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,eAAe,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,UAAU,CAAC;IAC9C,mDAAmD;IACnD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC;IAC9D,6EAA6E;IAC7E,YAAY,EAAE,oBAAoB,CAAC;IACnC,0BAA0B;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,eAAe,CAAC,GAC5E,SAAS,CAQX;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,sBAAsB,GAAG,iBAAiB,CA8C5F"}
|