agentfootprint 1.7.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CLAUDE.md +2 -2
  2. package/dist/concepts/Conditional.js +260 -0
  3. package/dist/concepts/Conditional.js.map +1 -0
  4. package/dist/concepts/index.js +4 -1
  5. package/dist/concepts/index.js.map +1 -1
  6. package/dist/esm/concepts/Conditional.js +255 -0
  7. package/dist/esm/concepts/Conditional.js.map +1 -0
  8. package/dist/esm/concepts/index.js +1 -0
  9. package/dist/esm/concepts/index.js.map +1 -1
  10. package/dist/esm/index.js +1 -1
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/esm/patterns/index.js +18 -0
  13. package/dist/esm/patterns/index.js.map +1 -0
  14. package/dist/esm/patterns/mapReduce.js +60 -0
  15. package/dist/esm/patterns/mapReduce.js.map +1 -0
  16. package/dist/esm/patterns/planExecute.js +43 -0
  17. package/dist/esm/patterns/planExecute.js.map +1 -0
  18. package/dist/esm/patterns/reflexion.js +58 -0
  19. package/dist/esm/patterns/reflexion.js.map +1 -0
  20. package/dist/esm/patterns/treeOfThoughts.js +71 -0
  21. package/dist/esm/patterns/treeOfThoughts.js.map +1 -0
  22. package/dist/esm/patterns.barrel.js +8 -0
  23. package/dist/esm/patterns.barrel.js.map +1 -0
  24. package/dist/index.js +4 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/patterns/index.js +25 -0
  27. package/dist/patterns/index.js.map +1 -0
  28. package/dist/patterns/mapReduce.js +64 -0
  29. package/dist/patterns/mapReduce.js.map +1 -0
  30. package/dist/patterns/planExecute.js +47 -0
  31. package/dist/patterns/planExecute.js.map +1 -0
  32. package/dist/patterns/reflexion.js +62 -0
  33. package/dist/patterns/reflexion.js.map +1 -0
  34. package/dist/patterns/treeOfThoughts.js +75 -0
  35. package/dist/patterns/treeOfThoughts.js.map +1 -0
  36. package/dist/patterns.barrel.js +24 -0
  37. package/dist/patterns.barrel.js.map +1 -0
  38. package/dist/types/concepts/Conditional.d.ts +120 -0
  39. package/dist/types/concepts/Conditional.d.ts.map +1 -0
  40. package/dist/types/concepts/index.d.ts +2 -0
  41. package/dist/types/concepts/index.d.ts.map +1 -1
  42. package/dist/types/index.d.ts +2 -2
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/patterns/index.d.ts +22 -0
  45. package/dist/types/patterns/index.d.ts.map +1 -0
  46. package/dist/types/patterns/mapReduce.d.ts +65 -0
  47. package/dist/types/patterns/mapReduce.d.ts.map +1 -0
  48. package/dist/types/patterns/planExecute.d.ts +49 -0
  49. package/dist/types/patterns/planExecute.d.ts.map +1 -0
  50. package/dist/types/patterns/reflexion.d.ts +65 -0
  51. package/dist/types/patterns/reflexion.d.ts.map +1 -0
  52. package/dist/types/patterns/treeOfThoughts.d.ts +65 -0
  53. package/dist/types/patterns/treeOfThoughts.d.ts.map +1 -0
  54. package/dist/types/patterns.barrel.d.ts +8 -0
  55. package/dist/types/patterns.barrel.d.ts.map +1 -0
  56. package/package.json +9 -1
package/CLAUDE.md CHANGED
@@ -5,7 +5,7 @@ This is the agentfootprint library — the explainable agent framework. Build AI
5
5
  ## Core Principles
6
6
 
7
7
  - **Adapter-swap testing.** Every concept uses `LLMProvider` — swap `mock([...])` for `createProvider(anthropic(...))` with zero code changes. $0 test runs, deterministic assertions.
8
- - **Concept ladder.** Five concepts, each a flowchart: LLMCall < RAG < Agent < FlowChart < Swarm. Each adds exactly one capability.
8
+ - **Concept ladder.** Seven concepts, each a flowchart: LLMCall (leaf), RAG (augmented leaf), Agent (ReAct cycle), Swarm (LLM dispatch), FlowChart (sequence), Parallel (fan-out), Conditional (branch). Each wraps a footprintjs primitive. DAG-complete: leaf + sequence + fan-out + branch + cycle covers every shape.
9
9
  - **Built-in recorders.** Observe tokens, cost, tool usage, quality, guardrails — all via `.recorder()` on the builder. Never shape behavior, only observe.
