@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,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentOS IngestRouter Module
|
|
3
|
+
*
|
|
4
|
+
* Input-stage LLM-as-judge orchestrator for memory ingest. Sibling of
|
|
5
|
+
* {@link MemoryRouter} (recall-stage), {@link QueryRouter} (Q&A-stage),
|
|
6
|
+
* and the output-stage guardrails. Together they form the agentos
|
|
7
|
+
* multi-stage guardrails pattern.
|
|
8
|
+
*
|
|
9
|
+
* Where MemoryRouter picks the recall architecture for a query,
|
|
10
|
+
* IngestRouter picks the storage architecture for incoming content. The
|
|
11
|
+
* choice affects what's STORED, which downstream MemoryRouter then queries.
|
|
12
|
+
*
|
|
13
|
+
* **Architecture Overview:**
|
|
14
|
+
* ```
|
|
15
|
+
* Content stream
|
|
16
|
+
* │
|
|
17
|
+
* ▼
|
|
18
|
+
* ┌────────────────────────────────────────────────┐
|
|
19
|
+
* │ IngestRouter │
|
|
20
|
+
* │ classify content → pick strategy → store │
|
|
21
|
+
* └────────────────────────────────────────────────┘
|
|
22
|
+
* │ │ │
|
|
23
|
+
* ▼ ▼ ▼
|
|
24
|
+
* raw-chunks summarized observational
|
|
25
|
+
* fact-graph hybrid skip
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @module @framers/agentos/ingest-router
|
|
29
|
+
*/
|
|
30
|
+
export { INGEST_CONTENT_KINDS } from './routing-tables.js';
|
|
31
|
+
export { RAW_CHUNKS_TABLE, SUMMARIZED_TABLE, OBSERVATIONAL_TABLE, HYBRID_TABLE, PRESET_INGEST_TABLES, } from './routing-tables.js';
|
|
32
|
+
export { RAW_CHUNKS_COST, SUMMARIZED_COST, OBSERVATIONAL_COST, FACT_GRAPH_COST, HYBRID_COST, SKIP_COST, DEFAULT_INGEST_COSTS, } from './costs.js';
|
|
33
|
+
export { selectIngestStrategy, IngestRouterUnknownKindError, IngestRouterBudgetExceededError, } from './select-strategy.js';
|
|
34
|
+
export { INGEST_CLASSIFIER_SYSTEM_PROMPT, INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOT, SAFE_INGEST_FALLBACK_KIND, LLMIngestClassifier, normalizeIngestClassifierOutput, parseIngestClassifierOutput, } from './classifier.js';
|
|
35
|
+
export { FunctionIngestDispatcher, UnsupportedIngestStrategyError, } from './dispatcher.js';
|
|
36
|
+
export { IngestRouter, IngestRouterDispatcherMissingError, } from './IngestRouter.js';
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ingest-router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAQH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAoC3D,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,SAAS,EACT,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,+BAA+B,EAC/B,uCAAuC,EACvC,yBAAyB,EACzB,mBAAmB,EACnB,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,YAAY,EACZ,kCAAkC,GACnC,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file routing-tables.ts
|
|
3
|
+
* @description Preset routing tables for {@link IngestRouter}.
|
|
4
|
+
*
|
|
5
|
+
* IngestRouter is the input-stage sibling of MemoryRouter. Where MemoryRouter
|
|
6
|
+
* picks the recall architecture for a query, IngestRouter picks the storage
|
|
7
|
+
* architecture for incoming content. The choice affects what's STORED, which
|
|
8
|
+
* downstream MemoryRouter then queries.
|
|
9
|
+
*
|
|
10
|
+
* Four shipping presets express different cost-vs-recall priorities:
|
|
11
|
+
*
|
|
12
|
+
* - {@link RAW_CHUNKS_TABLE}: stores everything as raw chunks. Cheapest at
|
|
13
|
+
* ingest time. Pushes all complexity to retrieval. Default for cost-
|
|
14
|
+
* sensitive workloads.
|
|
15
|
+
* - {@link SUMMARIZED_TABLE}: applies session/article summarization on long
|
|
16
|
+
* content. Anthropic-style "contextual retrieval" — every chunk gets a
|
|
17
|
+
* dense session-summary prefix before embedding.
|
|
18
|
+
* - {@link OBSERVATIONAL_TABLE}: extracts observation logs (Mastra-style)
|
|
19
|
+
* from long conversational content. Most expensive at ingest, best for
|
|
20
|
+
* multi-session synthesis recall.
|
|
21
|
+
* - {@link HYBRID_TABLE}: applies multiple ingest strategies in parallel
|
|
22
|
+
* for long content (raw chunks + summary + observations). Highest cost,
|
|
23
|
+
* highest recall flexibility — every retrieval strategy has its substrate.
|
|
24
|
+
*
|
|
25
|
+
* @module @framers/agentos/ingest-router/routing-tables
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* The six content kinds the LLM-as-judge ingest classifier can emit.
|
|
29
|
+
* Coarse taxonomy chosen to map cleanly onto distinct ingest strategies —
|
|
30
|
+
* extending the taxonomy means extending the routing tables consistently.
|
|
31
|
+
*/
|
|
32
|
+
export declare const INGEST_CONTENT_KINDS: readonly ["short-conversation", "long-conversation", "long-article", "code", "structured-data", "multimodal"];
|
|
33
|
+
export type IngestContentKind = (typeof INGEST_CONTENT_KINDS)[number];
|
|
34
|
+
/**
|
|
35
|
+
* The six storage strategies an IngestDispatcher can execute.
|
|
36
|
+
*
|
|
37
|
+
* - `raw-chunks`: standard turn-by-turn (or semantic) chunking, no LLM at
|
|
38
|
+
* ingest. The Memory.remember() default.
|
|
39
|
+
* - `summarized`: every chunk prepended with a dense session/document
|
|
40
|
+
* summary before embedding (Anthropic Sep 2024 "contextual retrieval").
|
|
41
|
+
* One LLM summarize call per session/document at ingest time.
|
|
42
|
+
* - `observational`: extract a structured observation log from the content
|
|
43
|
+
* (Mastra Observational Memory pattern). Multiple LLM extraction calls
|
|
44
|
+
* per session at ingest time. Recalled traces are observations rather
|
|
45
|
+
* than raw turns.
|
|
46
|
+
* - `fact-graph`: extract atomic fact triples from the content (Mem0-style).
|
|
47
|
+
* LLM-triple-extraction at ingest. Recall queries the fact graph.
|
|
48
|
+
* - `hybrid`: apply multiple strategies in parallel (e.g., raw-chunks +
|
|
49
|
+
* summarized + observational). Most expensive at ingest. Highest recall
|
|
50
|
+
* flexibility.
|
|
51
|
+
* - `skip`: do not ingest the content. For low-value session noise that
|
|
52
|
+
* wastes recall slots and inflates retrieval cost.
|
|
53
|
+
*/
|
|
54
|
+
export type IngestStrategyId = 'raw-chunks' | 'summarized' | 'observational' | 'fact-graph' | 'hybrid' | 'skip';
|
|
55
|
+
/**
|
|
56
|
+
* The shipping preset names. Each names a cost-vs-recall point.
|
|
57
|
+
*/
|
|
58
|
+
export type IngestRouterPreset = 'raw-chunks' | 'summarized' | 'observational' | 'hybrid';
|
|
59
|
+
/**
|
|
60
|
+
* A routing table maps every {@link IngestContentKind} to its preferred
|
|
61
|
+
* {@link IngestStrategyId}. Tables are frozen so consumers cannot mutate
|
|
62
|
+
* the routing surface from outside the module.
|
|
63
|
+
*/
|
|
64
|
+
export interface IngestRoutingTable {
|
|
65
|
+
readonly preset: IngestRouterPreset;
|
|
66
|
+
readonly defaultMapping: Readonly<Record<IngestContentKind, IngestStrategyId>>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Preset: raw-chunks (default for cost-sensitive workloads).
|
|
70
|
+
*
|
|
71
|
+
* Stores everything as raw chunks regardless of content kind. Zero LLM
|
|
72
|
+
* cost at ingest time. All complexity is pushed to retrieval where the
|
|
73
|
+
* MemoryRouter can compose hybrid retrieval over the raw chunks.
|
|
74
|
+
*
|
|
75
|
+
* Recommended when: ingest volume is high, retrieval-side compute is
|
|
76
|
+
* cheap, and you trust the retrieval stage to do the heavy lifting.
|
|
77
|
+
*/
|
|
78
|
+
export declare const RAW_CHUNKS_TABLE: IngestRoutingTable;
|
|
79
|
+
/**
|
|
80
|
+
* Preset: summarized (contextual retrieval for long content).
|
|
81
|
+
*
|
|
82
|
+
* Long content (long-conversation, long-article) gets a session/document
|
|
83
|
+
* summary prepended to every chunk before embedding. Short content stays
|
|
84
|
+
* as raw chunks. Code and structured data are summarized for the
|
|
85
|
+
* cross-file context. Multimodal stays raw — embedding modality is
|
|
86
|
+
* orthogonal to summarization.
|
|
87
|
+
*
|
|
88
|
+
* Recommended when: documents and conversations have meaningful global
|
|
89
|
+
* context that improves retrieval recall.
|
|
90
|
+
*/
|
|
91
|
+
export declare const SUMMARIZED_TABLE: IngestRoutingTable;
|
|
92
|
+
/**
|
|
93
|
+
* Preset: observational (Mastra-style for multi-session synthesis).
|
|
94
|
+
*
|
|
95
|
+
* Long conversational content (long-conversation) becomes a structured
|
|
96
|
+
* observation log via LLM extraction at ingest. Long articles get the
|
|
97
|
+
* cheaper summarized treatment. Short content, code, structured, and
|
|
98
|
+
* multimodal stay raw.
|
|
99
|
+
*
|
|
100
|
+
* Recommended when: workload is conversational and includes many
|
|
101
|
+
* multi-session synthesis questions ("what have we agreed to so far",
|
|
102
|
+
* "across our chats, what topics recur").
|
|
103
|
+
*/
|
|
104
|
+
export declare const OBSERVATIONAL_TABLE: IngestRoutingTable;
|
|
105
|
+
/**
|
|
106
|
+
* Preset: hybrid (maximum-recall workloads).
|
|
107
|
+
*
|
|
108
|
+
* Applies multiple ingest strategies in parallel for long content. Every
|
|
109
|
+
* downstream retrieval architecture has its substrate (raw chunks for
|
|
110
|
+
* canonical hybrid, summary prefix for contextual retrieval, observation
|
|
111
|
+
* log for OM-style synthesis). Highest cost at ingest; highest flexibility
|
|
112
|
+
* at retrieval.
|
|
113
|
+
*
|
|
114
|
+
* Recommended when: cost-per-ingest is acceptable AND retrieval workload
|
|
115
|
+
* is heterogeneous enough that no single strategy dominates.
|
|
116
|
+
*/
|
|
117
|
+
export declare const HYBRID_TABLE: IngestRoutingTable;
|
|
118
|
+
/**
|
|
119
|
+
* Preset registry keyed by name.
|
|
120
|
+
*/
|
|
121
|
+
export declare const PRESET_INGEST_TABLES: Readonly<Record<IngestRouterPreset, IngestRoutingTable>>;
|
|
122
|
+
//# sourceMappingURL=routing-tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing-tables.d.ts","sourceRoot":"","sources":["../../src/ingest-router/routing-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,+GAOvB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,QAAQ,GACR,MAAM,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,QAAQ,CAAC;AAEb;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAC/B,MAAM,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAC5C,CAAC;CACH;AAMD;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAUP,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAUP,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,kBAUV,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,kBAUH,CAAC;AAEzB;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CACzC,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAM9C,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file routing-tables.ts
|
|
3
|
+
* @description Preset routing tables for {@link IngestRouter}.
|
|
4
|
+
*
|
|
5
|
+
* IngestRouter is the input-stage sibling of MemoryRouter. Where MemoryRouter
|
|
6
|
+
* picks the recall architecture for a query, IngestRouter picks the storage
|
|
7
|
+
* architecture for incoming content. The choice affects what's STORED, which
|
|
8
|
+
* downstream MemoryRouter then queries.
|
|
9
|
+
*
|
|
10
|
+
* Four shipping presets express different cost-vs-recall priorities:
|
|
11
|
+
*
|
|
12
|
+
* - {@link RAW_CHUNKS_TABLE}: stores everything as raw chunks. Cheapest at
|
|
13
|
+
* ingest time. Pushes all complexity to retrieval. Default for cost-
|
|
14
|
+
* sensitive workloads.
|
|
15
|
+
* - {@link SUMMARIZED_TABLE}: applies session/article summarization on long
|
|
16
|
+
* content. Anthropic-style "contextual retrieval" — every chunk gets a
|
|
17
|
+
* dense session-summary prefix before embedding.
|
|
18
|
+
* - {@link OBSERVATIONAL_TABLE}: extracts observation logs (Mastra-style)
|
|
19
|
+
* from long conversational content. Most expensive at ingest, best for
|
|
20
|
+
* multi-session synthesis recall.
|
|
21
|
+
* - {@link HYBRID_TABLE}: applies multiple ingest strategies in parallel
|
|
22
|
+
* for long content (raw chunks + summary + observations). Highest cost,
|
|
23
|
+
* highest recall flexibility — every retrieval strategy has its substrate.
|
|
24
|
+
*
|
|
25
|
+
* @module @framers/agentos/ingest-router/routing-tables
|
|
26
|
+
*/
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// Types
|
|
29
|
+
// ============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* The six content kinds the LLM-as-judge ingest classifier can emit.
|
|
32
|
+
* Coarse taxonomy chosen to map cleanly onto distinct ingest strategies —
|
|
33
|
+
* extending the taxonomy means extending the routing tables consistently.
|
|
34
|
+
*/
|
|
35
|
+
export const INGEST_CONTENT_KINDS = [
|
|
36
|
+
'short-conversation',
|
|
37
|
+
'long-conversation',
|
|
38
|
+
'long-article',
|
|
39
|
+
'code',
|
|
40
|
+
'structured-data',
|
|
41
|
+
'multimodal',
|
|
42
|
+
];
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Preset tables
|
|
45
|
+
// ============================================================================
|
|
46
|
+
/**
|
|
47
|
+
* Preset: raw-chunks (default for cost-sensitive workloads).
|
|
48
|
+
*
|
|
49
|
+
* Stores everything as raw chunks regardless of content kind. Zero LLM
|
|
50
|
+
* cost at ingest time. All complexity is pushed to retrieval where the
|
|
51
|
+
* MemoryRouter can compose hybrid retrieval over the raw chunks.
|
|
52
|
+
*
|
|
53
|
+
* Recommended when: ingest volume is high, retrieval-side compute is
|
|
54
|
+
* cheap, and you trust the retrieval stage to do the heavy lifting.
|
|
55
|
+
*/
|
|
56
|
+
export const RAW_CHUNKS_TABLE = Object.freeze({
|
|
57
|
+
preset: 'raw-chunks',
|
|
58
|
+
defaultMapping: Object.freeze({
|
|
59
|
+
'short-conversation': 'raw-chunks',
|
|
60
|
+
'long-conversation': 'raw-chunks',
|
|
61
|
+
'long-article': 'raw-chunks',
|
|
62
|
+
code: 'raw-chunks',
|
|
63
|
+
'structured-data': 'raw-chunks',
|
|
64
|
+
multimodal: 'raw-chunks',
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* Preset: summarized (contextual retrieval for long content).
|
|
69
|
+
*
|
|
70
|
+
* Long content (long-conversation, long-article) gets a session/document
|
|
71
|
+
* summary prepended to every chunk before embedding. Short content stays
|
|
72
|
+
* as raw chunks. Code and structured data are summarized for the
|
|
73
|
+
* cross-file context. Multimodal stays raw — embedding modality is
|
|
74
|
+
* orthogonal to summarization.
|
|
75
|
+
*
|
|
76
|
+
* Recommended when: documents and conversations have meaningful global
|
|
77
|
+
* context that improves retrieval recall.
|
|
78
|
+
*/
|
|
79
|
+
export const SUMMARIZED_TABLE = Object.freeze({
|
|
80
|
+
preset: 'summarized',
|
|
81
|
+
defaultMapping: Object.freeze({
|
|
82
|
+
'short-conversation': 'raw-chunks',
|
|
83
|
+
'long-conversation': 'summarized',
|
|
84
|
+
'long-article': 'summarized',
|
|
85
|
+
code: 'summarized',
|
|
86
|
+
'structured-data': 'raw-chunks',
|
|
87
|
+
multimodal: 'raw-chunks',
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
/**
|
|
91
|
+
* Preset: observational (Mastra-style for multi-session synthesis).
|
|
92
|
+
*
|
|
93
|
+
* Long conversational content (long-conversation) becomes a structured
|
|
94
|
+
* observation log via LLM extraction at ingest. Long articles get the
|
|
95
|
+
* cheaper summarized treatment. Short content, code, structured, and
|
|
96
|
+
* multimodal stay raw.
|
|
97
|
+
*
|
|
98
|
+
* Recommended when: workload is conversational and includes many
|
|
99
|
+
* multi-session synthesis questions ("what have we agreed to so far",
|
|
100
|
+
* "across our chats, what topics recur").
|
|
101
|
+
*/
|
|
102
|
+
export const OBSERVATIONAL_TABLE = Object.freeze({
|
|
103
|
+
preset: 'observational',
|
|
104
|
+
defaultMapping: Object.freeze({
|
|
105
|
+
'short-conversation': 'raw-chunks',
|
|
106
|
+
'long-conversation': 'observational',
|
|
107
|
+
'long-article': 'summarized',
|
|
108
|
+
code: 'raw-chunks',
|
|
109
|
+
'structured-data': 'raw-chunks',
|
|
110
|
+
multimodal: 'raw-chunks',
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Preset: hybrid (maximum-recall workloads).
|
|
115
|
+
*
|
|
116
|
+
* Applies multiple ingest strategies in parallel for long content. Every
|
|
117
|
+
* downstream retrieval architecture has its substrate (raw chunks for
|
|
118
|
+
* canonical hybrid, summary prefix for contextual retrieval, observation
|
|
119
|
+
* log for OM-style synthesis). Highest cost at ingest; highest flexibility
|
|
120
|
+
* at retrieval.
|
|
121
|
+
*
|
|
122
|
+
* Recommended when: cost-per-ingest is acceptable AND retrieval workload
|
|
123
|
+
* is heterogeneous enough that no single strategy dominates.
|
|
124
|
+
*/
|
|
125
|
+
export const HYBRID_TABLE = Object.freeze({
|
|
126
|
+
preset: 'hybrid',
|
|
127
|
+
defaultMapping: Object.freeze({
|
|
128
|
+
'short-conversation': 'raw-chunks',
|
|
129
|
+
'long-conversation': 'hybrid',
|
|
130
|
+
'long-article': 'hybrid',
|
|
131
|
+
code: 'summarized',
|
|
132
|
+
'structured-data': 'raw-chunks',
|
|
133
|
+
multimodal: 'raw-chunks',
|
|
134
|
+
}),
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* Preset registry keyed by name.
|
|
138
|
+
*/
|
|
139
|
+
export const PRESET_INGEST_TABLES = Object.freeze({
|
|
140
|
+
'raw-chunks': RAW_CHUNKS_TABLE,
|
|
141
|
+
summarized: SUMMARIZED_TABLE,
|
|
142
|
+
observational: OBSERVATIONAL_TABLE,
|
|
143
|
+
hybrid: HYBRID_TABLE,
|
|
144
|
+
});
|
|
145
|
+
//# sourceMappingURL=routing-tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing-tables.js","sourceRoot":"","sources":["../../src/ingest-router/routing-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,oBAAoB;IACpB,mBAAmB;IACnB,cAAc;IACd,MAAM;IACN,iBAAiB;IACjB,YAAY;CACJ,CAAC;AAqDX,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAuB,MAAM,CAAC,MAAM,CAAC;IAChE,MAAM,EAAE,YAAqB;IAC7B,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC;QAC5B,oBAAoB,EAAE,YAAY;QAClC,mBAAmB,EAAE,YAAY;QACjC,cAAc,EAAE,YAAY;QAC5B,IAAI,EAAE,YAAY;QAClB,iBAAiB,EAAE,YAAY;QAC/B,UAAU,EAAE,YAAY;KACzB,CAAC;CACH,CAAuB,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAuB,MAAM,CAAC,MAAM,CAAC;IAChE,MAAM,EAAE,YAAqB;IAC7B,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC;QAC5B,oBAAoB,EAAE,YAAY;QAClC,mBAAmB,EAAE,YAAY;QACjC,cAAc,EAAE,YAAY;QAC5B,IAAI,EAAE,YAAY;QAClB,iBAAiB,EAAE,YAAY;QAC/B,UAAU,EAAE,YAAY;KACzB,CAAC;CACH,CAAuB,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAuB,MAAM,CAAC,MAAM,CAAC;IACnE,MAAM,EAAE,eAAwB;IAChC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC;QAC5B,oBAAoB,EAAE,YAAY;QAClC,mBAAmB,EAAE,eAAe;QACpC,cAAc,EAAE,YAAY;QAC5B,IAAI,EAAE,YAAY;QAClB,iBAAiB,EAAE,YAAY;QAC/B,UAAU,EAAE,YAAY;KACzB,CAAC;CACH,CAAuB,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAuB,MAAM,CAAC,MAAM,CAAC;IAC5D,MAAM,EAAE,QAAiB;IACzB,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC;QAC5B,oBAAoB,EAAE,YAAY;QAClC,mBAAmB,EAAE,QAAQ;QAC7B,cAAc,EAAE,QAAQ;QACxB,IAAI,EAAE,YAAY;QAClB,iBAAiB,EAAE,YAAY;QAC/B,UAAU,EAAE,YAAY;KACzB,CAAC;CACH,CAAuB,CAAC;AAEzB;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAE7B,MAAM,CAAC,MAAM,CAAC;IAChB,YAAY,EAAE,gBAAgB;IAC9B,UAAU,EAAE,gBAAgB;IAC5B,aAAa,EAAE,mBAAmB;IAClC,MAAM,EAAE,YAAY;CACrB,CAAC,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file select-strategy.ts
|
|
3
|
+
* @description Pure function that picks an ingest strategy from a
|
|
4
|
+
* predicted content kind + routing table + budget policy.
|
|
5
|
+
*
|
|
6
|
+
* Stateless. Deterministic. No I/O. Same shape as
|
|
7
|
+
* {@link selectBackend} in memory-router so the multi-stage guardrails
|
|
8
|
+
* orchestrator can compose them uniformly.
|
|
9
|
+
*
|
|
10
|
+
* @module @framers/agentos/ingest-router/select-strategy
|
|
11
|
+
*/
|
|
12
|
+
import type { IngestStrategyCostPoint } from './costs.js';
|
|
13
|
+
import type { IngestContentKind, IngestRouterPreset, IngestRoutingTable, IngestStrategyId } from './routing-tables.js';
|
|
14
|
+
/**
|
|
15
|
+
* Budget enforcement modes for ingest dispatch:
|
|
16
|
+
* - `hard`: throw {@link IngestRouterBudgetExceededError} if the
|
|
17
|
+
* routing-table pick exceeds the per-ingest USD ceiling.
|
|
18
|
+
* - `soft`: keep the picked strategy when the ceiling is exceeded
|
|
19
|
+
* (best-effort enforcement; flag exceeded in the decision).
|
|
20
|
+
* - `cheapest-fallback`: silently downgrade to the cheapest strategy
|
|
21
|
+
* that fits. If none fits, pick the absolute cheapest and flag.
|
|
22
|
+
*/
|
|
23
|
+
export type IngestBudgetMode = 'hard' | 'soft' | 'cheapest-fallback';
|
|
24
|
+
/**
|
|
25
|
+
* Configuration object for {@link selectIngestStrategy}.
|
|
26
|
+
*/
|
|
27
|
+
export interface IngestRouterConfig {
|
|
28
|
+
readonly table: IngestRoutingTable;
|
|
29
|
+
readonly budgetPerIngestUsd: number | null;
|
|
30
|
+
readonly budgetMode: IngestBudgetMode;
|
|
31
|
+
readonly strategyCosts: Readonly<Record<IngestStrategyId, IngestStrategyCostPoint>>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Output of {@link selectIngestStrategy}. Carries the chosen strategy
|
|
35
|
+
* plus full telemetry about how the decision was made.
|
|
36
|
+
*/
|
|
37
|
+
export interface IngestRoutingDecision {
|
|
38
|
+
readonly predictedKind: IngestContentKind;
|
|
39
|
+
/** Optional ground-truth kind (telemetry only; null in production). */
|
|
40
|
+
readonly groundTruthKind: IngestContentKind | null;
|
|
41
|
+
readonly chosenStrategy: IngestStrategyId;
|
|
42
|
+
readonly chosenStrategyReason: string;
|
|
43
|
+
readonly estimatedCostUsd: number;
|
|
44
|
+
readonly budgetCeiling: number | null;
|
|
45
|
+
readonly budgetExceeded: boolean;
|
|
46
|
+
readonly preset: IngestRouterPreset;
|
|
47
|
+
}
|
|
48
|
+
export declare class IngestRouterUnknownKindError extends Error {
|
|
49
|
+
readonly kind: string;
|
|
50
|
+
constructor(kind: string);
|
|
51
|
+
}
|
|
52
|
+
export declare class IngestRouterBudgetExceededError extends Error {
|
|
53
|
+
readonly strategy: IngestStrategyId;
|
|
54
|
+
readonly cost: number;
|
|
55
|
+
readonly budget: number;
|
|
56
|
+
constructor(strategy: IngestStrategyId, cost: number, budget: number);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Pure ingest-strategy selection. Mirrors selectBackend (memory-router)
|
|
60
|
+
* in structure for multi-stage composability.
|
|
61
|
+
*/
|
|
62
|
+
export declare function selectIngestStrategy(args: {
|
|
63
|
+
predictedKind: IngestContentKind;
|
|
64
|
+
groundTruthKind: IngestContentKind | null;
|
|
65
|
+
config: IngestRouterConfig;
|
|
66
|
+
}): IngestRoutingDecision;
|
|
67
|
+
//# sourceMappingURL=select-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-strategy.d.ts","sourceRoot":"","sources":["../../src/ingest-router/select-strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,mBAAmB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAC9B,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,CAClD,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC;IAC1C,uEAAuE;IACvE,QAAQ,CAAC,eAAe,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC;AAED,qBAAa,4BAA6B,SAAQ,KAAK;aACzB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAIzC;AAED,qBAAa,+BAAgC,SAAQ,KAAK;aAEtC,QAAQ,EAAE,gBAAgB;aAC1B,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;gBAFd,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAQjC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,aAAa,EAAE,iBAAiB,CAAC;IACjC,eAAe,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,MAAM,EAAE,kBAAkB,CAAC;CAC5B,GAAG,qBAAqB,CAsFxB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file select-strategy.ts
|
|
3
|
+
* @description Pure function that picks an ingest strategy from a
|
|
4
|
+
* predicted content kind + routing table + budget policy.
|
|
5
|
+
*
|
|
6
|
+
* Stateless. Deterministic. No I/O. Same shape as
|
|
7
|
+
* {@link selectBackend} in memory-router so the multi-stage guardrails
|
|
8
|
+
* orchestrator can compose them uniformly.
|
|
9
|
+
*
|
|
10
|
+
* @module @framers/agentos/ingest-router/select-strategy
|
|
11
|
+
*/
|
|
12
|
+
export class IngestRouterUnknownKindError extends Error {
|
|
13
|
+
constructor(kind) {
|
|
14
|
+
super(`IngestRouter: kind '${kind}' not in routing table`);
|
|
15
|
+
this.kind = kind;
|
|
16
|
+
this.name = 'IngestRouterUnknownKindError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class IngestRouterBudgetExceededError extends Error {
|
|
20
|
+
constructor(strategy, cost, budget) {
|
|
21
|
+
super(`IngestRouter: strategy '${strategy}' cost $${cost.toFixed(4)} ` +
|
|
22
|
+
`exceeds hard budget $${budget.toFixed(4)}`);
|
|
23
|
+
this.strategy = strategy;
|
|
24
|
+
this.cost = cost;
|
|
25
|
+
this.budget = budget;
|
|
26
|
+
this.name = 'IngestRouterBudgetExceededError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pure ingest-strategy selection. Mirrors selectBackend (memory-router)
|
|
31
|
+
* in structure for multi-stage composability.
|
|
32
|
+
*/
|
|
33
|
+
export function selectIngestStrategy(args) {
|
|
34
|
+
const { predictedKind, groundTruthKind, config } = args;
|
|
35
|
+
const { table, budgetPerIngestUsd, budgetMode, strategyCosts } = config;
|
|
36
|
+
const picked = table.defaultMapping[predictedKind];
|
|
37
|
+
if (!picked) {
|
|
38
|
+
throw new IngestRouterUnknownKindError(predictedKind);
|
|
39
|
+
}
|
|
40
|
+
const pickedCost = strategyCosts[picked].avgCostPerIngest;
|
|
41
|
+
if (budgetPerIngestUsd === null || pickedCost <= budgetPerIngestUsd) {
|
|
42
|
+
return {
|
|
43
|
+
predictedKind,
|
|
44
|
+
groundTruthKind,
|
|
45
|
+
chosenStrategy: picked,
|
|
46
|
+
chosenStrategyReason: budgetPerIngestUsd === null
|
|
47
|
+
? 'routing-table pick, no budget'
|
|
48
|
+
: 'routing-table pick fits budget',
|
|
49
|
+
estimatedCostUsd: pickedCost,
|
|
50
|
+
budgetCeiling: budgetPerIngestUsd,
|
|
51
|
+
budgetExceeded: false,
|
|
52
|
+
preset: table.preset,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (budgetMode === 'hard') {
|
|
56
|
+
throw new IngestRouterBudgetExceededError(picked, pickedCost, budgetPerIngestUsd);
|
|
57
|
+
}
|
|
58
|
+
const candidates = Object.values(strategyCosts).map((c) => ({ strategy: c.strategy, cost: c.avgCostPerIngest }));
|
|
59
|
+
const fits = candidates.filter((c) => c.cost <= budgetPerIngestUsd);
|
|
60
|
+
const cheapestFits = fits.length > 0
|
|
61
|
+
? fits.reduce((a, b) => (a.cost <= b.cost ? a : b))
|
|
62
|
+
: null;
|
|
63
|
+
if (!cheapestFits) {
|
|
64
|
+
const globallyCheapest = candidates.reduce((a, b) => a.cost <= b.cost ? a : b);
|
|
65
|
+
return {
|
|
66
|
+
predictedKind,
|
|
67
|
+
groundTruthKind,
|
|
68
|
+
chosenStrategy: globallyCheapest.strategy,
|
|
69
|
+
chosenStrategyReason: 'no strategy fits budget; picking absolute cheapest',
|
|
70
|
+
estimatedCostUsd: globallyCheapest.cost,
|
|
71
|
+
budgetCeiling: budgetPerIngestUsd,
|
|
72
|
+
budgetExceeded: true,
|
|
73
|
+
preset: table.preset,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (budgetMode === 'cheapest-fallback') {
|
|
77
|
+
return {
|
|
78
|
+
predictedKind,
|
|
79
|
+
groundTruthKind,
|
|
80
|
+
chosenStrategy: cheapestFits.strategy,
|
|
81
|
+
chosenStrategyReason: 'budget downgrade (cheapest-fallback mode)',
|
|
82
|
+
estimatedCostUsd: cheapestFits.cost,
|
|
83
|
+
budgetCeiling: budgetPerIngestUsd,
|
|
84
|
+
budgetExceeded: false,
|
|
85
|
+
preset: table.preset,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// soft: keep the pick, flag exceeded.
|
|
89
|
+
return {
|
|
90
|
+
predictedKind,
|
|
91
|
+
groundTruthKind,
|
|
92
|
+
chosenStrategy: picked,
|
|
93
|
+
chosenStrategyReason: 'soft exceed: keeping picked despite budget breach',
|
|
94
|
+
estimatedCostUsd: pickedCost,
|
|
95
|
+
budgetCeiling: budgetPerIngestUsd,
|
|
96
|
+
budgetExceeded: true,
|
|
97
|
+
preset: table.preset,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=select-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-strategy.js","sourceRoot":"","sources":["../../src/ingest-router/select-strategy.ts"],"names":[],"mappings":"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"}
|