@framers/agentos 0.2.6 → 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.
- package/dist/ingest-router/IngestRouter.d.ts +72 -0
- package/dist/ingest-router/IngestRouter.d.ts.map +1 -0
- package/dist/ingest-router/IngestRouter.js +98 -0
- package/dist/ingest-router/IngestRouter.js.map +1 -0
- package/dist/ingest-router/classifier.d.ts +63 -0
- package/dist/ingest-router/classifier.d.ts.map +1 -0
- package/dist/ingest-router/classifier.js +111 -0
- package/dist/ingest-router/classifier.js.map +1 -0
- package/dist/ingest-router/costs.d.ts +48 -0
- package/dist/ingest-router/costs.d.ts.map +1 -0
- package/dist/ingest-router/costs.js +63 -0
- package/dist/ingest-router/costs.js.map +1 -0
- package/dist/ingest-router/dispatcher.d.ts +35 -0
- package/dist/ingest-router/dispatcher.d.ts.map +1 -0
- package/dist/ingest-router/dispatcher.js +32 -0
- package/dist/ingest-router/dispatcher.js.map +1 -0
- package/dist/ingest-router/index.d.ts +43 -0
- package/dist/ingest-router/index.d.ts.map +1 -0
- package/dist/ingest-router/index.js +37 -0
- package/dist/ingest-router/index.js.map +1 -0
- package/dist/ingest-router/routing-tables.d.ts +122 -0
- package/dist/ingest-router/routing-tables.d.ts.map +1 -0
- package/dist/ingest-router/routing-tables.js +145 -0
- package/dist/ingest-router/routing-tables.js.map +1 -0
- package/dist/ingest-router/select-strategy.d.ts +67 -0
- package/dist/ingest-router/select-strategy.d.ts.map +1 -0
- package/dist/ingest-router/select-strategy.js +100 -0
- package/dist/ingest-router/select-strategy.js.map +1 -0
- package/dist/memory-router/MemoryRouter.d.ts +195 -0
- package/dist/memory-router/MemoryRouter.d.ts.map +1 -0
- package/dist/memory-router/MemoryRouter.js +155 -0
- package/dist/memory-router/MemoryRouter.js.map +1 -0
- package/dist/memory-router/adaptive.d.ts +142 -0
- package/dist/memory-router/adaptive.d.ts.map +1 -0
- package/dist/memory-router/adaptive.js +202 -0
- package/dist/memory-router/adaptive.js.map +1 -0
- package/dist/memory-router/backend-costs.d.ts +67 -0
- package/dist/memory-router/backend-costs.d.ts.map +1 -0
- package/dist/memory-router/backend-costs.js +136 -0
- package/dist/memory-router/backend-costs.js.map +1 -0
- package/dist/memory-router/classifier.d.ts +169 -0
- package/dist/memory-router/classifier.d.ts.map +1 -0
- package/dist/memory-router/classifier.js +193 -0
- package/dist/memory-router/classifier.js.map +1 -0
- package/dist/memory-router/dispatcher.d.ts +115 -0
- package/dist/memory-router/dispatcher.d.ts.map +1 -0
- package/dist/memory-router/dispatcher.js +84 -0
- package/dist/memory-router/dispatcher.js.map +1 -0
- package/dist/memory-router/index.d.ts +126 -0
- package/dist/memory-router/index.d.ts.map +1 -0
- package/dist/memory-router/index.js +122 -0
- package/dist/memory-router/index.js.map +1 -0
- package/dist/memory-router/routing-tables.d.ts +125 -0
- package/dist/memory-router/routing-tables.d.ts.map +1 -0
- package/dist/memory-router/routing-tables.js +137 -0
- package/dist/memory-router/routing-tables.js.map +1 -0
- package/dist/memory-router/select-backend.d.ts +136 -0
- package/dist/memory-router/select-backend.d.ts.map +1 -0
- package/dist/memory-router/select-backend.js +210 -0
- package/dist/memory-router/select-backend.js.map +1 -0
- package/dist/multi-stage-guardrails/index.d.ts +190 -0
- package/dist/multi-stage-guardrails/index.d.ts.map +1 -0
- package/dist/multi-stage-guardrails/index.js +186 -0
- package/dist/multi-stage-guardrails/index.js.map +1 -0
- package/dist/read-router/ReadRouter.d.ts +58 -0
- package/dist/read-router/ReadRouter.d.ts.map +1 -0
- package/dist/read-router/ReadRouter.js +91 -0
- package/dist/read-router/ReadRouter.js.map +1 -0
- package/dist/read-router/classifier.d.ts +54 -0
- package/dist/read-router/classifier.d.ts.map +1 -0
- package/dist/read-router/classifier.js +104 -0
- package/dist/read-router/classifier.js.map +1 -0
- package/dist/read-router/costs.d.ts +23 -0
- package/dist/read-router/costs.d.ts.map +1 -0
- package/dist/read-router/costs.js +51 -0
- package/dist/read-router/costs.js.map +1 -0
- package/dist/read-router/dispatcher.d.ts +33 -0
- package/dist/read-router/dispatcher.d.ts.map +1 -0
- package/dist/read-router/dispatcher.js +29 -0
- package/dist/read-router/dispatcher.js.map +1 -0
- package/dist/read-router/index.d.ts +23 -0
- package/dist/read-router/index.d.ts.map +1 -0
- package/dist/read-router/index.js +17 -0
- package/dist/read-router/index.js.map +1 -0
- package/dist/read-router/routing-tables.d.ts +85 -0
- package/dist/read-router/routing-tables.d.ts.map +1 -0
- package/dist/read-router/routing-tables.js +79 -0
- package/dist/read-router/routing-tables.js.map +1 -0
- package/dist/read-router/select-strategy.d.ts +42 -0
- package/dist/read-router/select-strategy.d.ts.map +1 -0
- package/dist/read-router/select-strategy.js +92 -0
- package/dist/read-router/select-strategy.js.map +1 -0
- package/package.json +21 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MemoryRouter.ts
|
|
3
|
+
* @description Top-level orchestrator that composes the LLM-as-judge
|
|
4
|
+
* classifier and the pure `selectBackend` decision function into a single
|
|
5
|
+
* per-query routing call.
|
|
6
|
+
*
|
|
7
|
+
* MemoryRouter is deliberately a THIN composition layer. It:
|
|
8
|
+
* 1. Runs the classifier on the incoming query → category + token counts.
|
|
9
|
+
* 2. Resolves the routing table from (preset | custom table | custom mapping).
|
|
10
|
+
* 3. Calls the pure selectBackend to get the routing decision.
|
|
11
|
+
* 4. Returns a {@link MemoryRouterDecision} bundling both.
|
|
12
|
+
*
|
|
13
|
+
* It does NOT execute the recall — backend execution is the job of
|
|
14
|
+
* {@link IMemoryDispatcher}. This split keeps the router pure-enough to
|
|
15
|
+
* be used in both "decide only" flows (benchmarks, dashboards, dry-runs)
|
|
16
|
+
* and "decide + execute" flows (production queries).
|
|
17
|
+
*
|
|
18
|
+
* @module @framers/agentos/memory-router/MemoryRouter
|
|
19
|
+
*/
|
|
20
|
+
import type { IMemoryClassifier, MemoryClassifierResult } from './classifier.js';
|
|
21
|
+
import { type MemoryBackendCostPoint } from './backend-costs.js';
|
|
22
|
+
import { type MemoryBackendId, type MemoryQueryCategory, type MemoryRouterPreset, type RoutingTable } from './routing-tables.js';
|
|
23
|
+
import { type MemoryBudgetMode, type MemoryRoutingDecision } from './select-backend.js';
|
|
24
|
+
import type { IMemoryDispatcher } from './dispatcher.js';
|
|
25
|
+
/**
|
|
26
|
+
* Per-query USD budget policy. Combined into a single nested object so
|
|
27
|
+
* consumers can enable budget enforcement without flat-argument sprawl.
|
|
28
|
+
*/
|
|
29
|
+
export interface MemoryBudgetPolicy {
|
|
30
|
+
/**
|
|
31
|
+
* Budget ceiling per query in USD. When omitted, routing passes
|
|
32
|
+
* through the table's pick regardless of cost.
|
|
33
|
+
*/
|
|
34
|
+
readonly perQueryUsd?: number;
|
|
35
|
+
/**
|
|
36
|
+
* How to handle budget overrun. Default `cheapest-fallback` for
|
|
37
|
+
* production safety (silently downgrades rather than throwing).
|
|
38
|
+
* See {@link MemoryBudgetMode}.
|
|
39
|
+
*/
|
|
40
|
+
readonly mode?: MemoryBudgetMode;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Constructor options for {@link MemoryRouter}.
|
|
44
|
+
*/
|
|
45
|
+
export interface MemoryRouterOptions {
|
|
46
|
+
/** LLM-as-judge classifier. Usually {@link LLMMemoryClassifier}. */
|
|
47
|
+
readonly classifier: IMemoryClassifier;
|
|
48
|
+
/**
|
|
49
|
+
* Shipping preset to use. Defaults to `minimize-cost` — the same
|
|
50
|
+
* Pareto-best-for-cost preset we use on LongMemEval-S Phase B.
|
|
51
|
+
*/
|
|
52
|
+
readonly preset?: MemoryRouterPreset;
|
|
53
|
+
/**
|
|
54
|
+
* Optional custom routing table override. When provided, replaces the
|
|
55
|
+
* preset's default table. The `preset` field is still used for
|
|
56
|
+
* telemetry labeling and must match.
|
|
57
|
+
*/
|
|
58
|
+
readonly routingTable?: RoutingTable;
|
|
59
|
+
/**
|
|
60
|
+
* Optional per-category routing override that patches the resolved
|
|
61
|
+
* routing table. Useful when a workload needs to change a single
|
|
62
|
+
* category's dispatch without rewriting the whole table.
|
|
63
|
+
*/
|
|
64
|
+
readonly mapping?: Partial<Record<MemoryQueryCategory, MemoryBackendId>>;
|
|
65
|
+
/**
|
|
66
|
+
* Optional budget policy. When omitted, no budget is enforced.
|
|
67
|
+
*/
|
|
68
|
+
readonly budget?: MemoryBudgetPolicy;
|
|
69
|
+
/**
|
|
70
|
+
* Optional custom backend cost-points (for workloads whose cost /
|
|
71
|
+
* accuracy profile diverges from LongMemEval-S Phase B). When omitted,
|
|
72
|
+
* uses {@link DEFAULT_MEMORY_BACKEND_COSTS}.
|
|
73
|
+
*/
|
|
74
|
+
readonly backendCosts?: Readonly<Record<MemoryBackendId, MemoryBackendCostPoint>>;
|
|
75
|
+
/**
|
|
76
|
+
* Default for {@link MemoryClassifierClassifyOptions.useFewShotPrompt}
|
|
77
|
+
* on every `decide()` call. Callers can still override per-call.
|
|
78
|
+
*/
|
|
79
|
+
readonly useFewShotPrompt?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Optional dispatcher. When supplied, {@link MemoryRouter.decideAndDispatch}
|
|
82
|
+
* is usable; otherwise callers must use {@link MemoryRouter.decide} and
|
|
83
|
+
* execute the chosen backend themselves.
|
|
84
|
+
*/
|
|
85
|
+
readonly dispatcher?: IMemoryDispatcher<unknown, unknown>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Per-call options for {@link MemoryRouter.decide}.
|
|
89
|
+
*/
|
|
90
|
+
export interface MemoryRouterDecideOptions {
|
|
91
|
+
/**
|
|
92
|
+
* Ground-truth category, passed through to the routing decision for
|
|
93
|
+
* telemetry. Not used in production. Benchmark adapters pass this when
|
|
94
|
+
* the gold label is available so downstream analysis can distinguish
|
|
95
|
+
* classifier misroutes from architectural misses.
|
|
96
|
+
*/
|
|
97
|
+
readonly groundTruthCategory?: MemoryQueryCategory | null;
|
|
98
|
+
/**
|
|
99
|
+
* Per-call override of the few-shot prompt variant. When omitted,
|
|
100
|
+
* inherits the router's constructor-scoped default.
|
|
101
|
+
*/
|
|
102
|
+
readonly useFewShotPrompt?: boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Bundled result of a `decide()` call. Carries the classifier result
|
|
106
|
+
* (for cost tracking + debugging) alongside the routing decision.
|
|
107
|
+
*/
|
|
108
|
+
export interface MemoryRouterDecision {
|
|
109
|
+
readonly classifier: MemoryClassifierResult;
|
|
110
|
+
readonly routing: MemoryRoutingDecision;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Bundled result of a `decideAndDispatch()` call. Combines the full
|
|
114
|
+
* {@link MemoryRouterDecision} with the dispatched traces so telemetry
|
|
115
|
+
* and answer-generation can consume both in one step.
|
|
116
|
+
*/
|
|
117
|
+
export interface MemoryRouterDispatchedDecision<TTrace> {
|
|
118
|
+
readonly decision: MemoryRouterDecision;
|
|
119
|
+
readonly traces: TTrace[];
|
|
120
|
+
readonly backend: MemoryBackendId;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Thrown when `decideAndDispatch` is called on a router that was
|
|
124
|
+
* constructed without a dispatcher.
|
|
125
|
+
*/
|
|
126
|
+
export declare class MemoryRouterDispatcherMissingError extends Error {
|
|
127
|
+
constructor();
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The public MemoryRouter primitive. One instance per memory-recall
|
|
131
|
+
* endpoint; construct once at app startup with the chosen preset and
|
|
132
|
+
* reuse across queries.
|
|
133
|
+
*
|
|
134
|
+
* @example Basic min-cost routing
|
|
135
|
+
* ```ts
|
|
136
|
+
* import { LLMMemoryClassifier, MemoryRouter } from '../memory-router';
|
|
137
|
+
*
|
|
138
|
+
* const router = new MemoryRouter({
|
|
139
|
+
* classifier: new LLMMemoryClassifier({ llm: myOpenAIAdapter }),
|
|
140
|
+
* preset: 'minimize-cost',
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* const decision = await router.decide("What's my current job title?");
|
|
144
|
+
* console.log(decision.classifier.category); // 'knowledge-update'
|
|
145
|
+
* console.log(decision.routing.chosenBackend); // 'canonical-hybrid'
|
|
146
|
+
* console.log(decision.routing.estimatedCostUsd); // 0.0189
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* @example With a strict budget
|
|
150
|
+
* ```ts
|
|
151
|
+
* const router = new MemoryRouter({
|
|
152
|
+
* classifier: myClassifier,
|
|
153
|
+
* preset: 'maximize-accuracy',
|
|
154
|
+
* budget: { perQueryUsd: 0.025, mode: 'cheapest-fallback' },
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export declare class MemoryRouter {
|
|
159
|
+
private readonly classifier;
|
|
160
|
+
private readonly preset;
|
|
161
|
+
private readonly routingTable;
|
|
162
|
+
private readonly budgetPerQuery;
|
|
163
|
+
private readonly budgetMode;
|
|
164
|
+
private readonly backendCosts;
|
|
165
|
+
private readonly defaultUseFewShotPrompt;
|
|
166
|
+
private readonly dispatcher;
|
|
167
|
+
constructor(options: MemoryRouterOptions);
|
|
168
|
+
/**
|
|
169
|
+
* Decide-only routing. Classifies the query, picks a backend, returns
|
|
170
|
+
* both pieces. Does NOT execute the recall — pair with an
|
|
171
|
+
* {@link IMemoryDispatcher} for the end-to-end flow, or call
|
|
172
|
+
* {@link MemoryRouter.decideAndDispatch} if a dispatcher is wired.
|
|
173
|
+
*
|
|
174
|
+
* @param query - The user's memory-recall query text.
|
|
175
|
+
* @param options - Per-call overrides (ground-truth telemetry, prompt variant).
|
|
176
|
+
* @returns A {@link MemoryRouterDecision} bundling classifier + routing results.
|
|
177
|
+
*/
|
|
178
|
+
decide(query: string, options?: MemoryRouterDecideOptions): Promise<MemoryRouterDecision>;
|
|
179
|
+
/**
|
|
180
|
+
* Decide + dispatch in one call. Requires the router to have been
|
|
181
|
+
* constructed with a {@link IMemoryDispatcher}.
|
|
182
|
+
*
|
|
183
|
+
* @typeParam TTrace - Caller's trace shape (passed through verbatim).
|
|
184
|
+
* @typeParam TPayload - Caller's payload shape for the dispatcher.
|
|
185
|
+
* @param query - User memory-recall query.
|
|
186
|
+
* @param dispatchPayload - Optional payload forwarded to the dispatcher's
|
|
187
|
+
* per-backend executor (e.g. topK, retrieval policy).
|
|
188
|
+
* @param options - Per-call overrides (ground-truth telemetry, prompt variant).
|
|
189
|
+
*
|
|
190
|
+
* @throws {@link MemoryRouterDispatcherMissingError} when no dispatcher
|
|
191
|
+
* was supplied at construction.
|
|
192
|
+
*/
|
|
193
|
+
decideAndDispatch<TTrace, TPayload = undefined>(query: string, dispatchPayload?: TPayload, options?: MemoryRouterDecideOptions): Promise<MemoryRouterDispatchedDecision<TTrace>>;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=MemoryRouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryRouter.d.ts","sourceRoot":"","sources":["../../src/memory-router/MemoryRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MemoryRouter.ts
|
|
3
|
+
* @description Top-level orchestrator that composes the LLM-as-judge
|
|
4
|
+
* classifier and the pure `selectBackend` decision function into a single
|
|
5
|
+
* per-query routing call.
|
|
6
|
+
*
|
|
7
|
+
* MemoryRouter is deliberately a THIN composition layer. It:
|
|
8
|
+
* 1. Runs the classifier on the incoming query → category + token counts.
|
|
9
|
+
* 2. Resolves the routing table from (preset | custom table | custom mapping).
|
|
10
|
+
* 3. Calls the pure selectBackend to get the routing decision.
|
|
11
|
+
* 4. Returns a {@link MemoryRouterDecision} bundling both.
|
|
12
|
+
*
|
|
13
|
+
* It does NOT execute the recall — backend execution is the job of
|
|
14
|
+
* {@link IMemoryDispatcher}. This split keeps the router pure-enough to
|
|
15
|
+
* be used in both "decide only" flows (benchmarks, dashboards, dry-runs)
|
|
16
|
+
* and "decide + execute" flows (production queries).
|
|
17
|
+
*
|
|
18
|
+
* @module @framers/agentos/memory-router/MemoryRouter
|
|
19
|
+
*/
|
|
20
|
+
import { DEFAULT_MEMORY_BACKEND_COSTS, } from './backend-costs.js';
|
|
21
|
+
import { PRESET_TABLES, } from './routing-tables.js';
|
|
22
|
+
import { selectBackend, } from './select-backend.js';
|
|
23
|
+
/**
|
|
24
|
+
* Thrown when `decideAndDispatch` is called on a router that was
|
|
25
|
+
* constructed without a dispatcher.
|
|
26
|
+
*/
|
|
27
|
+
export class MemoryRouterDispatcherMissingError extends Error {
|
|
28
|
+
constructor() {
|
|
29
|
+
super('MemoryRouter.decideAndDispatch requires a dispatcher. ' +
|
|
30
|
+
'Either pass a dispatcher in options, or call `decide` and dispatch yourself.');
|
|
31
|
+
this.name = 'MemoryRouterDispatcherMissingError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Class
|
|
36
|
+
// ============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* The public MemoryRouter primitive. One instance per memory-recall
|
|
39
|
+
* endpoint; construct once at app startup with the chosen preset and
|
|
40
|
+
* reuse across queries.
|
|
41
|
+
*
|
|
42
|
+
* @example Basic min-cost routing
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { LLMMemoryClassifier, MemoryRouter } from '../memory-router/index.js';
|
|
45
|
+
*
|
|
46
|
+
* const router = new MemoryRouter({
|
|
47
|
+
* classifier: new LLMMemoryClassifier({ llm: myOpenAIAdapter }),
|
|
48
|
+
* preset: 'minimize-cost',
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* const decision = await router.decide("What's my current job title?");
|
|
52
|
+
* console.log(decision.classifier.category); // 'knowledge-update'
|
|
53
|
+
* console.log(decision.routing.chosenBackend); // 'canonical-hybrid'
|
|
54
|
+
* console.log(decision.routing.estimatedCostUsd); // 0.0189
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @example With a strict budget
|
|
58
|
+
* ```ts
|
|
59
|
+
* const router = new MemoryRouter({
|
|
60
|
+
* classifier: myClassifier,
|
|
61
|
+
* preset: 'maximize-accuracy',
|
|
62
|
+
* budget: { perQueryUsd: 0.025, mode: 'cheapest-fallback' },
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export class MemoryRouter {
|
|
67
|
+
constructor(options) {
|
|
68
|
+
this.classifier = options.classifier;
|
|
69
|
+
this.preset = options.preset ?? 'minimize-cost';
|
|
70
|
+
this.dispatcher = options.dispatcher ?? null;
|
|
71
|
+
// Resolve routing table: explicit > preset's default.
|
|
72
|
+
const baseTable = options.routingTable ?? PRESET_TABLES[this.preset];
|
|
73
|
+
// Apply optional per-category mapping override.
|
|
74
|
+
if (options.mapping) {
|
|
75
|
+
const patched = {
|
|
76
|
+
...baseTable.defaultMapping,
|
|
77
|
+
};
|
|
78
|
+
for (const key of Object.keys(options.mapping)) {
|
|
79
|
+
const override = options.mapping[key];
|
|
80
|
+
if (override)
|
|
81
|
+
patched[key] = override;
|
|
82
|
+
}
|
|
83
|
+
this.routingTable = Object.freeze({
|
|
84
|
+
preset: baseTable.preset,
|
|
85
|
+
defaultMapping: Object.freeze(patched),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.routingTable = baseTable;
|
|
90
|
+
}
|
|
91
|
+
this.budgetPerQuery = options.budget?.perQueryUsd ?? null;
|
|
92
|
+
this.budgetMode = options.budget?.mode ?? 'cheapest-fallback';
|
|
93
|
+
this.backendCosts = options.backendCosts ?? DEFAULT_MEMORY_BACKEND_COSTS;
|
|
94
|
+
this.defaultUseFewShotPrompt = options.useFewShotPrompt ?? false;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Decide-only routing. Classifies the query, picks a backend, returns
|
|
98
|
+
* both pieces. Does NOT execute the recall — pair with an
|
|
99
|
+
* {@link IMemoryDispatcher} for the end-to-end flow, or call
|
|
100
|
+
* {@link MemoryRouter.decideAndDispatch} if a dispatcher is wired.
|
|
101
|
+
*
|
|
102
|
+
* @param query - The user's memory-recall query text.
|
|
103
|
+
* @param options - Per-call overrides (ground-truth telemetry, prompt variant).
|
|
104
|
+
* @returns A {@link MemoryRouterDecision} bundling classifier + routing results.
|
|
105
|
+
*/
|
|
106
|
+
async decide(query, options) {
|
|
107
|
+
const useFewShot = options?.useFewShotPrompt ?? this.defaultUseFewShotPrompt;
|
|
108
|
+
const classifierOptions = useFewShot
|
|
109
|
+
? { useFewShotPrompt: true }
|
|
110
|
+
: undefined;
|
|
111
|
+
const classifier = await this.classifier.classify(query, classifierOptions);
|
|
112
|
+
const routing = selectBackend({
|
|
113
|
+
predictedCategory: classifier.category,
|
|
114
|
+
groundTruthCategory: options?.groundTruthCategory ?? null,
|
|
115
|
+
config: {
|
|
116
|
+
table: this.routingTable,
|
|
117
|
+
budgetPerQuery: this.budgetPerQuery,
|
|
118
|
+
budgetMode: this.budgetMode,
|
|
119
|
+
backendCosts: this.backendCosts,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
return { classifier, routing };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Decide + dispatch in one call. Requires the router to have been
|
|
126
|
+
* constructed with a {@link IMemoryDispatcher}.
|
|
127
|
+
*
|
|
128
|
+
* @typeParam TTrace - Caller's trace shape (passed through verbatim).
|
|
129
|
+
* @typeParam TPayload - Caller's payload shape for the dispatcher.
|
|
130
|
+
* @param query - User memory-recall query.
|
|
131
|
+
* @param dispatchPayload - Optional payload forwarded to the dispatcher's
|
|
132
|
+
* per-backend executor (e.g. topK, retrieval policy).
|
|
133
|
+
* @param options - Per-call overrides (ground-truth telemetry, prompt variant).
|
|
134
|
+
*
|
|
135
|
+
* @throws {@link MemoryRouterDispatcherMissingError} when no dispatcher
|
|
136
|
+
* was supplied at construction.
|
|
137
|
+
*/
|
|
138
|
+
async decideAndDispatch(query, dispatchPayload, options) {
|
|
139
|
+
if (!this.dispatcher) {
|
|
140
|
+
throw new MemoryRouterDispatcherMissingError();
|
|
141
|
+
}
|
|
142
|
+
const decision = await this.decide(query, options);
|
|
143
|
+
const dispatched = (await this.dispatcher.dispatch({
|
|
144
|
+
backend: decision.routing.chosenBackend,
|
|
145
|
+
query,
|
|
146
|
+
payload: dispatchPayload,
|
|
147
|
+
}));
|
|
148
|
+
return {
|
|
149
|
+
decision,
|
|
150
|
+
traces: dispatched.traces,
|
|
151
|
+
backend: dispatched.backend,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=MemoryRouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryRouter.js","sourceRoot":"","sources":["../../src/memory-router/MemoryRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
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, type MemoryRouterOptions } from './MemoryRouter.js';
|
|
38
|
+
import { type MemoryBackendId, type MemoryQueryCategory, type RoutingTable } from './routing-tables.js';
|
|
39
|
+
/**
|
|
40
|
+
* One calibration sample. Caller produces these from running their own
|
|
41
|
+
* workload through each candidate backend and recording the outcome.
|
|
42
|
+
*/
|
|
43
|
+
export interface CalibrationSample {
|
|
44
|
+
readonly category: MemoryQueryCategory;
|
|
45
|
+
readonly backend: MemoryBackendId;
|
|
46
|
+
readonly costUsd: number;
|
|
47
|
+
/** 1 = correct, 0 = incorrect (or score in [0,1] for soft graders). */
|
|
48
|
+
readonly correct: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Aggregated calibration cell: one (category, backend) → mean cost +
|
|
52
|
+
* mean accuracy + sample count.
|
|
53
|
+
*/
|
|
54
|
+
export interface CalibrationCell {
|
|
55
|
+
readonly n: number;
|
|
56
|
+
readonly meanCost: number;
|
|
57
|
+
readonly meanAccuracy: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Map of (category, backend) → CalibrationCell. Categories or backends
|
|
61
|
+
* with no samples are simply absent from the map.
|
|
62
|
+
*/
|
|
63
|
+
export type AggregatedCalibration = Partial<Record<MemoryQueryCategory, Partial<Record<MemoryBackendId, CalibrationCell>>>>;
|
|
64
|
+
/**
|
|
65
|
+
* Preset selection rules for {@link selectByPreset}.
|
|
66
|
+
*
|
|
67
|
+
* - `minimize-cost`: pick the cheapest backend whose meanAccuracy is
|
|
68
|
+
* within `accuracyTolerance` (default 0.02 = 2pp) of the best
|
|
69
|
+
* meanAccuracy on this category. If no backend is within tolerance,
|
|
70
|
+
* pick the best-accuracy backend (the gap exceeds the tolerance,
|
|
71
|
+
* meaning accuracy gain justifies cost).
|
|
72
|
+
* - `maximize-accuracy`: pick the highest-meanAccuracy backend;
|
|
73
|
+
* ties broken by lower meanCost.
|
|
74
|
+
* - `balanced`: pick the lowest meanCost / meanAccuracy ratio
|
|
75
|
+
* ($/correct). Backends with zero meanAccuracy are skipped (would
|
|
76
|
+
* produce divide-by-zero).
|
|
77
|
+
*/
|
|
78
|
+
export type AdaptivePresetRule = 'minimize-cost' | 'balanced' | 'maximize-accuracy';
|
|
79
|
+
export interface SelectByPresetArgs {
|
|
80
|
+
readonly category: MemoryQueryCategory;
|
|
81
|
+
readonly agg: AggregatedCalibration;
|
|
82
|
+
readonly preset: AdaptivePresetRule;
|
|
83
|
+
/**
|
|
84
|
+
* Minimum sample count per (category, backend) cell required for
|
|
85
|
+
* adaptive selection. Cells below this threshold are ignored. Default
|
|
86
|
+
* 1 (any sample qualifies). Increase for noisier workloads.
|
|
87
|
+
*/
|
|
88
|
+
readonly minSamplesPerCell?: number;
|
|
89
|
+
/**
|
|
90
|
+
* For `minimize-cost`: max accuracy gap from the best-accuracy backend
|
|
91
|
+
* tolerated when picking the cheaper alternative. Default 0.02 (2pp).
|
|
92
|
+
*/
|
|
93
|
+
readonly accuracyTolerance?: number;
|
|
94
|
+
}
|
|
95
|
+
export interface BuildAdaptiveRoutingTableArgs {
|
|
96
|
+
readonly samples: readonly CalibrationSample[];
|
|
97
|
+
readonly preset: AdaptivePresetRule;
|
|
98
|
+
readonly minSamplesPerCell?: number;
|
|
99
|
+
readonly accuracyTolerance?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Fallback static table for categories with insufficient calibration.
|
|
102
|
+
* Defaults to the preset's shipping static table.
|
|
103
|
+
*/
|
|
104
|
+
readonly fallbackTable?: RoutingTable;
|
|
105
|
+
}
|
|
106
|
+
export interface AdaptiveMemoryRouterOptions extends Omit<MemoryRouterOptions, 'routingTable' | 'preset'> {
|
|
107
|
+
readonly calibrationSamples: readonly CalibrationSample[];
|
|
108
|
+
readonly preset: AdaptivePresetRule;
|
|
109
|
+
readonly minSamplesPerCell?: number;
|
|
110
|
+
readonly accuracyTolerance?: number;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Roll up raw calibration samples into per-(category, backend) cells.
|
|
114
|
+
* Each cell carries n, meanCost, meanAccuracy.
|
|
115
|
+
*/
|
|
116
|
+
export declare function aggregateCalibration(samples: readonly CalibrationSample[]): AggregatedCalibration;
|
|
117
|
+
/**
|
|
118
|
+
* Select a backend for one category from aggregated calibration data
|
|
119
|
+
* using the named preset rule. Falls back to the preset's static table
|
|
120
|
+
* when calibration is insufficient.
|
|
121
|
+
*/
|
|
122
|
+
export declare function selectByPreset(args: SelectByPresetArgs): MemoryBackendId;
|
|
123
|
+
/**
|
|
124
|
+
* Build a complete frozen routing table from calibration samples + a
|
|
125
|
+
* preset rule. Categories without enough calibration fall back to the
|
|
126
|
+
* preset's static table.
|
|
127
|
+
*/
|
|
128
|
+
export declare function buildAdaptiveRoutingTable(args: BuildAdaptiveRoutingTableArgs): RoutingTable;
|
|
129
|
+
/**
|
|
130
|
+
* Memory router whose routing table is derived from a calibration
|
|
131
|
+
* dataset rather than a static preset. Otherwise identical API to
|
|
132
|
+
* {@link MemoryRouter}.
|
|
133
|
+
*/
|
|
134
|
+
export declare class AdaptiveMemoryRouter extends MemoryRouter {
|
|
135
|
+
private readonly derivedTable;
|
|
136
|
+
constructor(options: AdaptiveMemoryRouterOptions);
|
|
137
|
+
/**
|
|
138
|
+
* Inspect the derived routing table for debugging / telemetry.
|
|
139
|
+
*/
|
|
140
|
+
getRoutingTable(): RoutingTable;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=adaptive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adaptive.d.ts","sourceRoot":"","sources":["../../src/memory-router/adaptive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAExB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAM7B;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,OAAO,CACzC,MAAM,CAAC,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC,CAC/E,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,UAAU,GACV,mBAAmB,CAAC;AAExB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,qBAAqB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC;CACvC;AAED,MAAM,WAAW,2BACf,SAAQ,IAAI,CAAC,mBAAmB,EAAE,cAAc,GAAG,QAAQ,CAAC;IAC5D,QAAQ,CAAC,kBAAkB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1D,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GACpC,qBAAqB,CA4BvB;AAMD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,CA8DxE;AAeD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,6BAA6B,GAClC,YAAY,CAqCd;AAMD;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAEhC,OAAO,EAAE,2BAA2B;IAiBhD;;OAEG;IACH,eAAe,IAAI,YAAY;CAGhC"}
|