JSPM

  • Created
  • Published
  • Downloads 1006
  • Score
    100M100P100Q110553F
  • License MIT

The explainable agent framework — build AI agents you can explain, audit, and trust. Built on footprintjs.

Package Exports

  • agentfootprint
  • agentfootprint/injection-engine
  • agentfootprint/llm-providers
  • agentfootprint/locales
  • agentfootprint/memory
  • agentfootprint/memory-agentcore
  • agentfootprint/memory-providers
  • agentfootprint/memory-redis
  • agentfootprint/observability-providers
  • agentfootprint/observe
  • agentfootprint/providers
  • agentfootprint/resilience
  • agentfootprint/security
  • agentfootprint/status
  • agentfootprint/stream
  • agentfootprint/tool-providers

Readme

agentfootprint logo

agentfootprint

Context engineering, abstracted.

CI Coverage npm version Downloads MIT


What is agentfootprint?

A framework for building AI agents by treating context as a first-class runtime system.

Most agent code becomes context plumbing: which instructions go in system, which messages get added after a tool returns, which tools should be exposed right now, which memory to load for this tenant, which parts of the prompt are stable enough to cache.

Without a framework, every agent hand-rolls this logic. Over time it becomes a fragile mix of prompt concatenation, tool routing, memory loading, cache markers, observability hooks, and retry logic.

agentfootprint abstracts that bookkeeping. You declare what context to inject, where it lands, and when it activates. The framework owns the agent loop, recomposes the LLM call every iteration, records typed events, applies caching, and persists replayable checkpoints.

You write the intent. agentfootprint owns the context loop.


The lineage

Every load-bearing dev tool of the last decade made the same move:

Framework You write The framework abstracts
PyTorch (autograd) Forward graph Gradient computation, backward pass
Express / Fastify Routes + handlers HTTP loop, middleware chain
Prisma Schema + query intent SQL generation, migrations
React Components + state DOM diffing, render path
agentfootprint Injections (slot × trigger × cache) Slot composition, iteration loop, caching, observation, replay

The closest structural parallel is autograd: you describe the graph, the framework traverses it, and because the framework owns the traversal it can record everything for free. Same idea here — typed events, replayable checkpoints, and provider-agnostic prompt caching are consequences of owning the loop, not extra features.


The core idea

Every LLM call has three slots:

system     messages     tools

Every agent feature — steering, instructions, skills, facts, memory, RAG, tool schemas — is content flowing into one of those slots. agentfootprint models all of them as one primitive:

Injection = slot × trigger × cache

An Injection answers three questions:

  1. Where does this content land? system, messages, or tools
  2. When does it activate? always · rule · on-tool-return · llm-activated
  3. How is it cached? always · never · while-active · predicate

That is the whole abstraction. Every named pattern in the agent literature — Reflexion, Tree-of-Thoughts, Skills, RAG, Constitutional AI — reduces to which slot + which trigger. You learn one model; the field's growth lands as new factories on the same primitive.

                         LLM call
        ┌────────────────────────────────────┐
        │   system      messages      tools  │
        │      ▲            ▲            ▲   │
        └──────┼────────────┼────────────┼───┘
               │            │            │
          Injection     Injection     Injection
               ▲
               │
      always · rule · on-tool-return · llm-activated

Why this isn't just an ergonomics win — Dynamic ReAct

Because the framework owns the loop, all three slots recompose every iteration based on what just happened.

  • LangChain assembles prompts once per turn.
  • LangGraph composes state per node, not per loop iteration.
  • agentfootprint recomposes per iteration.

Per-iteration recomposition is what makes context engineering compositional instead of static. It's also the structural prerequisite for the cache layer — cache markers can't track active injections in lockstep without it.

Classic ReAct                    Dynamic ReAct
───────────────                  ─────────────
iter 1: 12 tools shown           iter 1: 1 tool  (read_skill)
iter 2: 12 tools shown           iter 2: 5 tools (skill activated)
iter 3: 12 tools shown           iter 3: 5 tools