10
10
  - **Collect during traversal.** Inherited from footprintjs — all data collection happens as side effects of the single DFS traversal pass. Never post-process.
11
11
 
@@ -14,7 +14,7 @@ This is the agentfootprint library — the explainable agent framework. Build AI
14
14
  ```
15
15
  src/
16
16
  ├── core/ → AgentLoopConfig, AgentRecorder interface, PromptProvider/ToolProvider interfaces
17
- ├── concepts/ → 5 builders + runners (LLMCall, Agent, RAG, FlowChart, Swarm)
17
+ ├── concepts/ → 7 builders + runners (LLMCall, Agent, RAG, FlowChart, Swarm, Parallel, Conditional)
18
18
  ├── adapters/ → LLMProvider implementations (mock, anthropic, openai, bedrock, mcp, a2a)
19
19
  ├── models/ → ModelConfig factories (anthropic(), openai(), ollama(), bedrock())
20
20
  ├── providers/ → Strategy implementations (prompt/, messages/, tools/)
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ /**
3
+ * Conditional — branch to a runner based on predicates (DAG "if/else").
4
+ *
5
+ * Thin wrapper over footprintjs `addDeciderFunction` + `addFunctionBranch`.
6
+ * A conditional is a top-level routing decision between runners — distinct
7
+ * from `Agent.route()`, which branches INSIDE a ReAct loop. Use Conditional
8
+ * when the shape is "pick one runner and return its result" (triage, content
9
+ * classification, policy routing).
10
+ *
11
+ * Predicates are evaluated in the order `.when()` was called; first match
12
+ * wins. If every predicate misses, the `otherwise` branch runs. A predicate
13
+ * that throws is treated as a miss (fail-open) and the next branch is tried.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { Conditional, Agent, RAG } from 'agentfootprint';
18
+ *
19
+ * const triage = Conditional.create({ name: 'triage' })
20
+ * .when((input) => input.includes('refund'), refundAgent)
21
+ * .when((input) => input.length > 500, ragRunner)
22
+ * .otherwise(generalAgent)
23
+ * .build();
24
+ *
25
+ * const result = await triage.run('I want a refund please');
26
+ * // Narrative: "[triage] Chose refundAgent — predicate 0 matched"
27
+ * ```
28
+ *
29
+ * Conditional is a runner itself — plug it into `FlowChart`, `Parallel`,
30
+ * `Agent.route()`, or another `Conditional`. Composes like any other concept.
31
+ *
32
+ * ## Why this exists alongside footprintjs primitives
33
+ *
34
+ * footprintjs gives you `addDeciderFunction` + `addFunctionBranch` + `decide()`
35
+ * at the stage level. Conditional wraps those so you can compose **runners**
36
+ * (Agent, RAG, Swarm, user-built) instead of stage functions. Same underlying
37
+ * engine, same narrative, same evidence capture from `decide()`.
38
+ */
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.ConditionalRunner = exports.Conditional = void 0;
41
+ const footprintjs_1 = require("footprintjs");
42
+ const runnerAsStage_1 = require("../stages/runnerAsStage");
43
+ const RecorderBridge_1 = require("../recorders/RecorderBridge");
44
+ const specIcons_1 = require("./specIcons");
45
+ const narrative_1 = require("../lib/narrative");
46
+ /** Valid characters for a branch ID that feeds into runtimeStageId. */
47
+ const VALID_BRANCH_ID = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
48
+ function isRunnerLike(x) {
49
+ return x !== null && typeof x === 'object' && typeof x.run === 'function';
50
+ }
51
+ /**
52
+ * Builder for the Conditional concept. Each `.when()` adds a predicate →
53
+ * runner branch. `.otherwise()` sets the default (required). `.build()`
54
+ * returns a `ConditionalRunner`.
55
+ */
56
+ class Conditional {
57
+ conditionalName;
58
+ branches = [];
59
+ defaultRunner;
60
+ defaultName = 'Default';
61
+ recorders = [];
62
+ constructor(options) {
63
+ this.conditionalName = options.name ?? 'conditional';
64
+ }
65
+ static create(options = {}) {
66
+ return new Conditional(options);
67
+ }
68
+ /**
69
+ * Add a predicate → runner branch. Predicates are evaluated in the order
70
+ * they were added; first match wins. A throwing predicate is treated as a
71
+ * miss (fail-open) so a faulty branch never blocks a valid one.
72
+ *
73
+ * The `id` + optional `name` appear in narrative / decision evidence.
74
+ */
75
+ when(predicate, runner, options) {
76
+ if (typeof predicate !== 'function') {
77
+ throw new TypeError('Conditional.when: predicate must be a function (input, state) => boolean.');
78
+ }
79
+ if (!isRunnerLike(runner)) {
80
+ throw new TypeError('Conditional.when: runner must expose a run() method. Pass a built runner (Agent, LLMCall, etc.).');
81
+ }
82
+ const id = options?.id ?? `branch-${this.branches.length}`;
83
+ if (id === 'default') {
84
+ throw new Error("Conditional.when: branch ID 'default' is reserved for .otherwise(). Pass a different id.");
85
+ }
86
+ if (!VALID_BRANCH_ID.test(id)) {
87
+ throw new Error(`Conditional.when: branch ID '${id}' is invalid. Use alphanumerics, hyphens, or underscores — IDs feed into runtimeStageId and cannot contain '/' or whitespace.`);
88
+ }
89
+ if (this.branches.some((b) => b.id === id)) {
90
+ throw new Error(`Conditional: duplicate branch ID '${id}'.`);
91
+ }
92
+ this.branches.push({
93
+ id,
94
+ name: options?.name ?? id,
95
+ predicate,
96
+ runner,
97
+ });
98
+ return this;
99
+ }
100
+ /** Set the default runner — runs when every `.when()` predicate misses. */
101
+ otherwise(runner, options) {
102
+ if (!isRunnerLike(runner)) {
103
+ throw new TypeError('Conditional.otherwise: runner must expose a run() method. Pass a built runner (Agent, LLMCall, etc.).');
104
+ }
105
+ this.defaultRunner = runner;
106
+ if (options?.name)
107
+ this.defaultName = options.name;
108
+ return this;
109
+ }
110
+ recorder(rec) {
111
+ this.recorders.push(rec);
112
+ return this;
113
+ }
114
+ build() {
115
+ if (this.branches.length === 0) {
116
+ throw new Error('Conditional requires at least one .when() branch. Use FlowChart for unconditional single-runner pipelines.');
117
+ }
118
+ if (!this.defaultRunner) {
119
+ throw new Error('Conditional requires .otherwise(runner) — a default branch. Without it, an input matching nothing has no runner to route to.');
120
+ }
121
+ return new ConditionalRunner({
122
+ name: this.conditionalName,
123
+ branches: [...this.branches],
124
+ defaultRunner: this.defaultRunner,
125
+ defaultName: this.defaultName,
126
+ recorders: [...this.recorders],
127
+ });
128
+ }
129
+ }
130
+ exports.Conditional = Conditional;
131
+ /**
132
+ * Runner produced by `Conditional.build()`. Exposes the same surface as other
133
+ * runners: `run`, `getNarrative`, `getNarrativeEntries`, `getSnapshot`,
134
+ * `getSpec`, `toFlowChart`. Composes into FlowChart / Parallel / Agent.route
135
+ * like any other runner.
136
+ */
137
+ class ConditionalRunner {
138
+ opts;
139
+ lastExecutor;
140
+ lastSpec;
141
+ narrativeRenderer = (0, narrative_1.createAgentRenderer)();
142
+ constructor(opts) {
143
+ this.opts = opts;
144
+ }
145
+ async run(message, options) {
146
+ const startTime = Date.now();
147
+ const bridge = this.opts.recorders.length > 0 ? new RecorderBridge_1.RecorderBridge([...this.opts.recorders]) : null;
148
+ bridge?.dispatchTurnStart(message);
149
+ const chart = this.buildChart();
150
+ const executor = new footprintjs_1.FlowChartExecutor(chart, { enrichSnapshots: true });
151
+ executor.enableNarrative({ renderer: this.narrativeRenderer });
152
+ executor.attachRecorder(new footprintjs_1.MetricRecorder('metrics'));
153
+ try {
154
+ await executor.run({
155
+ input: { message },
156
+ signal: options?.signal,
157
+ timeoutMs: options?.timeoutMs,
158
+ });
159
+ }
160
+ catch (err) {
161
+ bridge?.dispatchError('llm', err);
162
+ throw err;
163
+ }
164
+ this.lastExecutor = executor;
165
+ const snapshot = executor.getSnapshot();
166
+ const state = snapshot?.sharedState ?? {};
167
+ const content = state.result ?? '';
168
+ bridge?.dispatchTurnComplete(content, 0);
169
+ return {
170
+ content,
171
+ agents: [],
172
+ totalLatencyMs: Date.now() - startTime,
173
+ };
174
+ }
175
+ buildChart() {
176
+ // Seed stage: store pipeline input so runner stages can read it.
177
+ const seedStage = (scope) => {
178
+ const args = scope.$getArgs();
179
+ scope.pipelineInput = args?.message ?? '';
180
+ };
181
+ // Decider: evaluate predicates in order. Use decide() so the matched
182
+ // branch id appears in the narrative as decision evidence.
183
+ //
184
+ // `decide()` returns a `DecisionResult<T>` — we extract `.value` to
185
+ // satisfy footprintjs's `addDeciderFunction` signature (string branch id).
186
+ // The full DecisionResult is still captured internally by the engine so
187
+ // it appears in the narrative / FlowRecorder `onDecision` evidence field.
188
+ const branches = this.opts.branches;
189
+ const deciderFn = (scope) => {
190
+ const input = scope.pipelineInput ?? '';
191
+ // Frozen state snapshot so a predicate can't accidentally mutate scope.
192
+ // Only exposes well-known fields — predicates must not depend on
193
+ // arbitrary scope keys (that's what stages are for).
194
+ const state = Object.freeze({
195
+ pipelineInput: input,
196
+ });
197
+ // decide() returns a DecisionResult whose `.branch` is the chosen id.
198
+ // footprintjs's addDeciderFunction accepts DecisionResult directly, but
199
+ // we extract `.branch` for a clearer string-typed return.
200
+ const result = (0, footprintjs_1.decide)(scope, branches.map((b) => ({
201
+ when: () => {
202
+ // Fail-open on throw so a broken predicate can't block other
203
+ // matching branches. Coerce non-boolean truthy returns to true.
204
+ try {
205
+ return Boolean(b.predicate(input, state));
206
+ }
207
+ catch {
208
+ return false;
209
+ }
210
+ },
211
+ then: b.id,
212
+ label: b.name,
213
+ })), 'default');
214
+ return result.branch;
215
+ };
216
+ let builder = (0, footprintjs_1.flowChart)('Seed', seedStage, 'seed');
217
+ let decider = builder.addDeciderFunction('Route', deciderFn, `${this.opts.name}-decide`, 'Pick the branch whose predicate matches first.');
218
+ // Mount every branch as `runnerAsStage` — it calls `runner.run(input)`
219
+ // and writes the output to `scope.result` on the parent. This keeps
220
+ // propagation simple: whichever branch fires, its content ends up on
221
+ // `result` for the caller to read. Subflow-mount variants (for UI
222
+ // drill-down) can be added behind a flag if/when needed.
223
+ for (const b of this.opts.branches) {
224
+ decider = decider.addFunctionBranch(b.id, b.name, (0, runnerAsStage_1.runnerAsStage)({ id: b.id, name: b.name, runner: b.runner }));
225
+ }
226
+ decider = decider.addFunctionBranch('default', this.opts.defaultName, (0, runnerAsStage_1.runnerAsStage)({
227
+ id: 'default',
228
+ name: this.opts.defaultName,
229
+ runner: this.opts.defaultRunner,
230
+ }));
231
+ builder = decider.setDefault('default').end();
232
+ this.lastSpec = (0, specIcons_1.annotateSpecIcons)(builder.toSpec());
233
+ return builder.build();
234
+ }
235
+ /** Get the flowchart spec (stage graph metadata). */
236
+ getSpec() {
237
+ if (!this.lastSpec) {
238
+ this.buildChart();
239
+ }
240
+ return this.lastSpec;
241
+ }
242
+ /** Expose the flowchart definition so this runner can be mounted as a subflow. */
243
+ toFlowChart() {
244
+ return this.buildChart();
245
+ }
246
+ /** Get the narrative from the last run. */
247
+ getNarrative() {
248
+ return this.lastExecutor?.getNarrative() ?? [];
249
+ }
250
+ /** Get structured narrative entries from the last run. */
251
+ getNarrativeEntries() {
252
+ return this.lastExecutor?.getNarrativeEntries() ?? [];
253
+ }
254
+ /** Get the full execution snapshot from the last run. */
255
+ getSnapshot() {
256
+ return this.lastExecutor?.getSnapshot();
257
+ }
258
+ }
259
+ exports.ConditionalRunner = ConditionalRunner;
260
+ //# sourceMappingURL=Conditional.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conditional.js","sourceRoot":"","sources":["../../src/concepts/Conditional.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ParallelRunner = exports.Parallel = exports.SwarmRunner = exports.Swarm = exports.FlowChartRunner = exports.FlowChart = exports.RAGRunner = exports.RAG = exports.LLMCallRunner = exports.LLMCall = exports.AgentRunner = exports.Agent = void 0;
3
+ exports.ConditionalRunner = exports.Conditional = exports.ParallelRunner = exports.Parallel = exports.SwarmRunner = exports.Swarm = exports.FlowChartRunner = exports.FlowChart = exports.RAGRunner = exports.RAG = exports.LLMCallRunner = exports.LLMCall = exports.AgentRunner = exports.Agent = void 0;
4
4
  // Agent rebuilt on library-of-libraries architecture (src/lib/)
