@framers/agentos 0.2.7 → 0.2.8

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 (69) hide show
  1. package/dist/ingest-router/IngestRouter.d.ts +72 -0
  2. package/dist/ingest-router/IngestRouter.d.ts.map +1 -0
  3. package/dist/ingest-router/IngestRouter.js +98 -0
  4. package/dist/ingest-router/IngestRouter.js.map +1 -0
  5. package/dist/ingest-router/classifier.d.ts +63 -0
  6. package/dist/ingest-router/classifier.d.ts.map +1 -0
  7. package/dist/ingest-router/classifier.js +111 -0
  8. package/dist/ingest-router/classifier.js.map +1 -0
  9. package/dist/ingest-router/costs.d.ts +48 -0
  10. package/dist/ingest-router/costs.d.ts.map +1 -0
  11. package/dist/ingest-router/costs.js +63 -0
  12. package/dist/ingest-router/costs.js.map +1 -0
  13. package/dist/ingest-router/dispatcher.d.ts +35 -0
  14. package/dist/ingest-router/dispatcher.d.ts.map +1 -0
  15. package/dist/ingest-router/dispatcher.js +32 -0
  16. package/dist/ingest-router/dispatcher.js.map +1 -0
  17. package/dist/ingest-router/index.d.ts +43 -0
  18. package/dist/ingest-router/index.d.ts.map +1 -0
  19. package/dist/ingest-router/index.js +37 -0
  20. package/dist/ingest-router/index.js.map +1 -0
  21. package/dist/ingest-router/routing-tables.d.ts +122 -0
  22. package/dist/ingest-router/routing-tables.d.ts.map +1 -0
  23. package/dist/ingest-router/routing-tables.js +145 -0
  24. package/dist/ingest-router/routing-tables.js.map +1 -0
  25. package/dist/ingest-router/select-strategy.d.ts +67 -0
  26. package/dist/ingest-router/select-strategy.d.ts.map +1 -0
  27. package/dist/ingest-router/select-strategy.js +100 -0
  28. package/dist/ingest-router/select-strategy.js.map +1 -0
  29. package/dist/memory-router/adaptive.d.ts +142 -0
  30. package/dist/memory-router/adaptive.d.ts.map +1 -0
  31. package/dist/memory-router/adaptive.js +202 -0
  32. package/dist/memory-router/adaptive.js.map +1 -0
  33. package/dist/memory-router/index.d.ts +2 -0
  34. package/dist/memory-router/index.d.ts.map +1 -1
  35. package/dist/memory-router/index.js +1 -0
  36. package/dist/memory-router/index.js.map +1 -1
  37. package/dist/multi-stage-guardrails/index.d.ts +190 -0
  38. package/dist/multi-stage-guardrails/index.d.ts.map +1 -0
  39. package/dist/multi-stage-guardrails/index.js +186 -0
  40. package/dist/multi-stage-guardrails/index.js.map +1 -0
  41. package/dist/read-router/ReadRouter.d.ts +58 -0
  42. package/dist/read-router/ReadRouter.d.ts.map +1 -0
  43. package/dist/read-router/ReadRouter.js +91 -0
  44. package/dist/read-router/ReadRouter.js.map +1 -0
  45. package/dist/read-router/classifier.d.ts +54 -0
  46. package/dist/read-router/classifier.d.ts.map +1 -0
  47. package/dist/read-router/classifier.js +104 -0
  48. package/dist/read-router/classifier.js.map +1 -0
  49. package/dist/read-router/costs.d.ts +23 -0
  50. package/dist/read-router/costs.d.ts.map +1 -0
  51. package/dist/read-router/costs.js +51 -0
  52. package/dist/read-router/costs.js.map +1 -0
  53. package/dist/read-router/dispatcher.d.ts +33 -0
  54. package/dist/read-router/dispatcher.d.ts.map +1 -0
  55. package/dist/read-router/dispatcher.js +29 -0
  56. package/dist/read-router/dispatcher.js.map +1 -0
  57. package/dist/read-router/index.d.ts +23 -0
  58. package/dist/read-router/index.d.ts.map +1 -0
  59. package/dist/read-router/index.js +17 -0
  60. package/dist/read-router/index.js.map +1 -0
  61. package/dist/read-router/routing-tables.d.ts +85 -0
  62. package/dist/read-router/routing-tables.d.ts.map +1 -0
  63. package/dist/read-router/routing-tables.js +79 -0
  64. package/dist/read-router/routing-tables.js.map +1 -0
  65. package/dist/read-router/select-strategy.d.ts +42 -0
  66. package/dist/read-router/select-strategy.d.ts.map +1 -0
  67. package/dist/read-router/select-strategy.js +92 -0
  68. package/dist/read-router/select-strategy.js.map +1 -0
  69. package/package.json +16 -1
