@animus-labs/cortex 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/budget-guard.d.ts +75 -0
- package/dist/budget-guard.d.ts.map +1 -0
- package/dist/budget-guard.js +142 -0
- package/dist/budget-guard.js.map +1 -0
- package/dist/compaction/compaction.d.ts +99 -0
- package/dist/compaction/compaction.d.ts.map +1 -0
- package/dist/compaction/compaction.js +302 -0
- package/dist/compaction/compaction.js.map +1 -0
- package/dist/compaction/failsafe.d.ts +57 -0
- package/dist/compaction/failsafe.d.ts.map +1 -0
- package/dist/compaction/failsafe.js +135 -0
- package/dist/compaction/failsafe.js.map +1 -0
- package/dist/compaction/index.d.ts +381 -0
- package/dist/compaction/index.d.ts.map +1 -0
- package/dist/compaction/index.js +979 -0
- package/dist/compaction/index.js.map +1 -0
- package/dist/compaction/microcompaction.d.ts +219 -0
- package/dist/compaction/microcompaction.d.ts.map +1 -0
- package/dist/compaction/microcompaction.js +536 -0
- package/dist/compaction/microcompaction.js.map +1 -0
- package/dist/compaction/observational/buffering.d.ts +225 -0
- package/dist/compaction/observational/buffering.d.ts.map +1 -0
- package/dist/compaction/observational/buffering.js +354 -0
- package/dist/compaction/observational/buffering.js.map +1 -0
- package/dist/compaction/observational/constants.d.ts +70 -0
- package/dist/compaction/observational/constants.d.ts.map +1 -0
- package/dist/compaction/observational/constants.js +507 -0
- package/dist/compaction/observational/constants.js.map +1 -0
- package/dist/compaction/observational/index.d.ts +219 -0
- package/dist/compaction/observational/index.d.ts.map +1 -0
- package/dist/compaction/observational/index.js +641 -0
- package/dist/compaction/observational/index.js.map +1 -0
- package/dist/compaction/observational/observer.d.ts +97 -0
- package/dist/compaction/observational/observer.d.ts.map +1 -0
- package/dist/compaction/observational/observer.js +424 -0
- package/dist/compaction/observational/observer.js.map +1 -0
- package/dist/compaction/observational/recall-tool.d.ts +27 -0
- package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
- package/dist/compaction/observational/recall-tool.js +93 -0
- package/dist/compaction/observational/recall-tool.js.map +1 -0
- package/dist/compaction/observational/reflector.d.ts +94 -0
- package/dist/compaction/observational/reflector.d.ts.map +1 -0
- package/dist/compaction/observational/reflector.js +167 -0
- package/dist/compaction/observational/reflector.js.map +1 -0
- package/dist/compaction/observational/types.d.ts +271 -0
- package/dist/compaction/observational/types.d.ts.map +1 -0
- package/dist/compaction/observational/types.js +15 -0
- package/dist/compaction/observational/types.js.map +1 -0
- package/dist/context-manager.d.ts +134 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +170 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/cortex-agent.d.ts +1020 -0
- package/dist/cortex-agent.d.ts.map +1 -0
- package/dist/cortex-agent.js +3589 -0
- package/dist/cortex-agent.js.map +1 -0
- package/dist/error-classifier.d.ts +48 -0
- package/dist/error-classifier.d.ts.map +1 -0
- package/dist/error-classifier.js +152 -0
- package/dist/error-classifier.js.map +1 -0
- package/dist/event-bridge.d.ts +166 -0
- package/dist/event-bridge.d.ts.map +1 -0
- package/dist/event-bridge.js +381 -0
- package/dist/event-bridge.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-client.d.ts +119 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +474 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/model-wrapper.d.ts +58 -0
- package/dist/model-wrapper.d.ts.map +1 -0
- package/dist/model-wrapper.js +86 -0
- package/dist/model-wrapper.js.map +1 -0
- package/dist/noop-logger.d.ts +4 -0
- package/dist/noop-logger.d.ts.map +1 -0
- package/dist/noop-logger.js +8 -0
- package/dist/noop-logger.js.map +1 -0
- package/dist/prompt-diagnostics.d.ts +47 -0
- package/dist/prompt-diagnostics.d.ts.map +1 -0
- package/dist/prompt-diagnostics.js +230 -0
- package/dist/prompt-diagnostics.js.map +1 -0
- package/dist/provider-manager.d.ts +224 -0
- package/dist/provider-manager.d.ts.map +1 -0
- package/dist/provider-manager.js +563 -0
- package/dist/provider-manager.js.map +1 -0
- package/dist/provider-registry.d.ts +115 -0
- package/dist/provider-registry.d.ts.map +1 -0
- package/dist/provider-registry.js +305 -0
- package/dist/provider-registry.js.map +1 -0
- package/dist/schema-converter.d.ts +20 -0
- package/dist/schema-converter.d.ts.map +1 -0
- package/dist/schema-converter.js +48 -0
- package/dist/schema-converter.js.map +1 -0
- package/dist/skill-preprocessor.d.ts +46 -0
- package/dist/skill-preprocessor.d.ts.map +1 -0
- package/dist/skill-preprocessor.js +237 -0
- package/dist/skill-preprocessor.js.map +1 -0
- package/dist/skill-registry.d.ts +107 -0
- package/dist/skill-registry.d.ts.map +1 -0
- package/dist/skill-registry.js +330 -0
- package/dist/skill-registry.js.map +1 -0
- package/dist/skill-tool.d.ts +54 -0
- package/dist/skill-tool.d.ts.map +1 -0
- package/dist/skill-tool.js +88 -0
- package/dist/skill-tool.js.map +1 -0
- package/dist/sub-agent-manager.d.ts +90 -0
- package/dist/sub-agent-manager.d.ts.map +1 -0
- package/dist/sub-agent-manager.js +192 -0
- package/dist/sub-agent-manager.js.map +1 -0
- package/dist/token-estimator.d.ts +23 -0
- package/dist/token-estimator.d.ts.map +1 -0
- package/dist/token-estimator.js +27 -0
- package/dist/token-estimator.js.map +1 -0
- package/dist/tool-contract.d.ts +68 -0
- package/dist/tool-contract.d.ts.map +1 -0
- package/dist/tool-contract.js +35 -0
- package/dist/tool-contract.js.map +1 -0
- package/dist/tool-result-persistence.d.ts +89 -0
- package/dist/tool-result-persistence.d.ts.map +1 -0
- package/dist/tool-result-persistence.js +152 -0
- package/dist/tool-result-persistence.js.map +1 -0
- package/dist/tools/bash/index.d.ts +71 -0
- package/dist/tools/bash/index.d.ts.map +1 -0
- package/dist/tools/bash/index.js +485 -0
- package/dist/tools/bash/index.js.map +1 -0
- package/dist/tools/bash/interactive.d.ts +47 -0
- package/dist/tools/bash/interactive.d.ts.map +1 -0
- package/dist/tools/bash/interactive.js +262 -0
- package/dist/tools/bash/interactive.js.map +1 -0
- package/dist/tools/bash/safety.d.ts +149 -0
- package/dist/tools/bash/safety.d.ts.map +1 -0
- package/dist/tools/bash/safety.js +1116 -0
- package/dist/tools/bash/safety.js.map +1 -0
- package/dist/tools/edit.d.ts +57 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +310 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +34 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +268 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +53 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +673 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +62 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/read.d.ts +43 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +459 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/runtime.d.ts +62 -0
- package/dist/tools/runtime.d.ts.map +1 -0
- package/dist/tools/runtime.js +116 -0
- package/dist/tools/runtime.js.map +1 -0
- package/dist/tools/shared/cwd-tracker.d.ts +32 -0
- package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
- package/dist/tools/shared/cwd-tracker.js +44 -0
- package/dist/tools/shared/cwd-tracker.js.map +1 -0
- package/dist/tools/shared/edit-history.d.ts +55 -0
- package/dist/tools/shared/edit-history.d.ts.map +1 -0
- package/dist/tools/shared/edit-history.js +72 -0
- package/dist/tools/shared/edit-history.js.map +1 -0
- package/dist/tools/shared/edit-matcher.d.ts +83 -0
- package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
- package/dist/tools/shared/edit-matcher.js +359 -0
- package/dist/tools/shared/edit-matcher.js.map +1 -0
- package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
- package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
- package/dist/tools/shared/file-mutation-lock.js +35 -0
- package/dist/tools/shared/file-mutation-lock.js.map +1 -0
- package/dist/tools/shared/gitignore.d.ts +17 -0
- package/dist/tools/shared/gitignore.d.ts.map +1 -0
- package/dist/tools/shared/gitignore.js +59 -0
- package/dist/tools/shared/gitignore.js.map +1 -0
- package/dist/tools/shared/pdf-extractor.d.ts +96 -0
- package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
- package/dist/tools/shared/pdf-extractor.js +196 -0
- package/dist/tools/shared/pdf-extractor.js.map +1 -0
- package/dist/tools/shared/read-registry.d.ts +66 -0
- package/dist/tools/shared/read-registry.d.ts.map +1 -0
- package/dist/tools/shared/read-registry.js +65 -0
- package/dist/tools/shared/read-registry.js.map +1 -0
- package/dist/tools/shared/safe-env.d.ts +18 -0
- package/dist/tools/shared/safe-env.d.ts.map +1 -0
- package/dist/tools/shared/safe-env.js +70 -0
- package/dist/tools/shared/safe-env.js.map +1 -0
- package/dist/tools/sub-agent.d.ts +91 -0
- package/dist/tools/sub-agent.d.ts.map +1 -0
- package/dist/tools/sub-agent.js +89 -0
- package/dist/tools/sub-agent.js.map +1 -0
- package/dist/tools/task-output.d.ts +38 -0
- package/dist/tools/task-output.d.ts.map +1 -0
- package/dist/tools/task-output.js +186 -0
- package/dist/tools/task-output.js.map +1 -0
- package/dist/tools/tool-search/index.d.ts +40 -0
- package/dist/tools/tool-search/index.d.ts.map +1 -0
- package/dist/tools/tool-search/index.js +110 -0
- package/dist/tools/tool-search/index.js.map +1 -0
- package/dist/tools/tool-search/registry.d.ts +82 -0
- package/dist/tools/tool-search/registry.d.ts.map +1 -0
- package/dist/tools/tool-search/registry.js +238 -0
- package/dist/tools/tool-search/registry.js.map +1 -0
- package/dist/tools/undo-edit.d.ts +51 -0
- package/dist/tools/undo-edit.d.ts.map +1 -0
- package/dist/tools/undo-edit.js +231 -0
- package/dist/tools/undo-edit.js.map +1 -0
- package/dist/tools/web-fetch/cache.d.ts +49 -0
- package/dist/tools/web-fetch/cache.d.ts.map +1 -0
- package/dist/tools/web-fetch/cache.js +89 -0
- package/dist/tools/web-fetch/cache.js.map +1 -0
- package/dist/tools/web-fetch/index.d.ts +53 -0
- package/dist/tools/web-fetch/index.d.ts.map +1 -0
- package/dist/tools/web-fetch/index.js +513 -0
- package/dist/tools/web-fetch/index.js.map +1 -0
- package/dist/tools/write.d.ts +59 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +316 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +881 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/working-tags.d.ts +44 -0
- package/dist/working-tags.d.ts.map +1 -0
- package/dist/working-tags.js +103 -0
- package/dist/working-tags.js.map +1 -0
- package/package.json +87 -0
- package/src/budget-guard.ts +170 -0
- package/src/compaction/compaction.ts +386 -0
- package/src/compaction/failsafe.ts +185 -0
- package/src/compaction/index.ts +1199 -0
- package/src/compaction/microcompaction.ts +709 -0
- package/src/compaction/observational/buffering.ts +430 -0
- package/src/compaction/observational/constants.ts +532 -0
- package/src/compaction/observational/index.ts +837 -0
- package/src/compaction/observational/observer.ts +510 -0
- package/src/compaction/observational/recall-tool.ts +130 -0
- package/src/compaction/observational/reflector.ts +221 -0
- package/src/compaction/observational/types.ts +343 -0
- package/src/context-manager.ts +237 -0
- package/src/cortex-agent.ts +4297 -0
- package/src/error-classifier.ts +199 -0
- package/src/event-bridge.ts +508 -0
- package/src/index.ts +292 -0
- package/src/mcp-client.ts +582 -0
- package/src/model-wrapper.ts +128 -0
- package/src/noop-logger.ts +9 -0
- package/src/prompt-diagnostics.ts +296 -0
- package/src/provider-manager.ts +823 -0
- package/src/provider-registry.ts +386 -0
- package/src/schema-converter.ts +51 -0
- package/src/skill-preprocessor.ts +314 -0
- package/src/skill-registry.ts +378 -0
- package/src/skill-tool.ts +130 -0
- package/src/sub-agent-manager.ts +236 -0
- package/src/token-estimator.ts +26 -0
- package/src/tool-contract.ts +113 -0
- package/src/tool-result-persistence.ts +197 -0
- package/src/tools/bash/index.ts +633 -0
- package/src/tools/bash/interactive.ts +302 -0
- package/src/tools/bash/safety.ts +1297 -0
- package/src/tools/edit.ts +422 -0
- package/src/tools/glob.ts +330 -0
- package/src/tools/grep.ts +819 -0
- package/src/tools/index.ts +110 -0
- package/src/tools/read.ts +580 -0
- package/src/tools/runtime.ts +173 -0
- package/src/tools/shared/cwd-tracker.ts +50 -0
- package/src/tools/shared/edit-history.ts +96 -0
- package/src/tools/shared/edit-matcher.ts +457 -0
- package/src/tools/shared/file-mutation-lock.ts +40 -0
- package/src/tools/shared/gitignore.ts +61 -0
- package/src/tools/shared/pdf-extractor.ts +290 -0
- package/src/tools/shared/read-registry.ts +93 -0
- package/src/tools/shared/safe-env.ts +82 -0
- package/src/tools/sub-agent.ts +171 -0
- package/src/tools/task-output.ts +236 -0
- package/src/tools/tool-search/index.ts +167 -0
- package/src/tools/tool-search/registry.ts +278 -0
- package/src/tools/undo-edit.ts +314 -0
- package/src/tools/web-fetch/cache.ts +112 -0
- package/src/tools/web-fetch/index.ts +604 -0
- package/src/tools/write.ts +385 -0
- package/src/types.ts +1057 -0
- package/src/working-tags.ts +118 -0
|
@@ -0,0 +1,237 @@
|
|
|
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
|
+
import type { ContextManagerConfig } from './types.js';
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Minimal pi-agent-core type contracts (no runtime dependency)
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Minimal interface for pi-agent-core's Agent.state.messages entries.
|
|
25
|
+
* The actual type is Message from @earendil-works/pi-ai, but we define
|
|
26
|
+
* only what we need to avoid a hard dependency.
|
|
27
|
+
*/
|
|
28
|
+
export interface AgentMessage {
|
|
29
|
+
role: 'user' | 'assistant' | 'toolResult';
|
|
30
|
+
content: string | Array<{ type: string; text?: string; [key: string]: unknown }>;
|
|
31
|
+
toolCallId?: string;
|
|
32
|
+
toolName?: string;
|
|
33
|
+
details?: unknown;
|
|
34
|
+
isError?: boolean;
|
|
35
|
+
/** Epoch milliseconds when this message was created. Stamped by Cortex at turn boundaries. */
|
|
36
|
+
timestamp: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Minimal interface for pi-agent-core's Agent to access state.messages.
|
|
41
|
+
* We only need to read and write the messages array.
|
|
42
|
+
*/
|
|
43
|
+
export interface AgentStateAccessor {
|
|
44
|
+
state: {
|
|
45
|
+
messages: AgentMessage[];
|
|
46
|
+
systemPrompt?: string;
|
|
47
|
+
model?: unknown;
|
|
48
|
+
thinkingLevel?: string;
|
|
49
|
+
tools?: unknown[];
|
|
50
|
+
error?: string;
|
|
51
|
+
errorMessage?: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The context object passed to transformContext hooks.
|
|
57
|
+
* Mirrors pi-agent-core's AgentContext shape.
|
|
58
|
+
*/
|
|
59
|
+
export interface AgentContext {
|
|
60
|
+
systemPrompt: string;
|
|
61
|
+
model: unknown;
|
|
62
|
+
messages: AgentMessage[];
|
|
63
|
+
tools: unknown[];
|
|
64
|
+
thinkingLevel: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// ContextManager
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
export class ContextManager {
|
|
72
|
+
private readonly agent: AgentStateAccessor;
|
|
73
|
+
private readonly slotNames: readonly string[];
|
|
74
|
+
private readonly slotIndexMap: ReadonlyMap<string, number>;
|
|
75
|
+
private ephemeralContent: string | null = null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Create a ContextManager.
|
|
79
|
+
*
|
|
80
|
+
* @param agent - The pi-agent-core Agent instance (or any object with state.messages)
|
|
81
|
+
* @param config - Configuration with ordered slot names
|
|
82
|
+
*/
|
|
83
|
+
constructor(agent: AgentStateAccessor, config: ContextManagerConfig) {
|
|
84
|
+
this.agent = agent;
|
|
85
|
+
this.slotNames = Object.freeze([...config.slots]);
|
|
86
|
+
|
|
87
|
+
// Build index map: slot name -> position in messages array
|
|
88
|
+
const indexMap = new Map<string, number>();
|
|
89
|
+
for (let i = 0; i < config.slots.length; i++) {
|
|
90
|
+
const name = config.slots[i]!;
|
|
91
|
+
if (indexMap.has(name)) {
|
|
92
|
+
throw new Error(`Duplicate slot name: "${name}"`);
|
|
93
|
+
}
|
|
94
|
+
indexMap.set(name, i);
|
|
95
|
+
}
|
|
96
|
+
this.slotIndexMap = indexMap;
|
|
97
|
+
|
|
98
|
+
// Initialize slot positions in the messages array with empty user-role messages.
|
|
99
|
+
// This ensures the array has the correct length from the start.
|
|
100
|
+
this.initializeSlots();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The number of context slots.
|
|
105
|
+
*/
|
|
106
|
+
get slotCount(): number {
|
|
107
|
+
return this.slotNames.length;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The ordered slot names (frozen copy).
|
|
112
|
+
*/
|
|
113
|
+
get slots(): readonly string[] {
|
|
114
|
+
return this.slotNames;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Update a slot's content. Immediately updates the corresponding
|
|
119
|
+
* message in agent.state.messages at the slot's position.
|
|
120
|
+
*
|
|
121
|
+
* @param name - The slot name (must match a name from the config)
|
|
122
|
+
* @param content - The raw string content (consumer handles formatting)
|
|
123
|
+
* @throws Error if the slot name is not recognized
|
|
124
|
+
*/
|
|
125
|
+
setSlot(name: string, content: string): void {
|
|
126
|
+
const index = this.slotIndexMap.get(name);
|
|
127
|
+
if (index === undefined) {
|
|
128
|
+
throw new Error(`Unknown slot name: "${name}". Valid slots: ${[...this.slotIndexMap.keys()].join(', ')}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
this.agent.state.messages[index] = {
|
|
132
|
+
role: 'user',
|
|
133
|
+
content,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Read current slot content.
|
|
140
|
+
*
|
|
141
|
+
* @param name - The slot name
|
|
142
|
+
* @returns The slot's content string, or null if the slot has not been set
|
|
143
|
+
* @throws Error if the slot name is not recognized
|
|
144
|
+
*/
|
|
145
|
+
getSlot(name: string): string | null {
|
|
146
|
+
const index = this.slotIndexMap.get(name);
|
|
147
|
+
if (index === undefined) {
|
|
148
|
+
throw new Error(`Unknown slot name: "${name}". Valid slots: ${[...this.slotIndexMap.keys()].join(', ')}`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const message = this.agent.state.messages[index];
|
|
152
|
+
if (!message) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Content can be a string or a content array
|
|
157
|
+
if (typeof message.content === 'string') {
|
|
158
|
+
return message.content;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// For content arrays, concatenate text parts
|
|
162
|
+
return message.content
|
|
163
|
+
.filter((part): part is { type: 'text'; text: string } => part.type === 'text' && typeof part.text === 'string')
|
|
164
|
+
.map((part) => part.text)
|
|
165
|
+
.join('');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Set ephemeral content for the next LLM call(s).
|
|
170
|
+
* Injected at the end of the message array inside the transformContext hook.
|
|
171
|
+
* Never written to agent.state.messages.
|
|
172
|
+
* Pass null to clear.
|
|
173
|
+
*
|
|
174
|
+
* @param content - The ephemeral content string, or null to clear
|
|
175
|
+
*/
|
|
176
|
+
setEphemeral(content: string | null): void {
|
|
177
|
+
this.ephemeralContent = content;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get the current ephemeral content.
|
|
182
|
+
*
|
|
183
|
+
* @returns The ephemeral content, or null if not set
|
|
184
|
+
*/
|
|
185
|
+
getEphemeral(): string | null {
|
|
186
|
+
return this.ephemeralContent;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Returns a transformContext hook function that appends ephemeral content.
|
|
191
|
+
*
|
|
192
|
+
* The hook is composable: the consumer can chain it with other transformContext
|
|
193
|
+
* logic (compaction, skill buffer, etc.).
|
|
194
|
+
*
|
|
195
|
+
* The ephemeral content is appended as a user-role message at the end of
|
|
196
|
+
* the messages array, after all conversation history but before the prompt.
|
|
197
|
+
* This placement ensures it does not invalidate the prefix cache for
|
|
198
|
+
* content above it.
|
|
199
|
+
*
|
|
200
|
+
* @returns A function suitable for use as a transformContext hook
|
|
201
|
+
*/
|
|
202
|
+
getTransformContextHook(): (context: AgentContext) => AgentContext {
|
|
203
|
+
return (context: AgentContext): AgentContext => {
|
|
204
|
+
if (this.ephemeralContent === null) {
|
|
205
|
+
return context;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Append ephemeral content as a user-role message at the end
|
|
209
|
+
return {
|
|
210
|
+
...context,
|
|
211
|
+
messages: [
|
|
212
|
+
...context.messages,
|
|
213
|
+
{
|
|
214
|
+
role: 'user' as const,
|
|
215
|
+
content: this.ephemeralContent,
|
|
216
|
+
timestamp: Date.now(),
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Initialize slot positions with empty user-role messages.
|
|
225
|
+
* Ensures the messages array has the correct length from construction.
|
|
226
|
+
*/
|
|
227
|
+
private initializeSlots(): void {
|
|
228
|
+
// Ensure the messages array exists and has at least slotCount entries
|
|
229
|
+
while (this.agent.state.messages.length < this.slotNames.length) {
|
|
230
|
+
this.agent.state.messages.push({
|
|
231
|
+
role: 'user',
|
|
232
|
+
content: '',
|
|
233
|
+
timestamp: 0,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|