@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Animus Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @animus-labs/cortex
2
+
3
+ Production-grade agent framework with structured context management. Built on `@earendil-works/pi-agent-core`.
4
+
5
+ Cortex treats the context window as a managed surface, not a flat chat log. Named slots, stability-ordered layout, observational memory, and classic compaction controls give you fine-grained control over what the model sees while maximizing prompt cache hit rates.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @animus-labs/cortex
11
+ ```
12
+
13
+ Requires Node.js 24+.
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { CortexAgent, ProviderManager } from '@animus-labs/cortex';
19
+
20
+ const providers = new ProviderManager();
21
+ const model = await providers.resolveModel('anthropic', 'claude-sonnet-4-20250514');
22
+
23
+ const agent = await CortexAgent.create({
24
+ model,
25
+ workingDirectory: process.cwd(),
26
+ initialBasePrompt: 'You are a helpful assistant.',
27
+ // Optional. If omitted, pi-ai falls back to provider environment variables.
28
+ getApiKey: async (provider) => {
29
+ if (provider === 'anthropic' && process.env.ANTHROPIC_API_KEY) {
30
+ return process.env.ANTHROPIC_API_KEY;
31
+ }
32
+ throw new Error(`No API key configured for ${provider}`);
33
+ },
34
+ });
35
+
36
+ agent.onTurnComplete((output) => {
37
+ if (output.userFacing) console.log(output.userFacing);
38
+ });
39
+
40
+ await agent.prompt('What files are in this directory?');
41
+ await agent.destroy();
42
+ ```
43
+
44
+ ## Key Features
45
+
46
+ - **Context Slots**: Named, stability-ordered content blocks for prompt cache optimization. Ephemeral context provides fresh per-loop state without accumulating in persistent history.
47
+ - **Compaction**: Observational memory by default, with classic microcompaction, summarization, and emergency truncation available via config
48
+ - **Built-in Tools**: Bash, TaskOutput, Read, Write, Edit, UndoEdit, Glob, Grep, WebFetch, SubAgent
49
+ - **MCP Support**: Integrate external tool servers via the Model Context Protocol
50
+ - **Skills**: Progressive disclosure system for dynamically loading capabilities
51
+ - **Tool Permissions**: Consumer-provided resolver hook for allow, block, or approval-required decisions
52
+ - **Budget Guards**: Token and cost limits to prevent runaway execution
53
+ - **Provider Management**: Multi-provider support with OAuth flows and model resolution
54
+ - **Event Bridge**: Normalized event stream for logging and observability
55
+
56
+ ## Main Exports
57
+
58
+ - `CortexAgent` - Core agentic loop with context management
59
+ - `ProviderManager` - Provider discovery, OAuth, and model resolution
60
+
61
+ ## Design Principles
62
+
63
+ 1. **Context is a managed surface.** Structure it, order it for caching, update it granularly.
64
+ 2. **Mechanism, not policy.** Cortex provides hooks and callbacks. Consumers implement domain logic.
65
+ 3. **No persistence opinions.** The consumer owns storage. Cortex owns the in-memory context surface.
66
+
67
+ ## Documentation
68
+
69
+ Start with the [consumer guide](../../docs/cortex/consumer-guide.md). The [docs](../../docs/cortex/) directory also contains architecture notes, API details, and tool references.
70
+
71
+ ## License
72
+
73
+ MIT
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Budget guard: enforces turn count and cost limits during the agentic loop.
3
+ *
4
+ * Monitors turn_end events for turn counting and cost accumulation.
5
+ * On breach, calls the provided abort function to stop the loop.
6
+ * Defaults to Infinity for both limits (no enforcement unless configured).
7
+ *
8
+ * Counters reset on agent_start (beginning of each agentic loop).
9
+ *
10
+ * Reference: cortex-architecture.md (Budget Guards section)
11
+ */
12
+ import type { BudgetGuardConfig, CortexLogger } from './types.js';
13
+ import type { EventBridge } from './event-bridge.js';
14
+ export declare class BudgetGuard {
15
+ private readonly maxTurns;
16
+ private readonly maxCost;
17
+ private readonly abortFn;
18
+ private readonly logger;
19
+ private turnCount;
20
+ private totalCost;
21
+ private breached;
22
+ private unsubscribers;
23
+ /**
24
+ * Create a BudgetGuard.
25
+ *
26
+ * @param config - Budget limits (maxTurns, maxCost). Both default to Infinity.
27
+ * @param abortFn - Function to call when a limit is breached (typically agent.abort())
28
+ * @param logger - Optional logger for diagnostics (defaults to silent no-op)
29
+ */
30
+ constructor(config: Partial<BudgetGuardConfig>, abortFn: () => void, logger?: CortexLogger);
31
+ /**
32
+ * Wire the guard to an event bridge.
33
+ * Subscribes to turn_end (for turn counting and cost) and loop_start (for reset).
34
+ *
35
+ * @param bridge - The EventBridge to subscribe to
36
+ */
37
+ wire(bridge: EventBridge): void;
38
+ /**
39
+ * Disconnect from the event bridge.
40
+ */
41
+ unwire(): void;
42
+ /**
43
+ * Get the current turn count.
44
+ */
45
+ getTurnCount(): number;
46
+ /**
47
+ * Get the accumulated cost.
48
+ */
49
+ getTotalCost(): number;
50
+ /**
51
+ * Get the maximum turn limit.
52
+ */
53
+ getMaxTurns(): number;
54
+ /**
55
+ * Get the maximum cost limit.
56
+ */
57
+ getMaxCost(): number;
58
+ /**
59
+ * Whether any limit has been breached.
60
+ */
61
+ isBreached(): boolean;
62
+ /**
63
+ * Reset counters. Called automatically on loop_start.
64
+ */
65
+ reset(): void;
66
+ /**
67
+ * Clean up all subscriptions.
68
+ */
69
+ destroy(): void;
70
+ /**
71
+ * Check if any limits have been exceeded and abort if so.
72
+ */
73
+ private checkLimits;
74
+ }
75
+ //# sourceMappingURL=budget-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget-guard.d.ts","sourceRoot":"","sources":["../src/budget-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMrD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,aAAa,CAAyB;IAE9C;;;;;;OAMG;gBACS,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,MAAM,CAAC,EAAE,YAAY;IAO1F;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IA4B/B;;OAEG;IACH,MAAM,IAAI,IAAI;IAOd;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,OAAO,CAAC,WAAW;CAyBpB"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Budget guard: enforces turn count and cost limits during the agentic loop.
3
+ *
4
+ * Monitors turn_end events for turn counting and cost accumulation.
5
+ * On breach, calls the provided abort function to stop the loop.
6
+ * Defaults to Infinity for both limits (no enforcement unless configured).
7
+ *
8
+ * Counters reset on agent_start (beginning of each agentic loop).
9
+ *
10
+ * Reference: cortex-architecture.md (Budget Guards section)
11
+ */
12
+ import { NOOP_LOGGER } from './noop-logger.js';
13
+ // ---------------------------------------------------------------------------
14
+ // BudgetGuard
15
+ // ---------------------------------------------------------------------------
16
+ export class BudgetGuard {
17
+ maxTurns;
18
+ maxCost;
19
+ abortFn;
20
+ logger;
21
+ turnCount = 0;
22
+ totalCost = 0;
23
+ breached = false;
24
+ unsubscribers = [];
25
+ /**
26
+ * Create a BudgetGuard.
27
+ *
28
+ * @param config - Budget limits (maxTurns, maxCost). Both default to Infinity.
29
+ * @param abortFn - Function to call when a limit is breached (typically agent.abort())
30
+ * @param logger - Optional logger for diagnostics (defaults to silent no-op)
31
+ */
32
+ constructor(config, abortFn, logger) {
33
+ this.maxTurns = config.maxTurns ?? Infinity;
34
+ this.maxCost = config.maxCost ?? Infinity;
35
+ this.abortFn = abortFn;
36
+ this.logger = logger ?? NOOP_LOGGER;
37
+ }
38
+ /**
39
+ * Wire the guard to an event bridge.
40
+ * Subscribes to turn_end (for turn counting and cost) and loop_start (for reset).
41
+ *
42
+ * @param bridge - The EventBridge to subscribe to
43
+ */
44
+ wire(bridge) {
45
+ // Clean up any previous wiring
46
+ this.unwire();
47
+ // Reset counters on agent_start (beginning of a new agentic loop)
48
+ this.unsubscribers.push(bridge.on('loop_start', () => {
49
+ this.reset();
50
+ }));
51
+ // Track turns and cost on turn_end
52
+ this.unsubscribers.push(bridge.on('turn_end', (event) => {
53
+ this.turnCount++;
54
+ // Read cost from typed usage (extracted by EventBridge)
55
+ const cost = event.usage?.cost?.total ?? 0;
56
+ if (cost > 0) {
57
+ this.totalCost += cost;
58
+ }
59
+ // Check limits
60
+ this.checkLimits();
61
+ }));
62
+ }
63
+ /**
64
+ * Disconnect from the event bridge.
65
+ */
66
+ unwire() {
67
+ for (const unsub of this.unsubscribers) {
68
+ unsub();
69
+ }
70
+ this.unsubscribers = [];
71
+ }
72
+ /**
73
+ * Get the current turn count.
74
+ */
75
+ getTurnCount() {
76
+ return this.turnCount;
77
+ }
78
+ /**
79
+ * Get the accumulated cost.
80
+ */
81
+ getTotalCost() {
82
+ return this.totalCost;
83
+ }
84
+ /**
85
+ * Get the maximum turn limit.
86
+ */
87
+ getMaxTurns() {
88
+ return this.maxTurns;
89
+ }
90
+ /**
91
+ * Get the maximum cost limit.
92
+ */
93
+ getMaxCost() {
94
+ return this.maxCost;
95
+ }
96
+ /**
97
+ * Whether any limit has been breached.
98
+ */
99
+ isBreached() {
100
+ return this.breached;
101
+ }
102
+ /**
103
+ * Reset counters. Called automatically on loop_start.
104
+ */
105
+ reset() {
106
+ this.turnCount = 0;
107
+ this.totalCost = 0;
108
+ this.breached = false;
109
+ }
110
+ /**
111
+ * Clean up all subscriptions.
112
+ */
113
+ destroy() {
114
+ this.unwire();
115
+ }
116
+ /**
117
+ * Check if any limits have been exceeded and abort if so.
118
+ */
119
+ checkLimits() {
120
+ if (this.breached) {
121
+ return; // Already breached, don't abort multiple times
122
+ }
123
+ if (this.turnCount >= this.maxTurns) {
124
+ this.breached = true;
125
+ this.logger.warn('[BudgetGuard] turn limit breached', {
126
+ turnCount: this.turnCount,
127
+ maxTurns: this.maxTurns,
128
+ });
129
+ this.abortFn();
130
+ return;
131
+ }
132
+ if (this.totalCost >= this.maxCost) {
133
+ this.breached = true;
134
+ this.logger.warn('[BudgetGuard] cost limit breached', {
135
+ totalCost: this.totalCost,
136
+ maxCost: this.maxCost,
137
+ });
138
+ this.abortFn();
139
+ }
140
+ }
141
+ }
142
+ //# sourceMappingURL=budget-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget-guard.js","sourceRoot":"","sources":["../src/budget-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Layer 2: Conversation Summarization.
3
+ *
4
+ * Replaces older conversation history with an LLM-generated summary
5
+ * while preserving a tail of recent turns. Uses the primary model
6
+ * for summarization quality (the conversation history is structurally
7
+ * complex with interleaved tool calls and multi-turn reasoning).
8
+ *
9
+ * Fires at 70% of context window (configurable). Emits lifecycle
10
+ * events (onBeforeCompaction, onPostCompaction) for consumer
11
+ * coordination (e.g., observational memory flush).
12
+ *
13
+ * References:
14
+ * - compaction-strategy.md (Layer 2: Conversation Summarization)
15
+ * - phase-5-compaction.md (5.3)
16
+ */
17
+ import type { AgentMessage } from '../context-manager.js';
18
+ import type { CompactionConfig, CompactionResult, CompactionTarget } from '../types.js';
19
+ export declare const COMPACTION_DEFAULTS: CompactionConfig;
20
+ /**
21
+ * Extract the <summary> content from the LLM's compaction output.
22
+ * The prompt asks for <analysis> (scratchpad) then <summary> (the actual summary).
23
+ * We strip the analysis and keep only the summary content.
24
+ * If no <summary> tags are found, return the full output (the model may
25
+ * have skipped the tags but still produced useful content).
26
+ */
27
+ export declare function extractSummaryContent(raw: string): string;
28
+ /**
29
+ * Partition conversation history into compaction target and preserved tail.
30
+ *
31
+ * @param history - The full conversation history (post-slot region)
32
+ * @param preserveRecentTurns - Number of recent turns to preserve
33
+ * @returns [target, preserved] where target is summarized and preserved is kept verbatim
34
+ */
35
+ export declare function partitionHistory(history: AgentMessage[], preserveRecentTurns: number): [AgentMessage[], AgentMessage[]];
36
+ /**
37
+ * Build the compaction summary message wrapping it in XML tags.
38
+ *
39
+ * @param summary - The LLM-generated summary text
40
+ * @param turnsCompacted - Number of turns that were summarized
41
+ * @returns A user-role message containing the tagged summary
42
+ */
43
+ export declare function buildSummaryMessage(summary: string, turnsCompacted: number): AgentMessage;
44
+ /**
45
+ * Format conversation turns for the summarization prompt.
46
+ * Extracts text content and labels each turn with role.
47
+ */
48
+ export declare function formatTurnsForSummarization(turns: AgentMessage[]): string;
49
+ /**
50
+ * Type for the LLM completion function.
51
+ * Matches the signature of CortexAgent.directComplete().
52
+ */
53
+ export type CompleteFn = (context: {
54
+ systemPrompt: string;
55
+ messages: unknown[];
56
+ }) => Promise<string>;
57
+ /**
58
+ * Type for the consumer's onBeforeCompaction handler.
59
+ */
60
+ export type BeforeCompactionHandler = (target: CompactionTarget) => Promise<void>;
61
+ /**
62
+ * Type for the consumer's onPostCompaction handler.
63
+ */
64
+ export type PostCompactionHandler = (result: CompactionResult) => void;
65
+ /**
66
+ * Type for the consumer's onCompactionError handler.
67
+ */
68
+ export type CompactionErrorHandler = (error: Error) => void;
69
+ /**
70
+ * Run Layer 2 conversation summarization.
71
+ *
72
+ * Steps:
73
+ * 1. Partition history into target and preserved tail
74
+ * 2. Emit onBeforeCompaction (awaited)
75
+ * 3. Generate summary via LLM
76
+ * 4. Build new history: [summary message] + [preserved tail]
77
+ * 5. Emit onPostCompaction
78
+ *
79
+ * @param history - Current conversation history (post-slot region)
80
+ * @param config - Compaction configuration
81
+ * @param complete - LLM completion function
82
+ * @param handlers - Consumer lifecycle handlers
83
+ * @returns The new conversation history and compaction result
84
+ */
85
+ export declare function runCompaction(history: AgentMessage[], config: CompactionConfig, complete: CompleteFn, handlers?: {
86
+ onBeforeCompaction?: BeforeCompactionHandler[];
87
+ onPostCompaction?: PostCompactionHandler[];
88
+ onCompactionError?: CompactionErrorHandler[];
89
+ },
90
+ /** Actual full-context token count (includes system prompt, slots, tools). When provided, used as tokensBefore instead of text-only heuristic. */
91
+ actualContextTokens?: number): Promise<{
92
+ newHistory: AgentMessage[];
93
+ result: CompactionResult;
94
+ }>;
95
+ /**
96
+ * Check if compaction should trigger based on token count and threshold.
97
+ */
98
+ export declare function shouldCompact(currentTokens: number, contextWindow: number, threshold: number): boolean;
99
+ //# sourceMappingURL=compaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../src/compaction/compaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQxF,eAAO,MAAM,mBAAmB,EAAE,gBAGjC,CAAC;AAkEF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQzD;AAMD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EAAE,EACvB,mBAAmB,EAAE,MAAM,GAC1B,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,CAAC,CAyBlC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,GACrB,YAAY,CAId;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAWzE;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAElF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,UAAU,EACpB,QAAQ,GAAE;IACR,kBAAkB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAC/C,gBAAgB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC3C,iBAAiB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACzC;AACN,kJAAkJ;AAClJ,mBAAmB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC;IAAE,UAAU,EAAE,YAAY,EAAE,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CA+GnE;AA2BD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAGT"}