Open-source TypeScript agent framework

Build agents whose answers can be checked.

Connect answers to recorded evidence, carry uncertainty forward, and run your app’s checks before an answer reaches the customer.

  • TypeScripttyped tools and answers
  • MITopen source
  • Your rulesexplicit answer checks
  • Keep the evidence. Record the tool calls, results and context made available during a run.
  • Keep the limits. Tools declare what they checked, what they missed and what they cannot cover.
  • Check before delivery. Your app defines the checks. In enforce mode, failed or unverified typed answers are withheld.
  • Inspect the decision. Follow the recorded execution and test dependence with a rerun.

Built on FootprintJS execution provenance. A record shows what ran and what was available; it does not prove external data is true or reveal a model’s private reasoning.

Six inspectable facets of an agent run: evidence, decision, reason, coverage, refusal and replay.Evidencewhat was availableDecisionwhat it choseReasonits declared basisCoveragewhat was missingRefusalwhere it stoppedReplaytest dependence
Six facets of an inspectable agent run.

Try an answer check

Same draft. Different evidence.

Run a real agent with a scripted reply. Your app declares the checks; the runtime decides whether that reply can be delivered.

Scripted fixture · no live model
Choose the lookup result

The draft matches a recent lookup for this customer and order.

01 · Lookup evidence

Refund: completed

Customer
customer-42
Order
A-1042
Read at
12:00 UTC

Bank settlement was not checked.

02 · Scripted draft

Refund: completed

For order A-1042, customer customer-42.

A candidate for checking. Showing it here does not mean it was delivered.

03 · App rules

Check before delivery

  • Same customer and order
  • Lookup no older than five minutes
  • Status and time match the lookup

Enforce mode · evidence read in the caller’s scope

Fixed fixture clock: 15 Jan 2026, 12:02 UTC. Nothing is refunded.

Choose a scenario and run it to see what reaches the customer.

This demonstrates configured checks, not model accuracy or independent verification of the refund ledger. Your app owns the rules, trusted sources and fallback wording. Unchecked prose is not covered.

Use answer validation →

The guarantee has a boundary

Check the claim your app knows how to check.

Honest answers need evidence, explicit limits and a delivery rule. Each has its own job.

01 · Evidence and limits

A tool result with its scope.

Use absent() or coverage() to declare what was checked and what remains unknown. Carry those limits with the answer.

The app owns these declarations. Model prose is not independent evidence.

Declare coverage →
02 · Configured checks

An answer held to your rules.

Use answerValidation() to check typed fields against scoped evidence. Enforce mode withholds failed or unverified answers; observe mode records and allows delivery.

Checks cover only what you configure. Withholding an answer does not undo a tool action.

Configure answer checks →
03 · Recorded execution

A decision you can inspect.

Inspect context, tool calls, results and decisions together. Rerun a case without a source to test whether the output depends on it.

Execution provenance is the foundation for an audit, not a universal truth guarantee.

Inspect a recorded run →
Where the newer “not found” checks stand

Typed negativeClaims() checks are opt-in and available in the source, but not recommended until measured. They check cited searches and write bounded statements; they still trust the app’s search declarations. Other model text remains unchecked.

Their accuracy and usefulness are unmeasured. The earlier free-text detector failed its benchmark; the revised detector is unmeasured and only adds warnings. A warning-free answer is not a verified answer. See the capability index for release availability, including features marked unreleased.

Choosing a framework

A focus on what supports the answer.

LangChain and Mastra help teams build agent applications, and both offer controls during execution. AgentFootprint’s emphasis is connecting recorded execution, evidence limits and configured answer delivery in one framework.

Different emphases, with overlapping capabilities.
FrameworkWhat to explore
LangChain / LangGraphIntegrations, orchestration and durable workflows, with runtime guardrails.
MastraTypeScript agents, workflows, memory, tracing and evaluations, with input and output processors.
AgentFootprintExecution provenance, declared evidence limits and app-configured checks before answer delivery.

This is a difference in emphasis, not a claim of exclusive capabilities or measured superiority.

The handoff

An agent inherits the context a person used to carry.

Then the runbook has to become executable.

The progressionWhat changes
  1. Humancarries context between systems
  2. Agentinherits the same responsibility
  3. Whole runbookloads every instruction at once
  4. Current stepreveals what is needed now
  5. Traversaladvances and records together

The path is already a footprint as it runs.

The runtime underneath the answer

Build, inspect, run and monitor the whole agent.

01 · Build

Turn the runbook into a path the agent can walk.

Scope

One state. One reachable skill.

With tool scoping enabled, the selected skill brings its procedure, tools and model into the step.

Build the graph →
With tool scoping enabled, a refund request selects billing.refund. That skill's procedure, three tools, and model enter the working set.

Route

Keep the payload out of the prompt.

For stored results, the model gets a ticket. Your product redeems the real data.

