@seanhogg/builderforce-memory 2026.7.14 → 2026.9.28
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/README.md +10 -0
- package/dist/bridges/AnthropicBridge.d.ts +9 -1
- package/dist/bridges/AnthropicBridge.d.ts.map +1 -1
- package/dist/bridges/AnthropicBridge.js +58 -2
- package/dist/bridges/AnthropicBridge.js.map +1 -1
- package/dist/bridges/CachingBridge.d.ts +9 -1
- package/dist/bridges/CachingBridge.d.ts.map +1 -1
- package/dist/bridges/CachingBridge.js +24 -1
- package/dist/bridges/CachingBridge.js.map +1 -1
- package/dist/bridges/OpenAIBridge.d.ts +4 -1
- package/dist/bridges/OpenAIBridge.d.ts.map +1 -1
- package/dist/bridges/OpenAIBridge.js +40 -2
- package/dist/bridges/OpenAIBridge.js.map +1 -1
- package/dist/bridges/SemanticCachingBridge.d.ts +8 -1
- package/dist/bridges/SemanticCachingBridge.d.ts.map +1 -1
- package/dist/bridges/SemanticCachingBridge.js +26 -1
- package/dist/bridges/SemanticCachingBridge.js.map +1 -1
- package/dist/bridges/TransformerBridge.d.ts +13 -0
- package/dist/bridges/TransformerBridge.d.ts.map +1 -1
- package/dist/bridges/VertexAIBridge.d.ts +102 -0
- package/dist/bridges/VertexAIBridge.d.ts.map +1 -0
- package/dist/bridges/VertexAIBridge.js +224 -0
- package/dist/bridges/VertexAIBridge.js.map +1 -0
- package/dist/bridges/index.d.ts +3 -1
- package/dist/bridges/index.d.ts.map +1 -1
- package/dist/bridges/index.js +1 -0
- package/dist/bridges/index.js.map +1 -1
- package/dist/eval/EvalHarness.d.ts +37 -0
- package/dist/eval/EvalHarness.d.ts.map +1 -0
- package/dist/eval/EvalHarness.js +178 -0
- package/dist/eval/EvalHarness.js.map +1 -0
- package/dist/eval/graders.d.ts +76 -0
- package/dist/eval/graders.d.ts.map +1 -0
- package/dist/eval/graders.js +168 -0
- package/dist/eval/graders.js.map +1 -0
- package/dist/eval/index.d.ts +26 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +26 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/types.d.ts +97 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +5 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/evermind/contract.d.ts +40 -0
- package/dist/evermind/contract.d.ts.map +1 -0
- package/dist/evermind/contract.js +13 -0
- package/dist/evermind/contract.js.map +1 -0
- package/dist/evermind/index.d.ts +15 -0
- package/dist/evermind/index.d.ts.map +1 -0
- package/dist/evermind/index.js +4 -0
- package/dist/evermind/index.js.map +1 -0
- package/dist/evermind/memoryBlock.d.ts +7 -0
- package/dist/evermind/memoryBlock.d.ts.map +1 -0
- package/dist/evermind/memoryBlock.js +37 -0
- package/dist/evermind/memoryBlock.js.map +1 -0
- package/dist/evermind/recall.d.ts +48 -0
- package/dist/evermind/recall.d.ts.map +1 -0
- package/dist/evermind/recall.js +105 -0
- package/dist/evermind/recall.js.map +1 -0
- package/dist/index.d.ts +18 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/ingest/IngestionPipeline.d.ts +95 -0
- package/dist/ingest/IngestionPipeline.d.ts.map +1 -0
- package/dist/ingest/IngestionPipeline.js +295 -0
- package/dist/ingest/IngestionPipeline.js.map +1 -0
- package/dist/ingest/index.d.ts +10 -0
- package/dist/ingest/index.d.ts.map +1 -0
- package/dist/ingest/index.js +8 -0
- package/dist/ingest/index.js.map +1 -0
- package/dist/ingest/parsers.d.ts +53 -0
- package/dist/ingest/parsers.d.ts.map +1 -0
- package/dist/ingest/parsers.js +306 -0
- package/dist/ingest/parsers.js.map +1 -0
- package/dist/ingest/types.d.ts +114 -0
- package/dist/ingest/types.d.ts.map +1 -0
- package/dist/ingest/types.js +19 -0
- package/dist/ingest/types.js.map +1 -0
- package/dist/memory/MemoryStore.d.ts +33 -0
- package/dist/memory/MemoryStore.d.ts.map +1 -1
- package/dist/memory/MemoryStore.js +29 -3
- package/dist/memory/MemoryStore.js.map +1 -1
- package/dist/memory/index.d.ts +1 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/orchestration/AgentGraph.d.ts +104 -0
- package/dist/orchestration/AgentGraph.d.ts.map +1 -0
- package/dist/orchestration/AgentGraph.js +364 -0
- package/dist/orchestration/AgentGraph.js.map +1 -0
- package/dist/orchestration/checkpoint.d.ts +58 -0
- package/dist/orchestration/checkpoint.d.ts.map +1 -0
- package/dist/orchestration/checkpoint.js +92 -0
- package/dist/orchestration/checkpoint.js.map +1 -0
- package/dist/orchestration/index.d.ts +14 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +10 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/patterns.d.ts +159 -0
- package/dist/orchestration/patterns.d.ts.map +1 -0
- package/dist/orchestration/patterns.js +371 -0
- package/dist/orchestration/patterns.js.map +1 -0
- package/dist/orchestration/types.d.ts +146 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/orchestration/types.js +20 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/rag/EnterpriseRetriever.d.ts +114 -0
- package/dist/rag/EnterpriseRetriever.d.ts.map +1 -0
- package/dist/rag/EnterpriseRetriever.js +240 -0
- package/dist/rag/EnterpriseRetriever.js.map +1 -0
- package/dist/rag/index.d.ts +6 -0
- package/dist/rag/index.d.ts.map +1 -0
- package/dist/rag/index.js +5 -0
- package/dist/rag/index.js.map +1 -0
- package/dist/retrieval/bm25.d.ts +48 -1
- package/dist/retrieval/bm25.d.ts.map +1 -1
- package/dist/retrieval/bm25.js +59 -13
- package/dist/retrieval/bm25.js.map +1 -1
- package/dist/retrieval/index.d.ts +2 -2
- package/dist/retrieval/index.d.ts.map +1 -1
- package/dist/retrieval/index.js +1 -1
- package/dist/retrieval/index.js.map +1 -1
- package/dist/runtime/SSMRuntime.d.ts +1 -1
- package/dist/runtime/SSMRuntime.d.ts.map +1 -1
- package/dist/telemetry/InstrumentedBridge.d.ts +62 -0
- package/dist/telemetry/InstrumentedBridge.d.ts.map +1 -0
- package/dist/telemetry/InstrumentedBridge.js +120 -0
- package/dist/telemetry/InstrumentedBridge.js.map +1 -0
- package/dist/telemetry/MetricsRegistry.d.ts +88 -0
- package/dist/telemetry/MetricsRegistry.d.ts.map +1 -0
- package/dist/telemetry/MetricsRegistry.js +167 -0
- package/dist/telemetry/MetricsRegistry.js.map +1 -0
- package/dist/telemetry/Tracer.d.ts +137 -0
- package/dist/telemetry/Tracer.d.ts.map +1 -0
- package/dist/telemetry/Tracer.js +244 -0
- package/dist/telemetry/Tracer.js.map +1 -0
- package/dist/telemetry/exporters.d.ts +68 -0
- package/dist/telemetry/exporters.d.ts.map +1 -0
- package/dist/telemetry/exporters.js +145 -0
- package/dist/telemetry/exporters.js.map +1 -0
- package/dist/telemetry/index.d.ts +19 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +12 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/pricing.d.ts +74 -0
- package/dist/telemetry/pricing.d.ts.map +1 -0
- package/dist/telemetry/pricing.js +98 -0
- package/dist/telemetry/pricing.js.map +1 -0
- package/dist/telemetry/traceparent.d.ts +50 -0
- package/dist/telemetry/traceparent.d.ts.map +1 -0
- package/dist/telemetry/traceparent.js +77 -0
- package/dist/telemetry/traceparent.js.map +1 -0
- package/dist/telemetry/types.d.ts +90 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +17 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/vectorstore/MemoryVectorStore.d.ts +72 -0
- package/dist/vectorstore/MemoryVectorStore.d.ts.map +1 -0
- package/dist/vectorstore/MemoryVectorStore.js +205 -0
- package/dist/vectorstore/MemoryVectorStore.js.map +1 -0
- package/dist/vectorstore/RestVectorStore.d.ts +79 -0
- package/dist/vectorstore/RestVectorStore.d.ts.map +1 -0
- package/dist/vectorstore/RestVectorStore.js +170 -0
- package/dist/vectorstore/RestVectorStore.js.map +1 -0
- package/dist/vectorstore/dialects.d.ts +101 -0
- package/dist/vectorstore/dialects.d.ts.map +1 -0
- package/dist/vectorstore/dialects.js +618 -0
- package/dist/vectorstore/dialects.js.map +1 -0
- package/dist/vectorstore/filter.d.ts +42 -0
- package/dist/vectorstore/filter.d.ts.map +1 -0
- package/dist/vectorstore/filter.js +132 -0
- package/dist/vectorstore/filter.js.map +1 -0
- package/dist/vectorstore/index.d.ts +15 -0
- package/dist/vectorstore/index.d.ts.map +1 -0
- package/dist/vectorstore/index.js +11 -0
- package/dist/vectorstore/index.js.map +1 -0
- package/dist/vectorstore/types.d.ts +151 -0
- package/dist/vectorstore/types.d.ts.map +1 -0
- package/dist/vectorstore/types.js +30 -0
- package/dist/vectorstore/types.js.map +1 -0
- package/package.json +39 -5
- package/src/bridges/AnthropicBridge.ts +68 -3
- package/src/bridges/CachingBridge.ts +28 -2
- package/src/bridges/OpenAIBridge.ts +48 -3
- package/src/bridges/SemanticCachingBridge.ts +29 -2
- package/src/bridges/TransformerBridge.ts +16 -0
- package/src/bridges/VertexAIBridge.ts +297 -0
- package/src/bridges/index.ts +3 -1
- package/src/eval/EvalHarness.ts +214 -0
- package/src/eval/graders.ts +218 -0
- package/src/eval/index.ts +26 -0
- package/src/eval/types.ts +107 -0
- package/src/evermind/contract.ts +39 -0
- package/src/evermind/index.ts +18 -0
- package/src/evermind/memoryBlock.ts +38 -0
- package/src/evermind/recall.ts +122 -0
- package/src/index.ts +232 -0
- package/src/ingest/IngestionPipeline.ts +378 -0
- package/src/ingest/index.ts +46 -0
- package/src/ingest/parsers.ts +318 -0
- package/src/ingest/types.ts +116 -0
- package/src/memory/MemoryStore.ts +55 -3
- package/src/memory/index.ts +1 -1
- package/src/orchestration/AgentGraph.ts +462 -0
- package/src/orchestration/checkpoint.ts +129 -0
- package/src/orchestration/index.ts +63 -0
- package/src/orchestration/patterns.ts +532 -0
- package/src/orchestration/types.ts +128 -0
- package/src/rag/EnterpriseRetriever.ts +348 -0
- package/src/rag/index.ts +18 -0
- package/src/retrieval/bm25.ts +71 -13
- package/src/retrieval/index.ts +2 -2
- package/src/telemetry/InstrumentedBridge.ts +152 -0
- package/src/telemetry/MetricsRegistry.ts +263 -0
- package/src/telemetry/Tracer.ts +310 -0
- package/src/telemetry/exporters.ts +187 -0
- package/src/telemetry/index.ts +56 -0
- package/src/telemetry/pricing.ts +129 -0
- package/src/telemetry/traceparent.ts +89 -0
- package/src/telemetry/types.ts +105 -0
- package/src/vectorstore/MemoryVectorStore.ts +250 -0
- package/src/vectorstore/RestVectorStore.ts +236 -0
- package/src/vectorstore/dialects.ts +702 -0
- package/src/vectorstore/filter.ts +148 -0
- package/src/vectorstore/index.ts +53 -0
- package/src/vectorstore/types.ts +149 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* orchestration/patterns.ts — ReAct, self-reflection, hierarchical delegation.
|
|
3
|
+
*
|
|
4
|
+
* These are the three patterns enterprise agent work actually reduces to, and each
|
|
5
|
+
* is a small graph rather than a bespoke loop, so they compose: a supervisor's
|
|
6
|
+
* worker can be a ReAct agent, and a ReAct agent's answer can be routed through a
|
|
7
|
+
* reflection pass. That composability is why they are built on {@link AgentGraph}
|
|
8
|
+
* instead of as three independent classes.
|
|
9
|
+
*
|
|
10
|
+
* The bridge port is plain text in, text out, so tool use is expressed as a strict
|
|
11
|
+
* textual protocol the model is instructed to follow, and violations are handled
|
|
12
|
+
* as data (an observation telling the model what it got wrong) rather than as
|
|
13
|
+
* exceptions. A model that emits a malformed action must be able to recover on the
|
|
14
|
+
* next turn; throwing would end the run over a formatting slip.
|
|
15
|
+
*/
|
|
16
|
+
import { AgentGraph, appendReducer, sumReducer } from './AgentGraph.js';
|
|
17
|
+
import { END, START } from './types.js';
|
|
18
|
+
/** Renders a transcript for a text-completion bridge. */
|
|
19
|
+
export function renderTranscript(turns) {
|
|
20
|
+
return turns
|
|
21
|
+
.map((turn) => {
|
|
22
|
+
if (turn.role === 'tool')
|
|
23
|
+
return `Observation (${turn.name ?? 'tool'}): ${turn.content}`;
|
|
24
|
+
if (turn.role === 'assistant')
|
|
25
|
+
return turn.content;
|
|
26
|
+
if (turn.role === 'system')
|
|
27
|
+
return turn.content;
|
|
28
|
+
return `Question: ${turn.content}`;
|
|
29
|
+
})
|
|
30
|
+
.join('\n');
|
|
31
|
+
}
|
|
32
|
+
export function renderToolCatalog(tools) {
|
|
33
|
+
return tools
|
|
34
|
+
.map((tool) => {
|
|
35
|
+
const params = tool.parameters
|
|
36
|
+
? ` Input fields: ${Object.entries(tool.parameters).map(([k, v]) => `${k} (${v})`).join(', ')}.`
|
|
37
|
+
: '';
|
|
38
|
+
return `- ${tool.name}: ${tool.description}${params}`;
|
|
39
|
+
})
|
|
40
|
+
.join('\n');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parses one ReAct turn.
|
|
44
|
+
*
|
|
45
|
+
* Tolerant on purpose: models drift on whitespace, casing and code fences far more
|
|
46
|
+
* often than they drift on intent, and a parser that rejects `**Action:**` burns a
|
|
47
|
+
* turn for no reason. Genuinely unparseable output returns `malformed` with a
|
|
48
|
+
* message that is fed back as an observation.
|
|
49
|
+
*/
|
|
50
|
+
export function parseReactTurn(text) {
|
|
51
|
+
const clean = text.replace(/\*\*/g, '').trim();
|
|
52
|
+
const finalMatch = /final\s*answer\s*:\s*([\s\S]*)$/i.exec(clean);
|
|
53
|
+
const actionMatch = /action\s*:\s*([^\n]+)/i.exec(clean);
|
|
54
|
+
const thoughtMatch = /thought\s*:\s*([^\n]+)/i.exec(clean);
|
|
55
|
+
const thought = thoughtMatch?.[1]?.trim();
|
|
56
|
+
// A turn containing both is a model hedging; the final answer wins only when it
|
|
57
|
+
// appears AFTER the action, matching the order the protocol asks for.
|
|
58
|
+
if (finalMatch && (!actionMatch || (finalMatch.index > actionMatch.index))) {
|
|
59
|
+
return {
|
|
60
|
+
kind: 'final',
|
|
61
|
+
...(thought ? { thought } : {}),
|
|
62
|
+
answer: (finalMatch[1] ?? '').trim(),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (!actionMatch) {
|
|
66
|
+
return {
|
|
67
|
+
kind: 'malformed',
|
|
68
|
+
...(thought ? { thought } : {}),
|
|
69
|
+
problem: 'No "Action:" or "Final Answer:" line was present.',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const tool = actionMatch[1].trim().replace(/[.`]+$/, '');
|
|
73
|
+
const inputMatch = /action\s*input\s*:\s*([\s\S]*?)(?:\n\s*(?:thought|action|observation|final answer)\s*:|$)/i
|
|
74
|
+
.exec(clean);
|
|
75
|
+
const rawInput = (inputMatch?.[1] ?? '').trim().replace(/^```(?:json)?/i, '').replace(/```$/, '').trim();
|
|
76
|
+
let input = {};
|
|
77
|
+
if (rawInput) {
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(rawInput);
|
|
80
|
+
input = parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
81
|
+
? parsed
|
|
82
|
+
// A bare scalar is a common and reasonable shape for single-argument
|
|
83
|
+
// tools; wrapping it beats rejecting the turn.
|
|
84
|
+
: { input: parsed };
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
input = { input: rawInput };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { kind: 'action', ...(thought ? { thought } : {}), tool, input };
|
|
91
|
+
}
|
|
92
|
+
export const REACT_PROTOCOL = 'Work in cycles. Each reply must be EITHER:\n' +
|
|
93
|
+
'Thought: <your reasoning>\nAction: <tool name>\nAction Input: <JSON object>\n' +
|
|
94
|
+
'OR, when you can answer:\nThought: <your reasoning>\nFinal Answer: <the answer>\n' +
|
|
95
|
+
'Use one action per reply and wait for the Observation before continuing.';
|
|
96
|
+
/**
|
|
97
|
+
* ReAct: interleaved reasoning and tool use.
|
|
98
|
+
*
|
|
99
|
+
* Two nodes and a conditional edge — `reason` produces a thought plus either an
|
|
100
|
+
* action or a final answer; `act` executes the tool and appends an observation;
|
|
101
|
+
* the edge routes back to `reason` or to END. The iteration cap is enforced in the
|
|
102
|
+
* routing rather than trusted to the model, because "decide when to stop" is the
|
|
103
|
+
* one judgement an unconverged agent is worst at.
|
|
104
|
+
*/
|
|
105
|
+
export function createReactAgent(opts) {
|
|
106
|
+
const maxIterations = Math.max(1, opts.maxIterations ?? 6);
|
|
107
|
+
const toolsByName = new Map(opts.tools.map((t) => [t.name, t]));
|
|
108
|
+
const catalog = renderToolCatalog(opts.tools);
|
|
109
|
+
const systemPrompt = [
|
|
110
|
+
opts.systemPrompt ?? 'You are a careful analyst that uses tools to gather evidence before answering.',
|
|
111
|
+
`Available tools:\n${catalog}`,
|
|
112
|
+
REACT_PROTOCOL,
|
|
113
|
+
].join('\n\n');
|
|
114
|
+
const graph = new AgentGraph({
|
|
115
|
+
name: 'react-agent',
|
|
116
|
+
channels: {
|
|
117
|
+
turns: { reducer: appendReducer, default: () => [] },
|
|
118
|
+
toolCalls: { reducer: sumReducer, default: () => 0 },
|
|
119
|
+
done: { default: () => false },
|
|
120
|
+
answer: { default: () => '' },
|
|
121
|
+
task: { default: () => '' },
|
|
122
|
+
},
|
|
123
|
+
recursionLimit: maxIterations * 2 + 2,
|
|
124
|
+
...(opts.tracer ? { tracer: opts.tracer } : {}),
|
|
125
|
+
...(opts.checkpointer ? { checkpointer: opts.checkpointer } : {}),
|
|
126
|
+
});
|
|
127
|
+
graph.addNode('reason', async (state, ctx) => {
|
|
128
|
+
const transcript = renderTranscript([
|
|
129
|
+
{ role: 'user', content: state.task },
|
|
130
|
+
...state.turns,
|
|
131
|
+
]);
|
|
132
|
+
const remaining = maxIterations - state.toolCalls;
|
|
133
|
+
const pressure = remaining <= 1
|
|
134
|
+
? '\n\nYou have no tool calls left. Reply with a Final Answer using what you already know.'
|
|
135
|
+
: '';
|
|
136
|
+
const reply = await opts.bridge.generate(`${transcript}${pressure}`, {
|
|
137
|
+
systemPrompt,
|
|
138
|
+
...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
|
|
139
|
+
...(opts.model !== undefined ? { model: opts.model } : {}),
|
|
140
|
+
});
|
|
141
|
+
const parsed = parseReactTurn(reply);
|
|
142
|
+
ctx.span?.setAttributes({ 'react.turn_kind': parsed.kind, 'react.tool': parsed.tool ?? '' });
|
|
143
|
+
if (parsed.kind === 'final') {
|
|
144
|
+
return {
|
|
145
|
+
turns: [{ role: 'assistant', content: reply }],
|
|
146
|
+
answer: parsed.answer ?? '',
|
|
147
|
+
done: true,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return { turns: [{ role: 'assistant', content: reply }], done: false };
|
|
151
|
+
});
|
|
152
|
+
graph.addNode('act', async (state, ctx) => {
|
|
153
|
+
const lastAssistant = [...state.turns].reverse().find((t) => t.role === 'assistant');
|
|
154
|
+
const parsed = parseReactTurn(lastAssistant?.content ?? '');
|
|
155
|
+
if (parsed.kind === 'malformed') {
|
|
156
|
+
// Fed back as an observation, not thrown: the model gets one clear
|
|
157
|
+
// chance to correct its formatting rather than killing the run.
|
|
158
|
+
return {
|
|
159
|
+
turns: [{
|
|
160
|
+
role: 'tool',
|
|
161
|
+
name: 'protocol',
|
|
162
|
+
content: `Your reply could not be parsed (${parsed.problem}). Reply using the exact format.`,
|
|
163
|
+
}],
|
|
164
|
+
toolCalls: 1,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const tool = toolsByName.get(parsed.tool);
|
|
168
|
+
if (!tool) {
|
|
169
|
+
return {
|
|
170
|
+
turns: [{
|
|
171
|
+
role: 'tool',
|
|
172
|
+
name: 'protocol',
|
|
173
|
+
content: `Unknown tool "${parsed.tool}". Choose one of: ${[...toolsByName.keys()].join(', ')}.`,
|
|
174
|
+
}],
|
|
175
|
+
toolCalls: 1,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const span = ctx.span?.child(`tool.${tool.name}`, { kind: 'tool' });
|
|
179
|
+
try {
|
|
180
|
+
const observation = await tool.run(parsed.input ?? {});
|
|
181
|
+
span?.setAttribute('tool.result_chars', observation.length);
|
|
182
|
+
span?.end('ok');
|
|
183
|
+
return {
|
|
184
|
+
turns: [{ role: 'tool', name: tool.name, content: observation }],
|
|
185
|
+
toolCalls: 1,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
// A failing tool is an observation too. An agent that can read "the API
|
|
190
|
+
// returned 503" can retry or route around it; one that crashes cannot.
|
|
191
|
+
span?.fail(err);
|
|
192
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
193
|
+
return {
|
|
194
|
+
turns: [{ role: 'tool', name: tool.name, content: `Tool failed: ${message}` }],
|
|
195
|
+
toolCalls: 1,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
graph.addEdge(START, 'reason');
|
|
200
|
+
graph.addConditionalEdges('reason', (state) => {
|
|
201
|
+
if (state.done)
|
|
202
|
+
return END;
|
|
203
|
+
return state.toolCalls >= maxIterations ? END : 'act';
|
|
204
|
+
});
|
|
205
|
+
graph.addEdge('act', 'reason');
|
|
206
|
+
return graph.compile();
|
|
207
|
+
}
|
|
208
|
+
export const DEFAULT_CRITIC_PROMPT = 'You are a demanding reviewer. Judge the draft against the task on correctness, ' +
|
|
209
|
+
'completeness and evidence. List concrete, actionable defects. ' +
|
|
210
|
+
'End your reply with exactly one verdict line: "VERDICT: APPROVED" or "VERDICT: REVISE".';
|
|
211
|
+
/**
|
|
212
|
+
* Generate → critique → revise, bounded.
|
|
213
|
+
*
|
|
214
|
+
* Reflection earns its cost only when the critic is allowed to be harsh and the
|
|
215
|
+
* loop is allowed to stop: an unbounded critic converges on nitpicking, and a
|
|
216
|
+
* critic that cannot say APPROVED doubles spend for no quality gain. Both limits
|
|
217
|
+
* are enforced here rather than requested in the prompt.
|
|
218
|
+
*/
|
|
219
|
+
export function createReflectionAgent(opts) {
|
|
220
|
+
const maxRevisions = Math.max(0, opts.maxRevisions ?? 2);
|
|
221
|
+
const isAcceptable = opts.isAcceptable ?? ((critique) => /verdict\s*:\s*approved/i.test(critique));
|
|
222
|
+
const graph = new AgentGraph({
|
|
223
|
+
name: 'reflection-agent',
|
|
224
|
+
channels: {
|
|
225
|
+
history: { reducer: appendReducer, default: () => [] },
|
|
226
|
+
revisions: { default: () => 0 },
|
|
227
|
+
accepted: { default: () => false },
|
|
228
|
+
draft: { default: () => '' },
|
|
229
|
+
critique: { default: () => '' },
|
|
230
|
+
task: { default: () => '' },
|
|
231
|
+
},
|
|
232
|
+
recursionLimit: (maxRevisions + 1) * 2 + 2,
|
|
233
|
+
...(opts.tracer ? { tracer: opts.tracer } : {}),
|
|
234
|
+
...(opts.checkpointer ? { checkpointer: opts.checkpointer } : {}),
|
|
235
|
+
});
|
|
236
|
+
const generate = async (state) => {
|
|
237
|
+
const prompt = state.draft
|
|
238
|
+
? `Task: ${state.task}\n\nPrevious draft:\n${state.draft}\n\nReviewer feedback:\n${state.critique}\n\nProduce an improved draft that resolves every point.`
|
|
239
|
+
: `Task: ${state.task}\n\nProduce your best draft.`;
|
|
240
|
+
const draft = await opts.bridge.generate(prompt, {
|
|
241
|
+
systemPrompt: opts.generatorPrompt ?? 'You produce precise, well-evidenced work.',
|
|
242
|
+
...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
|
|
243
|
+
...(opts.model !== undefined ? { model: opts.model } : {}),
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
draft,
|
|
247
|
+
history: [draft],
|
|
248
|
+
...(state.draft ? { revisions: state.revisions + 1 } : {}),
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
graph.addNode('generate', generate);
|
|
252
|
+
graph.addNode('critique', async (state, ctx) => {
|
|
253
|
+
const critique = await opts.bridge.generate(`Task: ${state.task}\n\nDraft:\n${state.draft}\n\nReview it.`, {
|
|
254
|
+
systemPrompt: opts.criticPrompt ?? DEFAULT_CRITIC_PROMPT,
|
|
255
|
+
...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
|
|
256
|
+
...(opts.model !== undefined ? { model: opts.model } : {}),
|
|
257
|
+
});
|
|
258
|
+
const accepted = isAcceptable(critique);
|
|
259
|
+
ctx.span?.setAttribute('reflection.accepted', accepted);
|
|
260
|
+
return { critique, accepted };
|
|
261
|
+
});
|
|
262
|
+
graph.addEdge(START, 'generate');
|
|
263
|
+
graph.addEdge('generate', 'critique');
|
|
264
|
+
graph.addConditionalEdges('critique', (state) => {
|
|
265
|
+
if (state.accepted)
|
|
266
|
+
return END;
|
|
267
|
+
return state.revisions >= maxRevisions ? END : 'generate';
|
|
268
|
+
});
|
|
269
|
+
return graph.compile();
|
|
270
|
+
}
|
|
271
|
+
export const FINISH = 'FINISH';
|
|
272
|
+
/**
|
|
273
|
+
* A supervisor that delegates to named workers and then composes the answer.
|
|
274
|
+
*
|
|
275
|
+
* Hierarchical delegation is worth its coordination overhead exactly when workers
|
|
276
|
+
* hold context the supervisor should not — a different tool set, a different
|
|
277
|
+
* corpus, a different tenant's data. Each worker returns a RESULT rather than its
|
|
278
|
+
* transcript, which is what keeps the supervisor's context from growing into the
|
|
279
|
+
* sum of everything its workers read.
|
|
280
|
+
*/
|
|
281
|
+
export function createSupervisor(opts) {
|
|
282
|
+
const maxHandoffs = Math.max(1, opts.maxHandoffs ?? 5);
|
|
283
|
+
const workersByName = new Map(opts.workers.map((w) => [w.name, w]));
|
|
284
|
+
const roster = opts.workers.map((w) => `- ${w.name}: ${w.description}`).join('\n');
|
|
285
|
+
const systemPrompt = [
|
|
286
|
+
opts.systemPrompt ?? 'You are a supervisor coordinating specialist workers.',
|
|
287
|
+
`Workers:\n${roster}`,
|
|
288
|
+
`Reply with exactly one line: "NEXT: <worker name>" to delegate, or "NEXT: ${FINISH}" ` +
|
|
289
|
+
'followed by a line "ANSWER: <the final answer>" when you have enough to answer.',
|
|
290
|
+
].join('\n\n');
|
|
291
|
+
const graph = new AgentGraph({
|
|
292
|
+
name: 'supervisor',
|
|
293
|
+
channels: {
|
|
294
|
+
turns: { reducer: appendReducer, default: () => [] },
|
|
295
|
+
handoffs: { reducer: sumReducer, default: () => 0 },
|
|
296
|
+
next: { default: () => '' },
|
|
297
|
+
answer: { default: () => '' },
|
|
298
|
+
task: { default: () => '' },
|
|
299
|
+
},
|
|
300
|
+
recursionLimit: maxHandoffs * 2 + 2,
|
|
301
|
+
...(opts.tracer ? { tracer: opts.tracer } : {}),
|
|
302
|
+
...(opts.checkpointer ? { checkpointer: opts.checkpointer } : {}),
|
|
303
|
+
});
|
|
304
|
+
graph.addNode('supervisor', async (state, ctx) => {
|
|
305
|
+
const transcript = renderTranscript([{ role: 'user', content: state.task }, ...state.turns]);
|
|
306
|
+
const pressure = state.handoffs >= maxHandoffs
|
|
307
|
+
? `\n\nYou have used all delegations. Reply with "NEXT: ${FINISH}" and your ANSWER.`
|
|
308
|
+
: '';
|
|
309
|
+
const reply = await opts.bridge.generate(`${transcript}${pressure}`, {
|
|
310
|
+
systemPrompt,
|
|
311
|
+
...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
|
|
312
|
+
...(opts.model !== undefined ? { model: opts.model } : {}),
|
|
313
|
+
});
|
|
314
|
+
const nextMatch = /next\s*:\s*([^\n]+)/i.exec(reply.replace(/\*\*/g, ''));
|
|
315
|
+
const answerMatch = /answer\s*:\s*([\s\S]*)$/i.exec(reply.replace(/\*\*/g, ''));
|
|
316
|
+
const requested = nextMatch?.[1]?.trim().replace(/[.`]+$/, '') ?? FINISH;
|
|
317
|
+
// An unknown worker name resolves to FINISH rather than throwing: a
|
|
318
|
+
// supervisor that hallucinates a worker should degrade to answering, not
|
|
319
|
+
// crash a run that may already have useful worker results in state.
|
|
320
|
+
const next = workersByName.has(requested) ? requested : FINISH;
|
|
321
|
+
ctx.span?.setAttributes({ 'supervisor.requested': requested, 'supervisor.next': next });
|
|
322
|
+
return {
|
|
323
|
+
turns: [{ role: 'assistant', content: reply }],
|
|
324
|
+
next,
|
|
325
|
+
...(next === FINISH ? { answer: (answerMatch?.[1] ?? reply).trim() } : {}),
|
|
326
|
+
};
|
|
327
|
+
});
|
|
328
|
+
graph.addNode('delegate', async (state, ctx) => {
|
|
329
|
+
const worker = workersByName.get(state.next);
|
|
330
|
+
if (!worker)
|
|
331
|
+
return { next: FINISH };
|
|
332
|
+
const span = ctx.span?.child(`worker.${worker.name}`, { kind: 'agent' });
|
|
333
|
+
try {
|
|
334
|
+
const result = await worker.run(state.task, { transcript: state.turns });
|
|
335
|
+
span?.setAttribute('worker.result_chars', result.length);
|
|
336
|
+
span?.end('ok');
|
|
337
|
+
return {
|
|
338
|
+
turns: [{ role: 'tool', name: worker.name, content: result }],
|
|
339
|
+
handoffs: 1,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
span?.fail(err);
|
|
344
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
345
|
+
return {
|
|
346
|
+
turns: [{ role: 'tool', name: worker.name, content: `Worker failed: ${message}` }],
|
|
347
|
+
handoffs: 1,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
graph.addEdge(START, 'supervisor');
|
|
352
|
+
graph.addConditionalEdges('supervisor', (state) => {
|
|
353
|
+
if (state.next === FINISH)
|
|
354
|
+
return END;
|
|
355
|
+
return state.handoffs >= maxHandoffs ? END : 'delegate';
|
|
356
|
+
});
|
|
357
|
+
graph.addEdge('delegate', 'supervisor');
|
|
358
|
+
return graph.compile();
|
|
359
|
+
}
|
|
360
|
+
/** Adapts a ReAct agent into a {@link Worker}, so hierarchies nest. */
|
|
361
|
+
export function asWorker(name, description, graph) {
|
|
362
|
+
return {
|
|
363
|
+
name,
|
|
364
|
+
description,
|
|
365
|
+
run: async (task) => {
|
|
366
|
+
const result = await graph.invoke({ task });
|
|
367
|
+
return result.state.answer || 'The worker produced no answer.';
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/orchestration/patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* orchestration/types.ts — the multi-agent vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* Multi-agent systems fail in production for reasons that are all state problems,
|
|
5
|
+
* not prompting problems: two agents write the same key and one silently wins; a
|
|
6
|
+
* loop never terminates; a run dies at minute nine of a twelve-minute job with no
|
|
7
|
+
* way to resume; nobody can say which agent produced the claim in the final
|
|
8
|
+
* answer. So state is modelled explicitly here — as CHANNELS with declared merge
|
|
9
|
+
* semantics — rather than left as an object everyone mutates.
|
|
10
|
+
*
|
|
11
|
+
* The execution model is supersteps (Pregel): a frontier of nodes runs, their
|
|
12
|
+
* updates are merged through the channel reducers, and the next frontier is
|
|
13
|
+
* computed from the edges. Concurrent fan-out is therefore the default rather than
|
|
14
|
+
* a special case, and "two agents wrote the same channel" has a defined answer
|
|
15
|
+
* instead of a race.
|
|
16
|
+
*/
|
|
17
|
+
import type { Span } from '../telemetry/Tracer.js';
|
|
18
|
+
/** Reserved node names: the graph's entry and terminal sentinels. */
|
|
19
|
+
export declare const START = "__start__";
|
|
20
|
+
export declare const END = "__end__";
|
|
21
|
+
export type GraphState = Record<string, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Merges a channel's existing value with an update produced this superstep.
|
|
24
|
+
* Called once per writing node, in node-name order, so a fan-out merge is
|
|
25
|
+
* deterministic and reproducible from a checkpoint.
|
|
26
|
+
*/
|
|
27
|
+
export type ChannelReducer<V = unknown> = (current: V | undefined, update: V) => V;
|
|
28
|
+
export interface ChannelSpec<V = unknown> {
|
|
29
|
+
/** Omit for last-write-wins. */
|
|
30
|
+
reducer?: ChannelReducer<V>;
|
|
31
|
+
/** Initial value factory, used when the channel is absent from the input. */
|
|
32
|
+
default?: () => V;
|
|
33
|
+
}
|
|
34
|
+
export type ChannelSpecs<S extends GraphState> = {
|
|
35
|
+
[K in keyof S]?: ChannelSpec<S[K]>;
|
|
36
|
+
};
|
|
37
|
+
export interface NodeContext<S extends GraphState> {
|
|
38
|
+
/** Superstep number, from 0. */
|
|
39
|
+
step: number;
|
|
40
|
+
/** The node's own span — pass it as `parent` so model calls nest correctly. */
|
|
41
|
+
span?: Span;
|
|
42
|
+
/** Emits a custom event into the run's stream (progress, intermediate output). */
|
|
43
|
+
emit(event: {
|
|
44
|
+
type: string;
|
|
45
|
+
data?: unknown;
|
|
46
|
+
}): void;
|
|
47
|
+
/** Cooperative cancellation — long nodes should check it between calls. */
|
|
48
|
+
signal?: AbortSignal;
|
|
49
|
+
/** Read-only view of the merged state at the start of this superstep. */
|
|
50
|
+
state: Readonly<S>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A node returns a PARTIAL state update, never a whole state. Returning the whole
|
|
54
|
+
* object is how a fan-out silently discards a sibling's work.
|
|
55
|
+
*/
|
|
56
|
+
export type NodeFn<S extends GraphState> = (state: Readonly<S>, ctx: NodeContext<S>) => Promise<Partial<S> | void> | Partial<S> | void;
|
|
57
|
+
/** Chooses the next node(s). Return {@link END} to finish this branch. */
|
|
58
|
+
export type EdgeCondition<S extends GraphState> = (state: Readonly<S>, ctx: {
|
|
59
|
+
step: number;
|
|
60
|
+
}) => string | string[] | Promise<string | string[]>;
|
|
61
|
+
export type GraphEvent<S extends GraphState> = {
|
|
62
|
+
type: 'step-start';
|
|
63
|
+
step: number;
|
|
64
|
+
frontier: string[];
|
|
65
|
+
} | {
|
|
66
|
+
type: 'node-start';
|
|
67
|
+
step: number;
|
|
68
|
+
node: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: 'node-end';
|
|
71
|
+
step: number;
|
|
72
|
+
node: string;
|
|
73
|
+
update: Partial<S>;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'node-error';
|
|
76
|
+
step: number;
|
|
77
|
+
node: string;
|
|
78
|
+
error: string;
|
|
79
|
+
} | {
|
|
80
|
+
type: 'custom';
|
|
81
|
+
step: number;
|
|
82
|
+
node: string;
|
|
83
|
+
event: {
|
|
84
|
+
type: string;
|
|
85
|
+
data?: unknown;
|
|
86
|
+
};
|
|
87
|
+
} | {
|
|
88
|
+
type: 'step-end';
|
|
89
|
+
step: number;
|
|
90
|
+
state: S;
|
|
91
|
+
} | {
|
|
92
|
+
type: 'interrupt';
|
|
93
|
+
step: number;
|
|
94
|
+
before: string[];
|
|
95
|
+
state: S;
|
|
96
|
+
} | {
|
|
97
|
+
type: 'end';
|
|
98
|
+
step: number;
|
|
99
|
+
state: S;
|
|
100
|
+
reason: GraphEndReason;
|
|
101
|
+
};
|
|
102
|
+
export type GraphEndReason =
|
|
103
|
+
/** Every branch reached END. */
|
|
104
|
+
'complete'
|
|
105
|
+
/** The recursion limit tripped — a cycle that did not converge. */
|
|
106
|
+
| 'recursion-limit'
|
|
107
|
+
/** Paused at an `interruptBefore` node, awaiting a human. */
|
|
108
|
+
| 'interrupted'
|
|
109
|
+
/** A node threw and the graph is configured to stop on error. */
|
|
110
|
+
| 'error';
|
|
111
|
+
export interface GraphRunResult<S extends GraphState> {
|
|
112
|
+
state: S;
|
|
113
|
+
reason: GraphEndReason;
|
|
114
|
+
steps: number;
|
|
115
|
+
/** Node names executed, in order — the audit trail of a run. */
|
|
116
|
+
path: string[];
|
|
117
|
+
traceId?: string;
|
|
118
|
+
/** Present when `reason` is `'interrupted'`; resume by passing it back. */
|
|
119
|
+
checkpointId?: string;
|
|
120
|
+
error?: string;
|
|
121
|
+
}
|
|
122
|
+
/** One durable snapshot of a run between supersteps. */
|
|
123
|
+
export interface Checkpoint<S extends GraphState> {
|
|
124
|
+
id: string;
|
|
125
|
+
threadId: string;
|
|
126
|
+
step: number;
|
|
127
|
+
state: S;
|
|
128
|
+
/** Nodes queued to run next — without this, resume cannot know where it was. */
|
|
129
|
+
frontier: string[];
|
|
130
|
+
path: string[];
|
|
131
|
+
createdAt: number;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Durable state between supersteps. An in-process implementation ships here; a
|
|
135
|
+
* production deployment points this at Durable Objects, Firestore or Postgres, at
|
|
136
|
+
* which point a twelve-minute multi-agent run survives a deploy.
|
|
137
|
+
*/
|
|
138
|
+
export interface Checkpointer<S extends GraphState = GraphState> {
|
|
139
|
+
save(checkpoint: Checkpoint<S>): Promise<void>;
|
|
140
|
+
/** Latest checkpoint for a thread, or a specific one by id. */
|
|
141
|
+
load(threadId: string, checkpointId?: string): Promise<Checkpoint<S> | undefined>;
|
|
142
|
+
/** History, newest first — the basis for time-travel debugging. */
|
|
143
|
+
list(threadId: string): Promise<Checkpoint<S>[]>;
|
|
144
|
+
clear(threadId: string): Promise<void>;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/orchestration/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* orchestration/types.ts — the multi-agent vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* Multi-agent systems fail in production for reasons that are all state problems,
|
|
5
|
+
* not prompting problems: two agents write the same key and one silently wins; a
|
|
6
|
+
* loop never terminates; a run dies at minute nine of a twelve-minute job with no
|
|
7
|
+
* way to resume; nobody can say which agent produced the claim in the final
|
|
8
|
+
* answer. So state is modelled explicitly here — as CHANNELS with declared merge
|
|
9
|
+
* semantics — rather than left as an object everyone mutates.
|
|
10
|
+
*
|
|
11
|
+
* The execution model is supersteps (Pregel): a frontier of nodes runs, their
|
|
12
|
+
* updates are merged through the channel reducers, and the next frontier is
|
|
13
|
+
* computed from the edges. Concurrent fan-out is therefore the default rather than
|
|
14
|
+
* a special case, and "two agents wrote the same channel" has a defined answer
|
|
15
|
+
* instead of a race.
|
|
16
|
+
*/
|
|
17
|
+
/** Reserved node names: the graph's entry and terminal sentinels. */
|
|
18
|
+
export const START = '__start__';
|
|
19
|
+
export const END = '__end__';
|
|
20
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/orchestration/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,qEAAqE;AACrE,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;AACjC,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAC"}
|