@illuma-ai/agents 1.1.28 → 1.3.1
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/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/spawnPath.cjs +104 -0
- package/dist/cjs/common/spawnPath.cjs.map +1 -0
- package/dist/cjs/graphs/Graph.cjs +89 -45
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/HandoffRegistry.cjs +47 -8
- package/dist/cjs/graphs/HandoffRegistry.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +493 -267
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/graphs/phases/flushLoop.cjs +214 -0
- package/dist/cjs/graphs/phases/flushLoop.cjs.map +1 -0
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +102 -0
- package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -0
- package/dist/cjs/llm/bedrock/index.cjs +4 -3
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +117 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/memory/citations.cjs +69 -0
- package/dist/cjs/memory/citations.cjs.map +1 -0
- package/dist/cjs/memory/compositeBackend.cjs +60 -0
- package/dist/cjs/memory/compositeBackend.cjs.map +1 -0
- package/dist/cjs/memory/constants.cjs +232 -0
- package/dist/cjs/memory/constants.cjs.map +1 -0
- package/dist/cjs/memory/embeddings.cjs +151 -0
- package/dist/cjs/memory/embeddings.cjs.map +1 -0
- package/dist/cjs/memory/factory.cjs +95 -0
- package/dist/cjs/memory/factory.cjs.map +1 -0
- package/dist/cjs/memory/migrate.cjs +81 -0
- package/dist/cjs/memory/migrate.cjs.map +1 -0
- package/dist/cjs/memory/mmr.cjs +138 -0
- package/dist/cjs/memory/mmr.cjs.map +1 -0
- package/dist/cjs/memory/paths.cjs +217 -0
- package/dist/cjs/memory/paths.cjs.map +1 -0
- package/dist/cjs/memory/pgvectorStore.cjs +225 -0
- package/dist/cjs/memory/pgvectorStore.cjs.map +1 -0
- package/dist/cjs/memory/recallTracking.cjs +98 -0
- package/dist/cjs/memory/recallTracking.cjs.map +1 -0
- package/dist/cjs/memory/schema.sql +51 -0
- package/dist/cjs/memory/temporalDecay.cjs +118 -0
- package/dist/cjs/memory/temporalDecay.cjs.map +1 -0
- package/dist/cjs/nodes/ApprovalGateNode.cjs +1 -1
- package/dist/cjs/nodes/ApprovalGateNode.cjs.map +1 -1
- package/dist/cjs/prompts/memoryFlushPrompt.cjs +49 -0
- package/dist/cjs/prompts/memoryFlushPrompt.cjs.map +1 -0
- package/dist/cjs/run.cjs +16 -3
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/AskUser.cjs +6 -1
- package/dist/cjs/tools/AskUser.cjs.map +1 -1
- package/dist/cjs/tools/BrowserTools.cjs +1 -1
- package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +127 -10
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/approval/constants.cjs +2 -2
- package/dist/cjs/tools/approval/constants.cjs.map +1 -1
- package/dist/cjs/tools/memory/index.cjs +58 -0
- package/dist/cjs/tools/memory/index.cjs.map +1 -0
- package/dist/cjs/tools/memory/memoryAppendTool.cjs +69 -0
- package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -0
- package/dist/cjs/tools/memory/memoryGetTool.cjs +49 -0
- package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -0
- package/dist/cjs/tools/memory/memorySearchTool.cjs +65 -0
- package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -0
- package/dist/cjs/tools/memory/shared.cjs +106 -0
- package/dist/cjs/tools/memory/shared.cjs.map +1 -0
- package/dist/cjs/types/graph.cjs.map +1 -1
- package/dist/cjs/utils/childAgentContext.cjs +242 -0
- package/dist/cjs/utils/childAgentContext.cjs.map +1 -0
- package/dist/cjs/utils/errors.cjs +113 -0
- package/dist/cjs/utils/errors.cjs.map +1 -0
- package/dist/cjs/utils/events.cjs +36 -7
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/finishReasons.cjs +44 -0
- package/dist/cjs/utils/finishReasons.cjs.map +1 -0
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/logging.cjs +34 -0
- package/dist/cjs/utils/logging.cjs.map +1 -0
- package/dist/cjs/utils/toolCallNormalization.cjs +250 -0
- package/dist/cjs/utils/toolCallNormalization.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/spawnPath.mjs +95 -0
- package/dist/esm/common/spawnPath.mjs.map +1 -0
- package/dist/esm/graphs/Graph.mjs +89 -45
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/HandoffRegistry.mjs +47 -8
- package/dist/esm/graphs/HandoffRegistry.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +493 -267
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/graphs/phases/flushLoop.mjs +209 -0
- package/dist/esm/graphs/phases/flushLoop.mjs.map +1 -0
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs +99 -0
- package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -0
- package/dist/esm/llm/bedrock/index.mjs +4 -3
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/main.mjs +21 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/memory/citations.mjs +64 -0
- package/dist/esm/memory/citations.mjs.map +1 -0
- package/dist/esm/memory/compositeBackend.mjs +58 -0
- package/dist/esm/memory/compositeBackend.mjs.map +1 -0
- package/dist/esm/memory/constants.mjs +198 -0
- package/dist/esm/memory/constants.mjs.map +1 -0
- package/dist/esm/memory/embeddings.mjs +148 -0
- package/dist/esm/memory/embeddings.mjs.map +1 -0
- package/dist/esm/memory/factory.mjs +93 -0
- package/dist/esm/memory/factory.mjs.map +1 -0
- package/dist/esm/memory/migrate.mjs +78 -0
- package/dist/esm/memory/migrate.mjs.map +1 -0
- package/dist/esm/memory/mmr.mjs +130 -0
- package/dist/esm/memory/mmr.mjs.map +1 -0
- package/dist/esm/memory/paths.mjs +207 -0
- package/dist/esm/memory/paths.mjs.map +1 -0
- package/dist/esm/memory/pgvectorStore.mjs +223 -0
- package/dist/esm/memory/pgvectorStore.mjs.map +1 -0
- package/dist/esm/memory/recallTracking.mjs +94 -0
- package/dist/esm/memory/recallTracking.mjs.map +1 -0
- package/dist/esm/memory/schema.sql +51 -0
- package/dist/esm/memory/temporalDecay.mjs +110 -0
- package/dist/esm/memory/temporalDecay.mjs.map +1 -0
- package/dist/esm/nodes/ApprovalGateNode.mjs +1 -1
- package/dist/esm/nodes/ApprovalGateNode.mjs.map +1 -1
- package/dist/esm/prompts/memoryFlushPrompt.mjs +44 -0
- package/dist/esm/prompts/memoryFlushPrompt.mjs.map +1 -0
- package/dist/esm/run.mjs +16 -3
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/AskUser.mjs +6 -1
- package/dist/esm/tools/AskUser.mjs.map +1 -1
- package/dist/esm/tools/BrowserTools.mjs +1 -1
- package/dist/esm/tools/BrowserTools.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +128 -11
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/approval/constants.mjs +2 -2
- package/dist/esm/tools/approval/constants.mjs.map +1 -1
- package/dist/esm/tools/memory/index.mjs +46 -0
- package/dist/esm/tools/memory/index.mjs.map +1 -0
- package/dist/esm/tools/memory/memoryAppendTool.mjs +67 -0
- package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -0
- package/dist/esm/tools/memory/memoryGetTool.mjs +47 -0
- package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -0
- package/dist/esm/tools/memory/memorySearchTool.mjs +63 -0
- package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -0
- package/dist/esm/tools/memory/shared.mjs +98 -0
- package/dist/esm/tools/memory/shared.mjs.map +1 -0
- package/dist/esm/types/graph.mjs.map +1 -1
- package/dist/esm/utils/childAgentContext.mjs +237 -0
- package/dist/esm/utils/childAgentContext.mjs.map +1 -0
- package/dist/esm/utils/errors.mjs +109 -0
- package/dist/esm/utils/errors.mjs.map +1 -0
- package/dist/esm/utils/events.mjs +36 -8
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/finishReasons.mjs +41 -0
- package/dist/esm/utils/finishReasons.mjs.map +1 -0
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/logging.mjs +31 -0
- package/dist/esm/utils/logging.mjs.map +1 -0
- package/dist/esm/utils/toolCallNormalization.mjs +247 -0
- package/dist/esm/utils/toolCallNormalization.mjs.map +1 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/common/spawnPath.d.ts +59 -0
- package/dist/types/graphs/HandoffRegistry.d.ts +24 -7
- package/dist/types/graphs/MultiAgentGraph.d.ts +43 -23
- package/dist/types/graphs/phases/flushLoop.d.ts +106 -0
- package/dist/types/graphs/phases/memoryFlushPhase.d.ts +100 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/memory/__tests__/mockBackend.d.ts +40 -0
- package/dist/types/memory/citations.d.ts +39 -0
- package/dist/types/memory/compositeBackend.d.ts +30 -0
- package/dist/types/memory/constants.d.ts +121 -0
- package/dist/types/memory/embeddings.d.ts +15 -0
- package/dist/types/memory/factory.d.ts +23 -0
- package/dist/types/memory/index.d.ts +21 -0
- package/dist/types/memory/migrate.d.ts +14 -0
- package/dist/types/memory/mmr.d.ts +50 -0
- package/dist/types/memory/paths.d.ts +107 -0
- package/dist/types/memory/pgvectorStore.d.ts +56 -0
- package/dist/types/memory/recallTracking.d.ts +30 -0
- package/dist/types/memory/temporalDecay.d.ts +53 -0
- package/dist/types/memory/types.d.ts +182 -0
- package/dist/types/prompts/memoryFlushPrompt.d.ts +54 -0
- package/dist/types/run.d.ts +1 -0
- package/dist/types/tools/AskUser.d.ts +1 -1
- package/dist/types/tools/BrowserTools.d.ts +2 -2
- package/dist/types/tools/approval/constants.d.ts +2 -2
- package/dist/types/tools/memory/index.d.ts +39 -0
- package/dist/types/tools/memory/memoryAppendTool.d.ts +27 -0
- package/dist/types/tools/memory/memoryGetTool.d.ts +22 -0
- package/dist/types/tools/memory/memorySearchTool.d.ts +22 -0
- package/dist/types/tools/memory/shared.d.ts +106 -0
- package/dist/types/types/graph.d.ts +10 -3
- package/dist/types/utils/childAgentContext.d.ts +99 -0
- package/dist/types/utils/errors.d.ts +37 -0
- package/dist/types/utils/events.d.ts +21 -0
- package/dist/types/utils/finishReasons.d.ts +32 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/logging.d.ts +2 -0
- package/dist/types/utils/toolCallNormalization.d.ts +44 -0
- package/package.json +6 -4
- package/src/agents/AgentContext.ts +12 -4
- package/src/common/__tests__/enum.test.ts +4 -2
- package/src/common/__tests__/spawnPath.test.ts +110 -0
- package/src/common/index.ts +1 -0
- package/src/common/spawnPath.ts +101 -0
- package/src/graphs/Graph.ts +95 -61
- package/src/graphs/HandoffRegistry.ts +48 -17
- package/src/graphs/MultiAgentGraph.ts +588 -327
- package/src/graphs/__tests__/HandoffRegistry.test.ts +4 -1
- package/src/graphs/__tests__/multi-agent-delegate.test.ts +61 -16
- package/src/graphs/__tests__/multi-agent-edges.test.ts +4 -2
- package/src/graphs/__tests__/multi-agent-nested-subgraph.test.ts +221 -0
- package/src/graphs/__tests__/structured-output.integration.test.ts +212 -118
- package/src/graphs/contextManagement.e2e.test.ts +1 -1
- package/src/graphs/phases/__tests__/flushLoop.test.ts +264 -0
- package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +37 -0
- package/src/graphs/phases/__tests__/runMemoryFlush.test.ts +150 -0
- package/src/graphs/phases/flushLoop.ts +303 -0
- package/src/graphs/phases/memoryFlushPhase.ts +209 -0
- package/src/index.ts +30 -1
- package/src/llm/bedrock/index.ts +4 -5
- package/src/memory/__tests__/citations.test.ts +61 -0
- package/src/memory/__tests__/compositeBackend.test.ts +79 -0
- package/src/memory/__tests__/isolation.test.ts +206 -0
- package/src/memory/__tests__/mmr.test.ts +148 -0
- package/src/memory/__tests__/mockBackend.ts +161 -0
- package/src/memory/__tests__/paths.test.ts +168 -0
- package/src/memory/__tests__/recallTracking.test.ts +96 -0
- package/src/memory/__tests__/temporalDecay.test.ts +151 -0
- package/src/memory/citations.ts +80 -0
- package/src/memory/compositeBackend.ts +99 -0
- package/src/memory/constants.ts +229 -0
- package/src/memory/embeddings.ts +188 -0
- package/src/memory/factory.ts +111 -0
- package/src/memory/index.ts +46 -0
- package/src/memory/migrate.ts +116 -0
- package/src/memory/mmr.ts +161 -0
- package/src/memory/paths.ts +258 -0
- package/src/memory/pgvectorStore.ts +324 -0
- package/src/memory/recallTracking.ts +127 -0
- package/src/memory/schema.sql +51 -0
- package/src/memory/temporalDecay.ts +134 -0
- package/src/memory/types.ts +185 -0
- package/src/nodes/ApprovalGateNode.ts +4 -10
- package/src/nodes/__tests__/ApprovalGateNode.test.ts +11 -20
- package/src/prompts/memoryFlushPrompt.ts +78 -0
- package/src/run.ts +17 -6
- package/src/scripts/test-bedrock-handoff-autonomous.ts +56 -20
- package/src/specs/agent-handoffs-bedrock.integration.test.ts +8 -5
- package/src/specs/agent-handoffs.test.ts +8 -2
- package/src/tools/AskUser.ts +7 -2
- package/src/tools/BrowserTools.ts +3 -5
- package/src/tools/ToolNode.ts +150 -13
- package/src/tools/__tests__/ToolApproval.test.ts +22 -9
- package/src/tools/approval/__tests__/constants.test.ts +1 -1
- package/src/tools/approval/constants.ts +2 -2
- package/src/tools/memory/__tests__/memoryTools.test.ts +205 -0
- package/src/tools/memory/index.ts +96 -0
- package/src/tools/memory/memoryAppendTool.ts +101 -0
- package/src/tools/memory/memoryGetTool.ts +53 -0
- package/src/tools/memory/memorySearchTool.ts +80 -0
- package/src/tools/memory/shared.ts +169 -0
- package/src/tools/search/search.test.ts +6 -1
- package/src/types/graph.ts +10 -3
- package/src/utils/__tests__/childAgentContext.test.ts +217 -0
- package/src/utils/__tests__/errors.test.ts +136 -0
- package/src/utils/__tests__/finishReasons.test.ts +55 -0
- package/src/utils/__tests__/toolCallNormalization.test.ts +181 -0
- package/src/utils/childAgentContext.ts +259 -0
- package/src/utils/errors.ts +115 -0
- package/src/utils/events.ts +37 -7
- package/src/utils/finishReasons.ts +40 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/llm.ts +0 -1
- package/src/utils/logging.ts +45 -8
- package/src/utils/toolCallNormalization.ts +271 -0
|
@@ -2,11 +2,12 @@ import type { BaseMessage } from '@langchain/core/messages';
|
|
|
2
2
|
import type * as t from '@/types';
|
|
3
3
|
/**
|
|
4
4
|
* Tracks the lifecycle of a spawned handoff child agent.
|
|
5
|
-
* Mirrors OpenClaw's SubagentRunRecord pattern.
|
|
6
5
|
*/
|
|
7
6
|
export type HandoffRecord = {
|
|
8
|
-
/**
|
|
7
|
+
/** Agent identity (destination agentId) — stable across multiple spawns of the same agent */
|
|
9
8
|
id: string;
|
|
9
|
+
/** Unique internal key for this specific spawn (agentId + monotonic counter) */
|
|
10
|
+
spawnKey: string;
|
|
10
11
|
/** Display name of the child agent */
|
|
11
12
|
name: string;
|
|
12
13
|
/** Task description / instructions passed to child */
|
|
@@ -29,7 +30,7 @@ export type HandoffRecord = {
|
|
|
29
30
|
/**
|
|
30
31
|
* Registry for async handoff execution.
|
|
31
32
|
*
|
|
32
|
-
* Enables the
|
|
33
|
+
* Enables the autonomous orchestration pattern:
|
|
33
34
|
* 1. Orchestrator spawns children (non-blocking)
|
|
34
35
|
* 2. Orchestrator stays alive to reason, spawn more, or check status
|
|
35
36
|
* 3. Orchestrator collects results when ready
|
|
@@ -38,9 +39,13 @@ export type HandoffRecord = {
|
|
|
38
39
|
*/
|
|
39
40
|
export declare class HandoffRegistry {
|
|
40
41
|
private records;
|
|
42
|
+
/** Monotonically increasing counter for unique spawn IDs */
|
|
43
|
+
private spawnCounter;
|
|
41
44
|
/**
|
|
42
45
|
* Register a spawned handoff child.
|
|
43
46
|
* The promise runs in the background — not awaited here.
|
|
47
|
+
* Uses a unique key per spawn so the same agent can be spawned multiple times
|
|
48
|
+
* across rounds without overwriting prior records.
|
|
44
49
|
*/
|
|
45
50
|
spawn(params: {
|
|
46
51
|
id: string;
|
|
@@ -59,13 +64,18 @@ export declare class HandoffRegistry {
|
|
|
59
64
|
listCompleted(): HandoffRecord[];
|
|
60
65
|
/** List all handoffs regardless of status */
|
|
61
66
|
listAll(): HandoffRecord[];
|
|
62
|
-
/**
|
|
63
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Get a handoff record by either its unique spawnKey or by agentId.
|
|
69
|
+
* - Exact spawnKey match wins (O(1)).
|
|
70
|
+
* - Falls back to the most recently spawned record for that agentId — matching
|
|
71
|
+
* lookups by callers that only know the agent identity, not the spawn round.
|
|
72
|
+
*/
|
|
73
|
+
get(idOrSpawnKey: string): HandoffRecord | undefined;
|
|
64
74
|
/** Check if any handoffs are still running */
|
|
65
75
|
hasPending(): boolean;
|
|
66
76
|
/**
|
|
67
|
-
* Wait for ALL pending handoffs to complete.
|
|
68
|
-
*
|
|
77
|
+
* Wait for ALL pending handoffs to complete and return all records.
|
|
78
|
+
* Records are NOT auto-cleared — caller removes collected records via remove().
|
|
69
79
|
*/
|
|
70
80
|
waitForAll(): Promise<HandoffRecord[]>;
|
|
71
81
|
/**
|
|
@@ -73,6 +83,13 @@ export declare class HandoffRegistry {
|
|
|
73
83
|
* Returns the newly completed record(s).
|
|
74
84
|
*/
|
|
75
85
|
waitForAny(): Promise<HandoffRecord[]>;
|
|
86
|
+
/**
|
|
87
|
+
* Remove record(s) by spawnKey or agentId.
|
|
88
|
+
* - Exact spawnKey match removes only that record.
|
|
89
|
+
* - agentId match removes ALL records for that agent (covers callers that
|
|
90
|
+
* want to forget everything tied to a given agent).
|
|
91
|
+
*/
|
|
92
|
+
remove(idOrSpawnKey: string): void;
|
|
76
93
|
/** Clear all records (for cleanup between graph invocations) */
|
|
77
94
|
clear(): void;
|
|
78
95
|
/** Number of total tracked handoffs */
|
|
@@ -47,10 +47,9 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
47
47
|
private lastActiveAgentId;
|
|
48
48
|
/**
|
|
49
49
|
* Registry for async handoff execution.
|
|
50
|
-
* Enables
|
|
50
|
+
* Enables autonomous orchestration: spawn children non-blocking,
|
|
51
51
|
* orchestrator stays alive to reason and collect results when ready.
|
|
52
52
|
*/
|
|
53
|
-
private handoffRegistry;
|
|
54
53
|
/**
|
|
55
54
|
* When set, the graph routes START to this agent instead of the default starting nodes.
|
|
56
55
|
* Enables multi-turn resumption: follow-up messages go to the agent that last handled
|
|
@@ -119,15 +118,27 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
119
118
|
* Builds orchestration guidance injected into the system message of agents
|
|
120
119
|
* that have handoff or transfer tools (i.e., orchestrator agents).
|
|
121
120
|
*
|
|
122
|
-
*
|
|
123
|
-
* -
|
|
124
|
-
* - Multi-round execution for dependent tasks
|
|
125
|
-
*
|
|
121
|
+
* Implements two orchestration primitives:
|
|
122
|
+
* - Execution bias guidance injected into the system prompt
|
|
123
|
+
* - Multi-round autonomous execution for dependent tasks
|
|
124
|
+
*
|
|
125
|
+
* Handoff tools are synchronous (browser-tool callback pattern): spawn the
|
|
126
|
+
* child, await completion, return the real text as the tool output. Parallel
|
|
127
|
+
* handoff tool calls in one turn run concurrently via LangGraph's ToolNode,
|
|
128
|
+
* so independent children run in parallel without explicit orchestration.
|
|
126
129
|
*
|
|
127
130
|
* @param childDescs - Display names (with optional descriptions) of child agents
|
|
128
131
|
* @param toolCount - Number of handoff/transfer tools available
|
|
129
132
|
*/
|
|
130
133
|
private buildOrchestratorGuidance;
|
|
134
|
+
/**
|
|
135
|
+
* Builds subagent context instructions injected into child agents that are
|
|
136
|
+
* handoff destinations. This tells the child agent it is a subagent with
|
|
137
|
+
* a focused task.
|
|
138
|
+
*
|
|
139
|
+
* @param orchestratorName - Display name of the parent orchestrator agent
|
|
140
|
+
*/
|
|
141
|
+
private buildChildAgentContext;
|
|
131
142
|
/**
|
|
132
143
|
* Builds a meaningful default description for a transfer tool when no explicit
|
|
133
144
|
* edge.description is provided. Uses the destination agent's name and description
|
|
@@ -150,8 +161,8 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
150
161
|
* Create handoff tools for an edge (handles multiple destinations).
|
|
151
162
|
* Each handoff tool spawns the child agent's compiled subgraph asynchronously
|
|
152
163
|
* and returns immediately. The orchestrator uses `collect_results` to retrieve
|
|
153
|
-
* outputs and `check_agents` to monitor status —
|
|
154
|
-
*
|
|
164
|
+
* outputs and `check_agents` to monitor status — a push-based autonomous
|
|
165
|
+
* orchestration pattern.
|
|
155
166
|
*
|
|
156
167
|
* @param edge - The graph edge defining the handoff
|
|
157
168
|
* @param sourceAgentId - The ID of the parent/supervisor agent
|
|
@@ -168,7 +179,7 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
168
179
|
/**
|
|
169
180
|
* Truncate handoff result using head/tail strategy (60/40 split).
|
|
170
181
|
* Preserves the beginning (key findings) and end (conclusions).
|
|
171
|
-
* Matches the TaskTool.truncateResult pattern
|
|
182
|
+
* Matches the TaskTool.truncateResult pattern used by host orchestrators.
|
|
172
183
|
* @param result - The full result text
|
|
173
184
|
* @param maxChars - Maximum allowed characters
|
|
174
185
|
*/
|
|
@@ -183,6 +194,20 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
183
194
|
* Create a complete agent subgraph (similar to createReactAgent)
|
|
184
195
|
*/
|
|
185
196
|
private createAgentSubgraph;
|
|
197
|
+
/**
|
|
198
|
+
* BFS from `rootAgentId` across sequence + transfer edges (NOT handoff edges).
|
|
199
|
+
* Returns the set of agents reachable in this agent's "local workflow".
|
|
200
|
+
*/
|
|
201
|
+
private computeReachableViaNonHandoff;
|
|
202
|
+
/**
|
|
203
|
+
* Build a compiled scoped StateGraph containing `agentIds` as nodes, rooted
|
|
204
|
+
* at `rootAgentId`. Linear sequence edges where both endpoints are in scope
|
|
205
|
+
* are wired directly; nodes with no outgoing in-scope edges route to END.
|
|
206
|
+
*
|
|
207
|
+
* Each node is wrapped around the per-agent `createAgentNode` compiled
|
|
208
|
+
* workflow (agent + tools loop) to preserve isolated tool context.
|
|
209
|
+
*/
|
|
210
|
+
private buildScopedSubgraph;
|
|
186
211
|
/**
|
|
187
212
|
* Detects if the current agent is receiving a handoff and processes the messages accordingly.
|
|
188
213
|
* Returns filtered messages with the transfer tool call/message removed, plus any instructions,
|
|
@@ -196,22 +221,17 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
196
221
|
* @returns Object with filtered messages, extracted instructions, source agent, and parallel siblings
|
|
197
222
|
*/
|
|
198
223
|
/**
|
|
199
|
-
* Prepare messages for a handoff child agent.
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* for the handoff tool itself, with no matching `tool_result`. Providers
|
|
204
|
-
* (Bedrock/Anthropic) reject this.
|
|
205
|
-
* 2. **Paired tool_use/tool_result in history**: The child may not have the same
|
|
206
|
-
* tools as the parent. Bedrock requires `toolConfig` when tool_use/tool_result
|
|
207
|
-
* blocks exist in the message history. Compacting these into text summaries
|
|
208
|
-
* avoids the requirement and reduces context bloat.
|
|
209
|
-
*
|
|
210
|
-
* Strategy:
|
|
211
|
-
* - Remove orphaned tool_use blocks (no matching tool_result)
|
|
212
|
-
* - Compact paired tool_use/tool_result interactions into text summaries
|
|
224
|
+
* Prepare messages for a handoff child agent. See
|
|
225
|
+
* {@link prepareHandoffMessagesUtil} for the full implementation and
|
|
226
|
+
* semantics — this static method is a thin delegate preserved for
|
|
227
|
+
* backward compatibility with existing call sites and unit tests.
|
|
213
228
|
*/
|
|
214
229
|
static prepareHandoffMessages(messages: BaseMessage[]): BaseMessage[];
|
|
230
|
+
/**
|
|
231
|
+
* Build an isolated message context for a downstream scoped-subgraph
|
|
232
|
+
* node. See {@link prepareIsolatedChildMessagesUtil} for details.
|
|
233
|
+
*/
|
|
234
|
+
static prepareIsolatedChildMessages(messages: BaseMessage[]): BaseMessage[];
|
|
215
235
|
private processTransferReception;
|
|
216
236
|
/**
|
|
217
237
|
* Create the multi-agent workflow with handoffs, transfers, and sequences
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic tool-execution loop for the memory-flush reflection turn.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from {@link runMemoryFlush} so the loop primitive is
|
|
5
|
+
* testable in isolation and reusable from any reflection-style phase
|
|
6
|
+
* that wants "invoke → execute tool_calls → feed results back → repeat".
|
|
7
|
+
*
|
|
8
|
+
* Design:
|
|
9
|
+
* - Bounded iterations — caller passes `maxIterations` (default
|
|
10
|
+
* {@link DEFAULT_MAX_FLUSH_ITERATIONS}). The loop exits as soon as
|
|
11
|
+
* the model stops emitting `tool_calls`, hits the cap, or the reply
|
|
12
|
+
* matches {@link SILENT_REPLY_TOKEN}.
|
|
13
|
+
* - Rich result — returns iteration count, attempted/successful
|
|
14
|
+
* appends, per-tool errors, silent-reply flag, and raw final text.
|
|
15
|
+
* The caller logs this; nothing is swallowed.
|
|
16
|
+
* - Self-contained tool execution — does not depend on LangGraph's
|
|
17
|
+
* ToolNode or any graph runtime. The only contract is the
|
|
18
|
+
* LangChain v0.3 `StructuredToolInterface.invoke(args)` shape.
|
|
19
|
+
* - Tool errors are captured as {@link ToolMessage}s with the raw
|
|
20
|
+
* JSON error, so the model can read them and self-correct (e.g.
|
|
21
|
+
* retry with a different path if the schema rejected its first
|
|
22
|
+
* attempt).
|
|
23
|
+
*/
|
|
24
|
+
import { AIMessage, type BaseMessage } from '@langchain/core/messages';
|
|
25
|
+
import type { StructuredToolInterface } from '@langchain/core/tools';
|
|
26
|
+
/** Minimal model contract the loop needs. */
|
|
27
|
+
export interface InvokableModel {
|
|
28
|
+
invoke(messages: BaseMessage[], options?: any): Promise<AIMessage>;
|
|
29
|
+
}
|
|
30
|
+
export interface FlushLoopParams {
|
|
31
|
+
model: InvokableModel;
|
|
32
|
+
tools: StructuredToolInterface[];
|
|
33
|
+
/** Initial messages — typically [SystemMessage, HumanMessage]. */
|
|
34
|
+
initialMessages: BaseMessage[];
|
|
35
|
+
/** Upper bound on model.invoke() calls. Default 8. */
|
|
36
|
+
maxIterations?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Optional debug hook — called once per iteration with `{ i, ai, toolCalls }`.
|
|
39
|
+
* Use for INFO-level tracing during rollout; pass `undefined` in prod.
|
|
40
|
+
*/
|
|
41
|
+
onIteration?: (event: {
|
|
42
|
+
i: number;
|
|
43
|
+
ai: AIMessage;
|
|
44
|
+
toolCalls: ToolCallLike[];
|
|
45
|
+
}) => void;
|
|
46
|
+
}
|
|
47
|
+
/** Shape LangChain emits on AIMessage.tool_calls (duck-typed). */
|
|
48
|
+
export interface ToolCallLike {
|
|
49
|
+
name: string;
|
|
50
|
+
args: Record<string, unknown>;
|
|
51
|
+
id?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface ToolErrorRecord {
|
|
54
|
+
iteration: number;
|
|
55
|
+
toolName: string;
|
|
56
|
+
toolCallId?: string;
|
|
57
|
+
error: string;
|
|
58
|
+
/** Raw args the model passed — useful for diagnosing schema drift. */
|
|
59
|
+
args?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
export interface FlushLoopResult {
|
|
62
|
+
/** Number of model.invoke() calls actually made. */
|
|
63
|
+
iterations: number;
|
|
64
|
+
/** Every `memory_append` tool_call the model emitted across all iterations. */
|
|
65
|
+
appendsAttempted: number;
|
|
66
|
+
/** How many of those returned `{ ok: true, ... }`. */
|
|
67
|
+
appendsSucceeded: number;
|
|
68
|
+
/** Tool errors the model saw (and may have reacted to). */
|
|
69
|
+
toolErrors: ToolErrorRecord[];
|
|
70
|
+
/** True if the final AIMessage text matched {@link SILENT_REPLY_TOKEN}. */
|
|
71
|
+
silentReply: boolean;
|
|
72
|
+
/** Whether the loop stopped because it hit `maxIterations`. */
|
|
73
|
+
hitIterationCap: boolean;
|
|
74
|
+
/** Final AIMessage content as plain text (best-effort). */
|
|
75
|
+
finalText: string;
|
|
76
|
+
/** Full message transcript — useful for debugging / tests. */
|
|
77
|
+
messages: BaseMessage[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Extract a flat text string from any AIMessage content shape
|
|
81
|
+
* (string, array of content blocks, etc).
|
|
82
|
+
*/
|
|
83
|
+
export declare function extractText(message: AIMessage): string;
|
|
84
|
+
/**
|
|
85
|
+
* Parse a tool result string. Memory tools return JSON with
|
|
86
|
+
* `{ ok: boolean, error?: string, path?: string }`. Non-JSON payloads
|
|
87
|
+
* are treated as opaque success strings.
|
|
88
|
+
*/
|
|
89
|
+
export declare function parseToolResult(raw: string): {
|
|
90
|
+
ok: boolean;
|
|
91
|
+
error?: string;
|
|
92
|
+
path?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Bind a tool array to a model if `bindTools` exists on the model.
|
|
96
|
+
* Exported so the caller (runMemoryFlush) can do it once and pass the
|
|
97
|
+
* bound model in, keeping this loop free of LangChain model-specific
|
|
98
|
+
* extensions.
|
|
99
|
+
*/
|
|
100
|
+
export declare function bindToolsIfSupported(model: any, tools: StructuredToolInterface[]): InvokableModel;
|
|
101
|
+
/**
|
|
102
|
+
* Run the agentic reflection loop until the model stops emitting
|
|
103
|
+
* tool_calls, the iteration cap is hit, or the final reply matches
|
|
104
|
+
* {@link SILENT_REPLY_TOKEN}.
|
|
105
|
+
*/
|
|
106
|
+
export declare function runFlushLoop(params: FlushLoopParams): Promise<FlushLoopResult>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory flush phase — trigger logic + reflection invocation.
|
|
3
|
+
*
|
|
4
|
+
* Ported from upstream's post-turn flush handler. The agent is re-invoked
|
|
5
|
+
* with a reflection system prompt and the `memory_append` tool unlocked;
|
|
6
|
+
* it writes notes to its future self, then the graph returns to normal.
|
|
7
|
+
*
|
|
8
|
+
* This module is INTENTIONALLY decoupled from the specific graph runtime —
|
|
9
|
+
* it exposes pure functions (`shouldFlushMemory`) plus a runner that takes
|
|
10
|
+
* the model as a parameter, so the same logic works from `createAgentNode`,
|
|
11
|
+
* `MultiAgentGraph`, or a future graph backend that wants to override
|
|
12
|
+
* flush behaviour.
|
|
13
|
+
*
|
|
14
|
+
* The agentic tool-execution loop (invoke → run tool_calls → feed results
|
|
15
|
+
* back → repeat until stop) lives in {@link ./flushLoop}. This module wires
|
|
16
|
+
* it up: build tools, resolve prompts, flip the phase, call the loop,
|
|
17
|
+
* shape the rich result.
|
|
18
|
+
*/
|
|
19
|
+
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
20
|
+
import { MEMORY_PHASE_FLUSHING, MEMORY_PHASE_NORMAL } from '@/memory/constants';
|
|
21
|
+
import type { MemoryConfig } from '@/memory/types';
|
|
22
|
+
import { type ToolErrorRecord } from './flushLoop';
|
|
23
|
+
export interface ShouldFlushInput {
|
|
24
|
+
currentTokens: number;
|
|
25
|
+
windowTokens: number;
|
|
26
|
+
reserveFloorTokens?: number;
|
|
27
|
+
softThresholdTokens?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pure trigger function: fires when the current context is within
|
|
31
|
+
* `softThreshold + reserveFloor` tokens of the model window. Matches
|
|
32
|
+
* upstream's formula.
|
|
33
|
+
*/
|
|
34
|
+
export declare function shouldFlushMemory(input: ShouldFlushInput): boolean;
|
|
35
|
+
export interface RunFlushParams {
|
|
36
|
+
model: BaseChatModel;
|
|
37
|
+
memory: MemoryConfig;
|
|
38
|
+
/** A compact summary of the conversation — last N turns, not raw history. */
|
|
39
|
+
conversationSummary: string;
|
|
40
|
+
/**
|
|
41
|
+
* Accessor the graph runtime uses to expose the current phase to the
|
|
42
|
+
* append tool. The runner sets this to `memory_flushing` for the duration
|
|
43
|
+
* of the reflection turn and restores it on exit.
|
|
44
|
+
*/
|
|
45
|
+
setPhase: (phase: typeof MEMORY_PHASE_NORMAL | typeof MEMORY_PHASE_FLUSHING) => void;
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated No longer used — the 8-path canonical-document model
|
|
48
|
+
* does not date-stamp files. Kept in the params shape for one release
|
|
49
|
+
* so host's callers don't break on the type signature.
|
|
50
|
+
*/
|
|
51
|
+
timezone?: string;
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Same as `timezone` — unused in the canonical-document model.
|
|
54
|
+
*/
|
|
55
|
+
nowMs?: number;
|
|
56
|
+
/** Override for the agentic-loop iteration cap. */
|
|
57
|
+
maxIterations?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Optional per-iteration callback for structured debug logging.
|
|
60
|
+
* Caller is expected to demote this to debug once the rollout is stable.
|
|
61
|
+
*/
|
|
62
|
+
onIteration?: (event: {
|
|
63
|
+
i: number;
|
|
64
|
+
toolCallCount: number;
|
|
65
|
+
toolNames: string[];
|
|
66
|
+
}) => void;
|
|
67
|
+
}
|
|
68
|
+
export interface RunFlushResult {
|
|
69
|
+
/** Did the flush actually run (false if disabled via config). */
|
|
70
|
+
ran: boolean;
|
|
71
|
+
/** Model.invoke() iterations actually performed. */
|
|
72
|
+
iterations?: number;
|
|
73
|
+
/** Total `memory_append` calls the model emitted. */
|
|
74
|
+
appendsAttempted?: number;
|
|
75
|
+
/** Subset that returned `{ ok: true }` from the backend. */
|
|
76
|
+
appendsSucceeded?: number;
|
|
77
|
+
/** Tool errors the model saw during the flush — surfaced for logging. */
|
|
78
|
+
toolErrors?: ToolErrorRecord[];
|
|
79
|
+
/** Final text reply equalled SILENT_REPLY_TOKEN (`NO_REPLY`). */
|
|
80
|
+
silentReply?: boolean;
|
|
81
|
+
/** Loop hit its iteration cap with tool_calls still pending. */
|
|
82
|
+
hitIterationCap?: boolean;
|
|
83
|
+
/** Final text reply from the last AIMessage. */
|
|
84
|
+
finalText?: string;
|
|
85
|
+
/** Error message if the flush threw. */
|
|
86
|
+
error?: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Run the reflection turn. The model is re-invoked with just the flush
|
|
90
|
+
* prompt + compact summary + the append tool unlocked. We intentionally
|
|
91
|
+
* drop the full history — the prompt tells the agent to write notes based
|
|
92
|
+
* on what it learned, not to continue the conversation.
|
|
93
|
+
*
|
|
94
|
+
* The loop keeps invoking the model until it stops emitting tool_calls,
|
|
95
|
+
* hits the iteration cap, or replies with {@link SILENT_REPLY_TOKEN}. Each
|
|
96
|
+
* `memory_append` tool_call is executed against the pgvector backend and
|
|
97
|
+
* the result (success path or error) is fed back as a ToolMessage so the
|
|
98
|
+
* model can self-correct (e.g. retry with a valid path).
|
|
99
|
+
*/
|
|
100
|
+
export declare function runMemoryFlush(params: RunFlushParams): Promise<RunFlushResult>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,6 +15,13 @@ export * from './tools/AskUser';
|
|
|
15
15
|
export * from './tools/schema';
|
|
16
16
|
export * from './tools/handlers';
|
|
17
17
|
export * from './tools/search';
|
|
18
|
+
export * from './tools/memory';
|
|
19
|
+
export * from './memory';
|
|
20
|
+
export { MEMORY_FLUSH_SYSTEM_PROMPT } from './prompts/memoryFlushPrompt';
|
|
21
|
+
export { shouldFlushMemory, runMemoryFlush, } from './graphs/phases/memoryFlushPhase';
|
|
22
|
+
export type { RunFlushParams, RunFlushResult, } from './graphs/phases/memoryFlushPhase';
|
|
23
|
+
export { runFlushLoop, bindToolsIfSupported, extractText as extractFlushText, parseToolResult as parseFlushToolResult, } from './graphs/phases/flushLoop';
|
|
24
|
+
export type { FlushLoopParams, FlushLoopResult, ToolCallLike, ToolErrorRecord, } from './graphs/phases/flushLoop';
|
|
18
25
|
export * from './schemas';
|
|
19
26
|
export * from './nodes';
|
|
20
27
|
export * from './common';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory mock implementation of {@link MemoryBackend} — for unit tests.
|
|
3
|
+
*
|
|
4
|
+
* Enforces the SAME invariants as the real pgvector store so behavior
|
|
5
|
+
* tests can run without Postgres:
|
|
6
|
+
*
|
|
7
|
+
* - writes validate path + scope via `assertWritablePath`
|
|
8
|
+
* - agent-tier paths store with `userId = null`
|
|
9
|
+
* - user-tier paths store with the caller's `userId`
|
|
10
|
+
* - reads apply the layered filter
|
|
11
|
+
* agent_id = $scope.agentId
|
|
12
|
+
* AND (user_id IS NULL OR user_id = $scope.userId)
|
|
13
|
+
* - UPSERT key is `(agentId, userId, path)` with NULL collisions
|
|
14
|
+
* (so `NULLS NOT DISTINCT` semantics are reproduced in-memory)
|
|
15
|
+
*/
|
|
16
|
+
import type { MemoryAppendInput, MemoryBackend, MemoryEntry, MemoryGetOptions, MemoryHealth, MemoryReadResult, MemoryScope, MemorySearchOptions } from '../types';
|
|
17
|
+
interface Row {
|
|
18
|
+
id: string;
|
|
19
|
+
agentId: string;
|
|
20
|
+
/** null for agent-tier rows; caller id for user-tier rows. */
|
|
21
|
+
userId: string | null;
|
|
22
|
+
/** Latest writer — provenance, tracked even on agent-tier rows. */
|
|
23
|
+
lastUserId: string | null;
|
|
24
|
+
path: string;
|
|
25
|
+
content: string;
|
|
26
|
+
createdAt: Date;
|
|
27
|
+
updatedAt: Date;
|
|
28
|
+
}
|
|
29
|
+
export declare class MockMemoryBackend implements MemoryBackend {
|
|
30
|
+
readonly kind: "vector";
|
|
31
|
+
private rows;
|
|
32
|
+
private seq;
|
|
33
|
+
search(scope: MemoryScope, query: string, opts?: MemorySearchOptions): Promise<MemoryEntry[]>;
|
|
34
|
+
get(scope: MemoryScope, opts: MemoryGetOptions): Promise<MemoryReadResult | null>;
|
|
35
|
+
append(scope: MemoryScope, input: MemoryAppendInput): Promise<void>;
|
|
36
|
+
health(): Promise<MemoryHealth>;
|
|
37
|
+
/** Test-only introspection. */
|
|
38
|
+
allRows(): readonly Row[];
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Citation decoration — Phase 2.
|
|
3
|
+
*
|
|
4
|
+
* Ported from upstream `extensions/memory-core/src/tools.citations.ts`.
|
|
5
|
+
* Decorates memory_search hits with `[path#L{start}-L{end}]` markers so
|
|
6
|
+
* the model can attribute claims back to specific memory files when it
|
|
7
|
+
* uses them in its answer.
|
|
8
|
+
*
|
|
9
|
+
* Since our backend stores files as single rows (not line-chunked), we
|
|
10
|
+
* compute line ranges from the returned content block on the fly:
|
|
11
|
+
* - `startLine` = 1 (line 1 of the file)
|
|
12
|
+
* - `endLine` = total number of lines in the block
|
|
13
|
+
* This matches upstream's output format exactly while keeping the pg
|
|
14
|
+
* schema chunk-free.
|
|
15
|
+
*/
|
|
16
|
+
export type MemoryCitationsMode = 'on' | 'off' | 'auto';
|
|
17
|
+
export declare const DEFAULT_CITATIONS_MODE: MemoryCitationsMode;
|
|
18
|
+
export declare function resolveMemoryCitationsMode(raw: string | undefined | null): MemoryCitationsMode;
|
|
19
|
+
export interface CitationCandidate {
|
|
20
|
+
path: string;
|
|
21
|
+
content: string;
|
|
22
|
+
startLine?: number;
|
|
23
|
+
endLine?: number;
|
|
24
|
+
citation?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Decorate each hit with a citation marker. Mirrors upstream's behavior:
|
|
28
|
+
* appends `\n\nSource: <citation>` to the content and sets `citation`.
|
|
29
|
+
* When `include=false`, clears any existing citation field.
|
|
30
|
+
*/
|
|
31
|
+
export declare function decorateCitations<T extends CitationCandidate>(hits: T[], include: boolean): T[];
|
|
32
|
+
/**
|
|
33
|
+
* Whether citations should be emitted for this call.
|
|
34
|
+
*
|
|
35
|
+
* Upstream keys `auto` off the session type (direct/group/channel). In
|
|
36
|
+
* Phase 1 we only have direct chat, so `auto` => `on`. Callers that
|
|
37
|
+
* later distinguish session types can pass `mode` explicitly.
|
|
38
|
+
*/
|
|
39
|
+
export declare function shouldIncludeCitations(mode: MemoryCitationsMode): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite memory backend — the architectural seam for a future graph layer.
|
|
3
|
+
*
|
|
4
|
+
* Today, memory is pgvector only. Tomorrow, a Graphiti or Neo4j-agent-memory
|
|
5
|
+
* adapter can implement the same {@link MemoryBackend} interface and be
|
|
6
|
+
* composed with the vector store here — without touching the tool
|
|
7
|
+
* definitions, prompts, or host wiring.
|
|
8
|
+
*
|
|
9
|
+
* Fan-out strategy (simple on purpose for Phase 1):
|
|
10
|
+
* - `search`: query every backend in parallel, merge, dedupe by id, sort by
|
|
11
|
+
* score, cap at maxResults. Graph hits and vector hits are interleaved by
|
|
12
|
+
* score — the LLM sees one ranked list.
|
|
13
|
+
* - `get`: the vector store owns file paths; graph stores don't. First
|
|
14
|
+
* backend that returns a non-null result wins. In practice this will almost
|
|
15
|
+
* always be the vector store, since append paths live there.
|
|
16
|
+
* - `append`: fan out to every backend. Vector store persists the note,
|
|
17
|
+
* graph backend runs its own extraction pipeline. An append failure in any
|
|
18
|
+
* single backend is surfaced — we fail loud rather than silently dropping
|
|
19
|
+
* writes.
|
|
20
|
+
*/
|
|
21
|
+
import type { MemoryAppendInput, MemoryBackend, MemoryEntry, MemoryGetOptions, MemoryHealth, MemoryReadResult, MemoryScope, MemorySearchOptions } from './types';
|
|
22
|
+
export declare class CompositeMemoryBackend implements MemoryBackend {
|
|
23
|
+
readonly kind: "composite";
|
|
24
|
+
private readonly backends;
|
|
25
|
+
constructor(backends: MemoryBackend[]);
|
|
26
|
+
search(scope: MemoryScope, query: string, opts?: MemorySearchOptions): Promise<MemoryEntry[]>;
|
|
27
|
+
get(scope: MemoryScope, opts: MemoryGetOptions): Promise<MemoryReadResult | null>;
|
|
28
|
+
append(scope: MemoryScope, input: MemoryAppendInput): Promise<void>;
|
|
29
|
+
health(): Promise<MemoryHealth>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autonomous memory — shared constants.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for defaults, limits, and magic strings used across
|
|
5
|
+
* the memory store, tools, flush phase, and tests. Changing a value here
|
|
6
|
+
* changes it everywhere — no hunting through files.
|
|
7
|
+
*/
|
|
8
|
+
/** Default embedding provider when {@link process.env.MEMORY_EMBEDDINGS_PROVIDER} is unset. */
|
|
9
|
+
export declare const DEFAULT_MEMORY_PROVIDER: "bedrock";
|
|
10
|
+
/** Default embedding model (Titan v2 — AWS-native, 6× cheaper than Cohere v4). */
|
|
11
|
+
export declare const DEFAULT_MEMORY_MODEL = "amazon.titan-embed-text-v2:0";
|
|
12
|
+
/** Default vector width (Titan v2 supports 256 / 512 / 1024). */
|
|
13
|
+
export declare const DEFAULT_MEMORY_DIMENSIONS = 1024;
|
|
14
|
+
/** Default Postgres table name; can be overridden via env for dev/prod sharing. */
|
|
15
|
+
export declare const DEFAULT_MEMORY_TABLE = "agent_memories";
|
|
16
|
+
/** Default Postgres schema. */
|
|
17
|
+
export declare const DEFAULT_MEMORY_SCHEMA = "public";
|
|
18
|
+
/** Phase values used by the flush-phase gate. */
|
|
19
|
+
export declare const MEMORY_PHASE_NORMAL = "normal";
|
|
20
|
+
export declare const MEMORY_PHASE_FLUSHING = "memory_flushing";
|
|
21
|
+
/**
|
|
22
|
+
* Search defaults — aligned with upstream's upstream defaults.
|
|
23
|
+
*
|
|
24
|
+
* Sources:
|
|
25
|
+
* - `upstream reference` → maxResults=6
|
|
26
|
+
* - `upstream reference` → maxInjectedChars=4000
|
|
27
|
+
*
|
|
28
|
+
* Keeping these in lockstep with upstream means the mandatory-recall tool
|
|
29
|
+
* description, budget clamps, and eval corpora line up with upstream's
|
|
30
|
+
* tuning — we inherit their calibration instead of re-tuning from scratch.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_MAX_SEARCH_RESULTS = 6;
|
|
33
|
+
export declare const DEFAULT_MIN_SCORE = 0.1;
|
|
34
|
+
export declare const DEFAULT_MAX_INJECTED_CHARS = 4000;
|
|
35
|
+
/** Hybrid retrieval weights — 70% vector cosine, 30% BM25 / ts_rank text score. */
|
|
36
|
+
export declare const HYBRID_VECTOR_WEIGHT = 0.7;
|
|
37
|
+
export declare const HYBRID_TEXT_WEIGHT = 0.3;
|
|
38
|
+
/**
|
|
39
|
+
* Phase 2 rerank defaults — ported from upstream.
|
|
40
|
+
*
|
|
41
|
+
* Sources:
|
|
42
|
+
* - `upstream reference` → lambda=0.7
|
|
43
|
+
* - `upstream reference` → halfLifeDays=30
|
|
44
|
+
*
|
|
45
|
+
* Both features are opt-in (enabled=false by default) — the Phase 2
|
|
46
|
+
* features are layered on top of hybrid search and don't change default
|
|
47
|
+
* behavior for callers that upgrade in place.
|
|
48
|
+
*/
|
|
49
|
+
export declare const DEFAULT_MMR_ENABLED = false;
|
|
50
|
+
export declare const DEFAULT_MMR_LAMBDA = 0.7;
|
|
51
|
+
export declare const DEFAULT_TEMPORAL_DECAY_ENABLED = false;
|
|
52
|
+
export declare const DEFAULT_TEMPORAL_DECAY_HALF_LIFE_DAYS = 30;
|
|
53
|
+
export declare const DEFAULT_RECALL_TRACKING_ENABLED = false;
|
|
54
|
+
export declare const DEFAULT_CITATIONS_MODE: "auto";
|
|
55
|
+
/**
|
|
56
|
+
* Flush trigger margins (token counts) — aligned with upstream upstream.
|
|
57
|
+
*
|
|
58
|
+
* Sources:
|
|
59
|
+
* - `upstream reference` → softThreshold=4000
|
|
60
|
+
* - `upstream reference` → reserveFloor=20000
|
|
61
|
+
*/
|
|
62
|
+
export declare const DEFAULT_FLUSH_SOFT_THRESHOLD_TOKENS = 4000;
|
|
63
|
+
export declare const DEFAULT_FLUSH_RESERVE_FLOOR_TOKENS = 20000;
|
|
64
|
+
/** Hard cap on append calls per flush phase — prevents runaway writes. */
|
|
65
|
+
export declare const DEFAULT_MAX_APPENDS_PER_FLUSH = 20;
|
|
66
|
+
/**
|
|
67
|
+
* Hard cap on agentic loop iterations inside {@link runMemoryFlush}.
|
|
68
|
+
*
|
|
69
|
+
* Each iteration = one model.invoke() followed by execution of any
|
|
70
|
+
* `memory_append` tool_calls it emits. Mirrors upstream's flush-plan
|
|
71
|
+
* loop cap; 8 is enough for ~2–3 reflections of batched notes while
|
|
72
|
+
* protecting against runaway cycles if the model refuses to stop.
|
|
73
|
+
*/
|
|
74
|
+
export declare const DEFAULT_MAX_FLUSH_ITERATIONS = 8;
|
|
75
|
+
/** Path prefix enforced on every append. Paths outside this are rejected. */
|
|
76
|
+
export declare const MEMORY_PATH_PREFIX = "memory/";
|
|
77
|
+
/** Tool names — kept as constants so server code + tests never drift. */
|
|
78
|
+
export declare const MEMORY_SEARCH_TOOL_NAME = "memory_search";
|
|
79
|
+
export declare const MEMORY_GET_TOOL_NAME = "memory_get";
|
|
80
|
+
export declare const MEMORY_APPEND_TOOL_NAME = "memory_append";
|
|
81
|
+
/**
|
|
82
|
+
* Mandatory-recall description — the single most load-bearing line in the
|
|
83
|
+
* whole memory system. Do not soften, shorten, or reword without an eval run.
|
|
84
|
+
*
|
|
85
|
+
* Ported VERBATIM from upstream `extensions/memory-core/src/tools.ts:186`.
|
|
86
|
+
* The wiki/corpus clause is retained even though Phase 1 doesn't ship
|
|
87
|
+
* compiled-wiki supplements — keeping the string identical means upstream's
|
|
88
|
+
* eval corpora remain drop-in valid.
|
|
89
|
+
*/
|
|
90
|
+
export declare const MEMORY_SEARCH_DESCRIPTION: string;
|
|
91
|
+
/**
|
|
92
|
+
* Ported VERBATIM from upstream `extensions/memory-core/src/tools.ts:322`.
|
|
93
|
+
*/
|
|
94
|
+
export declare const MEMORY_GET_DESCRIPTION: string;
|
|
95
|
+
/**
|
|
96
|
+
* `memory_append` tool description.
|
|
97
|
+
*
|
|
98
|
+
* Phase 1 historically wrote to a single date-keyed file
|
|
99
|
+
* (`memory/YYYY-MM-DD.md`), ported verbatim from upstream. That scheme
|
|
100
|
+
* is now replaced by an 8-path canonical whitelist — see
|
|
101
|
+
* {@link ./paths.MEMORY_ALL_PATHS}. The tool description no longer
|
|
102
|
+
* names a specific file; the flush-turn prompt renders the full rubric
|
|
103
|
+
* inline so the model sees every writable path at inference time.
|
|
104
|
+
*/
|
|
105
|
+
export declare const MEMORY_APPEND_DESCRIPTION: string;
|
|
106
|
+
/**
|
|
107
|
+
* Reply token that signals the flush turn produced no user-visible output.
|
|
108
|
+
* Ported VERBATIM from upstream `src/auto-reply/tokens.ts:4`.
|
|
109
|
+
*/
|
|
110
|
+
export declare const SILENT_REPLY_TOKEN = "NO_REPLY";
|
|
111
|
+
/**
|
|
112
|
+
* Placeholder replaced at flush time with the rendered path-rubric for
|
|
113
|
+
* the caller's scope. See `renderPathsRubric()` in `./paths.ts` and
|
|
114
|
+
* `resolveFlushPrompts()` in `../prompts/memoryFlushPrompt.ts`.
|
|
115
|
+
*
|
|
116
|
+
* Kept as a unique sentinel so `replaceAll` is safe even if the rubric
|
|
117
|
+
* content happens to contain regex metacharacters.
|
|
118
|
+
*/
|
|
119
|
+
export declare const FLUSH_PROMPT_RUBRIC_PLACEHOLDER = "{{MEMORY_PATHS_RUBRIC}}";
|
|
120
|
+
export declare const DEFAULT_MEMORY_FLUSH_PROMPT: string;
|
|
121
|
+
export declare const DEFAULT_MEMORY_FLUSH_SYSTEM_PROMPT: string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type EmbeddingProviderKind = 'bedrock' | 'openai';
|
|
2
|
+
export interface EmbeddingProvider {
|
|
3
|
+
readonly kind: EmbeddingProviderKind;
|
|
4
|
+
readonly model: string;
|
|
5
|
+
readonly dimensions: number;
|
|
6
|
+
embed(text: string): Promise<number[]>;
|
|
7
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Lazy singleton accessor. Same idiom as host's
|
|
11
|
+
* `getSharedSummaryBedrockClient()`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getMemoryEmbedder(): EmbeddingProvider;
|
|
14
|
+
/** Test hook — drops the cached embedder so the next call re-reads env. */
|
|
15
|
+
export declare function resetMemoryEmbedder(): void;
|