Retrieval
How Trayn retrieves relevant memories for the agent's current state.
RetrieverAdapter Interface
import type { EnvironmentState, RetrievalConfig } from "@trayn/memory";
import type { RetrievalOutput } from "@trayn/memory";
interface RetrieverAdapter {
retrieve(
sessionId: string,
currentRunId: string,
input: {
currentEnv: EnvironmentState;
currentStateEmbedding: number[];
},
config?: Partial<RetrievalConfig>,
): Promise<RetrievalOutput>;
}RetrievalConfig Schema
import { retrievalConfigSchema } from "@trayn/memory";
// retrievalConfigSchema validates:
interface RetrievalConfig {
envThreshold: number; // 0.0–1.0, minimum IoU score to consider (default: 0.7)
topK: number; // Max candidates after env filtering (default: 10)
finalK: number; // Final number of memories returned (default: 2)
}Default Pipeline (DefaultRetriever)
The built-in DefaultRetriever uses a multi-stage pipeline:
- Load — Fetch all graded memories for the session (excluding current run)
- Environment IoU — Score each memory's
envPre.elementsagainst current page elements using Intersection over Union. Filter belowenvThreshold - Top-K — Keep the top
topKby environment score - Cosine Ranking — Score by cosine similarity between the memory's
internalStateEmbeddingand the current state embedding. Rank by combined score (65% env + 35% intent) - Dedup — Collapse memories with identical action signatures (same action type + target + value)
- Final Selection — Pick
finalKmemories, prioritizing at least one AVOID and one REPEAT
Custom Retriever Example
import type { RetrieverAdapter } from "@trayn/memory";
import { setRetriever } from "@trayn/memory";
class VectorDBRetriever implements RetrieverAdapter {
async retrieve(sessionId, currentRunId, input, config) {
const results = await myVectorDB.query({
embedding: input.currentStateEmbedding,
filter: { sessionId },
topK: config?.finalK ?? 2,
});
return {
memories: results.map((r) => ({
memory: r.metadata,
envScore: r.score,
intScore: r.score,
})),
debug: {
totalLoaded: results.length,
envMatched: results.length,
envTopK: results.length,
stateRanked: results.length,
deduped: results.length,
aboveThreshold: results.length,
selected: results.length,
},
};
}
}
setRetriever(new VectorDBRetriever());Dependency Injection
import { setRetriever, getRetriever } from "@trayn/memory";
// Set a custom retriever
setRetriever(myRetriever);
// Use the retriever (falls back to DefaultRetriever if none set)
const result = await getRetriever().retrieve(sessionId, runId, input);Unlike getGrader(), getRetriever() automatically falls back to DefaultRetriever if no custom retriever is configured. You only need setRetriever() when replacing the default pipeline.