@@ -0,0 +1,202 @@
1
+ /**
2
+ * @file adaptive.ts
3
+ * @description Self-calibrating routing-table generator.
4
+ *
5
+ * The shipping {@link MINIMIZE_COST_TABLE} / {@link BALANCED_TABLE} /
6
+ * {@link MAXIMIZE_ACCURACY_TABLE} are calibrated from LongMemEval-S
7
+ * Phase B N=500 measurements. For workloads whose cost-accuracy profile
8
+ * diverges from that distribution, those tables are not optimal.
9
+ *
10
+ * AdaptiveMemoryRouter takes a workload-specific calibration dataset
11
+ * (a list of {category, backend, costUsd, correct} samples) and derives
12
+ * a routing table from it. Same MemoryRouter API; different table
13
+ * source.
14
+ *
15
+ * Calibration workflow:
16
+ * 1. Run a Phase A sweep on your workload (a few hundred queries
17
+ * across a small subset of expected categories, dispatched to all
18
+ * candidate backends).
19
+ * 2. Each sample contributes one (category, backend, costUsd, correct)
20
+ * data point.
21
+ * 3. AdaptiveMemoryRouter aggregates these into per-(category, backend)
22
+ * mean cost + mean accuracy.
23
+ * 4. Apply a preset selection rule:
24
+ * - 'minimize-cost': cheapest backend within 2pp of best accuracy;
25
+ * if none within tolerance, pick best accuracy.
26
+ * - 'maximize-accuracy': highest accuracy; ties broken by cost.
27
+ * - 'balanced': best $/correct (mean cost divided by mean
28
+ * accuracy).
29
+ * 5. Categories with insufficient samples fall back to the static
30
+ * preset table.
31
+ *
32
+ * The router is otherwise identical to {@link MemoryRouter} — same
33
+ * decide() / decideAndDispatch() / budget-aware dispatch.
34
+ *
35
+ * @module @framers/agentos/memory-router/adaptive
36
+ */
37
+ import { MemoryRouter } from './MemoryRouter.js';
38
+ import { PRESET_TABLES, } from './routing-tables.js';
39
+ // ============================================================================
40
+ // Aggregation
41
+ // ============================================================================
42
+ /**
43
+ * Roll up raw calibration samples into per-(category, backend) cells.
44
+ * Each cell carries n, meanCost, meanAccuracy.
45
+ */
46
+ export function aggregateCalibration(samples) {
47
+ const acc = {};
48
+ for (const s of samples) {
49
+ if (!acc[s.category])
50
+ acc[s.category] = {};
51
+ if (!acc[s.category][s.backend]) {
52
+ acc[s.category][s.backend] = { n: 0, sumCost: 0, sumCorrect: 0 };
53
+ }
54
+ const cell = acc[s.category][s.backend];
55
+ cell.n += 1;
56
+ cell.sumCost += s.costUsd;
57
+ cell.sumCorrect += s.correct;
58
+ }
59
+ const out = {};
60
+ for (const cat of Object.keys(acc)) {
61
+ out[cat] = {};
62
+ const inner = out[cat];
63
+ for (const backend of Object.keys(acc[cat])) {
64
+ const cell = acc[cat][backend];
65
+ inner[backend] = {
66
+ n: cell.n,
67
+ meanCost: cell.sumCost / cell.n,
68
+ meanAccuracy: cell.sumCorrect / cell.n,
69
+ };
70
+ }
71
+ }
72
+ return out;
73
+ }
74
+ // ============================================================================
75
+ // Per-category selection
76
+ // ============================================================================
77
+ /**
78
+ * Select a backend for one category from aggregated calibration data
79
+ * using the named preset rule. Falls back to the preset's static table
80
+ * when calibration is insufficient.
81
+ */
82
+ export function selectByPreset(args) {
83
+ const { category, agg, preset, minSamplesPerCell = 1, accuracyTolerance = 0.02, } = args;
84
+ const fallbackTable = PRESET_TABLES[preset];
85
+ const fallback = fallbackTable.defaultMapping[category];
86
+ const cells = agg[category];
87
+ if (!cells)
88
+ return fallback;
89
+ // Filter cells meeting min-sample threshold.
90
+ const eligible = Object.entries(cells)
91
+ .filter(([, cell]) => cell.n >= minSamplesPerCell);
92
+ if (eligible.length === 0)
93
+ return fallback;
94
+ if (preset === 'maximize-accuracy') {
95
+ return eligible.reduce((best, [backend, cell]) => {
96
+ const [bestBackend, bestCell] = best;
97
+ if (cell.meanAccuracy > bestCell.meanAccuracy)
98
+ return [backend, cell];
99
+ if (cell.meanAccuracy === bestCell.meanAccuracy) {
100
+ return cell.meanCost < bestCell.meanCost ? [backend, cell] : best;
101
+ }
102
+ return best;
103
+ }, eligible[0])[0];
104
+ }
105
+ if (preset === 'balanced') {
106
+ // best $/correct (skip zero-accuracy cells to avoid div-by-zero)
107
+ const valid = eligible.filter(([, cell]) => cell.meanAccuracy > 0);
108
+ if (valid.length === 0)
109
+ return fallback;
110
+ return valid.reduce((best, [backend, cell]) => {
111
+ const [bestBackend, bestCell] = best;
112
+ const cellCpc = cell.meanCost / cell.meanAccuracy;
113
+ const bestCpc = bestCell.meanCost / bestCell.meanAccuracy;
114
+ return cellCpc < bestCpc ? [backend, cell] : best;
115
+ }, valid[0])[0];
116
+ }
117
+ // minimize-cost: cheapest within accuracyTolerance of best accuracy.
118
+ const bestAccuracy = Math.max(...eligible.map(([, cell]) => cell.meanAccuracy));
119
+ const withinTolerance = eligible.filter(([, cell]) => bestAccuracy - cell.meanAccuracy <= accuracyTolerance);
120
+ if (withinTolerance.length === 0) {
121
+ // No candidates within tolerance is impossible (the best-accuracy
122
+ // backend itself qualifies), but guard anyway.
123
+ return fallback;
124
+ }
125
+ return withinTolerance.reduce((best, [backend, cell]) => {
126
+ const [bestBackend, bestCell] = best;
127
+ return cell.meanCost < bestCell.meanCost ? [backend, cell] : best;
128
+ }, withinTolerance[0])[0];
129
+ }
130
+ // ============================================================================
131
+ // Table construction
132
+ // ============================================================================
133
+ const ALL_CATEGORIES = [
134
+ 'single-session-user',
135
+ 'single-session-assistant',
136
+ 'single-session-preference',
137
+ 'knowledge-update',
138
+ 'multi-session',
139
+ 'temporal-reasoning',
140
+ ];
141
+ /**
142
+ * Build a complete frozen routing table from calibration samples + a
143
+ * preset rule. Categories without enough calibration fall back to the
144
+ * preset's static table.
145
+ */
146
+ export function buildAdaptiveRoutingTable(args) {
147
+ const { samples, preset, minSamplesPerCell, accuracyTolerance, fallbackTable, } = args;
148
+ const agg = aggregateCalibration(samples);
149
+ const fb = fallbackTable ?? PRESET_TABLES[preset];
150
+ const mapping = {};
151
+ for (const cat of ALL_CATEGORIES) {
152
+ mapping[cat] = selectByPreset({
153
+ category: cat,
154
+ agg,
155
+ preset,
156
+ minSamplesPerCell,
157
+ accuracyTolerance,
158
+ });
159
+ // selectByPreset falls back to the preset's STATIC default mapping,
160
+ // not the caller-supplied fallback table. Apply the explicit
161
+ // fallback only when the static fallback wasn't applied because of
162
+ // missing data — easiest is to override after the fact.
163
+ if (!agg[cat] && fb !== PRESET_TABLES[preset]) {
164
+ mapping[cat] = fb.defaultMapping[cat];
165
+ }
166
+ }
167
+ return Object.freeze({
168
+ preset: preset,
169
+ defaultMapping: Object.freeze(mapping),
170
+ });
171
+ }
172
+ // ============================================================================
173
+ // AdaptiveMemoryRouter class
174
+ // ============================================================================
175
+ /**
176
+ * Memory router whose routing table is derived from a calibration
177
+ * dataset rather than a static preset. Otherwise identical API to
178
+ * {@link MemoryRouter}.
179
+ */
180
+ export class AdaptiveMemoryRouter extends MemoryRouter {
181
+ constructor(options) {
182
+ const derivedTable = buildAdaptiveRoutingTable({
183
+ samples: options.calibrationSamples,
184
+ preset: options.preset,
185
+ minSamplesPerCell: options.minSamplesPerCell,
186
+ accuracyTolerance: options.accuracyTolerance,
187
+ });
188
+ super({
189
+ ...options,
190
+ preset: options.preset,
191
+ routingTable: derivedTable,
192
+ });
193
+ this.derivedTable = derivedTable;
194
+ }
195
+ /**
196
+ * Inspect the derived routing table for debugging / telemetry.
197
+ */
198
+ getRoutingTable() {
199
+ return this.derivedTable;
200
+ }
201
+ }
202
+ //# sourceMappingURL=adaptive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adaptive.js","sourceRoot":"","sources":["../../src/memory-router/adaptive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,YAAY,EAA4B,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,aAAa,GAKd,MAAM,qBAAqB,CAAC;AA4F7B,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAqC;IAErC,MAAM,GAAG,GAAuF,EAAE,CAAC;IAEnG,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC3C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QACpE,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC,CAAC,CAAC,OAAO,CAAE,CAAC;QAC1C,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,MAAM,GAAG,GAA0B,EAAE,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAA0B,EAAE,CAAC;QAC5D,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAE,CAAC;QACxB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAE,CAAsB,EAAE,CAAC;YAClE,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAE,CAAC,OAAO,CAAE,CAAC;YACjC,KAAK,CAAC,OAAO,CAAC,GAAG;gBACf,CAAC,EAAE,IAAI,CAAC,CAAC;gBACT,QAAQ,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;gBAC/B,YAAY,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;aACvC,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,MAAM,EACJ,QAAQ,EACR,GAAG,EACH,MAAM,EACN,iBAAiB,GAAG,CAAC,EACrB,iBAAiB,GAAG,IAAI,GACzB,GAAG,IAAI,CAAC;IAET,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAExD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAE5B,6CAA6C;IAC7C,MAAM,QAAQ,GAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAA0C;SAC7E,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC;IAErD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE3C,IAAI,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACnC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;YAC/C,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;YACrC,IAAI,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY;gBAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACtE,IAAI,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAChD,OAAO,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACpE,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;IAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,iEAAiE;QACjE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QACxC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;YAC5C,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC;YAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC;YAC1D,OAAO,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,CAAC,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED,qEAAqE;IACrE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC3B,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CACjD,CAAC;IACF,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CACrC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,iBAAiB,CACpE,CAAC;IAEF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,kEAAkE;QAClE,+CAA+C;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;QACtD,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;QACrC,OAAO,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC,EAAE,eAAe,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,MAAM,cAAc,GAAmC;IACrD,qBAAqB;IACrB,0BAA0B;IAC1B,2BAA2B;IAC3B,kBAAkB;IAClB,eAAe;IACf,oBAAoB;CACrB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAmC;IAEnC,MAAM,EACJ,OAAO,EACP,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,GAAG,IAAI,CAAC;IAET,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAElD,MAAM,OAAO,GAAiD,EAG7D,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC;YAC5B,QAAQ,EAAE,GAAG;YACb,GAAG;YACH,MAAM;YACN,iBAAiB;YACjB,iBAAiB;SAClB,CAAC,CAAC;QACH,oEAAoE;QACpE,6DAA6D;QAC7D,mEAAmE;QACnE,wDAAwD;QACxD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM,EAAE,MAA4B;QACpC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;KACvC,CAAiB,CAAC;AACrB,CAAC;AAED,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IAGpD,YAAY,OAAoC;QAC9C,MAAM,YAAY,GAAG,yBAAyB,CAAC;YAC7C,OAAO,EAAE,OAAO,CAAC,kBAAkB;YACnC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;SAC7C,CAAC,CAAC;QAEH,KAAK,CAAC;YACJ,GAAG,OAAO;YACV,MAAM,EAAE,OAAO,CAAC,MAA4B;YAC5C,YAAY,EAAE,YAAY;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF"}
@@ -121,4 +121,6 @@ export { selectBackend, MemoryRouterUnknownCategoryError, MemoryRouterBudgetExce
121
121
  export { CLASSIFIER_SYSTEM_PROMPT, CLASSIFIER_SYSTEM_PROMPT_FEWSHOT, SAFE_FALLBACK_CATEGORY, LLMMemoryClassifier, normalizeClassifierOutput, parseClassifierOutput, } from './classifier.js';
122
122
  export { FunctionMemoryDispatcher, UnsupportedMemoryBackendError, } from './dispatcher.js';
123
123
  export { MemoryRouter, MemoryRouterDispatcherMissingError, } from './MemoryRouter.js';
124
+ export type { CalibrationSample, CalibrationCell, AggregatedCalibration, AdaptivePresetRule, SelectByPresetArgs, BuildAdaptiveRoutingTableArgs, AdaptiveMemoryRouterOptions, } from './adaptive.js';
125
+ export { aggregateCalibration, selectByPreset, buildAdaptiveRoutingTable, AdaptiveMemoryRouter, } from './adaptive.js';
124
126
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory-router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAMH,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,gCAAgC,EAChC,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,YAAY,EACZ,kCAAkC,GACnC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory-router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAMH,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,gCAAgC,EAChC,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,YAAY,EACZ,kCAAkC,GACnC,MAAM,mBAAmB,CAAC;AAM3B,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
@@ -118,4 +118,5 @@ export { selectBackend, MemoryRouterUnknownCategoryError, MemoryRouterBudgetExce
118
118
  export { CLASSIFIER_SYSTEM_PROMPT, CLASSIFIER_SYSTEM_PROMPT_FEWSHOT, SAFE_FALLBACK_CATEGORY, LLMMemoryClassifier, normalizeClassifierOutput, parseClassifierOutput, } from './classifier.js';
119
119
  export { FunctionMemoryDispatcher, UnsupportedMemoryBackendError, } from './dispatcher.js';
120
120
  export { MemoryRouter, MemoryRouterDispatcherMissingError, } from './MemoryRouter.js';
121
+ export { aggregateCalibration, selectByPreset, buildAdaptiveRoutingTable, AdaptiveMemoryRouter, } from './adaptive.js';
121
122
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory-router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAYH,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAoC9D,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,gCAAgC,EAChC,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,YAAY,EACZ,kCAAkC,GACnC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory-router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAYH,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAoC9D,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,gCAAgC,EAChC,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,YAAY,EACZ,kCAAkC,GACnC,MAAM,mBAAmB,CAAC;AAgB3B,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * AgentOS MultiStageGuardrails Module
3
+ *
4
+ * Composition primitive that wires the LLM-as-judge stages of the
5
+ * agentos pipeline into one orchestrator. Each stage is independent and
6
+ * optional — wire only the stages you need, or compose all four.
7
+ *
8
+ * **The four stages:**
9
+ *
10
+ * ```
11
+ * Content Query Query
12
+ * │ │ │
13
+ * ▼ ▼ ▼
14
+ * ┌─────────┐ ┌─────────────┐ ┌─────────────┐
15
+ * │ Ingest │ │ Recall │ │ Read │
16
+ * │ Stage │ │ Stage │ │ Stage │
17
+ * │ (input) │ │ (memory) │ │ (reader) │
18
+ * └─────────┘ └─────────────┘ └─────────────┘
19
+ * │ │ │
20
+ * ▼ ▼ ▼
21
+ * Memory state Retrieved traces Final answer
22
+ * ```
23
+ *
24
+ * Plus the existing output-stage `core/guardrails` and
25
+ * `agentos-ext-grounding-guard` which validate the answer post-generation.
26
+ *
27
+ * **Why a composition primitive:** each individual router is independently
28
+ * useful and ships with its own classifier + dispatcher + table machinery.
29
+ * MultiStageGuardrails gives consumers a single object to coordinate the
30
+ * stages without duplicating per-stage wiring. It does NOT add new
31
+ * routing logic — it's a thin facade over the four primitives.
32
+ *
33
+ * The interfaces below ({@link IngestStage}, {@link RecallStage},
34
+ * {@link ReadStage}) are deliberately minimal so consumers can wire any
35
+ * implementation:
36
+ *
37
+ * - The shipping `IngestRouter` / `MemoryRouter` / `ReadRouter` classes
38
+ * each satisfy the corresponding stage interface via thin adapters
39
+ * (see `agentosStageAdapters` below).
40
+ * - Custom implementations (rule-based, ML-driven, mock for tests) can
41
+ * satisfy the same interfaces and slot in.
42
+ *
43
+ * @module @framers/agentos/multi-stage-guardrails
44
+ */
45
+ /**
46
+ * Generic decision metadata bundled with each stage's result. Stages
47
+ * report enough information for downstream telemetry without leaking
48
+ * stage-specific types into the orchestrator.
49
+ */
50
+ export interface IngestStageResult {
51
+ readonly writtenTraces: number;
52
+ readonly strategy: string;
53
+ readonly ingestRouterDecision: unknown;
54
+ }
55
+ export interface RecallStageResult<TTrace> {
56
+ readonly traces: TTrace[];
57
+ readonly backend: string;
58
+ readonly memoryRouterDecision: unknown;
59
+ }
60
+ export interface ReadStageResult<TOutcome> {
61
+ readonly outcome: TOutcome;
62
+ readonly strategy: string;
63
+ readonly readRouterDecision: unknown;
64
+ }
65
+ /**
66
+ * Pluggable input-stage. Wrap an {@link IngestRouter} or any equivalent
67
+ * implementation that turns content into stored traces.
68
+ */
69
+ export interface IngestStage {
70
+ ingest(content: string, payload?: unknown): Promise<IngestStageResult>;
71
+ }
72
+ /**
73
+ * Pluggable recall-stage. Wrap a {@link MemoryRouter} or any equivalent
74
+ * implementation that turns a query into retrieved traces.
75
+ */
76
+ export interface RecallStage<TTrace> {
77
+ recall(query: string, payload?: unknown): Promise<RecallStageResult<TTrace>>;
78
+ }
79
+ /**
80
+ * Pluggable read-stage. Wrap a {@link ReadRouter} or any equivalent
81
+ * implementation that turns a query+evidence pair into a final answer.
82
+ */
83
+ export interface ReadStage<TTrace, TOutcome> {
84
+ read(query: string, traces: TTrace[], payload?: unknown): Promise<ReadStageResult<TOutcome>>;
85
+ }
86
+ export interface RecallAndReadResult<TTrace, TOutcome> {
87
+ readonly recallStage: RecallStageResult<TTrace>;
88
+ readonly readStage: ReadStageResult<TOutcome>;
89
+ readonly outcome: TOutcome;
90
+ }
91
+ export interface MultiStageGuardrailsOptions<TTrace, TOutcome> {
92
+ readonly ingest?: IngestStage;
93
+ readonly recall?: RecallStage<TTrace>;
94
+ readonly read?: ReadStage<TTrace, TOutcome>;
95
+ }
96
+ export declare class MissingStageError extends Error {
97
+ constructor(stage: 'IngestStage' | 'RecallStage' | 'ReadStage');
98
+ }
99
+ /**
100
+ * Top-level pipeline composition. One instance per agent / endpoint;
101
+ * reuse across requests.
102
+ *
103
+ * @example Full pipeline
104
+ * ```ts
105
+ * import { MultiStageGuardrails } from '../multi-stage-guardrails';
106
+ * import { ingestRouterAsStage } from '../multi-stage-guardrails';
107
+ *
108
+ * const guardrails = new MultiStageGuardrails({
109
+ * ingest: ingestRouterAsStage(myIngestRouter),
110
+ * recall: memoryRouterAsStage(myMemoryRouter),
111
+ * read: readRouterAsStage(myReadRouter),
112
+ * });
113
+ *
114
+ * await guardrails.ingest(newContent);
115
+ * const { outcome } = await guardrails.recallAndRead("what's my latest job?");
116
+ * ```
117
+ */
118
+ export declare class MultiStageGuardrails<TTrace, TOutcome> {
119
+ private readonly ingestStage;
120
+ private readonly recallStage;
121
+ private readonly readStage;
122
+ constructor(options: MultiStageGuardrailsOptions<TTrace, TOutcome>);
123
+ get hasIngestStage(): boolean;
124
+ get hasRecallStage(): boolean;
125
+ get hasReadStage(): boolean;
126
+ ingest(content: string, payload?: unknown): Promise<IngestStageResult>;
127
+ recall(query: string, payload?: unknown): Promise<RecallStageResult<TTrace>>;
128
+ read(query: string, traces: TTrace[], payload?: unknown): Promise<ReadStageResult<TOutcome>>;
129
+ /**
130
+ * Recall traces for the query, then run the reader on those traces.
131
+ * Standard "ask a question, get an answer" path.
132
+ */
133
+ recallAndRead(query: string, recallPayload?: unknown, readPayload?: unknown): Promise<RecallAndReadResult<TTrace, TOutcome>>;
134
+ }
135
+ /**
136
+ * Wrap an {@link IngestRouter} as an {@link IngestStage}. The IngestRouter
137
+ * must have been constructed with a dispatcher; otherwise the stage will
138
+ * throw on every call.
139
+ */
140
+ export declare function ingestRouterAsStage<TOutcome extends {
141
+ writtenTraces?: number;
142
+ }>(router: {
143
+ decideAndDispatch: (content: string, payload?: unknown) => Promise<{
144
+ decision: {
145
+ routing: {
146
+ chosenStrategy: string;
147
+ };
148
+ };
149
+ outcome: TOutcome;
150
+ }>;
151
+ }): IngestStage;
152
+ /**
153
+ * Wrap a {@link MemoryRouter} as a {@link RecallStage}. The MemoryRouter
154
+ * must have been constructed with a dispatcher.
155
+ */
156
+ export declare function memoryRouterAsStage<TTrace>(router: {
157
+ decideAndDispatch: <T = TTrace>(query: string, payload?: unknown) => Promise<{
158
+ decision: {
159
+ routing: {
160
+ chosenBackend: string;
161
+ };
162
+ };
163
+ traces: T[];
164
+ backend: string;
165
+ }>;
166
+ }): RecallStage<TTrace>;
167
+ /**
168
+ * Wrap a {@link ReadRouter} as a {@link ReadStage}. The ReadRouter must
169
+ * have been constructed with a dispatcher.
170
+ */
171
+ export declare function readRouterAsStage<TTrace extends {
172
+ id?: string;
173
+ text?: string;
174
+ }, TOutcome>(router: {
175
+ decideAndDispatch: <T = TOutcome>(query: string, evidence: readonly string[], payload?: unknown) => Promise<{
176
+ decision: {
177
+ routing: {
178
+ chosenStrategy: string;
179
+ };
180
+ };
181
+ outcome: T;
182
+ }>;
183
+ },
184
+ /**
185
+ * Optional adapter to turn a TTrace into a string for the read-router's
186
+ * evidence array. Default: serialize `{id, text}`-shaped traces by
187
+ * concatenating text fields.
188
+ */
189
+ traceToString?: (trace: TTrace) => string): ReadStage<TTrace, TOutcome>;
190
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/multi-stage-guardrails/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * AgentOS MultiStageGuardrails Module
3
+ *
4
+ * Composition primitive that wires the LLM-as-judge stages of the
5
+ * agentos pipeline into one orchestrator. Each stage is independent and
6
+ * optional — wire only the stages you need, or compose all four.
7
+ *
8
+ * **The four stages:**
9
+ *
10
+ * ```
11
+ * Content Query Query
12
+ * │ │ │
13
+ * ▼ ▼ ▼
14
+ * ┌─────────┐ ┌─────────────┐ ┌─────────────┐
15
+ * │ Ingest │ │ Recall │ │ Read │
16
+ * │ Stage │ │ Stage │ │ Stage │
17
+ * │ (input) │ │ (memory) │ │ (reader) │
18
+ * └─────────┘ └─────────────┘ └─────────────┘
19
+ * │ │ │
20
+ * ▼ ▼ ▼
21
+ * Memory state Retrieved traces Final answer
22
+ * ```
23
+ *
24
+ * Plus the existing output-stage `core/guardrails` and
25
+ * `agentos-ext-grounding-guard` which validate the answer post-generation.
26
+ *
27
+ * **Why a composition primitive:** each individual router is independently
28
+ * useful and ships with its own classifier + dispatcher + table machinery.
29
+ * MultiStageGuardrails gives consumers a single object to coordinate the
30
+ * stages without duplicating per-stage wiring. It does NOT add new
31
+ * routing logic — it's a thin facade over the four primitives.
32
+ *
33
+ * The interfaces below ({@link IngestStage}, {@link RecallStage},
34
+ * {@link ReadStage}) are deliberately minimal so consumers can wire any
35
+ * implementation:
36
+ *
37
+ * - The shipping `IngestRouter` / `MemoryRouter` / `ReadRouter` classes
38
+ * each satisfy the corresponding stage interface via thin adapters
39
+ * (see `agentosStageAdapters` below).
40
+ * - Custom implementations (rule-based, ML-driven, mock for tests) can
41
+ * satisfy the same interfaces and slot in.
42
+ *
43
+ * @module @framers/agentos/multi-stage-guardrails
44
+ */
45
+ // ============================================================================
46
+ // Errors
47
+ // ============================================================================
48
+ export class MissingStageError extends Error {
49
+ constructor(stage) {
50
+ super(`MultiStageGuardrails: ${stage} is not configured. ` +
51
+ `Pass it in options at construction.`);
52
+ this.name = 'MissingStageError';
53
+ }
54
+ }
55
+ // ============================================================================
56
+ // Orchestrator
57
+ // ============================================================================
58
+ /**
59
+ * Top-level pipeline composition. One instance per agent / endpoint;
60
+ * reuse across requests.
61
+ *
62
+ * @example Full pipeline
63
+ * ```ts
64
+ * import { MultiStageGuardrails } from '../multi-stage-guardrails/index.js';
65
+ * import { ingestRouterAsStage } from '../multi-stage-guardrails';
66
+ *
67
+ * const guardrails = new MultiStageGuardrails({
68
+ * ingest: ingestRouterAsStage(myIngestRouter),
69
+ * recall: memoryRouterAsStage(myMemoryRouter),
70
+ * read: readRouterAsStage(myReadRouter),
71
+ * });
72
+ *
73
+ * await guardrails.ingest(newContent);
74
+ * const { outcome } = await guardrails.recallAndRead("what's my latest job?");
75
+ * ```
76
+ */
77
+ export class MultiStageGuardrails {
78
+ constructor(options) {
79
+ this.ingestStage = options.ingest ?? null;
80
+ this.recallStage = options.recall ?? null;
81
+ this.readStage = options.read ?? null;
82
+ }
83
+ get hasIngestStage() {
84
+ return this.ingestStage !== null;
85
+ }
86
+ get hasRecallStage() {
87
+ return this.recallStage !== null;
88
+ }
89
+ get hasReadStage() {
90
+ return this.readStage !== null;
91
+ }
92
+ async ingest(content, payload) {
93
+ if (!this.ingestStage)
94
+ throw new MissingStageError('IngestStage');
95
+ return this.ingestStage.ingest(content, payload);
96
+ }
97
+ async recall(query, payload) {
98
+ if (!this.recallStage)
99
+ throw new MissingStageError('RecallStage');
100
+ return this.recallStage.recall(query, payload);
101
+ }
102
+ async read(query, traces, payload) {
103
+ if (!this.readStage)
104
+ throw new MissingStageError('ReadStage');
105
+ return this.readStage.read(query, traces, payload);
106
+ }
107
+ /**
108
+ * Recall traces for the query, then run the reader on those traces.
109
+ * Standard "ask a question, get an answer" path.
110
+ */
111
+ async recallAndRead(query, recallPayload, readPayload) {
112
+ if (!this.recallStage)
113
+ throw new MissingStageError('RecallStage');
114
+ if (!this.readStage)
115
+ throw new MissingStageError('ReadStage');
116
+ const recallStage = await this.recallStage.recall(query, recallPayload);
117
+ const readStage = await this.readStage.read(query, recallStage.traces, readPayload);
118
+ return {
119
+ recallStage,
120
+ readStage,
121
+ outcome: readStage.outcome,
122
+ };
123
+ }
124
+ }
125
+ // ============================================================================
126
+ // Adapters: shipping routers → stage interfaces
127
+ // ============================================================================
128
+ /**
129
+ * Wrap an {@link IngestRouter} as an {@link IngestStage}. The IngestRouter
130
+ * must have been constructed with a dispatcher; otherwise the stage will
131
+ * throw on every call.
132
+ */
133
+ export function ingestRouterAsStage(router) {
134
+ return {
135
+ async ingest(content, payload) {
136
+ const result = await router.decideAndDispatch(content, payload);
137
+ return {
138
+ writtenTraces: result.outcome.writtenTraces ?? 0,
139
+ strategy: result.decision.routing.chosenStrategy,
140
+ ingestRouterDecision: result.decision,
141
+ };
142
+ },
143
+ };
144
+ }
145
+ /**
146
+ * Wrap a {@link MemoryRouter} as a {@link RecallStage}. The MemoryRouter
147
+ * must have been constructed with a dispatcher.
148
+ */
149
+ export function memoryRouterAsStage(router) {
150
+ return {
151
+ async recall(query, payload) {
152
+ const result = await router.decideAndDispatch(query, payload);
153
+ return {
154
+ traces: result.traces,
155
+ backend: result.backend,
156
+ memoryRouterDecision: result.decision,
157
+ };
158
+ },
159
+ };
160
+ }
161
+ /**
162
+ * Wrap a {@link ReadRouter} as a {@link ReadStage}. The ReadRouter must
163
+ * have been constructed with a dispatcher.
164
+ */
165
+ export function readRouterAsStage(router,
166
+ /**
167
+ * Optional adapter to turn a TTrace into a string for the read-router's
168
+ * evidence array. Default: serialize `{id, text}`-shaped traces by
169
+ * concatenating text fields.
170
+ */
171
+ traceToString) {
172
+ const toString = traceToString ??
173
+ ((t) => t.text ?? JSON.stringify(t));
174
+ return {
175
+ async read(query, traces, payload) {
176
+ const evidenceStrings = traces.map(toString);
177
+ const result = await router.decideAndDispatch(query, evidenceStrings, payload);
178
+ return {
179
+ outcome: result.outcome,
180
+ strategy: result.decision.routing.chosenStrategy,
181
+ readRouterDecision: result.decision,
182
+ };
183
+ },
184
+ };
185
+ }
186
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/multi-stage-guardrails/index.ts"],"names":[],"mappings":"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"}