Use Dynamic ReAct when your tools have dependencies (one tool's output implies which tool to call next). Use Classic ReAct when all tools are independent and ordering doesn't matter.

📖 Deep dive: Dynamic ReAct guide · Cache layer


Quick start — runs offline, no API key

npm install agentfootprint footprintjs
import { Agent, defineTool, mock } from 'agentfootprint';

const weather = defineTool({
  name: 'weather',
  description: 'Get current weather for a city.',
  inputSchema: {
    type: 'object',
    properties: { city: { type: 'string' } },
    required: ['city'],
  },
  execute: async ({ city }: { city: string }) => `${city}: 72°F, sunny`,
});

const agent = Agent.create({
  provider: mock({ reply: 'I checked: it is 72°F and sunny.' }),
  model: 'mock',
})
  .system('You answer weather questions using the weather tool.')
  .tool(weather)
  .build();

const result = await agent.run({ message: 'Weather in Paris?' });
console.log(result);  // → "I checked: it is 72°F and sunny."

Swap mock(...) for anthropic(...) / openai(...) / bedrock(...) / ollama(...) for production. Nothing else changes.


A real agent in 8 lines

const agent = Agent.create({ provider, model: 'claude-sonnet-4-5-20250929' })
  .system('You are a support assistant.')
  .steering(toneRule)            // always-on
  .instruction(urgentRule)       // rule-gated
  .skill(billingSkill)           // LLM-activated
  .memory(conversationMemory)    // cross-run, multi-tenant
  .tool(weather)
  .build();

await agent.run({ message: userInput, identity: { conversationId } });

The hand-rolled equivalent is ~80 lines of slot management, trigger evaluation, memory loading, and cache marker placement — and growing with every feature. The declarative version stays at 8.

📖 Compare: hand-rolled vs declarative · migration from LangChain / CrewAI / LangGraph


The differentiator: the trace is a cache of the agent's thinking

Other agent frameworks remember what was said. agentfootprint's causal memory records the decision evidence — every value the flowchart captured during the run, persisted as a JSON-portable snapshot.

That changes the cost structure of everything that happens after the agent runs:

  1. Audit / explain — six months later, "why was loan #42 rejected?" answers from the original evidence (creditScore=580, threshold=600), not reconstruction.
  2. Cheap-model triage — a trace from Sonnet is good input for Haiku to answer follow-up questions about that run. Memoization for agent reasoning.
  3. Training data — every successful production run is a labeled trajectory for SFT/DPO/process-RL, no separate data-collection phase.

One recording, three downstream consumers, no extra instrumentation.

📖 Deep dive: Causal memory guide


What you can build

// Customer support — skills + memory + audit + cache
const agent = Agent.create({ provider, model })
  .system('You are a friendly support assistant.')
  .skill(billingSkill)
  .steering(toneGuidelines)
  .memory(conversationMemory)
  .build();

// Research pipeline — multi-agent fan-out + merge
const research = Parallel.create()
  .branch(optimist).branch(skeptic).branch(historian)
  .merge(synthesizer)
  .build();

// Streaming chat — token-by-token to a browser via SSE
agent.on('agentfootprint.stream.token', (e) => res.write(toSSE(e)));
await agent.run({ message: req.query.message });

📖 Full examples: examples gallery · every example is also a CI test.


Mocks first, production second

Build the entire app against in-memory mocks with zero API cost, then swap real infrastructure one boundary at a time.

Boundary Dev Prod
LLM provider mock(...) anthropic() · openai() · bedrock() · ollama()
Memory store InMemoryStore RedisStore · AgentCoreStore · DynamoDB / Postgres / Pinecone
MCP mockMcpClient(...) mcpClient({ transport })
Cache strategy NoOpCacheStrategy auto-selected per provider

The flowchart, recorders, and tests don't change between dev and prod.


What ships today

  • 2 primitivesLLMCall, Agent (the ReAct loop)
  • 4 compositionsSequence, Parallel, Conditional, Loop
  • 7 LLM providers — Anthropic · OpenAI · Bedrock · Ollama · Browser-Anthropic · Browser-OpenAI · Mock
  • One Injection primitivedefineSkill / defineSteering / defineInstruction / defineFact
  • One Memory factory — 4 types × 7 strategies including Causal
  • Provider-agnostic prompt caching — declarative per-injection, per-iteration marker recomputation
  • RAG · MCP · Memory store adapters — InMemory · Redis · AgentCore
  • 48+ typed observability events across context · stream · agent · cost · skill · permission · eval · memory · cache · embedding · error
  • Pause / resume — JSON-serializable checkpoints; resume hours later on a different server
  • ResiliencewithRetry, withFallback, resilientProvider
  • AI-coding-tool support — Claude Code · Cursor · Windsurf · Cline · Kiro · Copilot

📖 Full feature list & API reference · CHANGELOG


Roadmap

Theme Focus
Reliability Circuit breaker, output fallback, auto-resume-on-error
Causal exports causalMemory.exportForTraining({ format: 'sft' | 'dpo' | 'process' })
Governance Policies, budget tracking, production memory adapters
Cache v2 Gemini handle-based caching, cost attribution
Deep agents Planning-before-execution, A2A protocol, Lens UI

Roadmap items are not current API claims. If a feature isn't in npm install agentfootprint today, it's listed here, not in the docs.


Design philosophy

Two principles shape the runtime:

Connected data (Palantir, 2003). Enterprise insight is bottlenecked by data fragmentation, not analyst skill. Agents face the same problem at runtime — disconnected tool state, lost decision evidence, scattered execution context. agentfootprint connects state, decisions, execution, and memory into one runtime footprint so the next iteration compounds the connection instead of paying for it again.

Modular boundaries (Liskov, 1974). Every framework boundary — LLMProvider, ToolProvider, CacheStrategy, Recorder, MemoryStore — is an LSP-substitutable interface. Swap implementations without changing agent code.

Connected data alone is fast but unmaintainable. Modular boundaries alone are clean but dumb. Together: a runtime that's both fast and reasonable.

📖 Long-form: the Palantir lineage · the Liskov lineage


Where to next

If you are... Go here
New to agents 5-minute quick start
Coming from LangChain / CrewAI / LangGraph Migration guide
Architecting an enterprise rollout Production guide
Doing due diligence Architecture overview
Researcher / extending Extension guide
Curious about design Inspiration docs

Or jump into the examples gallery — every example is also an end-to-end CI test.


Built on

footprintjs — the flowchart pattern for backend code. The decision-evidence capture, narrative recording, and time-travel checkpointing this library uses are footprintjs primitives. The same way autograd's forward-pass traversal is what makes gradient inspection automatic, footprintjs's flowchart traversal is what makes agentfootprint's typed-event stream and replayable traces automatic.

You don't need to learn footprintjs to use agentfootprint — but if you want to build your own primitives at this depth, start there.


License

MIT © Sanjay Krishna Anbalagan