context-accordion gives AI agents token-efficient, layered context delivery.
Context is always available — just collapsed by default. Like an accordion: all the notes exist, you only press the ones you need.
Installation · Quick Start · API Reference · Discussions · Issues
Every AI agent framework today does one of two things:
- Dump everything — shove the full history, full codebase, full goal tree into every prompt. Expensive, slow, hits context limits fast.
- Summarize and forget — compress context down to a summary and throw away the original. Cheap, but the agent can never go deeper when it needs to.
Both are wrong. The full content should never be discarded — it should be collapsed, retrievable on demand.
Four memory tiers. Each tier is always available but only loaded when needed:
L0 Identity — always loaded ~500 tokens who am I, what can I do
L1 Session — always loaded ~2000 tokens what am I doing right now
L2 Experience — loaded on start ~1000 tokens what have I learned before
L3 Archive — retrieved ~1500 tokens what happened in similar past runs
With the Accordion, you start at ~500 tokens (L0+L1) vs ~5000+ for a naive dump. The agent expands tiers on-demand, typically adding 500-2000 tokens when needed.
This package is in alpha status. The API may change in breaking ways between minor versions (0.x.x) until we reach 1.0.0 stability.
Breaking changes policy:
- We will document breaking changes in CHANGELOG.md
- For Harbor integration stability, pin to a specific version tag
The public API is exported from the main entry point and subpath exports.
| Export | Description |
|---|---|
AccordionComposer |
Main class for context composition |
OllamaEmbedding, OpenAIEmbedding |
Embedding providers |
| Types (AccordionBundle, AccordionPacket, AgentConfig, TaskContext, etc.) | TypeScript interfaces |
| Export | Description |
|---|---|
estimateTokens, enforceBudget, TIER_PRIORITY |
Budget utilities |
distill |
Experience distillation helper |
Framework adapters are the official integration boundary for external frameworks.
Use these instead of manually processing AccordionBundle:
| Subpath | Export | Purpose |
|---|---|---|
context-accordion/ai-sdk |
accordionSystemPrompt(bundle) |
Renders bundle as system prompt for Vercel AI SDK |
context-accordion/langchain |
toDocuments(bundle) |
Converts bundle to LangChain Documents |
context-accordion/langchain |
toSystemMessage(bundle) |
Renders bundle as single string for system message |
Why use adapters? They handle framework-specific formatting and are the
officially supported integration points. The core AccordionComposer is
framework-agnostic — adapters translate between the abstract bundle format
and your framework of choice.
For Harbor integration, use these adapters rather than processing bundles directly.
The following are internal implementation details — do not rely on them:
- Private methods on
AccordionComposer(e.g.,buildIdentityPacket,retrieveArchive) - Static cache state (
AccordionComposer.cache) — shared across instances - Internal type definitions not exported from index.ts
- Budget utilities (
enforceBudget,estimateTokens,TIER_PRIORITY) — marked as@alpha
Harbor consumers: Pin to specific version tags and use the wrapper adapters for framework integration.
npm install context-accordionimport { AccordionComposer } from 'context-accordion'
const composer = new AccordionComposer({
maxTokens: 8000,
vectorStore: {
url: process.env.QDRANT_URL, // optional — enables L3 archive tier
},
})
// Compose context for an agent run
const bundle = await composer.compose(
{
id: 'builder',
identity: 'You are a senior software engineer. You write clean, tested code.',
experiencePath: './agents/builder/experience.md', // L2 — learned lessons
},
{
id: 'issue-123',
title: 'Fix authentication bug in login flow',
description: 'Users are getting logged out after 5 minutes...',
priority: 'high',
type: 'bug',
},
{
includePriorTasks: true, // triggers L3 semantic retrieval
},
)
// bundle.packets — ordered, budget-enforced context packets
// bundle.totalTokens — actual token usage
// bundle.maxTokens — budget ceiling
// Render to a prompt string
const prompt = composer.render(bundle)The agent can request deeper context mid-run:
// Expand a specific tier during a run
const expanded = await composer.expand(bundle, {
tier: 'archive', // L3 — pull from vector store
reason: 'Need to check how similar auth bugs were fixed before',
limit: 5,
})
// Or expand experience tier
const withExperience = await composer.expand(bundle, {
tier: 'experience', // L2 — load full experience.md
experiencePath: './agents/builder/experience.md', // required for experience tier
})All expansion events are logged so you can see exactly what context the agent actually needed.
The composer enforces a token budget by dropping lower-priority packets first:
- Identity (priority 100) — never dropped
- Handoff (priority 90) — agent-to-agent continuity
- Experience (priority 85) — learned lessons
- Task (priority 80) — never dropped
- Goal (priority 70) — broader objective
- Repo (priority 60) — codebase context
- Archive (priority 50) — prior similar tasks
When budget is exceeded, lower-priority packets are dropped. If partial space remains (200+ tokens), packets are truncated rather than dropped.
Store completed tasks for semantic retrieval:
// After task completion, index the run
await composer.index({
taskId: 'issue-123',
content: 'Fixed authentication bug by...',
metadata: { type: 'bug', resolution: 'fixed' },
})
// Retrieval happens automatically during compose() when includePriorTasks: trueQdrant is optional. If vectorStore is not configured, L3 is silently skipped.
For L3 archive retrieval, configure an embedding provider:
import { AccordionComposer, OllamaEmbedding } from 'context-accordion'
const composer = new AccordionComposer({
maxTokens: 8000,
vectorStore: { url: 'http://localhost:6333' },
embeddingProvider: new OllamaEmbedding(), // or new OpenAIEmbedding()
})Works with any agent framework:
import { accordionSystemPrompt } from 'context-accordion/ai-sdk'
const { text } = await generateText({
model: openai('gpt-4o'),
system: accordionSystemPrompt(bundle),
prompt: userMessage,
})import { toDocuments, toSystemMessage } from 'context-accordion/langchain'
const docs = toDocuments(bundle)
// Use with LangChain's RetrievalQAChain
const systemMessage = toSystemMessage(bundle)
// Use as SystemMessage in chat chainsnew AccordionComposer(config?)Config:
| Option | Type | Default | Description |
|---|---|---|---|
maxTokens |
number |
8000 |
Default token budget |
cacheTtl |
number |
300000 |
Static cache TTL in ms |
vectorStore |
object |
- | Qdrant config |
embeddingProvider |
object |
- | Ollama or OpenAI |
onExpand |
function |
- | Expansion event callback |
compose(agent, task, options?)— Build a bundleexpand(bundle, options)— Expand a tier on-demandrender(bundle)— Render to stringindex(options)— Store task in archiveclearSessionCache()— Clear session cache
PRs and issues welcome. Please open an issue before sending a large PR so we can align on direction.
git clone https://github.com/AVANT-ICONIC/context-accordion.git
cd context-accordion
npm install
npm run testMIT — see LICENSE
Built by AVANT-ICONIC. Inspired by the problem of agents drowning in context they didn't ask for.