Skip to main content

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:

  1. A gpt-5-mini-style classifier reads the content (truncated to ~1k chars for the kind detection) and emits an IngestContentKind (short-conversation, long-conversation, long-article, code, structured-data, multimodal).
  2. The routing table picks an ingest strategy for that kind.
  3. 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

KindExamples
short-conversation1-3 turn chats, brief Q&A
long-conversationextended chat sessions, support threads
long-articleblog posts, paper sections, long emails
codesource files, configs, schemas
structured-dataCSV, JSON record lists, table dumps
multimodalcontent with images, video frames, audio

Six ingest strategies

StrategyWhat it writesCost (illustrative)
raw-chunksturn/chunk traces with embeddings$0.0001/ingest
summarizedsession/document summary prefixed to every chunk$0.005/ingest
observationalstructured observation log replacing raw turns$0.020/ingest
fact-graphextracted fact triples + entity-relation graph$0.015/ingest
hybridparallel raw + summarized + observational$0.030/ingest
skipcontent 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

PresetStrategy mixWhen to use
raw-chunks (default)every kind → raw-chunkshigh-volume / cost-sensitive workloads; retrieval does the work
summarizedlong-* and code → summarized; short stays rawdocuments/conversations with global context that aids recall
observationallong-conversation → observational; long-article → summarizedconversational workloads with multi-session synthesis questions
hybridlong-* → hybrid; short stays rawcost-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, IngestRoutingTable
  • INGEST_CONTENT_KINDS
  • RAW_CHUNKS_TABLE, SUMMARIZED_TABLE, OBSERVATIONAL_TABLE, HYBRID_TABLE, PRESET_INGEST_TABLES
  • IngestStrategyCostPoint, DEFAULT_INGEST_COSTS, plus per-strategy constants
  • selectIngestStrategy (pure function)
  • IngestRoutingDecision, IngestRouterConfig, IngestBudgetMode
  • IIngestClassifier, IIngestClassifierLLM, LLMIngestClassifier
  • INGEST_CLASSIFIER_SYSTEM_PROMPT, INGEST_CLASSIFIER_SYSTEM_PROMPT_FEWSHOT
  • IIngestDispatcher, FunctionIngestDispatcher
  • IngestRouter, 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.