Follow the two lanes →
In this configured artifact path, a large tool result splits into two parts. The payload is stored outside model context. A small artifact ticket enters the conversation, where the model can route it to the present tool. The product interface redeems the ticket and loads the payload from the artifact store.
The model routes the ticket.The UI redeems the payload.

02 · Debug

Open the run before you change the agent.

View · five lenses

One recorded run. Five ways to inspect it.

One run · backup_protection_triage
  1. Read the estate
  2. Assess each cluster
  3. Assess each subject
  4. Posture
  5. Collect
  1. FlowWhat did it actually run?Every stage, in the order it took them — the chart the run really walked, not a diagram of the chart you wrote.
  2. WhyWhy did it decide that?The decision and the evidence beneath it, quoted from the run, with time travel to any moment.
  3. StoryCan someone else follow it?The same run as prose, for the people who will never open a graph and still have to sign off.
  4. Skill graphWhat could it even reach?Which procedure was live at each step, and the tools that step exposed — instead of a flat surface of everything.
  5. Data graphWhere did the numbers come from?How rows were shaped, tool by tool, into the ones the answer rests on. Running in an application today, landing in the lens next.

Test

Remove one source. Rerun the case.

If the output changes under the same baseline, you have evidence of dependence in this case—not hidden reasoning.

Test a source →
One recorded runOne controlled change
original · 8f2recorded
  1. intentsupport.refund
  2. skillbilling.refund
  3. contextpolicy/refunds-v1suspect
decisionAPPROVEwrong output
rerunpolicy/refunds-v1
rerun · 8f2-r1same case
contextpolicy/refunds-v1removed
decisionDENYchanged result

Dependence confirmed

Counterfactual replay tests the recorded run. It does not expose private model reasoning.

03 · Run in production

Serve on your stack. Keep the graph.

Bind

One graph. Your stack.

Every backend is a typed port; every vendor is an adapter behind it. Pick the ground and the adapters resolve — the agent you wrote does not move.

Wire your first port →
The same agent runs on AWS, Google Cloud, Microsoft Foundry or your own hardware. Choosing AWS binds the model port to Bedrock, memory to S3 and PostgreSQL, the runtime to AgentCore, and observability to CloudWatch and X-Ray. The agent itself is unchanged.

Infrastructure detail

ModelsMemoryAFruntimeStorageTelemetry
Keep the graph. Swap the edges.

One customer implementation

~40 toolsfocused surface

Better evaluated responses with a lower-cost model.

Field result, not a benchmark. Reproduce it on your workload.See the comparison method →
Bring your infrastructure — AWS, Google Cloud, Microsoft Foundry, or your own hardwareThe runtime is the whole ecosystem: models, memory, tools, identity, sessions and telemetry. Provision with your CDK or SDK and connect through typed ports — detach telemetry when export must not gate the run. Nothing about the agent you wrote changes when the cloud does.
  • ModelsOpenAI · Anthropic · Bedrock · Gemini · Azure OpenAI · Foundry · Ollama
  • Memory + dataRedis · PostgreSQL · SQLite · S3 · Cloud Storage
  • Toolsyour functions · MCP servers, local or remote
  • Identity + secretsJWKS · Vault · Entra ID · declare-and-push credentials
  • Runtime + sessionsAgentCore · Vertex sessions · your own process
  • ObserveOpenTelemetry · CloudWatch · X-Ray · audit bundles
The same agent, on four groundsagentfootprint provisions nothing and wants none of your credentials — it connects to what you already run. Changing ground changes which adapters you construct at the edge, which is the only place a vendor name should appear in your codebase.
  • AWSBedrock models · AgentCore runtime · S3 · CloudWatch · X-Ray
  • Google CloudGemini and Vertex models · Vertex sessions · Cloud Storage
  • Microsoft FoundryFoundry hosting and models · Azure OpenAI · Entra ID
  • Your own hardwareOllama · PostgreSQL · SQLite · your process · OpenTelemetry

04 · Monitor

Watch, export, archive, and learn from the same event stream.

The monitoring foundation ships todaySubscribe to typed events while the agent runs, send them to your existing backend, or persist the complete recording. The joins are written during traversal, so each downstream tool starts from the same connected run.
  • Watch and exportUse .on() for typed decisions, tools, cost, errors, and coverage; mount .enable.observability() to send the same stream to OTel, CloudWatch, NDJSON, or an audit bundle.
  • Archive the joined runrecordRun() captures state, events, and structure together; persistRecording() writes the versioned envelope to your sink.
  • Learn across runscontextLedger() already aggregates which skills, tools, and injections earned their context. Dedicated cross-session coverage-gap queries are in progress; today, aggregate the typed absence and coverage events in your sink.

Try agentfootprint

Start with one answer, its evidence and the rule that decides whether it can be delivered.