Ingest Router (Input-Stage Smart Orchestration)
Input-stage smart orchestrator. Classifies incoming content and picks an ingest strategy: raw-chunks, summarized, observational, fact-graph, hybrid, or skip. The first stage of the Cognitive Pipeline.
What it actually does
Every piece of content entering memory (a new conversation turn, a long article, a code file, a CSV) goes through one classifier call:
- A
gpt-5-mini-style classifier reads the content (truncated to ~1k chars for the kind detection) and emits anIngestContentKind(short-conversation, long-conversation, long-article, code, structured-data, multimodal). - The routing table picks an ingest strategy for that kind.
- The dispatcher invokes a registered executor that actually writes to memory in the chosen format.
Why this matters: a 3-turn chat snippet doesn't justify the LLM cost of observation extraction; a 50-turn customer support thread does. A long-form article benefits from session-summarized contextual retrieval; structured CSV data doesn't. Picking the wrong strategy at ingest costs accuracy or money downstream.
Six content kinds
| Kind | Examples |
|---|---|
short-conversation | 1-3 turn chats, brief Q&A |
long-conversation | extended chat sessions, support threads |
long-article | blog posts, paper sections, long emails |
code | source files, configs, schemas |
structured-data | CSV, JSON record lists, table dumps |
multimodal | content with images, video frames, audio |
Six ingest strategies
| Strategy | What it writes | Cost (illustrative) |
|---|---|---|
raw-chunks | turn/chunk traces with embeddings | $0.0001/ingest |
summarized | session/document summary prefixed to every chunk | $0.005/ingest |
observational | structured observation log replacing raw turns | $0.020/ingest |
fact-graph | extracted fact triples + entity-relation graph | $0.015/ingest |
hybrid | parallel raw + summarized + observational | $0.030/ingest |
skip | content discarded; nothing written | $0 |
The summarized strategy implements Anthropic's "contextual retrieval" pattern (every chunk prepended with a dense session/document summary before embedding). The observational strategy implements Mastra's Observational Memory pattern (LLM-extracted observation log). The fact-graph strategy stores extracted typed facts plus an entity-relation graph at retrieval time — used by Hindsight (typed network of World, Experience, Opinion, Observation) and the original Mem0 v2 design. Mem0 v3 (Mar 2026) dropped its graph store in favor of single-pass ADD-only extraction with multi-signal hybrid search; the fact-graph ID here remains valid for systems that still want a queryable fact graph.
Four shipping presets
| Preset | Strategy mix | When to use |
|---|---|---|
raw-chunks (default) | every kind → raw-chunks | high-volume / cost-sensitive workloads; retrieval does the work |
summarized | long-* and code → summarized; short stays raw | documents/conversations with global context that aids recall |
observational | long-conversation → observational; long-article → summarized | conversational workloads with multi-session synthesis questions |
hybrid | long-* → hybrid; short stays raw | cost-tolerant workloads with heterogeneous retrieval needs |
Quickstart
import {
LLMIngestClassifier,
IngestRouter,
FunctionIngestDispatcher,
} from '@framers/agentos/ingest-router';
const router = new IngestRouter({
classifier: new LLMIngestClassifier({ llm: openaiAdapter }),
preset: 'summarized',
budget: { perIngestUsd: 0.01, mode: 'cheapest-fallback' },
dispatcher: new FunctionIngestDispatcher<{ writtenTraces: number }>({
'raw-chunks': async (content) => ({ writtenTraces: await rawIngest(content) }),
summarized: async (content) => ({ writtenTraces: await summarizedIngest(content) }),
observational: async (content) => ({ writtenTraces: await omIngest(content) }),
'fact-graph': async (content) => ({ writtenTraces: await factGraphIngest(content) }),
hybrid: async (content) => ({ writtenTraces: await hybridIngest(content) }),
skip: async () => ({ writtenTraces: 0 }),
}),
});
const { decision, outcome } = await router.decideAndDispatch(content);
console.log(decision.classifier.kind); // 'long-conversation'
console.log(decision.routing.chosenStrategy); // 'observational'
console.log(decision.routing.estimatedCostUsd); // 0.020
console.log(outcome.writtenTraces); // 47
Decision-only flow
const { classifier, routing } = await router.decide(content);
if (routing.chosenStrategy === 'summarized') {
await mySummarizeAndStore(content);
} else if (routing.chosenStrategy === 'skip') {
return; // content not worth storing
}
Manual kind override
When the caller already knows the content kind (file extension determines code, payload metadata says it's structured data), skip the classifier:
const decision = await router.decide(content, {
manualKind: 'code',
});
// classifier is not invoked; routing table consulted with 'code' directly.
Budget-aware dispatch
const router = new IngestRouter({
classifier,
preset: 'observational',
budget: {
perIngestUsd: 0.005,
mode: 'cheapest-fallback', // silently fall back to summarized or raw-chunks
},
});
Three modes (same as MemoryRouter): hard / soft / cheapest-fallback. The default is cheapest-fallback for production safety.
Few-shot classifier prompt
For ambiguous content (a long email vs a long article; structured data vs code), use the few-shot variant:
const router = new IngestRouter({
classifier,
preset: 'observational',
useFewShotPrompt: true,
});
API surface
IngestContentKind,IngestStrategyId,IngestRouterPreset,IngestRoutingTableINGEST_CONTENT_KINDSRAW_CHUNKS_TABLE,SUMMARIZED_TABLE,OBSERVATIONAL_TABLE,HYBRID_TABLE,PRESET_INGEST_TABLESIngestStrategyCostPoint,DEFAULT_INGEST_COSTS, plus per-strategy constantsselectIngestStrategy(pure function)IngestRoutingDecision,IngestRouterConfig,IngestBudgetModeIIngestClassifier,IIngestClassifierLLM,LLMIngestClassifierINGEST_CLASSIFIER_SYSTEM_PROMPT,INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOTIIngestDispatcher,FunctionIngestDispatcherIngestRouter,IngestRouterOptions,IngestRouterDecideOptions,IngestRouterDispatchedResult- Errors:
IngestRouterUnknownKindError,IngestRouterBudgetExceededError,UnsupportedIngestStrategyError,IngestRouterDispatcherMissingError
Calibration
The shipping cost-points are illustrative averages on a typical OpenAI stack. For workloads with very different ingest profiles (heavy observation extraction, custom triple-extraction LLM), supply your own strategyCosts map at construction.
Related
- Cognitive Pipeline — composition primitive
- Memory Router — recall stage sibling
- Read Router — read stage sibling
- Memory Auto-Ingest — the underlying auto-ingest primitives this router orchestrates
- Memory Document Ingestion — document-mode ingest pipeline