paybondpaybond
Sign in

Agent middleware

Model-agnostic run binding, tool registry, interceptors, and automatic evidence for multi-tool agent integrations.

Paybond agent middleware is the recommended integration path for multi-tool agents. Call paybond.instrument() to load policy and register tools (deferred by default), then bind() per session, pass a lazy context provider, or use paybond.agent() for sandbox quickstart.

Agent selection rule

  • Middleware: instrument() → run binding, registry, interceptor, required auto-evidence.
  • Manual guard: per-tool guardTool / guard_tool; you call submitEvidence yourself.
  • Model token caps: use provider-native usage controls — not Paybond.

Public product page: /kit/agent-middleware. Developer reference: /docs/kit/agent-middleware. CLI overview: /kit/cli.

When to use middleware vs manual guard

ApproachBest for
Agent middlewareMulti-tool agents, coding-agent automation, any integration that must not forget evidence on side-effecting tools
Per-tool guardToolSingle paid handler, legacy code, or advanced cases where you control evidence timing explicitly

Use middleware when:

  • The agent exposes multiple paid or side-effecting tools.
  • You want automatic evidence on every successful side-effecting call.
  • You need defaultDeny to catch forgotten wraps before production.
  • Coding agents or CI should test the full authorize → evidence path without vendor APIs.

Keep per-tool guardTool / guard_tool when:

  • You have a single paid tool and full control over evidence timing.
  • You are migrating incrementally from an existing guard wrapper.

See Agent integrations for single-handler examples.

Sandbox smoke (no integration code)

Local dev loop (recommended — policy scaffold, validate, smoke, trace URL):

Terminal
Terminal commandSwipe to inspect long lines
paybond dev loop --offline   # terminal 1
paybond dev trace            # terminal 2 — same project directory

With sandbox credentials:

Terminal
Terminal commandSwipe to inspect long lines
paybond login
paybond dev loop
paybond dev trace

The trace dashboard at http://127.0.0.1:9477 renders a vertical timeline (authorize → execute → evidence → settlement). Events persist to .paybond/dev-trace.jsonl so smoke and trace can run in separate terminals. See the middleware trace guide and developer reference for the event model and UI phases.

Manual smoke (explicit flags):

Terminal
Terminal commandSwipe to inspect long lines
paybond login
paybond agent sandbox smoke \
  --operation paid-tool \
  --requested-spend-cents 100 \
  --evidence-preset cost_and_completion \
  --result-body '{"status":"ok","cost_cents":100}' \
  --format json

For multi-step runs: paybond agent run bind --sandbox ... then paybond agent tool execute --run-id ..., then paybond agent run trace --run-id ... to inspect authorize → execute → evidence steps from the CLI. See the agent quickstart for paybond dev workflows, middleware trace for the visual dashboard, the agent middleware docs for SDK traceSink, and paybond doctor --agent for the same smoke path in diagnostics.

Trace events (SDK)

The interceptor emits structured events as each side-effecting tool runs: tool_selectedspend_authorizedtool_executedspend_finalizedevidence_submitted. Pass traceSink on bind to debug denied calls or wire custom telemetry:

paybond-session.ts

TS
TypeScript code sampleSwipe to inspect long lines
const run = await paybond.agentRun.bind({
  bootstrap: { kind: "sandbox", operation: "travel.book_hotel", requestedSpendCents: 20_000 },
  registry,
  traceSink: (event) => console.log(event.type, event),
});

paybond dev loop and paybond dev trace collect the same events locally without app code — timeline steps are written to .paybond/dev-trace.jsonl and rendered in the dashboard. For bind → execute workflows, paybond agent run trace --run-id <id> prints the per-run timeline from .paybond/runs/<run_id>.trace.json. Python: trace_sink on agent_run.bind(). Full reference: Trace events and observability.

SDK shape (TypeScript)

paybond-session.ts

TS
TypeScript code sampleSwipe to inspect long lines
import { Paybond } from "@paybond/kit";

const paybond = await Paybond.open({ apiKey: process.env.PAYBOND_API_KEY! });

const instrumented = await paybond.instrument({
  policy: "./paybond.policy.yaml", // or preset id "travel"
  tools: {
    "travel.book_hotel": bookHotel,
    searchWeb: searchWeb,
  },
});

// Sandbox quickstart: paybond.agent({ policy: "travel", tools }) binds sandbox automatically.
// Production: const runtime = await instrumented.bind({ intentId, capabilityToken });
// Or lazy: instrument({ ..., context: () => activeRequest.paybond })

Python: await paybond.instrument(policy=..., tools=...) with the same semantics; await instrumented.bind(...) or context=lambda: ... for lazy binding.

For step-by-step registry and bind control, see Agent middleware docs.

Framework adapters

Shipped adapter packs plug into the same run binding and registry:

FrameworkDocSmoke
Agent-agnostic (default)/docs/kit/agent-agnosticpaybond agent demo generic smoke
LangGraph (TypeScript and Python)/docs/kit/langgraphpaybond agent demo langgraph smoke
Claude Agent SDK (TypeScript and Python)/docs/kit/claude-agentspaybond agent demo claude-agents smoke
Vercel AI SDK (TypeScript only)/docs/kit/vercel-aipaybond agent demo vercel-ai smoke
OpenAI Agents SDK/docs/kit/openai-agentspaybond agent demo openai-agents smoke
MCP hosts (TypeScript and Python)/docs/kit/mcp-serverpaybond loginpaybond-mcp-server (see coding-agent setup)
CrewAI (Python only)/docs/kit/crewaipaybond agent demo crewai smoke
Pydantic AI (Python only)/docs/kit/pydantic-aipaybond agent demo pydantic-ai smoke
Google ADK (TypeScript and Python)/docs/kit/google-adkpaybond agent demo google-adk smoke
Microsoft Agent Framework (Python only)/docs/kit/microsoft-agent-frameworkpaybond agent demo microsoft-agent-framework smoke
Mastra (TypeScript only)/docs/kit/mastrapaybond agent demo mastra smoke
Cloudflare Agents (TypeScript only)/docs/kit/cloudflare-agentspaybond agent demo cloudflare-agents smoke

Planned (use agent-agnostic or MCP today; request an adapter):

FrameworkDocRecipe guide
LlamaIndex WorkflowsAgent-agnostic spend controls

Use paybond init agent-middleware --framework <name> to scaffold integration files.

Policy-as-code

For GitOps-friendly configuration, version a paybond.policy.yaml and validate before deploy:

Terminal
Terminal commandSwipe to inspect long lines
paybond policy validate-tools --file paybond.policy.yaml --local-only --format json

Buyer guide: /guides/agent-policy. Remote validation: /docs/kit/agent-policy-validate. Org policy inheritance: /docs/kit/enterprise-policy-inheritance. Long-lived processes: /docs/kit/policy-hot-reload.

Going to production

Sandbox smoke and paybond.agent() never require payee identities or signing seeds. When you attach to a funded production intent, see Production attach for CLI flags, SDK productionEvidence, and env fallbacks.

Performance and latency

Guarded tool calls add serial Gateway and Harbor round trips that usually dominate latency versus local handler time. For an overhead model, authorization-cache behavior, and what dev trace does not measure, see Middleware performance and latency.