active-meta-mgt
v0.1.8
Published
Token-budgeted context management framework with MobX-State-Tree for organizing knowledge objects across multiple context lanes
Maintainers
Readme
Active Meta-Context Management
Token-budgeted context management framework built with MobX-State-Tree. Organizes and prioritizes knowledge objects across multiple context "lanes" for LLM prompting.
Installation
npm install active-meta-mgt
# or
bun add active-meta-mgtQuick Start
import { makeDefaultActiveMetaContext } from "active-meta-mgt";
// 1. Create a context (comes with 5 default lanes: task, legal, personal, threat-model, implementation)
const ctx = makeDefaultActiveMetaContext("my-context");
// 2. Add knowledge objects with lane tags
ctx.upsertGoal({
id: "goal-1",
title: "Complete feature X",
tags: [{ key: "lane", value: "task" }],
priority: "p0",
});
ctx.upsertEvidence({
id: "ev-1",
summary: "User feedback indicates performance regression",
tags: [{ key: "lane", value: "task" }],
severity: "high",
confidence: "high",
});
ctx.upsertConstraint({
id: "con-1",
statement: "Must maintain backward compatibility",
tags: [{ key: "lane", value: "implementation" }],
priority: "p0",
});
// 3. Synthesize working memory from all lanes
ctx.synthesizeFromLanes({ tokenBudget: 600 });
// 4. Get LLM-ready payload
const payload = ctx.buildLLMContextPayload();
console.log(payload.workingMemory.text);Core Concepts
Knowledge Objects
Six types of domain entities stored globally:
| Type | Purpose | Key Fields |
| ---------------- | ---------------------------- | ----------------------------------------------------- |
| Goal | Objectives and targets | title, priority (p0-p3), status |
| Constraint | Requirements and limitations | statement, priority, status |
| Assumption | Beliefs and hypotheses | statement, confidence (low/medium/high), status |
| Evidence | Facts and findings | summary, detail, severity, confidence |
| OpenQuestion | Unanswered questions | question, priority, status |
| Decision | Choices with rationale | statement, rationale, status |
All objects support tags for lane filtering, provenance for source tracking, and timestamps for recency scoring.
Context Lanes
Lanes are separate selection domains that filter and score items independently:
// Create a custom lane
ctx.ensureLane("security", "Security Concerns");
const lane = ctx.lanes.get("security");
lane.setIncludeTagsAny([{ key: "lane", value: "security" }]);
lane.setWindowPolicy({ maxItems: 15, wSeverity: 2.0 });Lane states: enabled (participates in merge), muted (preserved but excluded), disabled (no selection).
Selection & Scoring
Each lane scores items using configurable weights:
{
wSeverity: 1.0, // Weight for severity (low=1, medium=2, high=3, critical=4)
wConfidence: 0.7, // Weight for confidence (low=1, medium=2, high=3)
wPriority: 0.8, // Weight for priority (p0=4, p1=3, p2=2, p3=1)
wRecency: 0.1, // Exponential decay for recency
wPinnedBoost: 1000, // Score boost for pinned items
maxItems: 30 // Maximum items per lane
}Synthesis Pipeline
// All-in-one
ctx.synthesizeFromLanes({ tokenBudget: 600, archiveRawItems: false });
// Or step by step
ctx.refreshAllLanes();
ctx.mergeLanesToActiveWindow();
ctx.synthesizeWorkingMemory({ tokenBudget: 600 });- Refresh - Each lane selects top-scored items matching its tag filter
- Merge - Enabled lanes combine into a unified active window (deduped, capped)
- Synthesize - Generate token-budgeted condensed text
- Archive - Store selection snapshot for audit trail
Lifecycle Hooks
Subscribe to framework events for logging, monitoring, or reactive workflows:
// Listen for specific events
const unsub = ctx.hooks.on("knowledgeObject:upserted", (event) => {
console.log(`${event.kind} ${event.id} was ${event.isNew ? "created" : "updated"}`);
});
// Listen for all events
ctx.hooks.onAny((event) => {
console.log(`[${event.timestamp}] ${event.type}`);
});
// One-time listener
ctx.hooks.once("workingMemory:synthesized", (event) => {
console.log(`Synthesis complete: ${event.actualTokens} tokens`);
});
// Cleanup
unsub();
ctx.hooks.offAll();Available events:
knowledgeObject:upserted- Item created or updatedlane:created,lane:removed,lane:statusChanged,lane:pinChanged- Lane lifecyclelane:refreshed,lanes:refreshedAll- Selection refreshactiveWindow:merged- Merge completedworkingMemory:synthesized- Synthesis completedarchive:created- Archive entry createdevidence:ingested- Evidence ingestion flow completed
API Reference
Upsert Methods
ctx.upsertGoal({ id: "g1", title: "...", priority: "p0", tags: [...] });
ctx.upsertConstraint({ id: "c1", statement: "...", priority: "p0", tags: [...] });
ctx.upsertAssumption({ id: "a1", statement: "...", confidence: "medium", tags: [...] });
ctx.upsertEvidence({ id: "e1", summary: "...", severity: "high", tags: [...] });
ctx.upsertQuestion({ id: "q1", question: "...", priority: "p1", tags: [...] });
ctx.upsertDecision({ id: "d1", statement: "...", rationale: "...", tags: [...] });Lane Management
ctx.ensureLane("newLane", "Display Name");
ctx.removeLane("laneId");
ctx.setLaneStatus("laneId", "enabled" | "muted" | "disabled");
ctx.pinInLane("laneId", "evidence", "item-id");
ctx.unpinInLane("laneId", "evidence", "item-id");Evidence Ingestion
Async flow for adding evidence and optionally triggering synthesis:
await ctx.ingestEvidence(
{ id: "e1", summary: "New finding", severity: "high", tags: [...] },
{ synthesize: true, tokenBudget: 800 }
);LLM Payload
const payload = ctx.buildLLMContextPayload();
// { metaContextId, name, generatedAt, workingMemory, selectedCount,
// goals, constraints, assumptions, evidence, questions, decisions }Token Counting
import { countTokens, countTokensSync } from "active-meta-mgt/tokenizer";
const tokens = await countTokens("text"); // Async BERT tokenization
const approx = countTokensSync("text"); // Sync approximation (chars / 4)Archive System
Every synthesis creates an ArchiveEntry with merged refs, working memory text, and a full MST snapshot for audit trail or rollback. Access via ctx.archive.
Example Application
See examples/vitalsWatch/ for a full-stack example (Apple Watch + Cloudflare Workers server) demonstrating the framework in a clinical vitals monitoring scenario.
Commands
bun test # Run all tests
bun test index.test.ts # Run specific test file
bun run typecheck # TypeScript type checking
bun install # Install dependenciesWho Is This For
This framework is built for problems where "just pass the whole conversation to the LLM" doesn't work — because of token limits, auditability requirements, or the need to prioritize competing concerns.
- Regulated enterprises (finance, healthcare, legal) — control what context the model sees, prove what it saw via the archive audit trail, and enforce domain boundaries between legal, engineering, and operational concerns.
- GRC / compliance platforms — governance, risk, and compliance tooling where evidence, constraints, and decisions need structured tracking with confidence scores and severity, not free-text chat history.
- AI-assisted incident response / SOC tooling — security operations where multiple information streams (alerts, threat intel, remediation decisions) compete for limited context and need prioritized synthesis under token budgets.
- Enterprise AI agent platforms — multi-step agents that need persistent, structured working memory across turns rather than relying on raw conversation history.
License
MIT © 2026 Geoff Seemueller
