@animus-labs/cortex 0.2.0
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/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/budget-guard.d.ts +75 -0
- package/dist/budget-guard.d.ts.map +1 -0
- package/dist/budget-guard.js +142 -0
- package/dist/budget-guard.js.map +1 -0
- package/dist/compaction/compaction.d.ts +99 -0
- package/dist/compaction/compaction.d.ts.map +1 -0
- package/dist/compaction/compaction.js +302 -0
- package/dist/compaction/compaction.js.map +1 -0
- package/dist/compaction/failsafe.d.ts +57 -0
- package/dist/compaction/failsafe.d.ts.map +1 -0
- package/dist/compaction/failsafe.js +135 -0
- package/dist/compaction/failsafe.js.map +1 -0
- package/dist/compaction/index.d.ts +381 -0
- package/dist/compaction/index.d.ts.map +1 -0
- package/dist/compaction/index.js +979 -0
- package/dist/compaction/index.js.map +1 -0
- package/dist/compaction/microcompaction.d.ts +219 -0
- package/dist/compaction/microcompaction.d.ts.map +1 -0
- package/dist/compaction/microcompaction.js +536 -0
- package/dist/compaction/microcompaction.js.map +1 -0
- package/dist/compaction/observational/buffering.d.ts +225 -0
- package/dist/compaction/observational/buffering.d.ts.map +1 -0
- package/dist/compaction/observational/buffering.js +354 -0
- package/dist/compaction/observational/buffering.js.map +1 -0
- package/dist/compaction/observational/constants.d.ts +70 -0
- package/dist/compaction/observational/constants.d.ts.map +1 -0
- package/dist/compaction/observational/constants.js +507 -0
- package/dist/compaction/observational/constants.js.map +1 -0
- package/dist/compaction/observational/index.d.ts +219 -0
- package/dist/compaction/observational/index.d.ts.map +1 -0
- package/dist/compaction/observational/index.js +641 -0
- package/dist/compaction/observational/index.js.map +1 -0
- package/dist/compaction/observational/observer.d.ts +97 -0
- package/dist/compaction/observational/observer.d.ts.map +1 -0
- package/dist/compaction/observational/observer.js +424 -0
- package/dist/compaction/observational/observer.js.map +1 -0
- package/dist/compaction/observational/recall-tool.d.ts +27 -0
- package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
- package/dist/compaction/observational/recall-tool.js +93 -0
- package/dist/compaction/observational/recall-tool.js.map +1 -0
- package/dist/compaction/observational/reflector.d.ts +94 -0
- package/dist/compaction/observational/reflector.d.ts.map +1 -0
- package/dist/compaction/observational/reflector.js +167 -0
- package/dist/compaction/observational/reflector.js.map +1 -0
- package/dist/compaction/observational/types.d.ts +271 -0
- package/dist/compaction/observational/types.d.ts.map +1 -0
- package/dist/compaction/observational/types.js +15 -0
- package/dist/compaction/observational/types.js.map +1 -0
- package/dist/context-manager.d.ts +134 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +170 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/cortex-agent.d.ts +1020 -0
- package/dist/cortex-agent.d.ts.map +1 -0
- package/dist/cortex-agent.js +3589 -0
- package/dist/cortex-agent.js.map +1 -0
- package/dist/error-classifier.d.ts +48 -0
- package/dist/error-classifier.d.ts.map +1 -0
- package/dist/error-classifier.js +152 -0
- package/dist/error-classifier.js.map +1 -0
- package/dist/event-bridge.d.ts +166 -0
- package/dist/event-bridge.d.ts.map +1 -0
- package/dist/event-bridge.js +381 -0
- package/dist/event-bridge.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-client.d.ts +119 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +474 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/model-wrapper.d.ts +58 -0
- package/dist/model-wrapper.d.ts.map +1 -0
- package/dist/model-wrapper.js +86 -0
- package/dist/model-wrapper.js.map +1 -0
- package/dist/noop-logger.d.ts +4 -0
- package/dist/noop-logger.d.ts.map +1 -0
- package/dist/noop-logger.js +8 -0
- package/dist/noop-logger.js.map +1 -0
- package/dist/prompt-diagnostics.d.ts +47 -0
- package/dist/prompt-diagnostics.d.ts.map +1 -0
- package/dist/prompt-diagnostics.js +230 -0
- package/dist/prompt-diagnostics.js.map +1 -0
- package/dist/provider-manager.d.ts +224 -0
- package/dist/provider-manager.d.ts.map +1 -0
- package/dist/provider-manager.js +563 -0
- package/dist/provider-manager.js.map +1 -0
- package/dist/provider-registry.d.ts +115 -0
- package/dist/provider-registry.d.ts.map +1 -0
- package/dist/provider-registry.js +305 -0
- package/dist/provider-registry.js.map +1 -0
- package/dist/schema-converter.d.ts +20 -0
- package/dist/schema-converter.d.ts.map +1 -0
- package/dist/schema-converter.js +48 -0
- package/dist/schema-converter.js.map +1 -0
- package/dist/skill-preprocessor.d.ts +46 -0
- package/dist/skill-preprocessor.d.ts.map +1 -0
- package/dist/skill-preprocessor.js +237 -0
- package/dist/skill-preprocessor.js.map +1 -0
- package/dist/skill-registry.d.ts +107 -0
- package/dist/skill-registry.d.ts.map +1 -0
- package/dist/skill-registry.js +330 -0
- package/dist/skill-registry.js.map +1 -0
- package/dist/skill-tool.d.ts +54 -0
- package/dist/skill-tool.d.ts.map +1 -0
- package/dist/skill-tool.js +88 -0
- package/dist/skill-tool.js.map +1 -0
- package/dist/sub-agent-manager.d.ts +90 -0
- package/dist/sub-agent-manager.d.ts.map +1 -0
- package/dist/sub-agent-manager.js +192 -0
- package/dist/sub-agent-manager.js.map +1 -0
- package/dist/token-estimator.d.ts +23 -0
- package/dist/token-estimator.d.ts.map +1 -0
- package/dist/token-estimator.js +27 -0
- package/dist/token-estimator.js.map +1 -0
- package/dist/tool-contract.d.ts +68 -0
- package/dist/tool-contract.d.ts.map +1 -0
- package/dist/tool-contract.js +35 -0
- package/dist/tool-contract.js.map +1 -0
- package/dist/tool-result-persistence.d.ts +89 -0
- package/dist/tool-result-persistence.d.ts.map +1 -0
- package/dist/tool-result-persistence.js +152 -0
- package/dist/tool-result-persistence.js.map +1 -0
- package/dist/tools/bash/index.d.ts +71 -0
- package/dist/tools/bash/index.d.ts.map +1 -0
- package/dist/tools/bash/index.js +485 -0
- package/dist/tools/bash/index.js.map +1 -0
- package/dist/tools/bash/interactive.d.ts +47 -0
- package/dist/tools/bash/interactive.d.ts.map +1 -0
- package/dist/tools/bash/interactive.js +262 -0
- package/dist/tools/bash/interactive.js.map +1 -0
- package/dist/tools/bash/safety.d.ts +149 -0
- package/dist/tools/bash/safety.d.ts.map +1 -0
- package/dist/tools/bash/safety.js +1116 -0
- package/dist/tools/bash/safety.js.map +1 -0
- package/dist/tools/edit.d.ts +57 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +310 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +34 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +268 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +53 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +673 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +62 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/read.d.ts +43 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +459 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/runtime.d.ts +62 -0
- package/dist/tools/runtime.d.ts.map +1 -0
- package/dist/tools/runtime.js +116 -0
- package/dist/tools/runtime.js.map +1 -0
- package/dist/tools/shared/cwd-tracker.d.ts +32 -0
- package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
- package/dist/tools/shared/cwd-tracker.js +44 -0
- package/dist/tools/shared/cwd-tracker.js.map +1 -0
- package/dist/tools/shared/edit-history.d.ts +55 -0
- package/dist/tools/shared/edit-history.d.ts.map +1 -0
- package/dist/tools/shared/edit-history.js +72 -0
- package/dist/tools/shared/edit-history.js.map +1 -0
- package/dist/tools/shared/edit-matcher.d.ts +83 -0
- package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
- package/dist/tools/shared/edit-matcher.js +359 -0
- package/dist/tools/shared/edit-matcher.js.map +1 -0
- package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
- package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
- package/dist/tools/shared/file-mutation-lock.js +35 -0
- package/dist/tools/shared/file-mutation-lock.js.map +1 -0
- package/dist/tools/shared/gitignore.d.ts +17 -0
- package/dist/tools/shared/gitignore.d.ts.map +1 -0
- package/dist/tools/shared/gitignore.js +59 -0
- package/dist/tools/shared/gitignore.js.map +1 -0
- package/dist/tools/shared/pdf-extractor.d.ts +96 -0
- package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
- package/dist/tools/shared/pdf-extractor.js +196 -0
- package/dist/tools/shared/pdf-extractor.js.map +1 -0
- package/dist/tools/shared/read-registry.d.ts +66 -0
- package/dist/tools/shared/read-registry.d.ts.map +1 -0
- package/dist/tools/shared/read-registry.js +65 -0
- package/dist/tools/shared/read-registry.js.map +1 -0
- package/dist/tools/shared/safe-env.d.ts +18 -0
- package/dist/tools/shared/safe-env.d.ts.map +1 -0
- package/dist/tools/shared/safe-env.js +70 -0
- package/dist/tools/shared/safe-env.js.map +1 -0
- package/dist/tools/sub-agent.d.ts +91 -0
- package/dist/tools/sub-agent.d.ts.map +1 -0
- package/dist/tools/sub-agent.js +89 -0
- package/dist/tools/sub-agent.js.map +1 -0
- package/dist/tools/task-output.d.ts +38 -0
- package/dist/tools/task-output.d.ts.map +1 -0
- package/dist/tools/task-output.js +186 -0
- package/dist/tools/task-output.js.map +1 -0
- package/dist/tools/tool-search/index.d.ts +40 -0
- package/dist/tools/tool-search/index.d.ts.map +1 -0
- package/dist/tools/tool-search/index.js +110 -0
- package/dist/tools/tool-search/index.js.map +1 -0
- package/dist/tools/tool-search/registry.d.ts +82 -0
- package/dist/tools/tool-search/registry.d.ts.map +1 -0
- package/dist/tools/tool-search/registry.js +238 -0
- package/dist/tools/tool-search/registry.js.map +1 -0
- package/dist/tools/undo-edit.d.ts +51 -0
- package/dist/tools/undo-edit.d.ts.map +1 -0
- package/dist/tools/undo-edit.js +231 -0
- package/dist/tools/undo-edit.js.map +1 -0
- package/dist/tools/web-fetch/cache.d.ts +49 -0
- package/dist/tools/web-fetch/cache.d.ts.map +1 -0
- package/dist/tools/web-fetch/cache.js +89 -0
- package/dist/tools/web-fetch/cache.js.map +1 -0
- package/dist/tools/web-fetch/index.d.ts +53 -0
- package/dist/tools/web-fetch/index.d.ts.map +1 -0
- package/dist/tools/web-fetch/index.js +513 -0
- package/dist/tools/web-fetch/index.js.map +1 -0
- package/dist/tools/write.d.ts +59 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +316 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +881 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/working-tags.d.ts +44 -0
- package/dist/working-tags.d.ts.map +1 -0
- package/dist/working-tags.js +103 -0
- package/dist/working-tags.js.map +1 -0
- package/package.json +87 -0
- package/src/budget-guard.ts +170 -0
- package/src/compaction/compaction.ts +386 -0
- package/src/compaction/failsafe.ts +185 -0
- package/src/compaction/index.ts +1199 -0
- package/src/compaction/microcompaction.ts +709 -0
- package/src/compaction/observational/buffering.ts +430 -0
- package/src/compaction/observational/constants.ts +532 -0
- package/src/compaction/observational/index.ts +837 -0
- package/src/compaction/observational/observer.ts +510 -0
- package/src/compaction/observational/recall-tool.ts +130 -0
- package/src/compaction/observational/reflector.ts +221 -0
- package/src/compaction/observational/types.ts +343 -0
- package/src/context-manager.ts +237 -0
- package/src/cortex-agent.ts +4297 -0
- package/src/error-classifier.ts +199 -0
- package/src/event-bridge.ts +508 -0
- package/src/index.ts +292 -0
- package/src/mcp-client.ts +582 -0
- package/src/model-wrapper.ts +128 -0
- package/src/noop-logger.ts +9 -0
- package/src/prompt-diagnostics.ts +296 -0
- package/src/provider-manager.ts +823 -0
- package/src/provider-registry.ts +386 -0
- package/src/schema-converter.ts +51 -0
- package/src/skill-preprocessor.ts +314 -0
- package/src/skill-registry.ts +378 -0
- package/src/skill-tool.ts +130 -0
- package/src/sub-agent-manager.ts +236 -0
- package/src/token-estimator.ts +26 -0
- package/src/tool-contract.ts +113 -0
- package/src/tool-result-persistence.ts +197 -0
- package/src/tools/bash/index.ts +633 -0
- package/src/tools/bash/interactive.ts +302 -0
- package/src/tools/bash/safety.ts +1297 -0
- package/src/tools/edit.ts +422 -0
- package/src/tools/glob.ts +330 -0
- package/src/tools/grep.ts +819 -0
- package/src/tools/index.ts +110 -0
- package/src/tools/read.ts +580 -0
- package/src/tools/runtime.ts +173 -0
- package/src/tools/shared/cwd-tracker.ts +50 -0
- package/src/tools/shared/edit-history.ts +96 -0
- package/src/tools/shared/edit-matcher.ts +457 -0
- package/src/tools/shared/file-mutation-lock.ts +40 -0
- package/src/tools/shared/gitignore.ts +61 -0
- package/src/tools/shared/pdf-extractor.ts +290 -0
- package/src/tools/shared/read-registry.ts +93 -0
- package/src/tools/shared/safe-env.ts +82 -0
- package/src/tools/sub-agent.ts +171 -0
- package/src/tools/task-output.ts +236 -0
- package/src/tools/tool-search/index.ts +167 -0
- package/src/tools/tool-search/registry.ts +278 -0
- package/src/tools/undo-edit.ts +314 -0
- package/src/tools/web-fetch/cache.ts +112 -0
- package/src/tools/web-fetch/index.ts +604 -0
- package/src/tools/write.ts +385 -0
- package/src/types.ts +1057 -0
- package/src/working-tags.ts +118 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubAgentManager: tracks active sub-agents, enforces concurrency limits,
|
|
3
|
+
* manages lifecycle, and delivers background completion notifications.
|
|
4
|
+
*
|
|
5
|
+
* Each sub-agent is an independent CortexAgent instance tracked by task ID.
|
|
6
|
+
* The manager does not own the CortexAgent; it tracks references and
|
|
7
|
+
* coordinates lifecycle events for the consumer.
|
|
8
|
+
*
|
|
9
|
+
* References:
|
|
10
|
+
* - docs/cortex/tools/sub-agent.md
|
|
11
|
+
* - docs/cortex/plans/phase-4-sub-agents-and-skills.md
|
|
12
|
+
*/
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// SubAgentManager
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export class SubAgentManager {
|
|
17
|
+
agents = new Map();
|
|
18
|
+
maxConcurrent;
|
|
19
|
+
hooks = {};
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.maxConcurrent = config?.maxConcurrent ?? 4;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Set lifecycle hooks. Called by CortexAgent to wire consumer event handlers.
|
|
25
|
+
*/
|
|
26
|
+
setHooks(hooks) {
|
|
27
|
+
this.hooks = hooks;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if another sub-agent can be spawned within the concurrency limit.
|
|
31
|
+
*/
|
|
32
|
+
canSpawn() {
|
|
33
|
+
return this.agents.size < this.maxConcurrent;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the number of currently active sub-agents.
|
|
37
|
+
*/
|
|
38
|
+
get activeCount() {
|
|
39
|
+
return this.agents.size;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the concurrency limit.
|
|
43
|
+
*/
|
|
44
|
+
get limit() {
|
|
45
|
+
return this.maxConcurrent;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Register a newly spawned sub-agent.
|
|
49
|
+
* Returns false if the concurrency limit would be exceeded.
|
|
50
|
+
*/
|
|
51
|
+
track(entry) {
|
|
52
|
+
if (this.agents.size >= this.maxConcurrent) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
this.agents.set(entry.taskId, entry);
|
|
56
|
+
// Fire lifecycle hook
|
|
57
|
+
try {
|
|
58
|
+
this.hooks.onSpawned?.(entry.taskId, entry.instructions, entry.background);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Swallow hook errors
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Mark a sub-agent as completed and remove it from tracking.
|
|
67
|
+
*/
|
|
68
|
+
complete(taskId, result) {
|
|
69
|
+
const entry = this.agents.get(taskId);
|
|
70
|
+
if (!entry)
|
|
71
|
+
return;
|
|
72
|
+
this.agents.delete(taskId);
|
|
73
|
+
// Resolve the completion promise
|
|
74
|
+
entry.resolve(result);
|
|
75
|
+
// Fire lifecycle hook (pass full result metadata including toolCalls)
|
|
76
|
+
try {
|
|
77
|
+
const usageWithToolCalls = { ...result.usage };
|
|
78
|
+
if (result.toolCalls) {
|
|
79
|
+
usageWithToolCalls['toolCalls'] = result.toolCalls;
|
|
80
|
+
}
|
|
81
|
+
this.hooks.onCompleted?.(taskId, result.output, result.status, usageWithToolCalls);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Swallow hook errors
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Mark a sub-agent as failed and remove it from tracking.
|
|
89
|
+
*/
|
|
90
|
+
fail(taskId, error) {
|
|
91
|
+
const entry = this.agents.get(taskId);
|
|
92
|
+
if (!entry)
|
|
93
|
+
return;
|
|
94
|
+
this.agents.delete(taskId);
|
|
95
|
+
// Resolve the completion promise with a failed result
|
|
96
|
+
entry.resolve({
|
|
97
|
+
output: '',
|
|
98
|
+
status: 'failed',
|
|
99
|
+
usage: { turns: 0, cost: 0, durationMs: Date.now() - entry.spawnedAt, contextTokens: 0 },
|
|
100
|
+
});
|
|
101
|
+
// Fire lifecycle hook
|
|
102
|
+
try {
|
|
103
|
+
this.hooks.onFailed?.(taskId, error);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Swallow hook errors
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get a tracked sub-agent by task ID.
|
|
111
|
+
*/
|
|
112
|
+
get(taskId) {
|
|
113
|
+
return this.agents.get(taskId);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Update tool activity for a running sub-agent.
|
|
117
|
+
* Called when child tool_call_start events are forwarded via EventBridge.
|
|
118
|
+
*/
|
|
119
|
+
updateToolActivity(taskId, toolName, summary) {
|
|
120
|
+
const entry = this.agents.get(taskId);
|
|
121
|
+
if (!entry)
|
|
122
|
+
return;
|
|
123
|
+
entry.toolCount++;
|
|
124
|
+
entry.lastToolName = toolName;
|
|
125
|
+
entry.lastToolSummary = summary;
|
|
126
|
+
entry.lastToolStartedAt = Date.now();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get all active sub-agent task IDs.
|
|
130
|
+
*/
|
|
131
|
+
getActiveTaskIds() {
|
|
132
|
+
return [...this.agents.keys()];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get completion promises for all background sub-agents.
|
|
136
|
+
* Used to build follow-up messages when background agents complete.
|
|
137
|
+
*/
|
|
138
|
+
getBackgroundCompletions() {
|
|
139
|
+
const results = [];
|
|
140
|
+
for (const [taskId, entry] of this.agents) {
|
|
141
|
+
if (entry.background) {
|
|
142
|
+
results.push({ taskId, completion: entry.completion });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return results;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Cancel all active sub-agents. Called during parent destroy().
|
|
149
|
+
* Aborts each sub-agent and removes it from tracking.
|
|
150
|
+
*
|
|
151
|
+
* @param abortFn - Function to abort a CortexAgent (passed to avoid circular dep)
|
|
152
|
+
*/
|
|
153
|
+
async cancelAll(abortFn) {
|
|
154
|
+
const entries = [...this.agents.values()];
|
|
155
|
+
this.agents.clear();
|
|
156
|
+
const settled = await Promise.allSettled(entries.map(async (entry) => {
|
|
157
|
+
try {
|
|
158
|
+
await abortFn(entry.agent);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Best-effort abort
|
|
162
|
+
}
|
|
163
|
+
// Resolve the completion promise as cancelled
|
|
164
|
+
entry.resolve({
|
|
165
|
+
output: '',
|
|
166
|
+
status: 'cancelled',
|
|
167
|
+
usage: { turns: 0, cost: 0, durationMs: Date.now() - entry.spawnedAt, contextTokens: 0 },
|
|
168
|
+
});
|
|
169
|
+
// Fire failure hook
|
|
170
|
+
try {
|
|
171
|
+
this.hooks.onFailed?.(entry.taskId, 'Parent agent destroyed');
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Swallow hook errors
|
|
175
|
+
}
|
|
176
|
+
}));
|
|
177
|
+
// Log any unexpected errors (consumer should provide logging)
|
|
178
|
+
for (const result of settled) {
|
|
179
|
+
if (result.status === 'rejected') {
|
|
180
|
+
// Swallowed: best-effort cleanup
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Clean up all state. Called during parent destroy().
|
|
186
|
+
*/
|
|
187
|
+
destroy() {
|
|
188
|
+
this.agents.clear();
|
|
189
|
+
this.hooks = {};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=sub-agent-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sub-agent-manager.js","sourceRoot":"","sources":["../src/sub-agent-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic token estimation.
|
|
3
|
+
*
|
|
4
|
+
* Uses character-based heuristic (chars / 4), the community standard and
|
|
5
|
+
* closest to Anthropic's official recommendation (chars / 3.5).
|
|
6
|
+
* Character-based is more stable than word-based across content types
|
|
7
|
+
* (prose, code, JSON, markdown).
|
|
8
|
+
*
|
|
9
|
+
* This is a duplicate of the same utility in @animus-labs/shared,
|
|
10
|
+
* kept inline to avoid a dependency from cortex to shared.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Estimate the number of tokens in a text string.
|
|
14
|
+
*
|
|
15
|
+
* Uses chars / 4 heuristic (community standard, ~15% underestimate for Claude).
|
|
16
|
+
* Not a tokenizer; a fast estimation for budget decisions and compaction triggers.
|
|
17
|
+
* For exact counts, use the Anthropic count_tokens API.
|
|
18
|
+
*
|
|
19
|
+
* @param text - The text to estimate tokens for
|
|
20
|
+
* @returns Estimated token count (always at least 0, rounded up)
|
|
21
|
+
*/
|
|
22
|
+
export declare function estimateTokens(text: string): number;
|
|
23
|
+
//# sourceMappingURL=token-estimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../src/token-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic token estimation.
|
|
3
|
+
*
|
|
4
|
+
* Uses character-based heuristic (chars / 4), the community standard and
|
|
5
|
+
* closest to Anthropic's official recommendation (chars / 3.5).
|
|
6
|
+
* Character-based is more stable than word-based across content types
|
|
7
|
+
* (prose, code, JSON, markdown).
|
|
8
|
+
*
|
|
9
|
+
* This is a duplicate of the same utility in @animus-labs/shared,
|
|
10
|
+
* kept inline to avoid a dependency from cortex to shared.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Estimate the number of tokens in a text string.
|
|
14
|
+
*
|
|
15
|
+
* Uses chars / 4 heuristic (community standard, ~15% underestimate for Claude).
|
|
16
|
+
* Not a tokenizer; a fast estimation for budget decisions and compaction triggers.
|
|
17
|
+
* For exact counts, use the Anthropic count_tokens API.
|
|
18
|
+
*
|
|
19
|
+
* @param text - The text to estimate tokens for
|
|
20
|
+
* @returns Estimated token count (always at least 0, rounded up)
|
|
21
|
+
*/
|
|
22
|
+
export function estimateTokens(text) {
|
|
23
|
+
if (!text)
|
|
24
|
+
return 0;
|
|
25
|
+
return Math.ceil(text.length / 4);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=token-estimator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../src/token-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ToolExecuteContext } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cortex's canonical in-process tool contract.
|
|
4
|
+
*
|
|
5
|
+
* All tools registered with CortexAgent are normalized to this signature.
|
|
6
|
+
* Cortex adapts this shape to pi-agent-core's execute signature at the
|
|
7
|
+
* registration boundary.
|
|
8
|
+
*/
|
|
9
|
+
export interface CortexTool<TParams = unknown, TResult = unknown> {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
parameters: unknown;
|
|
13
|
+
execute: (params: TParams, context?: ToolExecuteContext) => Promise<TResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Marks this tool as eligible for deferred loading. When the agent has
|
|
16
|
+
* `deferredTools.enabled = true`, deferred tools are NOT included in the
|
|
17
|
+
* `tools` array sent to the model on every turn. Instead, only their names
|
|
18
|
+
* appear in the `_available_tools` slot, and the model uses ToolSearch to
|
|
19
|
+
* load full schemas on demand.
|
|
20
|
+
*
|
|
21
|
+
* MCP tools get `isMcp: true` set automatically by the MCP client and are
|
|
22
|
+
* deferred when `deferredTools.deferMcp` is true (default). Built-in or
|
|
23
|
+
* consumer-supplied tools can opt in via `shouldDefer: true`.
|
|
24
|
+
*/
|
|
25
|
+
shouldDefer?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Forces this tool to always be sent in the `tools` array, even if it
|
|
28
|
+
* matches deferral criteria (e.g., an MCP tool the consumer wants always
|
|
29
|
+
* available). Overrides `shouldDefer` and the `deferMcp` config.
|
|
30
|
+
*/
|
|
31
|
+
alwaysLoad?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Marker indicating this tool was wrapped from an MCP server. Set
|
|
34
|
+
* automatically by the MCP client. Consumers should not set this manually.
|
|
35
|
+
*/
|
|
36
|
+
isMcp?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Optional pi-agent-core execution hint. Use "sequential" for tools that
|
|
39
|
+
* must update shared agent state before later tool calls in the same batch.
|
|
40
|
+
*/
|
|
41
|
+
executionMode?: 'sequential' | 'parallel';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Raw pi-agent-core tool contract.
|
|
45
|
+
*
|
|
46
|
+
* Use fromPiAgentTool() to explicitly adapt a tool with this signature into
|
|
47
|
+
* Cortex's canonical CortexTool shape.
|
|
48
|
+
*/
|
|
49
|
+
export interface PiAgentTool<TParams = unknown, TResult = unknown> {
|
|
50
|
+
name: string;
|
|
51
|
+
description: string;
|
|
52
|
+
parameters: unknown;
|
|
53
|
+
executionMode?: 'sequential' | 'parallel';
|
|
54
|
+
execute: (toolCallId: string, params: TParams, signal?: AbortSignal, onUpdate?: (partialResult: unknown) => void) => Promise<TResult>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Explicitly adapt a pi-agent-core-style tool into Cortex's canonical tool contract.
|
|
58
|
+
*/
|
|
59
|
+
export declare function fromPiAgentTool<TParams = unknown, TResult = unknown>(tool: PiAgentTool<TParams, TResult>): CortexTool<TParams, TResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Validate that a tool matches Cortex's canonical execute signature.
|
|
62
|
+
*
|
|
63
|
+
* Cortex does not infer tool execution contracts from function arity. Tools
|
|
64
|
+
* that already use pi-agent-core's raw execute signature must be adapted
|
|
65
|
+
* explicitly with fromPiAgentTool().
|
|
66
|
+
*/
|
|
67
|
+
export declare function assertValidCortexTool(tool: CortexTool): CortexTool;
|
|
68
|
+
//# sourceMappingURL=tool-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-contract.d.ts","sourceRoot":"","sources":["../src/tool-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,WAAW,UAAU,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7E;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,aAAa,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IAC1C,OAAO,EAAE,CACP,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,KACxC,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAClE,IAAI,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GAClC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAkB9B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAalE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explicitly adapt a pi-agent-core-style tool into Cortex's canonical tool contract.
|
|
3
|
+
*/
|
|
4
|
+
export function fromPiAgentTool(tool) {
|
|
5
|
+
const cortexTool = {
|
|
6
|
+
name: tool.name,
|
|
7
|
+
description: tool.description,
|
|
8
|
+
parameters: tool.parameters,
|
|
9
|
+
execute: (params, context) => {
|
|
10
|
+
return tool.execute(context?.toolCallId ?? `${tool.name}-direct`, params, context?.signal, context?.onUpdate);
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
if (tool.executionMode) {
|
|
14
|
+
cortexTool.executionMode = tool.executionMode;
|
|
15
|
+
}
|
|
16
|
+
return cortexTool;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validate that a tool matches Cortex's canonical execute signature.
|
|
20
|
+
*
|
|
21
|
+
* Cortex does not infer tool execution contracts from function arity. Tools
|
|
22
|
+
* that already use pi-agent-core's raw execute signature must be adapted
|
|
23
|
+
* explicitly with fromPiAgentTool().
|
|
24
|
+
*/
|
|
25
|
+
export function assertValidCortexTool(tool) {
|
|
26
|
+
if (typeof tool.execute !== 'function') {
|
|
27
|
+
throw new Error(`Tool "${tool.name}" is missing an execute() function.`);
|
|
28
|
+
}
|
|
29
|
+
if (tool.execute.length > 2) {
|
|
30
|
+
throw new Error(`Tool "${tool.name}" does not use Cortex's execute(params, context?) contract. ` +
|
|
31
|
+
'Wrap raw pi-agent-core tools with fromPiAgentTool() before passing them to CortexAgent.create().');
|
|
32
|
+
}
|
|
33
|
+
return tool;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=tool-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-contract.js","sourceRoot":"","sources":["../src/tool-contract.ts"],"names":[],"mappings":"AAmEA;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAmC;IAEnC,MAAM,UAAU,GAAiC;QAC/C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,OAAO,EAAE,CAAC,MAAe,EAAE,OAA4B,EAAE,EAAE;YACzD,OAAO,IAAI,CAAC,OAAO,CACjB,OAAO,EAAE,UAAU,IAAI,GAAG,IAAI,CAAC,IAAI,SAAS,EAC5C,MAAM,EACN,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,QAA0D,CACpE,CAAC;QACJ,CAAC;KACF,CAAC;IACF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,UAAU,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IAChD,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAgB;IACpD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,qCAAqC,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,SAAS,IAAI,CAAC,IAAI,8DAA8D;YAChF,kGAAkG,CACnG,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool result persistence: bookend-and-persist for oversized tool results.
|
|
3
|
+
*
|
|
4
|
+
* Sits at the tool execution boundary (refreshTools wrapper). After a tool
|
|
5
|
+
* returns its result, this module checks whether the text content exceeds
|
|
6
|
+
* the per-result threshold and either:
|
|
7
|
+
* - passes through unchanged (under threshold or skipped tool)
|
|
8
|
+
* - persists to disk (when `persistResult` is configured) and returns
|
|
9
|
+
* a bookend preview (head + tail) plus a file reference
|
|
10
|
+
* - returns a bookend preview only (when no `persistResult` is configured)
|
|
11
|
+
*
|
|
12
|
+
* This replaces ad-hoc per-tool truncation (Grep, Bash, WebFetch) with a
|
|
13
|
+
* single, uniform mechanism. Reuses `applyBookend` and `getToolCategory`
|
|
14
|
+
* from the existing compaction infrastructure.
|
|
15
|
+
*
|
|
16
|
+
* Reference: docs/cortex/tool-result-persistence.md
|
|
17
|
+
*/
|
|
18
|
+
import type { PersistResultFn, ToolCategory } from './types.js';
|
|
19
|
+
/** Default per-tool token threshold. Results larger than this trigger persistence/bookend. */
|
|
20
|
+
export declare const MAX_RESULT_TOKENS = 25000;
|
|
21
|
+
/** Bookend size for the preview (head and tail each). 1,500 chars ≈ 375 tokens. */
|
|
22
|
+
export declare const BOOKEND_CHARS = 1500;
|
|
23
|
+
/**
|
|
24
|
+
* Tools whose results bypass the interceptor entirely.
|
|
25
|
+
*
|
|
26
|
+
* Either inherently bounded (Edit, Write, Glob) or content already on disk
|
|
27
|
+
* where the model can use offset/limit on the original file (Read).
|
|
28
|
+
*/
|
|
29
|
+
export declare const SKIP_RESULT_PERSISTENCE: Set<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Built-in per-tool threshold overrides. Tools listed here use a different
|
|
32
|
+
* token limit than `MAX_RESULT_TOKENS` (25K).
|
|
33
|
+
*
|
|
34
|
+
* Rationale per tool:
|
|
35
|
+
* - Bash: command output is verbose with low signal density (logs, stack
|
|
36
|
+
* traces, build spam). A tighter cap reduces noise in context while still
|
|
37
|
+
* preserving full output via persistence.
|
|
38
|
+
*
|
|
39
|
+
* Consumers can extend or override this map via `CortexAgentConfig.toolResultThresholds`.
|
|
40
|
+
*/
|
|
41
|
+
export declare const DEFAULT_TOOL_THRESHOLDS: Record<string, number>;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the effective threshold for a tool.
|
|
44
|
+
* Order of precedence: consumer overrides > built-in defaults > MAX_RESULT_TOKENS.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveThreshold(toolName: string, consumerOverrides?: Record<string, number>): number;
|
|
47
|
+
export interface ApplyPersistenceOptions {
|
|
48
|
+
toolName: string;
|
|
49
|
+
toolCallId: string;
|
|
50
|
+
persistResult?: PersistResultFn | undefined;
|
|
51
|
+
toolCategories?: Record<string, ToolCategory> | undefined;
|
|
52
|
+
/** Consumer-provided per-tool threshold overrides (in tokens). */
|
|
53
|
+
thresholds?: Record<string, number> | undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Options for processing a full tool result (with potentially multiple parts).
|
|
57
|
+
* Same shape as ApplyPersistenceOptions minus the per-call identifiers.
|
|
58
|
+
*/
|
|
59
|
+
export interface ProcessResultOptions {
|
|
60
|
+
toolName: string;
|
|
61
|
+
toolCallId: string;
|
|
62
|
+
persistResult?: PersistResultFn | undefined;
|
|
63
|
+
toolCategories?: Record<string, ToolCategory> | undefined;
|
|
64
|
+
thresholds?: Record<string, number> | undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Process a tool result text part for size limiting.
|
|
68
|
+
*
|
|
69
|
+
* - Under threshold or skipped tool: returns content unchanged
|
|
70
|
+
* - Over threshold + `persistResult` configured: persists, returns bookend + file ref
|
|
71
|
+
* - Over threshold + no `persistResult`: returns bookend only (lossy, but bounded)
|
|
72
|
+
*
|
|
73
|
+
* Pure async helper; never throws. Persist failures fall back to bookend-only.
|
|
74
|
+
*/
|
|
75
|
+
export declare function applyResultPersistence(content: string, options: ApplyPersistenceOptions): Promise<string>;
|
|
76
|
+
/**
|
|
77
|
+
* Process a full tool result (potentially multi-part) through the
|
|
78
|
+
* persistence interceptor.
|
|
79
|
+
*
|
|
80
|
+
* - Iterates the `content` array
|
|
81
|
+
* - For each `text` part, runs `applyResultPersistence`
|
|
82
|
+
* - Other part types (e.g., `image`) pass through unchanged
|
|
83
|
+
* - Returns the same object reference if nothing changed (no allocation)
|
|
84
|
+
*
|
|
85
|
+
* Used by `CortexAgent.refreshTools()` at the tool execution boundary.
|
|
86
|
+
* Exported so the wrapper logic is unit-testable.
|
|
87
|
+
*/
|
|
88
|
+
export declare function processToolResult(result: unknown, options: ProcessResultOptions): Promise<unknown>;
|
|
89
|
+
//# sourceMappingURL=tool-result-persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-persistence.d.ts","sourceRoot":"","sources":["../src/tool-result-persistence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQhE,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,mFAAmF;AACnF,eAAO,MAAM,aAAa,OAAQ,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,aAMlC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAE1D,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,MAAM,CAIR;AAMD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,CAAC;IAC1D,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAkCjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAkClB"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool result persistence: bookend-and-persist for oversized tool results.
|
|
3
|
+
*
|
|
4
|
+
* Sits at the tool execution boundary (refreshTools wrapper). After a tool
|
|
5
|
+
* returns its result, this module checks whether the text content exceeds
|
|
6
|
+
* the per-result threshold and either:
|
|
7
|
+
* - passes through unchanged (under threshold or skipped tool)
|
|
8
|
+
* - persists to disk (when `persistResult` is configured) and returns
|
|
9
|
+
* a bookend preview (head + tail) plus a file reference
|
|
10
|
+
* - returns a bookend preview only (when no `persistResult` is configured)
|
|
11
|
+
*
|
|
12
|
+
* This replaces ad-hoc per-tool truncation (Grep, Bash, WebFetch) with a
|
|
13
|
+
* single, uniform mechanism. Reuses `applyBookend` and `getToolCategory`
|
|
14
|
+
* from the existing compaction infrastructure.
|
|
15
|
+
*
|
|
16
|
+
* Reference: docs/cortex/tool-result-persistence.md
|
|
17
|
+
*/
|
|
18
|
+
import { applyBookend, getToolCategory } from './compaction/microcompaction.js';
|
|
19
|
+
import { estimateTokens } from './token-estimator.js';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Constants
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/** Default per-tool token threshold. Results larger than this trigger persistence/bookend. */
|
|
24
|
+
export const MAX_RESULT_TOKENS = 25_000;
|
|
25
|
+
/** Bookend size for the preview (head and tail each). 1,500 chars ≈ 375 tokens. */
|
|
26
|
+
export const BOOKEND_CHARS = 1_500;
|
|
27
|
+
/**
|
|
28
|
+
* Tools whose results bypass the interceptor entirely.
|
|
29
|
+
*
|
|
30
|
+
* Either inherently bounded (Edit, Write, Glob) or content already on disk
|
|
31
|
+
* where the model can use offset/limit on the original file (Read).
|
|
32
|
+
*/
|
|
33
|
+
export const SKIP_RESULT_PERSISTENCE = new Set([
|
|
34
|
+
'Read',
|
|
35
|
+
'Edit',
|
|
36
|
+
'UndoEdit',
|
|
37
|
+
'Write',
|
|
38
|
+
'Glob',
|
|
39
|
+
]);
|
|
40
|
+
/**
|
|
41
|
+
* Built-in per-tool threshold overrides. Tools listed here use a different
|
|
42
|
+
* token limit than `MAX_RESULT_TOKENS` (25K).
|
|
43
|
+
*
|
|
44
|
+
* Rationale per tool:
|
|
45
|
+
* - Bash: command output is verbose with low signal density (logs, stack
|
|
46
|
+
* traces, build spam). A tighter cap reduces noise in context while still
|
|
47
|
+
* preserving full output via persistence.
|
|
48
|
+
*
|
|
49
|
+
* Consumers can extend or override this map via `CortexAgentConfig.toolResultThresholds`.
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_TOOL_THRESHOLDS = {
|
|
52
|
+
Bash: 7_500,
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the effective threshold for a tool.
|
|
56
|
+
* Order of precedence: consumer overrides > built-in defaults > MAX_RESULT_TOKENS.
|
|
57
|
+
*/
|
|
58
|
+
export function resolveThreshold(toolName, consumerOverrides) {
|
|
59
|
+
if (consumerOverrides && toolName in consumerOverrides)
|
|
60
|
+
return consumerOverrides[toolName];
|
|
61
|
+
if (toolName in DEFAULT_TOOL_THRESHOLDS)
|
|
62
|
+
return DEFAULT_TOOL_THRESHOLDS[toolName];
|
|
63
|
+
return MAX_RESULT_TOKENS;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Process a tool result text part for size limiting.
|
|
67
|
+
*
|
|
68
|
+
* - Under threshold or skipped tool: returns content unchanged
|
|
69
|
+
* - Over threshold + `persistResult` configured: persists, returns bookend + file ref
|
|
70
|
+
* - Over threshold + no `persistResult`: returns bookend only (lossy, but bounded)
|
|
71
|
+
*
|
|
72
|
+
* Pure async helper; never throws. Persist failures fall back to bookend-only.
|
|
73
|
+
*/
|
|
74
|
+
export async function applyResultPersistence(content, options) {
|
|
75
|
+
if (SKIP_RESULT_PERSISTENCE.has(options.toolName))
|
|
76
|
+
return content;
|
|
77
|
+
const threshold = resolveThreshold(options.toolName, options.thresholds);
|
|
78
|
+
const tokens = estimateTokens(content);
|
|
79
|
+
if (tokens <= threshold)
|
|
80
|
+
return content;
|
|
81
|
+
const bookended = applyBookend(content, BOOKEND_CHARS, BOOKEND_CHARS, tokens);
|
|
82
|
+
if (options.persistResult) {
|
|
83
|
+
const category = getToolCategory(options.toolName, options.toolCategories) ?? 'ephemeral';
|
|
84
|
+
try {
|
|
85
|
+
const path = await options.persistResult(content, {
|
|
86
|
+
toolName: options.toolName,
|
|
87
|
+
toolCallId: options.toolCallId,
|
|
88
|
+
category,
|
|
89
|
+
});
|
|
90
|
+
return [
|
|
91
|
+
`[Result persisted: ${path} (${content.length.toLocaleString()} chars, ~${tokens.toLocaleString()} tokens)]`,
|
|
92
|
+
'',
|
|
93
|
+
bookended,
|
|
94
|
+
'',
|
|
95
|
+
'Use the Read tool with offset/limit to examine specific sections.',
|
|
96
|
+
].join('\n');
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Persist failed; fall through to bookend-only path below.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return [
|
|
103
|
+
`[Result truncated: ~${tokens.toLocaleString()} tokens exceeded ${threshold.toLocaleString()} token limit]`,
|
|
104
|
+
'',
|
|
105
|
+
bookended,
|
|
106
|
+
].join('\n');
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Process a full tool result (potentially multi-part) through the
|
|
110
|
+
* persistence interceptor.
|
|
111
|
+
*
|
|
112
|
+
* - Iterates the `content` array
|
|
113
|
+
* - For each `text` part, runs `applyResultPersistence`
|
|
114
|
+
* - Other part types (e.g., `image`) pass through unchanged
|
|
115
|
+
* - Returns the same object reference if nothing changed (no allocation)
|
|
116
|
+
*
|
|
117
|
+
* Used by `CortexAgent.refreshTools()` at the tool execution boundary.
|
|
118
|
+
* Exported so the wrapper logic is unit-testable.
|
|
119
|
+
*/
|
|
120
|
+
export async function processToolResult(result, options) {
|
|
121
|
+
if (!result || typeof result !== 'object')
|
|
122
|
+
return result;
|
|
123
|
+
const asObj = result;
|
|
124
|
+
const content = asObj['content'];
|
|
125
|
+
if (!Array.isArray(content) || content.length === 0)
|
|
126
|
+
return result;
|
|
127
|
+
let modified = false;
|
|
128
|
+
const newContent = await Promise.all(content.map(async (part) => {
|
|
129
|
+
if (part &&
|
|
130
|
+
typeof part === 'object' &&
|
|
131
|
+
part['type'] === 'text' &&
|
|
132
|
+
typeof part['text'] === 'string') {
|
|
133
|
+
const text = part.text;
|
|
134
|
+
const processed = await applyResultPersistence(text, {
|
|
135
|
+
toolName: options.toolName,
|
|
136
|
+
toolCallId: options.toolCallId,
|
|
137
|
+
persistResult: options.persistResult,
|
|
138
|
+
toolCategories: options.toolCategories,
|
|
139
|
+
thresholds: options.thresholds,
|
|
140
|
+
});
|
|
141
|
+
if (processed !== text) {
|
|
142
|
+
modified = true;
|
|
143
|
+
return { ...part, text: processed };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return part;
|
|
147
|
+
}));
|
|
148
|
+
if (!modified)
|
|
149
|
+
return result;
|
|
150
|
+
return { ...asObj, content: newContent };
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=tool-result-persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-persistence.js","sourceRoot":"","sources":["../src/tool-result-persistence.ts"],"names":[],"mappings":"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"}
|