@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,134 @@
1
+ /**
2
+ * ContextManager: slot-based persistent context + ephemeral per-call injection.
3
+ *
4
+ * Manages the content an agent sees through two mechanisms:
5
+ * - **Slots**: Named content blocks at the start of the message array.
6
+ * Persistent, updated immediately via setSlot(). Ordered by stability
7
+ * (most stable first) for prefix cache optimization.
8
+ * - **Ephemeral context**: Per-call content injected via transformContext.
9
+ * Never stored in agent.state.messages. Rebuilt every LLM call.
10
+ *
11
+ * Message array layout:
12
+ * [SLOT REGION (0..N-1)] [CONVERSATION HISTORY] [EPHEMERAL (in transformContext)] [PROMPT]
13
+ *
14
+ * Reference: context-manager.md
15
+ */
16
+ import type { ContextManagerConfig } from './types.js';
17
+ /**
18
+ * Minimal interface for pi-agent-core's Agent.state.messages entries.
19
+ * The actual type is Message from @earendil-works/pi-ai, but we define
20
+ * only what we need to avoid a hard dependency.
21
+ */
22
+ export interface AgentMessage {
23
+ role: 'user' | 'assistant' | 'toolResult';
24
+ content: string | Array<{
25
+ type: string;
26
+ text?: string;
27
+ [key: string]: unknown;
28
+ }>;
29
+ toolCallId?: string;
30
+ toolName?: string;
31
+ details?: unknown;
32
+ isError?: boolean;
33
+ /** Epoch milliseconds when this message was created. Stamped by Cortex at turn boundaries. */
34
+ timestamp: number;
35
+ }
36
+ /**
37
+ * Minimal interface for pi-agent-core's Agent to access state.messages.
38
+ * We only need to read and write the messages array.
39
+ */
40
+ export interface AgentStateAccessor {
41
+ state: {
42
+ messages: AgentMessage[];
43
+ systemPrompt?: string;
44
+ model?: unknown;
45
+ thinkingLevel?: string;
46
+ tools?: unknown[];
47
+ error?: string;
48
+ errorMessage?: string;
49
+ };
50
+ }
51
+ /**
52
+ * The context object passed to transformContext hooks.
53
+ * Mirrors pi-agent-core's AgentContext shape.
54
+ */
55
+ export interface AgentContext {
56
+ systemPrompt: string;
57
+ model: unknown;
58
+ messages: AgentMessage[];
59
+ tools: unknown[];
60
+ thinkingLevel: string;
61
+ }
62
+ export declare class ContextManager {
63
+ private readonly agent;
64
+ private readonly slotNames;
65
+ private readonly slotIndexMap;
66
+ private ephemeralContent;
67
+ /**
68
+ * Create a ContextManager.
69
+ *
70
+ * @param agent - The pi-agent-core Agent instance (or any object with state.messages)
71
+ * @param config - Configuration with ordered slot names
72
+ */
73
+ constructor(agent: AgentStateAccessor, config: ContextManagerConfig);
74
+ /**
75
+ * The number of context slots.
76
+ */
77
+ get slotCount(): number;
78
+ /**
79
+ * The ordered slot names (frozen copy).
80
+ */
81
+ get slots(): readonly string[];
82
+ /**
83
+ * Update a slot's content. Immediately updates the corresponding
84
+ * message in agent.state.messages at the slot's position.
85
+ *
86
+ * @param name - The slot name (must match a name from the config)
87
+ * @param content - The raw string content (consumer handles formatting)
88
+ * @throws Error if the slot name is not recognized
89
+ */
90
+ setSlot(name: string, content: string): void;
91
+ /**
92
+ * Read current slot content.
93
+ *
94
+ * @param name - The slot name
95
+ * @returns The slot's content string, or null if the slot has not been set
96
+ * @throws Error if the slot name is not recognized
97
+ */
98
+ getSlot(name: string): string | null;
99
+ /**
100
+ * Set ephemeral content for the next LLM call(s).
101
+ * Injected at the end of the message array inside the transformContext hook.
102
+ * Never written to agent.state.messages.
103
+ * Pass null to clear.
104
+ *
105
+ * @param content - The ephemeral content string, or null to clear
106
+ */
107
+ setEphemeral(content: string | null): void;
108
+ /**
109
+ * Get the current ephemeral content.
110
+ *
111
+ * @returns The ephemeral content, or null if not set
112
+ */
113
+ getEphemeral(): string | null;
114
+ /**
115
+ * Returns a transformContext hook function that appends ephemeral content.
116
+ *
117
+ * The hook is composable: the consumer can chain it with other transformContext
118
+ * logic (compaction, skill buffer, etc.).
119
+ *
120
+ * The ephemeral content is appended as a user-role message at the end of
121
+ * the messages array, after all conversation history but before the prompt.
122
+ * This placement ensures it does not invalidate the prefix cache for
123
+ * content above it.
124
+ *
125
+ * @returns A function suitable for use as a transformContext hook
126
+ */
127
+ getTransformContextHook(): (context: AgentContext) => AgentContext;
128
+ /**
129
+ * Initialize slot positions with empty user-role messages.
130
+ * Ensures the messages array has the correct length from construction.
131
+ */
132
+ private initializeSlots;
133
+ }
134
+ //# sourceMappingURL=context-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-manager.d.ts","sourceRoot":"","sources":["../src/context-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAMvD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;IAC1C,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE;QACL,QAAQ,EAAE,YAAY,EAAE,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8B;IAC3D,OAAO,CAAC,gBAAgB,CAAuB;IAE/C;;;;;OAKG;gBACS,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,oBAAoB;IAoBnE;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,SAAS,MAAM,EAAE,CAE7B;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAa5C;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAuBpC;;;;;;;OAOG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI1C;;;;OAIG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B;;;;;;;;;;;;OAYG;IACH,uBAAuB,IAAI,CAAC,OAAO,EAAE,YAAY,KAAK,YAAY;IAqBlE;;;OAGG;IACH,OAAO,CAAC,eAAe;CAUxB"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * ContextManager: slot-based persistent context + ephemeral per-call injection.
3
+ *
4
+ * Manages the content an agent sees through two mechanisms:
5
+ * - **Slots**: Named content blocks at the start of the message array.
6
+ * Persistent, updated immediately via setSlot(). Ordered by stability
7
+ * (most stable first) for prefix cache optimization.
8
+ * - **Ephemeral context**: Per-call content injected via transformContext.
9
+ * Never stored in agent.state.messages. Rebuilt every LLM call.
10
+ *
11
+ * Message array layout:
12
+ * [SLOT REGION (0..N-1)] [CONVERSATION HISTORY] [EPHEMERAL (in transformContext)] [PROMPT]
13
+ *
14
+ * Reference: context-manager.md
15
+ */
16
+ // ---------------------------------------------------------------------------
17
+ // ContextManager
18
+ // ---------------------------------------------------------------------------
19
+ export class ContextManager {
20
+ agent;
21
+ slotNames;
22
+ slotIndexMap;
23
+ ephemeralContent = null;
24
+ /**
25
+ * Create a ContextManager.
26
+ *
27
+ * @param agent - The pi-agent-core Agent instance (or any object with state.messages)
28
+ * @param config - Configuration with ordered slot names
29
+ */
30
+ constructor(agent, config) {
31
+ this.agent = agent;
32
+ this.slotNames = Object.freeze([...config.slots]);
33
+ // Build index map: slot name -> position in messages array
34
+ const indexMap = new Map();
35
+ for (let i = 0; i < config.slots.length; i++) {
36
+ const name = config.slots[i];
37
+ if (indexMap.has(name)) {
38
+ throw new Error(`Duplicate slot name: "${name}"`);
39
+ }
40
+ indexMap.set(name, i);
41
+ }
42
+ this.slotIndexMap = indexMap;
43
+ // Initialize slot positions in the messages array with empty user-role messages.
44
+ // This ensures the array has the correct length from the start.
45
+ this.initializeSlots();
46
+ }
47
+ /**
48
+ * The number of context slots.
49
+ */
50
+ get slotCount() {
51
+ return this.slotNames.length;
52
+ }
53
+ /**
54
+ * The ordered slot names (frozen copy).
55
+ */
56
+ get slots() {
57
+ return this.slotNames;
58
+ }
59
+ /**
60
+ * Update a slot's content. Immediately updates the corresponding
61
+ * message in agent.state.messages at the slot's position.
62
+ *
63
+ * @param name - The slot name (must match a name from the config)
64
+ * @param content - The raw string content (consumer handles formatting)
65
+ * @throws Error if the slot name is not recognized
66
+ */
67
+ setSlot(name, content) {
68
+ const index = this.slotIndexMap.get(name);
69
+ if (index === undefined) {
70
+ throw new Error(`Unknown slot name: "${name}". Valid slots: ${[...this.slotIndexMap.keys()].join(', ')}`);
71
+ }
72
+ this.agent.state.messages[index] = {
73
+ role: 'user',
74
+ content,
75
+ timestamp: Date.now(),
76
+ };
77
+ }
78
+ /**
79
+ * Read current slot content.
80
+ *
81
+ * @param name - The slot name
82
+ * @returns The slot's content string, or null if the slot has not been set
83
+ * @throws Error if the slot name is not recognized
84
+ */
85
+ getSlot(name) {
86
+ const index = this.slotIndexMap.get(name);
87
+ if (index === undefined) {
88
+ throw new Error(`Unknown slot name: "${name}". Valid slots: ${[...this.slotIndexMap.keys()].join(', ')}`);
89
+ }
90
+ const message = this.agent.state.messages[index];
91
+ if (!message) {
92
+ return null;
93
+ }
94
+ // Content can be a string or a content array
95
+ if (typeof message.content === 'string') {
96
+ return message.content;
97
+ }
98
+ // For content arrays, concatenate text parts
99
+ return message.content
100
+ .filter((part) => part.type === 'text' && typeof part.text === 'string')
101
+ .map((part) => part.text)
102
+ .join('');
103
+ }
104
+ /**
105
+ * Set ephemeral content for the next LLM call(s).
106
+ * Injected at the end of the message array inside the transformContext hook.
107
+ * Never written to agent.state.messages.
108
+ * Pass null to clear.
109
+ *
110
+ * @param content - The ephemeral content string, or null to clear
111
+ */
112
+ setEphemeral(content) {
113
+ this.ephemeralContent = content;
114
+ }
115
+ /**
116
+ * Get the current ephemeral content.
117
+ *
118
+ * @returns The ephemeral content, or null if not set
119
+ */
120
+ getEphemeral() {
121
+ return this.ephemeralContent;
122
+ }
123
+ /**
124
+ * Returns a transformContext hook function that appends ephemeral content.
125
+ *
126
+ * The hook is composable: the consumer can chain it with other transformContext
127
+ * logic (compaction, skill buffer, etc.).
128
+ *
129
+ * The ephemeral content is appended as a user-role message at the end of
130
+ * the messages array, after all conversation history but before the prompt.
131
+ * This placement ensures it does not invalidate the prefix cache for
132
+ * content above it.
133
+ *
134
+ * @returns A function suitable for use as a transformContext hook
135
+ */
136
+ getTransformContextHook() {
137
+ return (context) => {
138
+ if (this.ephemeralContent === null) {
139
+ return context;
140
+ }
141
+ // Append ephemeral content as a user-role message at the end
142
+ return {
143
+ ...context,
144
+ messages: [
145
+ ...context.messages,
146
+ {
147
+ role: 'user',
148
+ content: this.ephemeralContent,
149
+ timestamp: Date.now(),
150
+ },
151
+ ],
152
+ };
153
+ };
154
+ }
155
+ /**
156
+ * Initialize slot positions with empty user-role messages.
157
+ * Ensures the messages array has the correct length from construction.
158
+ */
159
+ initializeSlots() {
160
+ // Ensure the messages array exists and has at least slotCount entries
161
+ while (this.agent.state.messages.length < this.slotNames.length) {
162
+ this.agent.state.messages.push({
163
+ role: 'user',
164
+ content: '',
165
+ timestamp: 0,
166
+ });
167
+ }
168
+ }
169
+ }
170
+ //# sourceMappingURL=context-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-manager.js","sourceRoot":"","sources":["../src/context-manager.ts"],"names":[],"mappings":"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"}