@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,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observer module for the observational memory system.
|
|
3
|
+
*
|
|
4
|
+
* Handles extracting observations from raw conversation messages via a
|
|
5
|
+
* background LLM call. The observer watches the conversation and produces
|
|
6
|
+
* structured, timestamped observations that become the agent's sole
|
|
7
|
+
* memory of past interactions.
|
|
8
|
+
*
|
|
9
|
+
* References:
|
|
10
|
+
* - observational-memory-architecture.md (Observer System section)
|
|
11
|
+
* - compaction-strategy.md
|
|
12
|
+
*/
|
|
13
|
+
import type { CompleteFn } from '../compaction.js';
|
|
14
|
+
import type { AgentMessage } from '../../context-manager.js';
|
|
15
|
+
import type { ObserverOutput } from './types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Converts an array of AgentMessages into a formatted string for the
|
|
18
|
+
* observer LLM.
|
|
19
|
+
*
|
|
20
|
+
* Each message is formatted with role and positional timestamp. Messages
|
|
21
|
+
* with content arrays (tool calls/results) receive structured formatting
|
|
22
|
+
* so the observer can extract meaningful takeaways.
|
|
23
|
+
*
|
|
24
|
+
* Messages with timestamps are formatted with their actual date and time.
|
|
25
|
+
* Messages without timestamps fall back to sequential labels.
|
|
26
|
+
* Messages are grouped by date when timestamps are available.
|
|
27
|
+
*/
|
|
28
|
+
export declare function formatMessagesForObserver(messages: AgentMessage[]): string;
|
|
29
|
+
/**
|
|
30
|
+
* Parse the raw LLM output from the observer.
|
|
31
|
+
*
|
|
32
|
+
* Extracts content from `<observations>`, `<current-task>`, and
|
|
33
|
+
* `<suggested-response>` XML blocks. Uses simple string matching
|
|
34
|
+
* (not a DOM parser) and is lenient with malformed output.
|
|
35
|
+
*
|
|
36
|
+
* If no `<observations>` tag is found, the entire output is used as
|
|
37
|
+
* observations (graceful fallback).
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseObserverOutput(raw: string): ObserverOutput;
|
|
40
|
+
/**
|
|
41
|
+
* Build the full observer system prompt.
|
|
42
|
+
*
|
|
43
|
+
* Starts with `OBSERVER_SYSTEM_PROMPT` from constants and optionally
|
|
44
|
+
* appends consumer-provided custom instructions.
|
|
45
|
+
*
|
|
46
|
+
* @param previousObservations - Previous observations for context (unused in system prompt, kept for signature consistency)
|
|
47
|
+
* @param previousObserverTokens - Token budget for previous observations (unused in system prompt)
|
|
48
|
+
* @param customInstruction - Optional consumer-provided instruction to append
|
|
49
|
+
* @returns The complete system prompt string
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildObserverPrompt(previousObservations: string | null, previousObserverTokens: number, customInstruction?: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Build the message array to send to the observer LLM.
|
|
54
|
+
*
|
|
55
|
+
* Constructs a sequence of user messages:
|
|
56
|
+
* 1. (Optional) Previous observations for deduplication context
|
|
57
|
+
* 2. The formatted message history
|
|
58
|
+
* 3. A task instruction to extract observations
|
|
59
|
+
*
|
|
60
|
+
* @param messages - The conversation messages to observe
|
|
61
|
+
* @param previousObservations - Previous observations to prevent duplication
|
|
62
|
+
* @param previousObserverTokens - Token budget for the previous observations context
|
|
63
|
+
* @returns Array of message objects for the LLM call
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildObserverMessages(messages: AgentMessage[], previousObservations: string | null, previousObserverTokens: number): unknown[];
|
|
66
|
+
/**
|
|
67
|
+
* Check if the output contains degenerate repetition.
|
|
68
|
+
*
|
|
69
|
+
* Detects a line appearing 5+ times consecutively, which is a known
|
|
70
|
+
* failure mode of LLMs under certain conditions (e.g., high temperature,
|
|
71
|
+
* long context, repetitive input patterns).
|
|
72
|
+
*
|
|
73
|
+
* @param text - The text to check for repetition
|
|
74
|
+
* @returns true if degenerate repetition is detected
|
|
75
|
+
*/
|
|
76
|
+
export declare function detectDegenerateRepetition(text: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Run the observer LLM call to extract observations from messages.
|
|
79
|
+
*
|
|
80
|
+
* Orchestrates the full observer pipeline:
|
|
81
|
+
* 1. Builds the system prompt (with optional custom instructions)
|
|
82
|
+
* 2. Builds the message array (with previous observations context)
|
|
83
|
+
* 3. Calls the LLM via `complete`
|
|
84
|
+
* 4. Parses the structured output
|
|
85
|
+
* 5. Detects and retries on degenerate repetition (once)
|
|
86
|
+
*
|
|
87
|
+
* @param complete - The LLM completion function
|
|
88
|
+
* @param messages - The conversation messages to observe
|
|
89
|
+
* @param previousObservations - Previous observations for deduplication
|
|
90
|
+
* @param config - Observer configuration
|
|
91
|
+
* @returns Parsed observer output with observations, current task, and suggested response
|
|
92
|
+
*/
|
|
93
|
+
export declare function runObserver(complete: CompleteFn, messages: AgentMessage[], previousObservations: string | null, config: {
|
|
94
|
+
previousObserverTokens: number;
|
|
95
|
+
observerInstruction?: string;
|
|
96
|
+
}): Promise<ObserverOutput>;
|
|
97
|
+
//# sourceMappingURL=observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../../../src/compaction/observational/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQjD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAkD1E;AA4JD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAoB/D;AAwDD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,oBAAoB,EAAE,MAAM,GAAG,IAAI,EACnC,sBAAsB,EAAE,MAAM,EAC9B,iBAAiB,CAAC,EAAE,MAAM,GACzB,MAAM,CAQR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EAAE,EACxB,oBAAoB,EAAE,MAAM,GAAG,IAAI,EACnC,sBAAsB,EAAE,MAAM,GAC7B,OAAO,EAAE,CAsBX;AA+BD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAwBhE;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,YAAY,EAAE,EACxB,oBAAoB,EAAE,MAAM,GAAG,IAAI,EACnC,MAAM,EAAE;IACN,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GACA,OAAO,CAAC,cAAc,CAAC,CAuBzB"}
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observer module for the observational memory system.
|
|
3
|
+
*
|
|
4
|
+
* Handles extracting observations from raw conversation messages via a
|
|
5
|
+
* background LLM call. The observer watches the conversation and produces
|
|
6
|
+
* structured, timestamped observations that become the agent's sole
|
|
7
|
+
* memory of past interactions.
|
|
8
|
+
*
|
|
9
|
+
* References:
|
|
10
|
+
* - observational-memory-architecture.md (Observer System section)
|
|
11
|
+
* - compaction-strategy.md
|
|
12
|
+
*/
|
|
13
|
+
import { OBSERVER_SYSTEM_PROMPT } from './constants.js';
|
|
14
|
+
import { estimateTokens } from '../../token-estimator.js';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Message Formatting
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Converts an array of AgentMessages into a formatted string for the
|
|
20
|
+
* observer LLM.
|
|
21
|
+
*
|
|
22
|
+
* Each message is formatted with role and positional timestamp. Messages
|
|
23
|
+
* with content arrays (tool calls/results) receive structured formatting
|
|
24
|
+
* so the observer can extract meaningful takeaways.
|
|
25
|
+
*
|
|
26
|
+
* Messages with timestamps are formatted with their actual date and time.
|
|
27
|
+
* Messages without timestamps fall back to sequential labels.
|
|
28
|
+
* Messages are grouped by date when timestamps are available.
|
|
29
|
+
*/
|
|
30
|
+
export function formatMessagesForObserver(messages) {
|
|
31
|
+
if (messages.length === 0)
|
|
32
|
+
return '';
|
|
33
|
+
const lines = [];
|
|
34
|
+
let currentDateHeader = null;
|
|
35
|
+
for (let i = 0; i < messages.length; i++) {
|
|
36
|
+
const msg = messages[i];
|
|
37
|
+
const roleLabel = msg.role;
|
|
38
|
+
// Build the timestamp label from message metadata
|
|
39
|
+
let label;
|
|
40
|
+
if (msg.timestamp !== 0) {
|
|
41
|
+
const date = new Date(msg.timestamp);
|
|
42
|
+
const dateHeader = formatDateHeader(date);
|
|
43
|
+
// Insert a date header when the date changes
|
|
44
|
+
if (dateHeader !== currentDateHeader) {
|
|
45
|
+
if (currentDateHeader !== null) {
|
|
46
|
+
lines.push(''); // blank line between date groups
|
|
47
|
+
}
|
|
48
|
+
lines.push(`Date: ${dateHeader}`);
|
|
49
|
+
currentDateHeader = dateHeader;
|
|
50
|
+
}
|
|
51
|
+
label = formatTime(date);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// No timestamp available; use a sequential fallback
|
|
55
|
+
if (currentDateHeader === null) {
|
|
56
|
+
lines.push('Date: (not specified)');
|
|
57
|
+
currentDateHeader = '(not specified)';
|
|
58
|
+
}
|
|
59
|
+
label = `Message ${i + 1}`;
|
|
60
|
+
}
|
|
61
|
+
if (typeof msg.content === 'string') {
|
|
62
|
+
lines.push(`**${roleLabel} (${label})**: ${msg.content}`);
|
|
63
|
+
}
|
|
64
|
+
else if (Array.isArray(msg.content)) {
|
|
65
|
+
const parts = formatContentParts(msg.content);
|
|
66
|
+
if (parts) {
|
|
67
|
+
lines.push(`**${roleLabel} (${label})**:\n${parts}`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
lines.push(`**${roleLabel} (${label})**: [empty]`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
lines.push(`**${roleLabel} (${label})**: [empty]`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return lines.join('\n\n');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Format a date for the observer date header.
|
|
81
|
+
* Example: "April 11, 2026"
|
|
82
|
+
*/
|
|
83
|
+
function formatDateHeader(date) {
|
|
84
|
+
return date.toLocaleDateString('en-US', {
|
|
85
|
+
month: 'long',
|
|
86
|
+
day: 'numeric',
|
|
87
|
+
year: 'numeric',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Format a time for a message label.
|
|
92
|
+
* Example: "2:30 PM"
|
|
93
|
+
*/
|
|
94
|
+
function formatTime(date) {
|
|
95
|
+
return date.toLocaleTimeString('en-US', {
|
|
96
|
+
hour: 'numeric',
|
|
97
|
+
minute: '2-digit',
|
|
98
|
+
hour12: true,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Format an array of content parts from a structured message.
|
|
103
|
+
*
|
|
104
|
+
* Handles text, tool_use, and tool_result part types. Other part types
|
|
105
|
+
* are rendered with their type label.
|
|
106
|
+
*/
|
|
107
|
+
function formatContentParts(parts) {
|
|
108
|
+
const formatted = [];
|
|
109
|
+
for (const part of parts) {
|
|
110
|
+
switch (part.type) {
|
|
111
|
+
case 'text': {
|
|
112
|
+
if (typeof part.text === 'string' && part.text.length > 0) {
|
|
113
|
+
formatted.push(part.text);
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'tool_use': {
|
|
118
|
+
const toolName = typeof part['name'] === 'string' ? part['name'] : 'unknown';
|
|
119
|
+
const argsSummary = summarizeToolArgs(part['input']);
|
|
120
|
+
formatted.push(`[Tool Call: ${toolName}] ${argsSummary}`);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case 'tool_result': {
|
|
124
|
+
const toolUseId = typeof part['tool_use_id'] === 'string'
|
|
125
|
+
? part['tool_use_id']
|
|
126
|
+
: undefined;
|
|
127
|
+
// Resolve tool name: check for a name field on the part, fall back to tool_use_id reference
|
|
128
|
+
const resultToolName = typeof part['name'] === 'string'
|
|
129
|
+
? part['name']
|
|
130
|
+
: undefined;
|
|
131
|
+
const header = resultToolName
|
|
132
|
+
? `[Tool Result: ${resultToolName}]`
|
|
133
|
+
: toolUseId
|
|
134
|
+
? `[Tool Result (ref: ${toolUseId})]`
|
|
135
|
+
: '[Tool Result]';
|
|
136
|
+
const content = extractToolResultContent(part);
|
|
137
|
+
if (content) {
|
|
138
|
+
formatted.push(`${header}\n${content}`);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
formatted.push(header);
|
|
142
|
+
}
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
default: {
|
|
146
|
+
// Unknown part type: include type label and any text
|
|
147
|
+
if (typeof part.text === 'string' && part.text.length > 0) {
|
|
148
|
+
formatted.push(`[${part.type}]: ${part.text}`);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return formatted.join('\n');
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Summarize tool call arguments into a brief string.
|
|
158
|
+
*
|
|
159
|
+
* Produces a compact summary of the key arguments without reproducing
|
|
160
|
+
* large values verbatim.
|
|
161
|
+
*/
|
|
162
|
+
function summarizeToolArgs(input) {
|
|
163
|
+
if (input === null || input === undefined)
|
|
164
|
+
return '';
|
|
165
|
+
if (typeof input === 'string')
|
|
166
|
+
return `{${truncateValue(input, 100)}}`;
|
|
167
|
+
if (typeof input === 'object' && !Array.isArray(input)) {
|
|
168
|
+
const obj = input;
|
|
169
|
+
const entries = Object.entries(obj);
|
|
170
|
+
if (entries.length === 0)
|
|
171
|
+
return '{}';
|
|
172
|
+
const parts = entries.slice(0, 5).map(([key, value]) => {
|
|
173
|
+
return `${key}: ${truncateValue(String(value), 80)}`;
|
|
174
|
+
});
|
|
175
|
+
const suffix = entries.length > 5 ? `, ... (+${entries.length - 5} more)` : '';
|
|
176
|
+
return `{${parts.join(', ')}${suffix}}`;
|
|
177
|
+
}
|
|
178
|
+
return String(input);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Extract text content from a tool_result part.
|
|
182
|
+
*/
|
|
183
|
+
function extractToolResultContent(part) {
|
|
184
|
+
// Direct text field
|
|
185
|
+
if (typeof part.text === 'string' && part.text.length > 0) {
|
|
186
|
+
return part.text;
|
|
187
|
+
}
|
|
188
|
+
// Content may be nested in a 'content' field (some tool result formats)
|
|
189
|
+
const nested = part['content'];
|
|
190
|
+
if (typeof nested === 'string' && nested.length > 0) {
|
|
191
|
+
return nested;
|
|
192
|
+
}
|
|
193
|
+
if (Array.isArray(nested)) {
|
|
194
|
+
const textParts = nested
|
|
195
|
+
.filter((p) => typeof p === 'object' && p !== null && typeof p.text === 'string')
|
|
196
|
+
.map(p => p.text);
|
|
197
|
+
if (textParts.length > 0)
|
|
198
|
+
return textParts.join('\n');
|
|
199
|
+
}
|
|
200
|
+
return '';
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Truncate a string value for argument summaries.
|
|
204
|
+
*/
|
|
205
|
+
function truncateValue(value, maxLen) {
|
|
206
|
+
if (value.length <= maxLen)
|
|
207
|
+
return value;
|
|
208
|
+
return value.slice(0, maxLen) + '...';
|
|
209
|
+
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Output Parsing
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
/**
|
|
214
|
+
* Parse the raw LLM output from the observer.
|
|
215
|
+
*
|
|
216
|
+
* Extracts content from `<observations>`, `<current-task>`, and
|
|
217
|
+
* `<suggested-response>` XML blocks. Uses simple string matching
|
|
218
|
+
* (not a DOM parser) and is lenient with malformed output.
|
|
219
|
+
*
|
|
220
|
+
* If no `<observations>` tag is found, the entire output is used as
|
|
221
|
+
* observations (graceful fallback).
|
|
222
|
+
*/
|
|
223
|
+
export function parseObserverOutput(raw) {
|
|
224
|
+
const observations = extractTagContent(raw, 'observations') ?? raw.trim();
|
|
225
|
+
const rawTask = extractTagContent(raw, 'current-task');
|
|
226
|
+
const rawSuggested = extractTagContent(raw, 'suggested-response');
|
|
227
|
+
const result = {
|
|
228
|
+
observations: observations.trim(),
|
|
229
|
+
};
|
|
230
|
+
const trimmedTask = rawTask?.trim();
|
|
231
|
+
if (trimmedTask && hasMeaningfulContent(trimmedTask)) {
|
|
232
|
+
result.currentTask = trimmedTask;
|
|
233
|
+
}
|
|
234
|
+
const trimmedSuggested = rawSuggested?.trim();
|
|
235
|
+
if (trimmedSuggested && hasMeaningfulContent(trimmedSuggested)) {
|
|
236
|
+
result.suggestedResponse = trimmedSuggested;
|
|
237
|
+
}
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Check whether extracted tag content is meaningful (not just placeholder
|
|
242
|
+
* labels echoed from the prompt template).
|
|
243
|
+
*
|
|
244
|
+
* The observer prompt shows a structure like "- Primary:" and "- Secondary:"
|
|
245
|
+
* as a template. Some model outputs echo the template without filling in
|
|
246
|
+
* real content. This check rejects such outputs so the caller can fall back
|
|
247
|
+
* to prior hints or mark the field as missing.
|
|
248
|
+
*/
|
|
249
|
+
function hasMeaningfulContent(value) {
|
|
250
|
+
const contentOnly = value
|
|
251
|
+
.split('\n')
|
|
252
|
+
.map(line => line
|
|
253
|
+
.replace(/^\s*[-*]\s*/, '')
|
|
254
|
+
.replace(/^Primary\s*:\s*/i, '')
|
|
255
|
+
.replace(/^Secondary\s*:\s*/i, '')
|
|
256
|
+
.trim())
|
|
257
|
+
.filter(line => line.length > 0)
|
|
258
|
+
.join(' ')
|
|
259
|
+
.trim();
|
|
260
|
+
return contentOnly.length >= 8;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Extract content between XML-style tags.
|
|
264
|
+
*
|
|
265
|
+
* Lenient: handles whitespace around tags, multiline content, and
|
|
266
|
+
* nested content. Returns null if the tag pair is not found.
|
|
267
|
+
*/
|
|
268
|
+
function extractTagContent(text, tagName) {
|
|
269
|
+
const openPattern = new RegExp(`<${tagName}>`, 'i');
|
|
270
|
+
const closePattern = new RegExp(`</${tagName}>`, 'i');
|
|
271
|
+
const openMatch = openPattern.exec(text);
|
|
272
|
+
if (!openMatch)
|
|
273
|
+
return null;
|
|
274
|
+
const startIndex = openMatch.index + openMatch[0].length;
|
|
275
|
+
const closeMatch = closePattern.exec(text.slice(startIndex));
|
|
276
|
+
if (!closeMatch) {
|
|
277
|
+
// Opening tag found but no closing tag: return everything after the opening tag
|
|
278
|
+
return text.slice(startIndex);
|
|
279
|
+
}
|
|
280
|
+
return text.slice(startIndex, startIndex + closeMatch.index);
|
|
281
|
+
}
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
// Prompt Building
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
/**
|
|
286
|
+
* Build the full observer system prompt.
|
|
287
|
+
*
|
|
288
|
+
* Starts with `OBSERVER_SYSTEM_PROMPT` from constants and optionally
|
|
289
|
+
* appends consumer-provided custom instructions.
|
|
290
|
+
*
|
|
291
|
+
* @param previousObservations - Previous observations for context (unused in system prompt, kept for signature consistency)
|
|
292
|
+
* @param previousObserverTokens - Token budget for previous observations (unused in system prompt)
|
|
293
|
+
* @param customInstruction - Optional consumer-provided instruction to append
|
|
294
|
+
* @returns The complete system prompt string
|
|
295
|
+
*/
|
|
296
|
+
export function buildObserverPrompt(previousObservations, previousObserverTokens, customInstruction) {
|
|
297
|
+
let prompt = OBSERVER_SYSTEM_PROMPT;
|
|
298
|
+
if (customInstruction) {
|
|
299
|
+
prompt += `\n\n## Additional Instructions\n\n${customInstruction}`;
|
|
300
|
+
}
|
|
301
|
+
return prompt;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Build the message array to send to the observer LLM.
|
|
305
|
+
*
|
|
306
|
+
* Constructs a sequence of user messages:
|
|
307
|
+
* 1. (Optional) Previous observations for deduplication context
|
|
308
|
+
* 2. The formatted message history
|
|
309
|
+
* 3. A task instruction to extract observations
|
|
310
|
+
*
|
|
311
|
+
* @param messages - The conversation messages to observe
|
|
312
|
+
* @param previousObservations - Previous observations to prevent duplication
|
|
313
|
+
* @param previousObserverTokens - Token budget for the previous observations context
|
|
314
|
+
* @returns Array of message objects for the LLM call
|
|
315
|
+
*/
|
|
316
|
+
export function buildObserverMessages(messages, previousObservations, previousObserverTokens) {
|
|
317
|
+
const result = [];
|
|
318
|
+
// 1. Previous observations context (if available)
|
|
319
|
+
if (previousObservations && previousObservations.trim().length > 0) {
|
|
320
|
+
const preamble = 'These are the observations that have already been captured. Do not repeat them. Only add NEW observations from the messages below.\n\n';
|
|
321
|
+
const truncated = tailTruncateToTokenBudget(previousObservations, previousObserverTokens);
|
|
322
|
+
result.push({ role: 'user', content: preamble + truncated });
|
|
323
|
+
}
|
|
324
|
+
// 2. Formatted message history (timestamps from message metadata)
|
|
325
|
+
const formatted = formatMessagesForObserver(messages);
|
|
326
|
+
result.push({ role: 'user', content: formatted });
|
|
327
|
+
// 3. Task instruction
|
|
328
|
+
result.push({
|
|
329
|
+
role: 'user',
|
|
330
|
+
content: 'Extract observations from the message history above. Follow the output format exactly.',
|
|
331
|
+
});
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Tail-truncate a string to fit within a token budget.
|
|
336
|
+
*
|
|
337
|
+
* Keeps the end of the string (most recent observations) and trims
|
|
338
|
+
* from the beginning if the string exceeds the budget.
|
|
339
|
+
*/
|
|
340
|
+
function tailTruncateToTokenBudget(text, tokenBudget) {
|
|
341
|
+
const currentTokens = estimateTokens(text);
|
|
342
|
+
if (currentTokens <= tokenBudget)
|
|
343
|
+
return text;
|
|
344
|
+
// Estimate chars to keep (tokens * 4 chars/token approximation)
|
|
345
|
+
const charsToKeep = tokenBudget * 4;
|
|
346
|
+
if (charsToKeep >= text.length)
|
|
347
|
+
return text;
|
|
348
|
+
const truncated = text.slice(text.length - charsToKeep);
|
|
349
|
+
// Try to start at a line boundary for cleaner output
|
|
350
|
+
const firstNewline = truncated.indexOf('\n');
|
|
351
|
+
if (firstNewline > 0 && firstNewline < truncated.length * 0.2) {
|
|
352
|
+
return '[...truncated...]\n' + truncated.slice(firstNewline + 1);
|
|
353
|
+
}
|
|
354
|
+
return '[...truncated...]\n' + truncated;
|
|
355
|
+
}
|
|
356
|
+
// ---------------------------------------------------------------------------
|
|
357
|
+
// Degenerate Repetition Detection
|
|
358
|
+
// ---------------------------------------------------------------------------
|
|
359
|
+
/**
|
|
360
|
+
* Check if the output contains degenerate repetition.
|
|
361
|
+
*
|
|
362
|
+
* Detects a line appearing 5+ times consecutively, which is a known
|
|
363
|
+
* failure mode of LLMs under certain conditions (e.g., high temperature,
|
|
364
|
+
* long context, repetitive input patterns).
|
|
365
|
+
*
|
|
366
|
+
* @param text - The text to check for repetition
|
|
367
|
+
* @returns true if degenerate repetition is detected
|
|
368
|
+
*/
|
|
369
|
+
export function detectDegenerateRepetition(text) {
|
|
370
|
+
const lines = text.split('\n');
|
|
371
|
+
if (lines.length < 5)
|
|
372
|
+
return false;
|
|
373
|
+
let consecutiveCount = 1;
|
|
374
|
+
let previousLine = lines[0];
|
|
375
|
+
for (let i = 1; i < lines.length; i++) {
|
|
376
|
+
const currentLine = lines[i];
|
|
377
|
+
// Skip empty lines for comparison
|
|
378
|
+
if (currentLine.trim() === '' && previousLine.trim() === '') {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (currentLine === previousLine && currentLine.trim().length > 0) {
|
|
382
|
+
consecutiveCount++;
|
|
383
|
+
if (consecutiveCount >= 5)
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
consecutiveCount = 1;
|
|
388
|
+
previousLine = currentLine;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
// ---------------------------------------------------------------------------
|
|
394
|
+
// Runner
|
|
395
|
+
// ---------------------------------------------------------------------------
|
|
396
|
+
/**
|
|
397
|
+
* Run the observer LLM call to extract observations from messages.
|
|
398
|
+
*
|
|
399
|
+
* Orchestrates the full observer pipeline:
|
|
400
|
+
* 1. Builds the system prompt (with optional custom instructions)
|
|
401
|
+
* 2. Builds the message array (with previous observations context)
|
|
402
|
+
* 3. Calls the LLM via `complete`
|
|
403
|
+
* 4. Parses the structured output
|
|
404
|
+
* 5. Detects and retries on degenerate repetition (once)
|
|
405
|
+
*
|
|
406
|
+
* @param complete - The LLM completion function
|
|
407
|
+
* @param messages - The conversation messages to observe
|
|
408
|
+
* @param previousObservations - Previous observations for deduplication
|
|
409
|
+
* @param config - Observer configuration
|
|
410
|
+
* @returns Parsed observer output with observations, current task, and suggested response
|
|
411
|
+
*/
|
|
412
|
+
export async function runObserver(complete, messages, previousObservations, config) {
|
|
413
|
+
const systemPrompt = buildObserverPrompt(previousObservations, config.previousObserverTokens, config.observerInstruction);
|
|
414
|
+
const observerMessages = buildObserverMessages(messages, previousObservations, config.previousObserverTokens);
|
|
415
|
+
const raw = await complete({ systemPrompt, messages: observerMessages });
|
|
416
|
+
const output = parseObserverOutput(raw);
|
|
417
|
+
// Detect degenerate repetition and retry once
|
|
418
|
+
if (detectDegenerateRepetition(output.observations)) {
|
|
419
|
+
const retryRaw = await complete({ systemPrompt, messages: observerMessages });
|
|
420
|
+
return parseObserverOutput(retryRaw);
|
|
421
|
+
}
|
|
422
|
+
return output;
|
|
423
|
+
}
|
|
424
|
+
//# sourceMappingURL=observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.js","sourceRoot":"","sources":["../../../src/compaction/observational/observer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recall tool: search through past conversation history.
|
|
3
|
+
*
|
|
4
|
+
* The consumer provides a search function via RecallConfig. This module
|
|
5
|
+
* wraps it into a CortexTool that the agent can invoke to retrieve
|
|
6
|
+
* specific details from persisted messages. Observations include
|
|
7
|
+
* timestamps, enabling temporal anchoring for precise recall queries.
|
|
8
|
+
*
|
|
9
|
+
* Reference: docs/cortex/observational-memory-architecture.md (Recall Tool)
|
|
10
|
+
*/
|
|
11
|
+
import type { CortexTool } from '../../tool-contract.js';
|
|
12
|
+
import type { RecallConfig } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Create a CortexTool that wraps the consumer's recall search function.
|
|
15
|
+
*
|
|
16
|
+
* The returned tool lets the agent search through persisted conversation
|
|
17
|
+
* history using a free-text query and optional time range derived from
|
|
18
|
+
* observation timestamps.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createRecallTool(recallConfig: RecallConfig): CortexTool<{
|
|
21
|
+
query: string;
|
|
22
|
+
timeRange?: {
|
|
23
|
+
start?: string;
|
|
24
|
+
end?: string;
|
|
25
|
+
};
|
|
26
|
+
}, string>;
|
|
27
|
+
//# sourceMappingURL=recall-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall-tool.d.ts","sourceRoot":"","sources":["../../../src/compaction/observational/recall-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAC;AA0E7D;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,UAAU,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C,EAAE,MAAM,CAAC,CAgCT"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recall tool: search through past conversation history.
|
|
3
|
+
*
|
|
4
|
+
* The consumer provides a search function via RecallConfig. This module
|
|
5
|
+
* wraps it into a CortexTool that the agent can invoke to retrieve
|
|
6
|
+
* specific details from persisted messages. Observations include
|
|
7
|
+
* timestamps, enabling temporal anchoring for precise recall queries.
|
|
8
|
+
*
|
|
9
|
+
* Reference: docs/cortex/observational-memory-architecture.md (Recall Tool)
|
|
10
|
+
*/
|
|
11
|
+
import { Type } from 'typebox';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Schema
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const RecallParams = Type.Object({
|
|
16
|
+
query: Type.String({
|
|
17
|
+
description: 'What to search for in past conversation history',
|
|
18
|
+
}),
|
|
19
|
+
timeRange: Type.Optional(Type.Object({
|
|
20
|
+
start: Type.Optional(Type.String({ description: 'ISO date string for range start' })),
|
|
21
|
+
end: Type.Optional(Type.String({ description: 'ISO date string for range end' })),
|
|
22
|
+
}, {
|
|
23
|
+
description: 'Optional time range to narrow results. Use timestamps from your observations.',
|
|
24
|
+
})),
|
|
25
|
+
});
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Constants
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/** Maximum number of results to include in the formatted output. */
|
|
30
|
+
const MAX_RESULTS = 10;
|
|
31
|
+
/** Maximum character length per individual result content. */
|
|
32
|
+
const MAX_RESULT_CHARS = 2_000;
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Formatting
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
function formatResult(result) {
|
|
37
|
+
const role = result.role ?? result.type;
|
|
38
|
+
const timestamp = result.timestamp.toISOString();
|
|
39
|
+
const content = result.content.length > MAX_RESULT_CHARS
|
|
40
|
+
? result.content.slice(0, MAX_RESULT_CHARS) + '... (truncated)'
|
|
41
|
+
: result.content;
|
|
42
|
+
return `[${role}] (${timestamp}): ${content}`;
|
|
43
|
+
}
|
|
44
|
+
function formatResults(results) {
|
|
45
|
+
if (results.length === 0) {
|
|
46
|
+
return 'No results found for your query.';
|
|
47
|
+
}
|
|
48
|
+
const limited = results.slice(0, MAX_RESULTS);
|
|
49
|
+
const lines = limited.map(formatResult);
|
|
50
|
+
if (results.length > MAX_RESULTS) {
|
|
51
|
+
lines.push(`\n(${results.length - MAX_RESULTS} additional results omitted)`);
|
|
52
|
+
}
|
|
53
|
+
return lines.join('\n\n');
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Tool factory
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
/**
|
|
59
|
+
* Create a CortexTool that wraps the consumer's recall search function.
|
|
60
|
+
*
|
|
61
|
+
* The returned tool lets the agent search through persisted conversation
|
|
62
|
+
* history using a free-text query and optional time range derived from
|
|
63
|
+
* observation timestamps.
|
|
64
|
+
*/
|
|
65
|
+
export function createRecallTool(recallConfig) {
|
|
66
|
+
return {
|
|
67
|
+
name: 'recall',
|
|
68
|
+
description: 'Search through past conversation history for specific details. ' +
|
|
69
|
+
'Use when your observations mention something but lack the detail needed, ' +
|
|
70
|
+
'or when you need exact content (code, errors, quotes, URLs). ' +
|
|
71
|
+
'Include a timeRange from your observation timestamps for precision.',
|
|
72
|
+
parameters: RecallParams,
|
|
73
|
+
async execute(params) {
|
|
74
|
+
const { query, timeRange } = params;
|
|
75
|
+
// Build the time range object without assigning undefined to optional
|
|
76
|
+
// properties (exactOptionalPropertyTypes is enabled).
|
|
77
|
+
let options;
|
|
78
|
+
if (timeRange) {
|
|
79
|
+
const range = {};
|
|
80
|
+
if (timeRange.start) {
|
|
81
|
+
range.start = new Date(timeRange.start);
|
|
82
|
+
}
|
|
83
|
+
if (timeRange.end) {
|
|
84
|
+
range.end = new Date(timeRange.end);
|
|
85
|
+
}
|
|
86
|
+
options = { timeRange: range };
|
|
87
|
+
}
|
|
88
|
+
const results = await recallConfig.search(query, options);
|
|
89
|
+
return formatResults(results);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=recall-tool.js.map
|