agentfootprint 2.11.1 → 2.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/core/Agent.js +81 -1238
  2. package/dist/core/Agent.js.map +1 -1
  3. package/dist/core/agent/AgentBuilder.js +489 -0
  4. package/dist/core/agent/AgentBuilder.js.map +1 -0
  5. package/dist/core/agent/buildAgentChart.js +227 -0
  6. package/dist/core/agent/buildAgentChart.js.map +1 -0
  7. package/dist/core/agent/buildToolRegistry.js +115 -0
  8. package/dist/core/agent/buildToolRegistry.js.map +1 -0
  9. package/dist/core/agent/stages/breakFinal.js +28 -0
  10. package/dist/core/agent/stages/breakFinal.js.map +1 -0
  11. package/dist/core/agent/stages/callLLM.js +129 -0
  12. package/dist/core/agent/stages/callLLM.js.map +1 -0
  13. package/dist/core/agent/stages/iterationStart.js +24 -0
  14. package/dist/core/agent/stages/iterationStart.js.map +1 -0
  15. package/dist/core/agent/stages/prepareFinal.js +45 -0
  16. package/dist/core/agent/stages/prepareFinal.js.map +1 -0
  17. package/dist/core/agent/stages/route.js +36 -0
  18. package/dist/core/agent/stages/route.js.map +1 -0
  19. package/dist/core/agent/stages/seed.js +95 -0
  20. package/dist/core/agent/stages/seed.js.map +1 -0
  21. package/dist/core/agent/stages/toolCalls.js +250 -0
  22. package/dist/core/agent/stages/toolCalls.js.map +1 -0
  23. package/dist/esm/core/Agent.js +83 -1239
  24. package/dist/esm/core/Agent.js.map +1 -1
  25. package/dist/esm/core/agent/AgentBuilder.js +485 -0
  26. package/dist/esm/core/agent/AgentBuilder.js.map +1 -0
  27. package/dist/esm/core/agent/buildAgentChart.js +223 -0
  28. package/dist/esm/core/agent/buildAgentChart.js.map +1 -0
  29. package/dist/esm/core/agent/buildToolRegistry.js +111 -0
  30. package/dist/esm/core/agent/buildToolRegistry.js.map +1 -0
  31. package/dist/esm/core/agent/stages/breakFinal.js +24 -0
  32. package/dist/esm/core/agent/stages/breakFinal.js.map +1 -0
  33. package/dist/esm/core/agent/stages/callLLM.js +125 -0
  34. package/dist/esm/core/agent/stages/callLLM.js.map +1 -0
  35. package/dist/esm/core/agent/stages/iterationStart.js +20 -0
  36. package/dist/esm/core/agent/stages/iterationStart.js.map +1 -0
  37. package/dist/esm/core/agent/stages/prepareFinal.js +41 -0
  38. package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -0
  39. package/dist/esm/core/agent/stages/route.js +32 -0
  40. package/dist/esm/core/agent/stages/route.js.map +1 -0
  41. package/dist/esm/core/agent/stages/seed.js +91 -0
  42. package/dist/esm/core/agent/stages/seed.js.map +1 -0
  43. package/dist/esm/core/agent/stages/toolCalls.js +246 -0
  44. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -0
  45. package/dist/types/core/Agent.d.ts +5 -333
  46. package/dist/types/core/Agent.d.ts.map +1 -1
  47. package/dist/types/core/agent/AgentBuilder.d.ts +348 -0
  48. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -0
  49. package/dist/types/core/agent/buildAgentChart.d.ts +74 -0
  50. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -0
  51. package/dist/types/core/agent/buildToolRegistry.d.ts +62 -0
  52. package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -0
  53. package/dist/types/core/agent/stages/breakFinal.d.ts +23 -0
  54. package/dist/types/core/agent/stages/breakFinal.d.ts.map +1 -0
  55. package/dist/types/core/agent/stages/callLLM.d.ts +54 -0
  56. package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -0
  57. package/dist/types/core/agent/stages/iterationStart.d.ts +16 -0
  58. package/dist/types/core/agent/stages/iterationStart.d.ts.map +1 -0
  59. package/dist/types/core/agent/stages/prepareFinal.d.ts +20 -0
  60. package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -0
  61. package/dist/types/core/agent/stages/route.d.ts +19 -0
  62. package/dist/types/core/agent/stages/route.d.ts.map +1 -0
  63. package/dist/types/core/agent/stages/seed.d.ts +54 -0
  64. package/dist/types/core/agent/stages/seed.d.ts.map +1 -0
  65. package/dist/types/core/agent/stages/toolCalls.d.ts +50 -0
  66. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -0
  67. package/package.json +1 -1
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ /**
3
+ * buildAgentChart — assemble the agent's full footprintjs FlowChart
4
+ * from stage functions + slot subflows + memory wiring.
5
+ *
6
+ * This is the "chart composition" that used to live inline in
7
+ * `Agent.buildChart()`. Extracted for v2.11.2 so:
8
+ *
9
+ * 1. Agent.ts focuses on Agent class lifecycle (constructor, run,
10
+ * attach, getSpec) instead of chart wiring details.
11
+ * 2. The reliability gate chart (v2.11.x) wires into ONE focused
12
+ * file rather than surgically into Agent.ts's 250-line composition
13
+ * block.
14
+ * 3. The composition is independently readable + reviewable —
15
+ * consumers building custom agent shapes have a reference.
16
+ *
17
+ * Chart shape:
18
+ *
19
+ * Seed
20
+ * → [memory READ subflows for each .memory()]
21
+ * → InjectionEngine (subflow)
22
+ * → SystemPrompt (slot subflow)
23
+ * → Messages (slot subflow)
24
+ * → Tools (slot subflow)
25
+ * → CacheDecision (subflow)
26
+ * → UpdateSkillHistory
27
+ * → CacheGate (decider) → ApplyMarkers / SkipCaching
28
+ * → IterationStart
29
+ * → CallLLM
30
+ * → Route (decider) → tool-calls (pausable) / final (subflow)
31
+ * |
32
+ * ┌────── PrepareFinal ▼
33
+ * ├──── [memory WRITE subflows]
34
+ * └──── BreakFinal ($break)
35
+ * loopTo(InjectionEngine)
36
+ *
37
+ * (When v2.11.x reliability is configured, the reliability gate chart
38
+ * mounts as a subflow between IterationStart and CallLLM with a
39
+ * TranslateFailFast stage after it. Lands in the next commit.)
40
+ */
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.buildAgentChart = void 0;
43
+ const advanced_1 = require("footprintjs/advanced");
44
+ const footprintjs_1 = require("footprintjs");
45
+ const conventions_js_1 = require("../../conventions.js");
46
+ const define_types_js_1 = require("../../memory/define.types.js");
47
+ const define_js_1 = require("../../memory/define.js");
48
+ const mountMemoryPipeline_js_1 = require("../../memory/wire/mountMemoryPipeline.js");
49
+ const breakFinal_js_1 = require("./stages/breakFinal.js");
50
+ const prepareFinal_js_1 = require("./stages/prepareFinal.js");
51
+ /**
52
+ * Build the agent's complete FlowChart from the supplied deps.
53
+ */
54
+ function buildAgentChart(deps) {
55
+ // ── Final-branch subflow ─────────────────────────────────────
56
+ // Split so memory-write subflows can mount BETWEEN setting
57
+ // finalContent and breaking the ReAct loop. PrepareFinal captures
58
+ // the turn payload; BreakFinal terminates the loop.
59
+ let finalBranchBuilder = (0, footprintjs_1.flowChart)('PrepareFinal', prepareFinal_js_1.prepareFinalStage, 'prepare-final', undefined, 'Capture turn payload (finalContent + newMessages)');
60
+ for (const m of deps.memories) {
61
+ if (m.write) {
62
+ finalBranchBuilder = (0, mountMemoryPipeline_js_1.mountMemoryWrite)(finalBranchBuilder, {
63
+ pipeline: {
64
+ read: (0, define_js_1.unwrapMemoryFlowChart)(m.read),
65
+ write: (0, define_js_1.unwrapMemoryFlowChart)(m.write),
66
+ },
67
+ identityKey: 'runIdentity',
68
+ turnNumberKey: 'turnNumber',
69
+ contextTokensKey: 'contextTokensRemaining',
70
+ newMessagesKey: 'newMessages',
71
+ writeSubflowId: `sf-memory-write-${m.id}`,
72
+ });
73
+ }
74
+ }
75
+ const finalBranchChart = finalBranchBuilder
76
+ .addFunction('BreakFinal', breakFinal_js_1.breakFinalStage, 'break-final', 'Terminate the ReAct loop')
77
+ .build();
78
+ // ── Main chart ──────────────────────────────────────────────
79
+ // Description prefix `Agent:` is a taxonomy marker — consumers
80
+ // (Lens + FlowchartRecorder) detect Agent-primitive subflows via
81
+ // this prefix and flag them as true agent boundaries (separate
82
+ // from LLMCall subflows which use `LLMCall:` prefix).
83
+ let builder = (0, footprintjs_1.flowChart)('Seed', deps.seed, conventions_js_1.STAGE_IDS.SEED, undefined, 'Agent: ReAct loop');
84
+ // Memory READ subflows — mounted between Seed and InjectionEngine
85
+ // for TURN_START timing (default). Each memory writes to its own
86
+ // scope key (`memoryInjection_${id}`) so multiple `.memory()`
87
+ // registrations layer without colliding.
88
+ for (const m of deps.memories) {
89
+ builder = (0, mountMemoryPipeline_js_1.mountMemoryRead)(builder, {
90
+ pipeline: {
91
+ read: (0, define_js_1.unwrapMemoryFlowChart)(m.read),
92
+ ...(m.write !== undefined && { write: (0, define_js_1.unwrapMemoryFlowChart)(m.write) }),
93
+ },
94
+ identityKey: 'runIdentity',
95
+ turnNumberKey: 'turnNumber',
96
+ contextTokensKey: 'contextTokensRemaining',
97
+ injectionKey: (0, define_types_js_1.memoryInjectionKey)(m.id),
98
+ readSubflowId: `sf-memory-read-${m.id}`,
99
+ });
100
+ }
101
+ builder = builder
102
+ // Injection Engine — evaluates every Injection's trigger once
103
+ // per iteration; writes activeInjections[] to parent scope for
104
+ // the slot subflows to consume. Skipped if no injections were
105
+ // registered (no observable difference, just one more no-op
106
+ // subflow boundary).
107
+ .addSubFlowChartNext(conventions_js_1.SUBFLOW_IDS.INJECTION_ENGINE, deps.injectionEngineSubflow, 'Injection Engine', {
108
+ inputMapper: (parent) => ({
109
+ iteration: parent.iteration,
110
+ userMessage: parent.userMessage,
111
+ history: parent.history,
112
+ lastToolResult: parent.lastToolResult,
113
+ activatedInjectionIds: parent.activatedInjectionIds ?? [],
114
+ }),
115
+ outputMapper: (sf) => ({ activeInjections: sf.activeInjections }),
116
+ // CRITICAL: footprintjs's default `applyOutputMapping`
117
+ // CONCATENATES arrays from subflow output with the parent's
118
+ // existing array values. Without `Replace`, the parent's
119
+ // `activeInjections` from iter N gets CONCATENATED with the
120
+ // subflow's iter N+1 fresh evaluation — producing
121
+ // 8 → 16 → 24 → 32 cumulative injections per turn.
122
+ arrayMerge: advanced_1.ArrayMergeMode.Replace,
123
+ })
124
+ .addSubFlowChartNext(conventions_js_1.SUBFLOW_IDS.SYSTEM_PROMPT, deps.systemPromptSubflow, 'System Prompt', {
125
+ inputMapper: (parent) => ({
126
+ userMessage: parent.userMessage,
127
+ iteration: parent.iteration,
128
+ activeInjections: parent.activeInjections,
129
+ }),
130
+ outputMapper: (sf) => ({ systemPromptInjections: sf.systemPromptInjections }),
131
+ arrayMerge: advanced_1.ArrayMergeMode.Replace,
132
+ })
133
+ .addSubFlowChartNext(conventions_js_1.SUBFLOW_IDS.MESSAGES, deps.messagesSubflow, 'Messages', {
134
+ inputMapper: (parent) => ({
135
+ messages: parent.history,
136
+ iteration: parent.iteration,
137
+ activeInjections: parent.activeInjections,
138
+ }),
139
+ outputMapper: (sf) => ({ messagesInjections: sf.messagesInjections }),
140
+ arrayMerge: advanced_1.ArrayMergeMode.Replace,
141
+ })
142
+ .addSubFlowChartNext(conventions_js_1.SUBFLOW_IDS.TOOLS, deps.toolsSubflow, 'Tools', {
143
+ inputMapper: (parent) => ({
144
+ iteration: parent.iteration,
145
+ activeInjections: parent.activeInjections,
146
+ // The slot subflow reads these to build the per-iteration
147
+ // ToolDispatchContext when an external `.toolProvider()` is
148
+ // configured. Without them the provider sees activeSkillId
149
+ // = undefined every iteration, breaking skillScopedTools etc.
150
+ activatedInjectionIds: parent.activatedInjectionIds,
151
+ runIdentity: parent.runIdentity,
152
+ }),
153
+ outputMapper: (sf) => ({
154
+ toolsInjections: sf.toolsInjections,
155
+ // Pass merged tool schemas (registry + injection-supplied)
156
+ // back up so callLLM uses the right list for THIS iteration.
157
+ dynamicToolSchemas: sf.toolSchemas,
158
+ }),
159
+ // Same array-concat hazard as InjectionEngine — replace, don't
160
+ // concatenate. Without Replace the deduped tool list re-acquires
161
+ // duplicates that providers reject.
162
+ arrayMerge: advanced_1.ArrayMergeMode.Replace,
163
+ })
164
+ // ── Cache layer (v2.6) ─────────────────────────────────────
165
+ .addSubFlowChartNext(conventions_js_1.SUBFLOW_IDS.CACHE_DECISION, deps.cacheDecisionSubflow, 'CacheDecision', {
166
+ inputMapper: (parent) => ({
167
+ activeInjections: parent.activeInjections ?? [],
168
+ iteration: parent.iteration ?? 1,
169
+ maxIterations: parent.maxIterations ?? deps.maxIterations,
170
+ userMessage: parent.userMessage ?? '',
171
+ ...(parent.lastToolResult !== undefined && {
172
+ lastToolName: parent.lastToolResult?.toolName,
173
+ }),
174
+ cumulativeInputTokens: parent.totalInputTokens ?? 0,
175
+ systemPromptCachePolicy: deps.systemPromptCachePolicy,
176
+ cachingDisabled: parent.cachingDisabled ?? false,
177
+ }),
178
+ outputMapper: (sf) => ({ cacheMarkers: sf.cacheMarkers }),
179
+ arrayMerge: advanced_1.ArrayMergeMode.Replace,
180
+ })
181
+ .addFunction('UpdateSkillHistory', deps.updateSkillHistoryStage, conventions_js_1.STAGE_IDS.UPDATE_SKILL_HISTORY, 'Update skill-history rolling window for CacheGate churn detection')
182
+ .addDeciderFunction('CacheGate', deps.cacheGateDecide, conventions_js_1.STAGE_IDS.CACHE_GATE, 'Gate cache-marker application: kill switch / hit-rate / skill-churn')
183
+ .addFunctionBranch(conventions_js_1.STAGE_IDS.APPLY_MARKERS, 'ApplyMarkers',
184
+ // Pass-through stage — markers stay in scope as-is.
185
+ // BuildLLMRequest (Phase 7+) reads them on the next stage.
186
+ () => undefined, 'Proceed with cache markers from CacheDecision')
187
+ .addFunctionBranch(conventions_js_1.STAGE_IDS.SKIP_CACHING, 'SkipCaching',
188
+ // Clear markers so BuildLLMRequest sees an empty list and
189
+ // makes the request unmodified.
190
+ (scope) => {
191
+ scope.cacheMarkers = [];
192
+ }, 'Skip caching this iteration')
193
+ .end()
194
+ .addFunction('IterationStart', deps.iterationStart, 'iteration-start', 'Iteration begin marker')
195
+ .addFunction('CallLLM', deps.callLLM, conventions_js_1.STAGE_IDS.CALL_LLM, 'LLM invocation')
196
+ .addDeciderFunction('Route', deps.routeDecider, conventions_js_1.SUBFLOW_IDS.ROUTE, 'ReAct routing')
197
+ .addPausableFunctionBranch('tool-calls', 'ToolCalls', deps.toolCallsHandler, 'Tool execution (pausable via pauseHere)')
198
+ .addSubFlowChartBranch('final', finalBranchChart, 'Final', {
199
+ // Pass through the read-only state the sub-chart needs;
200
+ // OMIT keys the sub-chart writes (finalContent, newMessages)
201
+ // — passing those via inputMapper would freeze them as args.
202
+ inputMapper: (parent) => {
203
+ const { finalContent: _f, newMessages: _nm, ...rest } = parent;
204
+ void _f;
205
+ void _nm;
206
+ return rest;
207
+ },
208
+ outputMapper: (sf) => ({
209
+ finalContent: sf.finalContent,
210
+ }),
211
+ // BreakFinal's $break() must reach the outer loopTo so the
212
+ // ReAct iteration terminates; without this the inner break
213
+ // only exits the sub-chart and the outer loop continues.
214
+ propagateBreak: true,
215
+ })
216
+ .setDefault('final')
217
+ .end()
218
+ // Dynamic ReAct: loop back to the InjectionEngine so EVERY iteration
219
+ // re-evaluates triggers (rule predicates, on-tool-return,
220
+ // llm-activated) against the freshest context (the just-appended
221
+ // tool result). Without this, the InjectionEngine runs ONCE per
222
+ // turn — quietly breaking the framework's "Dynamic ReAct" claim.
223
+ .loopTo(conventions_js_1.SUBFLOW_IDS.INJECTION_ENGINE);
224
+ return builder.build();
225
+ }
226
+ exports.buildAgentChart = buildAgentChart;
227
+ //# sourceMappingURL=buildAgentChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAgentChart.js","sourceRoot":"","sources":["../../../src/core/agent/buildAgentChart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * buildToolRegistry — pure function that composes the agent's
4
+ * augmented tool registry from three sources:
5
+ *
6
+ * 1. **Static registry** — tools registered via `.tool()`. Always
7
+ * visible to the LLM; always executable.
8
+ * 2. **`read_skill`** — auto-attached when ≥1 Skill is registered.
9
+ * Activation tool for LLM-guided Skills.
10
+ * 3. **Skill-supplied tools** (`Skill.inject.tools[]`) — visible
11
+ * only when the Skill is active (filtered by tools-slot subflow);
12
+ * MUST always be in the executor registry so when the LLM calls
13
+ * one, the tool-calls handler can dispatch.
14
+ *
15
+ * Tool-name uniqueness is enforced across all three sources at build
16
+ * time. The LLM only sees `tool.schema.name` (no ids), so names ARE
17
+ * the runtime dispatch key — collisions break the LLM's ability to
18
+ * call the right tool. Throw early instead of subtly shadowing.
19
+ *
20
+ * **Block C runtime — `autoActivate: 'currentSkill'` semantics:**
21
+ * When a skill's `defineSkill({ autoActivate: 'currentSkill' })` is
22
+ * set, its tools are EXCLUDED from the static registry. They flow
23
+ * into the LLM's tool list ONLY through `dynamicSchemas` (the
24
+ * buildToolsSlot path that reads activeInjections), which means
25
+ * they're visible ONLY on iterations after the skill is activated by
26
+ * `read_skill('id')`. Without this, the LLM sees every skill's tools
27
+ * on every iteration and the per-skill-narrowing autoActivate
28
+ * promised in `defineSkill` doesn't actually narrow anything. Skills
29
+ * WITHOUT autoActivate keep the v2.4 behavior (tools always visible)
30
+ * for back-compat.
31
+ *
32
+ * **autoActivate dispatch invariant:** autoActivate skill tools live
33
+ * OUTSIDE the LLM-visible registry (so they don't pollute the
34
+ * per-iteration tool list before the skill activates), but they MUST
35
+ * still be findable by the dispatch handler — the LLM calls them by
36
+ * name once the skill is active, and dispatch looks up by name. We
37
+ * add them to the dispatch map (`registryByName`) so `lookupTool`
38
+ * resolves correctly.
39
+ */
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.buildToolRegistry = void 0;
42
+ const skillTools_js_1 = require("../../lib/injection-engine/skillTools.js");
43
+ /**
44
+ * Compose the augmented tool registry from the static `.tool()`
45
+ * registry + the agent's injections (skills only). Throws on tool-
46
+ * name collisions across sources.
47
+ */
48
+ function buildToolRegistry(registry, injections) {
49
+ const skills = injections.filter((i) => i.flavor === 'skill');
50
+ // Collect skill tools, deduping by name when the SAME Tool reference
51
+ // is shared across skills. Different Tool implementations under the
52
+ // same name throws (already validated upstream by
53
+ // validateToolNameUniqueness) — we keep the runtime check as
54
+ // belt-and-suspenders.
55
+ const skillToolEntries = [];
56
+ const sharedSkillTools = new Map();
57
+ for (const skill of skills) {
58
+ const meta = skill.metadata;
59
+ const isAutoActivate = meta?.autoActivate === 'currentSkill';
60
+ const toolsFromSkill = skill.inject.tools ?? [];
61
+ for (const tool of toolsFromSkill) {
62
+ const name = tool.schema.name;
63
+ const existing = sharedSkillTools.get(name);
64
+ if (existing) {
65
+ if (existing !== tool) {
66
+ throw new Error(`Agent: tool name '${name}' is declared by multiple skills with different ` +
67
+ `Tool implementations. Skills MAY share the SAME Tool reference; they may ` +
68
+ `NOT register different functions under the same name.`);
69
+ }
70
+ continue; // dedupe — same reference already added
71
+ }
72
+ sharedSkillTools.set(name, tool);
73
+ // autoActivate skills: their tools come ONLY through dynamicSchemas
74
+ // (buildToolsSlot.ts pulls them from activeInjections.inject.tools
75
+ // when the skill is active). Don't pre-load in the static registry.
76
+ if (isAutoActivate)
77
+ continue;
78
+ skillToolEntries.push({ name, tool });
79
+ }
80
+ }
81
+ // buildReadSkillTool returns undefined when skills is empty; the length
82
+ // check below short-circuits so the non-null assertion is safe.
83
+ const readSkillEntries = skills.length > 0 ? [{ name: 'read_skill', tool: (0, skillTools_js_1.buildReadSkillTool)(skills) }] : [];
84
+ const augmentedRegistry = [
85
+ ...registry,
86
+ ...readSkillEntries,
87
+ ...skillToolEntries,
88
+ ];
89
+ // Final cross-source name-uniqueness check: static .tool() vs
90
+ // read_skill vs (deduped) skill tools. Catches collisions BETWEEN
91
+ // sources (e.g., a static .tool('foo') colliding with a Skill's foo).
92
+ const seenNames = new Set();
93
+ for (const entry of augmentedRegistry) {
94
+ if (seenNames.has(entry.name)) {
95
+ throw new Error(`Agent: duplicate tool name '${entry.name}'. Tool names must be unique ` +
96
+ `across .tool() registrations and Skills' inject.tools (after deduping ` +
97
+ `same-reference shares across skills). The LLM dispatches by name; ` +
98
+ `collisions break tool routing.`);
99
+ }
100
+ seenNames.add(entry.name);
101
+ }
102
+ const registryByName = new Map(augmentedRegistry.map((e) => [e.name, e.tool]));
103
+ // autoActivate skill tools live outside augmentedRegistry but MUST
104
+ // be findable by name at dispatch time. Add them to the dispatch
105
+ // map so `lookupTool` resolves correctly when the skill activates.
106
+ for (const [name, tool] of sharedSkillTools.entries()) {
107
+ if (!registryByName.has(name)) {
108
+ registryByName.set(name, tool);
109
+ }
110
+ }
111
+ const toolSchemas = augmentedRegistry.map((e) => e.tool.schema);
112
+ return { augmentedRegistry, registryByName, toolSchemas };
113
+ }
114
+ exports.buildToolRegistry = buildToolRegistry;
115
+ //# sourceMappingURL=buildToolRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildToolRegistry.js","sourceRoot":"","sources":["../../../src/core/agent/buildToolRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * breakFinal — terminal stage of the agent's "Final" branch subflow.
4
+ *
5
+ * Fires after the (optional) memory-write subflows have persisted the
6
+ * (user, assistant) pair. `$break()` stops execution before the outer
7
+ * loopTo can re-enter the ReAct loop, ending the iteration cleanly.
8
+ * Returns `scope.finalContent` so the parent's `outputMapper` can
9
+ * surface it as the agent's response.
10
+ *
11
+ * Mounted in the final-branch subflow (built in `buildAgentChart`) as
12
+ * the LAST stage. The parent agent chart mounts the final-branch
13
+ * subflow under the Route decider's `'final'` branch with
14
+ * `propagateBreak: true`, so this $break terminates the outer ReAct
15
+ * loop too.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.breakFinalStage = void 0;
19
+ /**
20
+ * Pure stage function — no dependencies, no closure over Agent state.
21
+ * Exported as a const, not a factory, since there's nothing to inject.
22
+ */
23
+ const breakFinalStage = (scope) => {
24
+ scope.$break();
25
+ return scope.finalContent;
26
+ };
27
+ exports.breakFinalStage = breakFinalStage;
28
+ //# sourceMappingURL=breakFinal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakFinal.js","sourceRoot":"","sources":["../../../../src/core/agent/stages/breakFinal.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAKH;;;GAGG;AACI,MAAM,eAAe,GAAG,CAAC,KAA6B,EAAU,EAAE;IACvE,KAAK,CAAC,MAAM,EAAE,CAAC;IACf,OAAO,KAAK,CAAC,YAAY,CAAC;AAC5B,CAAC,CAAC;AAHW,QAAA,eAAe,mBAG1B"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ /**
3
+ * callLLM — the LLM-invocation stage of the agent's chart.
4
+ *
5
+ * Reads the assembled prompt + messages from scope (populated by the
6
+ * upstream slot subflows: SystemPrompt, Messages, Tools, CacheDecision,
7
+ * CacheGate). Calls `provider.stream()` if available (token streaming
8
+ * with per-chunk events) else falls back to `provider.complete()`.
9
+ * Writes the response to scope (`llmLatestContent`, `llmLatestToolCalls`,
10
+ * cumulative tokens) for the downstream Route decider to read.
11
+ *
12
+ * Emits `agentfootprint.stream.llm_start` + `llm_end` brackets for
13
+ * observability adapters and per-chunk `stream.token` events during
14
+ * streaming. Emits `cost.tick` via `emitCostTick` when a `pricingTable`
15
+ * is configured.
16
+ *
17
+ * Factory signature so the chart-build-time provider/model/etc. deps
18
+ * are explicit. The `toolSchemas` value is late-bound via a getter
19
+ * because tool schema composition completes after the seed factory is
20
+ * built but before the chart actually runs.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.buildCallLLMStage = void 0;
24
+ const typedEmit_js_1 = require("../../../recorders/core/typedEmit.js");
25
+ const cost_js_1 = require("../../cost.js");
26
+ /**
27
+ * Build the callLLM stage function. Captures the LLM provider + model
28
+ * config + cache strategy via the deps object; everything per-iteration
29
+ * comes from scope.
30
+ */
31
+ function buildCallLLMStage(deps) {
32
+ return async (scope) => {
33
+ const systemPromptInjections = scope.systemPromptInjections ?? [];
34
+ // `scope.messagesInjections` is read by ContextRecorder for
35
+ // observability; the LLM-wire path now reads scope.history directly.
36
+ const iteration = scope.iteration;
37
+ const systemPrompt = systemPromptInjections
38
+ .map((r) => r.rawContent ?? '')
39
+ .filter((s) => s.length > 0)
40
+ .join('\n\n');
41
+ // Read the LLM message stream from `scope.history` directly. The
42
+ // `messagesInjections` projection is for observability — it
43
+ // flattens InjectionRecords for event reporting and doesn't carry
44
+ // the full LLM-protocol shape (assistant `toolCalls[]`, etc.). For
45
+ // Anthropic's API contract we need the original LLMMessage with
46
+ // `toolCalls` intact so tool_use → tool_result correlation survives.
47
+ const messages = scope.history ?? [];
48
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.stream.llm_start', {
49
+ iteration,
50
+ provider: deps.provider.name,
51
+ model: deps.model,
52
+ systemPromptChars: systemPrompt.length,
53
+ messagesCount: messages.length,
54
+ toolsCount: deps.toolSchemas.length,
55
+ ...(deps.temperature !== undefined && { temperature: deps.temperature }),
56
+ });
57
+ const startMs = Date.now();
58
+ // Use dynamic schemas — registry tools + injection-supplied tools
59
+ // (Skills' `inject.tools` when their Injection is active). Falls
60
+ // back to the static schemas at startup before the tools slot has
61
+ // run for the first time.
62
+ const activeToolSchemas = scope.dynamicToolSchemas ?? deps.toolSchemas;
63
+ const baseRequest = {
64
+ ...(systemPrompt.length > 0 && { systemPrompt }),
65
+ messages,
66
+ ...(activeToolSchemas.length > 0 && { tools: activeToolSchemas }),
67
+ model: deps.model,
68
+ ...(deps.temperature !== undefined && { temperature: deps.temperature }),
69
+ ...(deps.maxTokens !== undefined && { maxTokens: deps.maxTokens }),
70
+ };
71
+ // v2.6+ — call cache strategy to attach provider-specific cache
72
+ // hints. CacheGate has already routed (apply-markers / no-markers)
73
+ // and populated scope.cacheMarkers accordingly. Strategy.prepareRequest
74
+ // is a pass-through for empty markers.
75
+ const cacheMarkers = scope.cacheMarkers ?? [];
76
+ const cachePrepared = await deps.cacheStrategy.prepareRequest(baseRequest, cacheMarkers, {
77
+ iteration,
78
+ iterationsRemaining: Math.max(0, deps.maxIterations - iteration),
79
+ recentHitRate: scope.recentHitRate,
80
+ cachingDisabled: scope.cachingDisabled ?? false,
81
+ });
82
+ const llmRequest = cachePrepared.request;
83
+ // Streaming-first: when the provider implements `stream()` we
84
+ // consume chunk-by-chunk so consumers see tokens as they arrive
85
+ // instead of waiting for the full LLM call to finish. Each
86
+ // non-terminal chunk fires `agentfootprint.stream.token`. The
87
+ // terminal chunk SHOULD carry the authoritative `LLMResponse`;
88
+ // when it doesn't (older providers, partial implementations) we
89
+ // fall back to `complete()` for the authoritative payload —
90
+ // keeping the ReAct loop deterministic.
91
+ let response;
92
+ if (deps.provider.stream) {
93
+ for await (const chunk of deps.provider.stream(llmRequest)) {
94
+ if (chunk.done) {
95
+ if (chunk.response)
96
+ response = chunk.response;
97
+ break;
98
+ }
99
+ if (chunk.content.length > 0) {
100
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.stream.token', {
101
+ iteration,
102
+ tokenIndex: chunk.tokenIndex,
103
+ content: chunk.content,
104
+ });
105
+ }
106
+ }
107
+ }
108
+ if (!response) {
109
+ // No `stream()` OR stream finished without a response payload.
110
+ response = await deps.provider.complete(llmRequest);
111
+ }
112
+ const durationMs = Date.now() - startMs;
113
+ scope.totalInputTokens = scope.totalInputTokens + response.usage.input;
114
+ scope.totalOutputTokens = scope.totalOutputTokens + response.usage.output;
115
+ scope.llmLatestContent = response.content;
116
+ scope.llmLatestToolCalls = response.toolCalls;
117
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.stream.llm_end', {
118
+ iteration,
119
+ content: response.content,
120
+ toolCallCount: response.toolCalls.length,
121
+ usage: response.usage,
122
+ stopReason: response.stopReason,
123
+ durationMs,
124
+ });
125
+ (0, cost_js_1.emitCostTick)(scope, deps.pricingTable, deps.costBudget, deps.model, response.usage);
126
+ };
127
+ }
128
+ exports.buildCallLLMStage = buildCallLLMStage;
129
+ //# sourceMappingURL=callLLM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callLLM.js","sourceRoot":"","sources":["../../../../src/core/agent/stages/callLLM.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * iterationStart — per-iteration marker stage.
4
+ *
5
+ * Emits `agentfootprint.agent.iteration_start` so observability adapters
6
+ * + recorders can bracket each ReAct iteration. Fires AFTER the slot
7
+ * subflows (SystemPrompt, Messages, Tools, CacheDecision, CacheGate)
8
+ * have produced this iteration's prompt assembly and BEFORE CallLLM.
9
+ *
10
+ * `turnIndex: 0` is intentional — the agent currently runs ONE turn per
11
+ * `agent.run()`. The turn index is reserved for future multi-turn
12
+ * orchestration; iteration index is the per-iteration counter.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.iterationStartStage = void 0;
16
+ const typedEmit_js_1 = require("../../../recorders/core/typedEmit.js");
17
+ const iterationStartStage = (scope) => {
18
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.agent.iteration_start', {
19
+ turnIndex: 0,
20
+ iterIndex: scope.iteration,
21
+ });
22
+ };
23
+ exports.iterationStartStage = iterationStartStage;
24
+ //# sourceMappingURL=iterationStart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iterationStart.js","sourceRoot":"","sources":["../../../../src/core/agent/stages/iterationStart.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAGH,uEAAiE;AAG1D,MAAM,mBAAmB,GAAG,CAAC,KAA6B,EAAQ,EAAE;IACzE,IAAA,wBAAS,EAAC,KAAK,EAAE,sCAAsC,EAAE;QACvD,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC,CAAC;AACL,CAAC,CAAC;AALW,QAAA,mBAAmB,uBAK9B"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * prepareFinal — first stage of the agent's "Final" branch subflow.
4
+ *
5
+ * Captures the turn payload (`finalContent` from the LLM's latest
6
+ * content; `newMessages` as the `[user, assistant]` pair the memory-
7
+ * write subflows persist) and emits the per-turn observability
8
+ * brackets (`iteration_end`, `turn_end`).
9
+ *
10
+ * Mounted as the FIRST stage of the final-branch subflow built in
11
+ * `buildAgentChart`. Subsequent memory-write subflows mount AFTER this
12
+ * stage so they have `newMessages` available; `breakFinal` is the
13
+ * terminal stage that stops the ReAct loop.
14
+ *
15
+ * Pure function — no closure over Agent class state. Imported and
16
+ * passed directly to `flowChart(...)` in buildAgentChart.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.prepareFinalStage = void 0;
20
+ const typedEmit_js_1 = require("../../../recorders/core/typedEmit.js");
21
+ const prepareFinalStage = (scope) => {
22
+ const iteration = scope.iteration;
23
+ scope.finalContent = scope.llmLatestContent;
24
+ // The turn payload memory writes persist: the user's message
25
+ // paired with the agent's final answer.
26
+ scope.newMessages = [
27
+ { role: 'user', content: scope.userMessage },
28
+ { role: 'assistant', content: scope.finalContent },
29
+ ];
30
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.agent.iteration_end', {
31
+ turnIndex: 0,
32
+ iterIndex: iteration,
33
+ toolCallCount: 0,
34
+ });
35
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.agent.turn_end', {
36
+ turnIndex: 0,
37
+ finalContent: scope.finalContent,
38
+ totalInputTokens: scope.totalInputTokens,
39
+ totalOutputTokens: scope.totalOutputTokens,
40
+ iterationCount: iteration,
41
+ durationMs: Date.now() - scope.turnStartMs,
42
+ });
43
+ };
44
+ exports.prepareFinalStage = prepareFinalStage;
45
+ //# sourceMappingURL=prepareFinal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepareFinal.js","sourceRoot":"","sources":["../../../../src/core/agent/stages/prepareFinal.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAGH,uEAAiE;AAG1D,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAAQ,EAAE;IACvE,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC5C,6DAA6D;IAC7D,wCAAwC;IACxC,KAAK,CAAC,WAAW,GAAG;QAClB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE;QAC5C,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE;KACnD,CAAC;IAEF,IAAA,wBAAS,EAAC,KAAK,EAAE,oCAAoC,EAAE;QACrD,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,SAAS;QACpB,aAAa,EAAE,CAAC;KACjB,CAAC,CAAC;IACH,IAAA,wBAAS,EAAC,KAAK,EAAE,+BAA+B,EAAE;QAChD,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,cAAc,EAAE,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,WAAW;KAC3C,CAAC,CAAC;AACL,CAAC,CAAC;AAvBW,QAAA,iBAAiB,qBAuB5B"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * route — decider that branches the ReAct loop into 'tool-calls' or 'final'.
4
+ *
5
+ * Runs after CallLLM. If the LLM returned tool calls AND we haven't hit
6
+ * `maxIterations`, route to the tool execution branch (which loops back
7
+ * to PromptBuilder). Otherwise route to the final-branch subflow which
8
+ * persists memory writes and breaks the loop.
9
+ *
10
+ * Emits `agentfootprint.agent.route_decided` with the chosen branch +
11
+ * a human-readable rationale (visible in narrative + observability).
12
+ *
13
+ * Pure function — no closure over Agent class state. Imported and
14
+ * passed directly to `addDeciderFunction(...)` in buildAgentChart.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.routeDeciderStage = void 0;
18
+ const typedEmit_js_1 = require("../../../recorders/core/typedEmit.js");
19
+ const routeDeciderStage = (scope) => {
20
+ const toolCalls = scope.llmLatestToolCalls;
21
+ const iteration = scope.iteration;
22
+ const chosen = toolCalls.length > 0 && iteration < scope.maxIterations ? 'tool-calls' : 'final';
23
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.agent.route_decided', {
24
+ turnIndex: 0,
25
+ iterIndex: iteration,
26
+ chosen,
27
+ rationale: chosen === 'tool-calls'
28
+ ? `LLM requested ${toolCalls.length} tool call(s)`
29
+ : iteration >= scope.maxIterations
30
+ ? 'maxIterations reached — forcing final'
31
+ : 'LLM produced no tool calls — final answer',
32
+ });
33
+ return chosen;
34
+ };
35
+ exports.routeDeciderStage = routeDeciderStage;
36
+ //# sourceMappingURL=route.js.map