@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.
Files changed (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/budget-guard.d.ts +75 -0
  4. package/dist/budget-guard.d.ts.map +1 -0
  5. package/dist/budget-guard.js +142 -0
  6. package/dist/budget-guard.js.map +1 -0
  7. package/dist/compaction/compaction.d.ts +99 -0
  8. package/dist/compaction/compaction.d.ts.map +1 -0
  9. package/dist/compaction/compaction.js +302 -0
  10. package/dist/compaction/compaction.js.map +1 -0
  11. package/dist/compaction/failsafe.d.ts +57 -0
  12. package/dist/compaction/failsafe.d.ts.map +1 -0
  13. package/dist/compaction/failsafe.js +135 -0
  14. package/dist/compaction/failsafe.js.map +1 -0
  15. package/dist/compaction/index.d.ts +381 -0
  16. package/dist/compaction/index.d.ts.map +1 -0
  17. package/dist/compaction/index.js +979 -0
  18. package/dist/compaction/index.js.map +1 -0
  19. package/dist/compaction/microcompaction.d.ts +219 -0
  20. package/dist/compaction/microcompaction.d.ts.map +1 -0
  21. package/dist/compaction/microcompaction.js +536 -0
  22. package/dist/compaction/microcompaction.js.map +1 -0
  23. package/dist/compaction/observational/buffering.d.ts +225 -0
  24. package/dist/compaction/observational/buffering.d.ts.map +1 -0
  25. package/dist/compaction/observational/buffering.js +354 -0
  26. package/dist/compaction/observational/buffering.js.map +1 -0
  27. package/dist/compaction/observational/constants.d.ts +70 -0
  28. package/dist/compaction/observational/constants.d.ts.map +1 -0
  29. package/dist/compaction/observational/constants.js +507 -0
  30. package/dist/compaction/observational/constants.js.map +1 -0
  31. package/dist/compaction/observational/index.d.ts +219 -0
  32. package/dist/compaction/observational/index.d.ts.map +1 -0
  33. package/dist/compaction/observational/index.js +641 -0
  34. package/dist/compaction/observational/index.js.map +1 -0
  35. package/dist/compaction/observational/observer.d.ts +97 -0
  36. package/dist/compaction/observational/observer.d.ts.map +1 -0
  37. package/dist/compaction/observational/observer.js +424 -0
  38. package/dist/compaction/observational/observer.js.map +1 -0
  39. package/dist/compaction/observational/recall-tool.d.ts +27 -0
  40. package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
  41. package/dist/compaction/observational/recall-tool.js +93 -0
  42. package/dist/compaction/observational/recall-tool.js.map +1 -0
  43. package/dist/compaction/observational/reflector.d.ts +94 -0
  44. package/dist/compaction/observational/reflector.d.ts.map +1 -0
  45. package/dist/compaction/observational/reflector.js +167 -0
  46. package/dist/compaction/observational/reflector.js.map +1 -0
  47. package/dist/compaction/observational/types.d.ts +271 -0
  48. package/dist/compaction/observational/types.d.ts.map +1 -0
  49. package/dist/compaction/observational/types.js +15 -0
  50. package/dist/compaction/observational/types.js.map +1 -0
  51. package/dist/context-manager.d.ts +134 -0
  52. package/dist/context-manager.d.ts.map +1 -0
  53. package/dist/context-manager.js +170 -0
  54. package/dist/context-manager.js.map +1 -0
  55. package/dist/cortex-agent.d.ts +1020 -0
  56. package/dist/cortex-agent.d.ts.map +1 -0
  57. package/dist/cortex-agent.js +3589 -0
  58. package/dist/cortex-agent.js.map +1 -0
  59. package/dist/error-classifier.d.ts +48 -0
  60. package/dist/error-classifier.d.ts.map +1 -0
  61. package/dist/error-classifier.js +152 -0
  62. package/dist/error-classifier.js.map +1 -0
  63. package/dist/event-bridge.d.ts +166 -0
  64. package/dist/event-bridge.d.ts.map +1 -0
  65. package/dist/event-bridge.js +381 -0
  66. package/dist/event-bridge.js.map +1 -0
  67. package/dist/index.d.ts +55 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +57 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/mcp-client.d.ts +119 -0
  72. package/dist/mcp-client.d.ts.map +1 -0
  73. package/dist/mcp-client.js +474 -0
  74. package/dist/mcp-client.js.map +1 -0
  75. package/dist/model-wrapper.d.ts +58 -0
  76. package/dist/model-wrapper.d.ts.map +1 -0
  77. package/dist/model-wrapper.js +86 -0
  78. package/dist/model-wrapper.js.map +1 -0
  79. package/dist/noop-logger.d.ts +4 -0
  80. package/dist/noop-logger.d.ts.map +1 -0
  81. package/dist/noop-logger.js +8 -0
  82. package/dist/noop-logger.js.map +1 -0
  83. package/dist/prompt-diagnostics.d.ts +47 -0
  84. package/dist/prompt-diagnostics.d.ts.map +1 -0
  85. package/dist/prompt-diagnostics.js +230 -0
  86. package/dist/prompt-diagnostics.js.map +1 -0
  87. package/dist/provider-manager.d.ts +224 -0
  88. package/dist/provider-manager.d.ts.map +1 -0
  89. package/dist/provider-manager.js +563 -0
  90. package/dist/provider-manager.js.map +1 -0
  91. package/dist/provider-registry.d.ts +115 -0
  92. package/dist/provider-registry.d.ts.map +1 -0
  93. package/dist/provider-registry.js +305 -0
  94. package/dist/provider-registry.js.map +1 -0
  95. package/dist/schema-converter.d.ts +20 -0
  96. package/dist/schema-converter.d.ts.map +1 -0
  97. package/dist/schema-converter.js +48 -0
  98. package/dist/schema-converter.js.map +1 -0
  99. package/dist/skill-preprocessor.d.ts +46 -0
  100. package/dist/skill-preprocessor.d.ts.map +1 -0
  101. package/dist/skill-preprocessor.js +237 -0
  102. package/dist/skill-preprocessor.js.map +1 -0
  103. package/dist/skill-registry.d.ts +107 -0
  104. package/dist/skill-registry.d.ts.map +1 -0
  105. package/dist/skill-registry.js +330 -0
  106. package/dist/skill-registry.js.map +1 -0
  107. package/dist/skill-tool.d.ts +54 -0
  108. package/dist/skill-tool.d.ts.map +1 -0
  109. package/dist/skill-tool.js +88 -0
  110. package/dist/skill-tool.js.map +1 -0
  111. package/dist/sub-agent-manager.d.ts +90 -0
  112. package/dist/sub-agent-manager.d.ts.map +1 -0
  113. package/dist/sub-agent-manager.js +192 -0
  114. package/dist/sub-agent-manager.js.map +1 -0
  115. package/dist/token-estimator.d.ts +23 -0
  116. package/dist/token-estimator.d.ts.map +1 -0
  117. package/dist/token-estimator.js +27 -0
  118. package/dist/token-estimator.js.map +1 -0
  119. package/dist/tool-contract.d.ts +68 -0
  120. package/dist/tool-contract.d.ts.map +1 -0
  121. package/dist/tool-contract.js +35 -0
  122. package/dist/tool-contract.js.map +1 -0
  123. package/dist/tool-result-persistence.d.ts +89 -0
  124. package/dist/tool-result-persistence.d.ts.map +1 -0
  125. package/dist/tool-result-persistence.js +152 -0
  126. package/dist/tool-result-persistence.js.map +1 -0
  127. package/dist/tools/bash/index.d.ts +71 -0
  128. package/dist/tools/bash/index.d.ts.map +1 -0
  129. package/dist/tools/bash/index.js +485 -0
  130. package/dist/tools/bash/index.js.map +1 -0
  131. package/dist/tools/bash/interactive.d.ts +47 -0
  132. package/dist/tools/bash/interactive.d.ts.map +1 -0
  133. package/dist/tools/bash/interactive.js +262 -0
  134. package/dist/tools/bash/interactive.js.map +1 -0
  135. package/dist/tools/bash/safety.d.ts +149 -0
  136. package/dist/tools/bash/safety.d.ts.map +1 -0
  137. package/dist/tools/bash/safety.js +1116 -0
  138. package/dist/tools/bash/safety.js.map +1 -0
  139. package/dist/tools/edit.d.ts +57 -0
  140. package/dist/tools/edit.d.ts.map +1 -0
  141. package/dist/tools/edit.js +310 -0
  142. package/dist/tools/edit.js.map +1 -0
  143. package/dist/tools/glob.d.ts +34 -0
  144. package/dist/tools/glob.d.ts.map +1 -0
  145. package/dist/tools/glob.js +268 -0
  146. package/dist/tools/glob.js.map +1 -0
  147. package/dist/tools/grep.d.ts +53 -0
  148. package/dist/tools/grep.d.ts.map +1 -0
  149. package/dist/tools/grep.js +673 -0
  150. package/dist/tools/grep.js.map +1 -0
  151. package/dist/tools/index.d.ts +62 -0
  152. package/dist/tools/index.d.ts.map +1 -0
  153. package/dist/tools/index.js +52 -0
  154. package/dist/tools/index.js.map +1 -0
  155. package/dist/tools/read.d.ts +43 -0
  156. package/dist/tools/read.d.ts.map +1 -0
  157. package/dist/tools/read.js +459 -0
  158. package/dist/tools/read.js.map +1 -0
  159. package/dist/tools/runtime.d.ts +62 -0
  160. package/dist/tools/runtime.d.ts.map +1 -0
  161. package/dist/tools/runtime.js +116 -0
  162. package/dist/tools/runtime.js.map +1 -0
  163. package/dist/tools/shared/cwd-tracker.d.ts +32 -0
  164. package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
  165. package/dist/tools/shared/cwd-tracker.js +44 -0
  166. package/dist/tools/shared/cwd-tracker.js.map +1 -0
  167. package/dist/tools/shared/edit-history.d.ts +55 -0
  168. package/dist/tools/shared/edit-history.d.ts.map +1 -0
  169. package/dist/tools/shared/edit-history.js +72 -0
  170. package/dist/tools/shared/edit-history.js.map +1 -0
  171. package/dist/tools/shared/edit-matcher.d.ts +83 -0
  172. package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
  173. package/dist/tools/shared/edit-matcher.js +359 -0
  174. package/dist/tools/shared/edit-matcher.js.map +1 -0
  175. package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
  176. package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
  177. package/dist/tools/shared/file-mutation-lock.js +35 -0
  178. package/dist/tools/shared/file-mutation-lock.js.map +1 -0
  179. package/dist/tools/shared/gitignore.d.ts +17 -0
  180. package/dist/tools/shared/gitignore.d.ts.map +1 -0
  181. package/dist/tools/shared/gitignore.js +59 -0
  182. package/dist/tools/shared/gitignore.js.map +1 -0
  183. package/dist/tools/shared/pdf-extractor.d.ts +96 -0
  184. package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
  185. package/dist/tools/shared/pdf-extractor.js +196 -0
  186. package/dist/tools/shared/pdf-extractor.js.map +1 -0
  187. package/dist/tools/shared/read-registry.d.ts +66 -0
  188. package/dist/tools/shared/read-registry.d.ts.map +1 -0
  189. package/dist/tools/shared/read-registry.js +65 -0
  190. package/dist/tools/shared/read-registry.js.map +1 -0
  191. package/dist/tools/shared/safe-env.d.ts +18 -0
  192. package/dist/tools/shared/safe-env.d.ts.map +1 -0
  193. package/dist/tools/shared/safe-env.js +70 -0
  194. package/dist/tools/shared/safe-env.js.map +1 -0
  195. package/dist/tools/sub-agent.d.ts +91 -0
  196. package/dist/tools/sub-agent.d.ts.map +1 -0
  197. package/dist/tools/sub-agent.js +89 -0
  198. package/dist/tools/sub-agent.js.map +1 -0
  199. package/dist/tools/task-output.d.ts +38 -0
  200. package/dist/tools/task-output.d.ts.map +1 -0
  201. package/dist/tools/task-output.js +186 -0
  202. package/dist/tools/task-output.js.map +1 -0
  203. package/dist/tools/tool-search/index.d.ts +40 -0
  204. package/dist/tools/tool-search/index.d.ts.map +1 -0
  205. package/dist/tools/tool-search/index.js +110 -0
  206. package/dist/tools/tool-search/index.js.map +1 -0
  207. package/dist/tools/tool-search/registry.d.ts +82 -0
  208. package/dist/tools/tool-search/registry.d.ts.map +1 -0
  209. package/dist/tools/tool-search/registry.js +238 -0
  210. package/dist/tools/tool-search/registry.js.map +1 -0
  211. package/dist/tools/undo-edit.d.ts +51 -0
  212. package/dist/tools/undo-edit.d.ts.map +1 -0
  213. package/dist/tools/undo-edit.js +231 -0
  214. package/dist/tools/undo-edit.js.map +1 -0
  215. package/dist/tools/web-fetch/cache.d.ts +49 -0
  216. package/dist/tools/web-fetch/cache.d.ts.map +1 -0
  217. package/dist/tools/web-fetch/cache.js +89 -0
  218. package/dist/tools/web-fetch/cache.js.map +1 -0
  219. package/dist/tools/web-fetch/index.d.ts +53 -0
  220. package/dist/tools/web-fetch/index.d.ts.map +1 -0
  221. package/dist/tools/web-fetch/index.js +513 -0
  222. package/dist/tools/web-fetch/index.js.map +1 -0
  223. package/dist/tools/write.d.ts +59 -0
  224. package/dist/tools/write.d.ts.map +1 -0
  225. package/dist/tools/write.js +316 -0
  226. package/dist/tools/write.js.map +1 -0
  227. package/dist/types.d.ts +881 -0
  228. package/dist/types.d.ts.map +1 -0
  229. package/dist/types.js +16 -0
  230. package/dist/types.js.map +1 -0
  231. package/dist/working-tags.d.ts +44 -0
  232. package/dist/working-tags.d.ts.map +1 -0
  233. package/dist/working-tags.js +103 -0
  234. package/dist/working-tags.js.map +1 -0
  235. package/package.json +87 -0
  236. package/src/budget-guard.ts +170 -0
  237. package/src/compaction/compaction.ts +386 -0
  238. package/src/compaction/failsafe.ts +185 -0
  239. package/src/compaction/index.ts +1199 -0
  240. package/src/compaction/microcompaction.ts +709 -0
  241. package/src/compaction/observational/buffering.ts +430 -0
  242. package/src/compaction/observational/constants.ts +532 -0
  243. package/src/compaction/observational/index.ts +837 -0
  244. package/src/compaction/observational/observer.ts +510 -0
  245. package/src/compaction/observational/recall-tool.ts +130 -0
  246. package/src/compaction/observational/reflector.ts +221 -0
  247. package/src/compaction/observational/types.ts +343 -0
  248. package/src/context-manager.ts +237 -0
  249. package/src/cortex-agent.ts +4297 -0
  250. package/src/error-classifier.ts +199 -0
  251. package/src/event-bridge.ts +508 -0
  252. package/src/index.ts +292 -0
  253. package/src/mcp-client.ts +582 -0
  254. package/src/model-wrapper.ts +128 -0
  255. package/src/noop-logger.ts +9 -0
  256. package/src/prompt-diagnostics.ts +296 -0
  257. package/src/provider-manager.ts +823 -0
  258. package/src/provider-registry.ts +386 -0
  259. package/src/schema-converter.ts +51 -0
  260. package/src/skill-preprocessor.ts +314 -0
  261. package/src/skill-registry.ts +378 -0
  262. package/src/skill-tool.ts +130 -0
  263. package/src/sub-agent-manager.ts +236 -0
  264. package/src/token-estimator.ts +26 -0
  265. package/src/tool-contract.ts +113 -0
  266. package/src/tool-result-persistence.ts +197 -0
  267. package/src/tools/bash/index.ts +633 -0
  268. package/src/tools/bash/interactive.ts +302 -0
  269. package/src/tools/bash/safety.ts +1297 -0
  270. package/src/tools/edit.ts +422 -0
  271. package/src/tools/glob.ts +330 -0
  272. package/src/tools/grep.ts +819 -0
  273. package/src/tools/index.ts +110 -0
  274. package/src/tools/read.ts +580 -0
  275. package/src/tools/runtime.ts +173 -0
  276. package/src/tools/shared/cwd-tracker.ts +50 -0
  277. package/src/tools/shared/edit-history.ts +96 -0
  278. package/src/tools/shared/edit-matcher.ts +457 -0
  279. package/src/tools/shared/file-mutation-lock.ts +40 -0
  280. package/src/tools/shared/gitignore.ts +61 -0
  281. package/src/tools/shared/pdf-extractor.ts +290 -0
  282. package/src/tools/shared/read-registry.ts +93 -0
  283. package/src/tools/shared/safe-env.ts +82 -0
  284. package/src/tools/sub-agent.ts +171 -0
  285. package/src/tools/task-output.ts +236 -0
  286. package/src/tools/tool-search/index.ts +167 -0
  287. package/src/tools/tool-search/registry.ts +278 -0
  288. package/src/tools/undo-edit.ts +314 -0
  289. package/src/tools/web-fetch/cache.ts +112 -0
  290. package/src/tools/web-fetch/index.ts +604 -0
  291. package/src/tools/write.ts +385 -0
  292. package/src/types.ts +1057 -0
  293. 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":"AAAA;;;;;;;;;;;GAWG;AAmBH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,MAAM,OAAO,eAAe;IACT,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC5C,aAAa,CAAS;IAC/B,KAAK,GAA2B,EAAE,CAAC;IAE3C,YAAY,MAAuC;QACjD,IAAI,CAAC,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAA6B;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAsB;QAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAErC,sBAAsB;QACtB,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,MAAc,EAAE,MAAsB;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE3B,iCAAiC;QACjC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEtB,sEAAsE;QACtE,IAAI,CAAC;YACH,MAAM,kBAAkB,GAA4B,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;YACxE,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,kBAAkB,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CACtB,MAAM,EACN,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,MAAM,EACb,kBAAkB,CACnB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,MAAc,EAAE,KAAa;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE3B,sDAAsD;QACtD,KAAK,CAAC,OAAO,CAAC;YACZ,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,EAAE;SACzF,CAAC,CAAC;QAEH,sBAAsB;QACtB,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,MAAc;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,MAAc,EAAE,QAAgB,EAAE,OAAe;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,KAAK,CAAC,SAAS,EAAE,CAAC;QAClB,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC9B,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC;QAChC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,wBAAwB;QACtB,MAAM,OAAO,GAAmE,EAAE,CAAC;QACnF,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,OAA0C;QACxD,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC1B,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,oBAAoB;YACtB,CAAC;YAED,8CAA8C;YAC9C,KAAK,CAAC,OAAO,CAAC;gBACZ,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,WAAW;gBACnB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,EAAE;aACzF,CAAC,CAAC;YAEH,oBAAoB;YACpB,IAAI,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;YAChE,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QAEF,8DAA8D;QAC9D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,iCAAiC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;CACF"}
@@ -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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"}