5
5
  var concepts_1 = require("../lib/concepts");
6
6
  Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return concepts_1.Agent; } });
@@ -20,4 +20,7 @@ Object.defineProperty(exports, "SwarmRunner", { enumerable: true, get: function
20
20
  var Parallel_1 = require("./Parallel");
21
21
  Object.defineProperty(exports, "Parallel", { enumerable: true, get: function () { return Parallel_1.Parallel; } });
22
22
  Object.defineProperty(exports, "ParallelRunner", { enumerable: true, get: function () { return Parallel_1.ParallelRunner; } });
23
+ var Conditional_1 = require("./Conditional");
24
+ Object.defineProperty(exports, "Conditional", { enumerable: true, get: function () { return Conditional_1.Conditional; } });
25
+ Object.defineProperty(exports, "ConditionalRunner", { enumerable: true, get: function () { return Conditional_1.ConditionalRunner; } });
23
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/concepts/index.ts"],"names":[],"mappings":";;;AAAA,gEAAgE;AAChE,4CAAqD;AAA5C,iGAAA,KAAK,OAAA;AAAE,uGAAA,WAAW,OAAA;AAE3B,qCAAmD;AAA1C,kGAAA,OAAO,OAAA;AAAE,wGAAA,aAAa,OAAA;AAE/B,6BAAuC;AAA9B,0FAAA,GAAG,OAAA;AAAE,gGAAA,SAAS,OAAA;AAEvB,yCAAyD;AAAhD,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AACnC,iCAA6C;AAApC,8FAAA,KAAK,OAAA;AAAE,oGAAA,WAAW,OAAA;AAE3B,uCAAsD;AAA7C,oGAAA,QAAQ,OAAA;AAAE,0GAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/concepts/index.ts"],"names":[],"mappings":";;;AAAA,gEAAgE;AAChE,4CAAqD;AAA5C,iGAAA,KAAK,OAAA;AAAE,uGAAA,WAAW,OAAA;AAE3B,qCAAmD;AAA1C,kGAAA,OAAO,OAAA;AAAE,wGAAA,aAAa,OAAA;AAE/B,6BAAuC;AAA9B,0FAAA,GAAG,OAAA;AAAE,gGAAA,SAAS,OAAA;AAEvB,yCAAyD;AAAhD,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AACnC,iCAA6C;AAApC,8FAAA,KAAK,OAAA;AAAE,oGAAA,WAAW,OAAA;AAE3B,uCAAsD;AAA7C,oGAAA,QAAQ,OAAA;AAAE,0GAAA,cAAc,OAAA;AAEjC,6CAA+D;AAAtD,0GAAA,WAAW,OAAA;AAAE,gHAAA,iBAAiB,OAAA"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * Conditional — branch to a runner based on predicates (DAG "if/else").
3
+ *
4
+ * Thin wrapper over footprintjs `addDeciderFunction` + `addFunctionBranch`.
5
+ * A conditional is a top-level routing decision between runners — distinct
6
+ * from `Agent.route()`, which branches INSIDE a ReAct loop. Use Conditional
7
+ * when the shape is "pick one runner and return its result" (triage, content
8
+ * classification, policy routing).
9
+ *
10
+ * Predicates are evaluated in the order `.when()` was called; first match
11
+ * wins. If every predicate misses, the `otherwise` branch runs. A predicate
12
+ * that throws is treated as a miss (fail-open) and the next branch is tried.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { Conditional, Agent, RAG } from 'agentfootprint';
17
+ *
18
+ * const triage = Conditional.create({ name: 'triage' })
19
+ * .when((input) => input.includes('refund'), refundAgent)
20
+ * .when((input) => input.length > 500, ragRunner)
21
+ * .otherwise(generalAgent)
22
+ * .build();
23
+ *
24
+ * const result = await triage.run('I want a refund please');
25
+ * // Narrative: "[triage] Chose refundAgent — predicate 0 matched"
26
+ * ```
27
+ *
28
+ * Conditional is a runner itself — plug it into `FlowChart`, `Parallel`,
29
+ * `Agent.route()`, or another `Conditional`. Composes like any other concept.
30
+ *
31
+ * ## Why this exists alongside footprintjs primitives
32
+ *
33
+ * footprintjs gives you `addDeciderFunction` + `addFunctionBranch` + `decide()`
34
+ * at the stage level. Conditional wraps those so you can compose **runners**
35
+ * (Agent, RAG, Swarm, user-built) instead of stage functions. Same underlying
36
+ * engine, same narrative, same evidence capture from `decide()`.
37
+ */
38
+ import { flowChart as buildFlowChart, FlowChartExecutor, MetricRecorder, decide, } from 'footprintjs';
39
+ import { runnerAsStage } from '../stages/runnerAsStage';
40
+ import { RecorderBridge } from '../recorders/RecorderBridge';
41
+ import { annotateSpecIcons } from './specIcons';
42
+ import { createAgentRenderer } from '../lib/narrative';
43
+ /** Valid characters for a branch ID that feeds into runtimeStageId. */
44
+ const VALID_BRANCH_ID = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
45
+ function isRunnerLike(x) {
46
+ return x !== null && typeof x === 'object' && typeof x.run === 'function';
47
+ }
48
+ /**
49
+ * Builder for the Conditional concept. Each `.when()` adds a predicate →
50
+ * runner branch. `.otherwise()` sets the default (required). `.build()`
51
+ * returns a `ConditionalRunner`.
52
+ */
53
+ export class Conditional {
54
+ conditionalName;
55
+ branches = [];
56
+ defaultRunner;
57
+ defaultName = 'Default';
58
+ recorders = [];
59
+ constructor(options) {
60
+ this.conditionalName = options.name ?? 'conditional';
61
+ }
62
+ static create(options = {}) {
63
+ return new Conditional(options);
64
+ }
65
+ /**
66
+ * Add a predicate → runner branch. Predicates are evaluated in the order
67
+ * they were added; first match wins. A throwing predicate is treated as a
68
+ * miss (fail-open) so a faulty branch never blocks a valid one.
69
+ *
70
+ * The `id` + optional `name` appear in narrative / decision evidence.
71
+ */
72
+ when(predicate, runner, options) {
73
+ if (typeof predicate !== 'function') {
74
+ throw new TypeError('Conditional.when: predicate must be a function (input, state) => boolean.');
75
+ }
76
+ if (!isRunnerLike(runner)) {
77
+ throw new TypeError('Conditional.when: runner must expose a run() method. Pass a built runner (Agent, LLMCall, etc.).');
78
+ }
79
+ const id = options?.id ?? `branch-${this.branches.length}`;
80
+ if (id === 'default') {
81
+ throw new Error("Conditional.when: branch ID 'default' is reserved for .otherwise(). Pass a different id.");
82
+ }
83
+ if (!VALID_BRANCH_ID.test(id)) {
84
+ throw new Error(`Conditional.when: branch ID '${id}' is invalid. Use alphanumerics, hyphens, or underscores — IDs feed into runtimeStageId and cannot contain '/' or whitespace.`);
85
+ }
86
+ if (this.branches.some((b) => b.id === id)) {
87
+ throw new Error(`Conditional: duplicate branch ID '${id}'.`);
88
+ }
89
+ this.branches.push({
90
+ id,
91
+ name: options?.name ?? id,
92
+ predicate,
93
+ runner,
94
+ });
95
+ return this;
96
+ }
97
+ /** Set the default runner — runs when every `.when()` predicate misses. */
98
+ otherwise(runner, options) {
99
+ if (!isRunnerLike(runner)) {
100
+ throw new TypeError('Conditional.otherwise: runner must expose a run() method. Pass a built runner (Agent, LLMCall, etc.).');
101
+ }
102
+ this.defaultRunner = runner;
103
+ if (options?.name)
104
+ this.defaultName = options.name;
105
+ return this;
106
+ }
107
+ recorder(rec) {
108
+ this.recorders.push(rec);
109
+ return this;
110
+ }
111
+ build() {
112
+ if (this.branches.length === 0) {
113
+ throw new Error('Conditional requires at least one .when() branch. Use FlowChart for unconditional single-runner pipelines.');
114
+ }
115
+ if (!this.defaultRunner) {
116
+ throw new Error('Conditional requires .otherwise(runner) — a default branch. Without it, an input matching nothing has no runner to route to.');
117
+ }
118
+ return new ConditionalRunner({
119
+ name: this.conditionalName,
120
+ branches: [...this.branches],
121
+ defaultRunner: this.defaultRunner,
122
+ defaultName: this.defaultName,
123
+ recorders: [...this.recorders],
124
+ });
125
+ }
126
+ }
127
+ /**
128
+ * Runner produced by `Conditional.build()`. Exposes the same surface as other
129
+ * runners: `run`, `getNarrative`, `getNarrativeEntries`, `getSnapshot`,
130
+ * `getSpec`, `toFlowChart`. Composes into FlowChart / Parallel / Agent.route
131
+ * like any other runner.
132
+ */
133
+ export class ConditionalRunner {
134
+ opts;
135
+ lastExecutor;
136
+ lastSpec;
137
+ narrativeRenderer = createAgentRenderer();
138
+ constructor(opts) {
139
+ this.opts = opts;
140
+ }
141
+ async run(message, options) {
142
+ const startTime = Date.now();
143
+ const bridge = this.opts.recorders.length > 0 ? new RecorderBridge([...this.opts.recorders]) : null;
144
+ bridge?.dispatchTurnStart(message);
145
+ const chart = this.buildChart();
146
+ const executor = new FlowChartExecutor(chart, { enrichSnapshots: true });
147
+ executor.enableNarrative({ renderer: this.narrativeRenderer });
148
+ executor.attachRecorder(new MetricRecorder('metrics'));
149
+ try {
150
+ await executor.run({
151
+ input: { message },
152
+ signal: options?.signal,
153
+ timeoutMs: options?.timeoutMs,
154
+ });
155
+ }
156
+ catch (err) {
157
+ bridge?.dispatchError('llm', err);
158
+ throw err;
159
+ }
160
+ this.lastExecutor = executor;
161
+ const snapshot = executor.getSnapshot();
162
+ const state = snapshot?.sharedState ?? {};
163
+ const content = state.result ?? '';
164
+ bridge?.dispatchTurnComplete(content, 0);
165
+ return {
166
+ content,
167
+ agents: [],
168
+ totalLatencyMs: Date.now() - startTime,
169
+ };
170
+ }
171
+ buildChart() {
172
+ // Seed stage: store pipeline input so runner stages can read it.
173
+ const seedStage = (scope) => {
174
+ const args = scope.$getArgs();
175
+ scope.pipelineInput = args?.message ?? '';
176
+ };
177
+ // Decider: evaluate predicates in order. Use decide() so the matched
178
+ // branch id appears in the narrative as decision evidence.
179
+ //
180
+ // `decide()` returns a `DecisionResult<T>` — we extract `.value` to
181
+ // satisfy footprintjs's `addDeciderFunction` signature (string branch id).
182
+ // The full DecisionResult is still captured internally by the engine so
183
+ // it appears in the narrative / FlowRecorder `onDecision` evidence field.
184
+ const branches = this.opts.branches;
185
+ const deciderFn = (scope) => {
186
+ const input = scope.pipelineInput ?? '';
187
+ // Frozen state snapshot so a predicate can't accidentally mutate scope.
188
+ // Only exposes well-known fields — predicates must not depend on
189
+ // arbitrary scope keys (that's what stages are for).
190
+ const state = Object.freeze({
191
+ pipelineInput: input,
192
+ });
193
+ // decide() returns a DecisionResult whose `.branch` is the chosen id.
194
+ // footprintjs's addDeciderFunction accepts DecisionResult directly, but
195
+ // we extract `.branch` for a clearer string-typed return.
196
+ const result = decide(scope, branches.map((b) => ({
197
+ when: () => {
198
+ // Fail-open on throw so a broken predicate can't block other
199
+ // matching branches. Coerce non-boolean truthy returns to true.
200
+ try {
201
+ return Boolean(b.predicate(input, state));
202
+ }
203
+ catch {
204
+ return false;
205
+ }
206
+ },
207
+ then: b.id,
208
+ label: b.name,
209
+ })), 'default');
210
+ return result.branch;
211
+ };
212
+ let builder = buildFlowChart('Seed', seedStage, 'seed');
213
+ let decider = builder.addDeciderFunction('Route', deciderFn, `${this.opts.name}-decide`, 'Pick the branch whose predicate matches first.');
214
+ // Mount every branch as `runnerAsStage` — it calls `runner.run(input)`
215
+ // and writes the output to `scope.result` on the parent. This keeps
216
+ // propagation simple: whichever branch fires, its content ends up on
217
+ // `result` for the caller to read. Subflow-mount variants (for UI
218
+ // drill-down) can be added behind a flag if/when needed.
219
+ for (const b of this.opts.branches) {
220
+ decider = decider.addFunctionBranch(b.id, b.name, runnerAsStage({ id: b.id, name: b.name, runner: b.runner }));
221
+ }
222
+ decider = decider.addFunctionBranch('default', this.opts.defaultName, runnerAsStage({
223
+ id: 'default',
224
+ name: this.opts.defaultName,
225
+ runner: this.opts.defaultRunner,
226
+ }));
227
+ builder = decider.setDefault('default').end();
228
+ this.lastSpec = annotateSpecIcons(builder.toSpec());
229
+ return builder.build();
230
+ }
231
+ /** Get the flowchart spec (stage graph metadata). */
232
+ getSpec() {
233
+ if (!this.lastSpec) {
234
+ this.buildChart();
235
+ }
236
+ return this.lastSpec;
237
+ }
238
+ /** Expose the flowchart definition so this runner can be mounted as a subflow. */
239
+ toFlowChart() {
240
+ return this.buildChart();
241
+ }
242
+ /** Get the narrative from the last run. */
243
+ getNarrative() {
244
+ return this.lastExecutor?.getNarrative() ?? [];
245
+ }
246
+ /** Get structured narrative entries from the last run. */
247
+ getNarrativeEntries() {
248
+ return this.lastExecutor?.getNarrativeEntries() ?? [];
249
+ }
250
+ /** Get the full execution snapshot from the last run. */
251
+ getSnapshot() {
252
+ return this.lastExecutor?.getSnapshot();
253
+ }
254
+ }
255
+ //# sourceMappingURL=Conditional.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conditional.js","sourceRoot":"","sources":["../../../src/concepts/Conditional.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,5 @@ export { RAG, RAGRunner } from './RAG';
5
5
  export { FlowChart, FlowChartRunner } from './FlowChart';
6
6
  export { Swarm, SwarmRunner } from './Swarm';
7
7
  export { Parallel, ParallelRunner } from './Parallel';
8
+ export { Conditional, ConditionalRunner } from './Conditional';
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/concepts/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/concepts/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
package/dist/esm/index.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * agentfootprint/stream → Real-time lifecycle events
13
13
  */
14
14
  // ── Concepts (Builders + Runners) ───────────────────────────
15
- export { Agent, AgentRunner, LLMCall, LLMCallRunner, RAG, RAGRunner, FlowChart, FlowChartRunner, Swarm, SwarmRunner, Parallel, ParallelRunner, } from './concepts';
15
+ export { Agent, AgentRunner, LLMCall, LLMCallRunner, RAG, RAGRunner, FlowChart, FlowChartRunner, Swarm, SwarmRunner, Parallel, ParallelRunner, Conditional, ConditionalRunner, } from './concepts';
16
16
  // ── Tools ───────────────────────────────────────────────────
17
17
  export { defineTool, askHuman, ToolRegistry } from './tools';
18
18
  // ── Providers (core — you can't build an agent without these) ─
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+DAA+D;AAC/D,OAAO,EACL,KAAK,EACL,WAAW,EACX,OAAO,EACP,aAAa,EACb,GAAG,EACH,SAAS,EACT,SAAS,EACT,eAAe,EACf,KAAK,EACL,WAAW,EACX,QAAQ,EACR,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,+DAA+D;AAC/D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE7D,iEAAiE;AACjE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAuBlF,+DAA+D;AAC/D,OAAO,EACL,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,WAAW,EACX,QAAQ,GACT,MAAM,SAAS,CAAC;AAEjB,+DAA+D;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA0BnC,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,uEAAuE;AACvE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGnF,+DAA+D;AAC/D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+DAA+D;AAC/D,OAAO,EACL,KAAK,EACL,WAAW,EACX,OAAO,EACP,aAAa,EACb,GAAG,EACH,SAAS,EACT,SAAS,EACT,eAAe,EACf,KAAK,EACL,WAAW,EACX,QAAQ,EACR,cAAc,EACd,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAQpB,+DAA+D;AAC/D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE7D,iEAAiE;AACjE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAuBlF,+DAA+D;AAC/D,OAAO,EACL,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,WAAW,EACX,QAAQ,GACT,MAAM,SAAS,CAAC;AAEjB,+DAA+D;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA0BnC,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,uEAAuE;AACvE,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGnF,+DAA+D;AAC/D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * agentfootprint/patterns — canonical agent composition patterns.
3
+ *
4
+ * Each pattern is a thin factory over the existing concepts (`FlowChart`,
5
+ * `Parallel`, `Conditional`, `Agent`, `LLMCall`, `RAG`, `Swarm`). No new
6
+ * primitives. The source of each file shows the composition — read it to
7
+ * learn how to build your own.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { treeOfThoughts, reflexion, planExecute, mapReduce } from 'agentfootprint/patterns';
12
+ * ```
13
+ */
14
+ export { planExecute } from './planExecute';
15
+ export { mapReduce } from './mapReduce';
16
+ export { treeOfThoughts } from './treeOfThoughts';
17
+ export { reflexion } from './reflexion';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}