Signed, independently verifiable decision evidence for Vercel AI SDK 7 agents using LoopGrid.
Vercel AI SDK runs the agent. Your application owns authority, policy, human approval and the real downstream outcome. LoopGrid preserves signed evidence around those facts and verifies the record independently.
AI SDK 7 exposes a first-class Telemetry integration surface with model-call and tool-execution lifecycle events. loopgrid-vercel-ai-sdk implements that native interface instead of wrapping models or replacing tools.
For consequential decisions, the integration uses decision-scoped per-call telemetry. This gives each AI SDK generation an explicit LoopGrid decision binding and avoids cross-request correlation mistakes under concurrency.
Requirements:
- Node.js 22+
ai7.x- LoopGrid Core 0.8.1-design-partner validation target
npm install loopgrid-vercel-ai-sdk aiimport { generateText } from 'ai';
import { LoopGridAISDK } from 'loopgrid-vercel-ai-sdk';
const loopgrid = new LoopGridAISDK({
baseUrl: 'http://127.0.0.1:8000',
workspaceId: 'default',
});
const { decisionId } = await loopgrid.startDecision({
decisionType: 'customer_refund',
agent: { id: 'refund-agent', version: '1.0.0' },
authority: { acting_for: 'Acme Support', scope: ['refund:create'], limit_usd: 100 },
model: { provider: 'openai', name: 'gpt-5.5' },
context: { prompt_version: 'refund-v3' },
proposedAction: { tool: 'refund', amount: 25, currency: 'USD' },
policy: {
policy_id: 'refund-policy',
version: '3',
decision: 'auto_allowed',
reason: 'Within delegated limit',
},
});
const result = await generateText({
model,
prompt,
tools,
telemetry: loopgrid.telemetryOptions(decisionId, {
functionId: 'refund-agent',
}),
});
await loopgrid.flush(decisionId);
loopgrid.assertHealthy();
// Application-owned fact, observed from the real downstream system:
await loopgrid.recordOutcome(decisionId, {
status: 'settled',
external_id: 'refund_123',
});| Fact | Source | LoopGrid evidence |
|---|---|---|
| Agent identity | Application | decision record |
| Delegated authority | Application | decision record |
| Model provenance | Application + AI SDK model event | decision + model_completed |
| Context version | Application | decision record |
| Policy | Application / policy engine | policy_evaluated |
| Tool proposed | AI SDK onToolExecutionStart |
tool_requested |
| Tool returned / errored | AI SDK onToolExecutionEnd |
tool_executed / tool_result |
| Human reviewer | Application | human_approved / human_rejected |
| Observed downstream outcome | Application / external system | outcome_observed |
| Integrity | LoopGrid | Ed25519 + SHA-256 chain verification |
A successful tool callback is not automatically an observed business outcome. A tool can return before a downstream system settles, reject later, or represent only a request. recordOutcome() is therefore explicit.
Likewise, toolApproval: { tool: 'user-approval' } does not tell LoopGrid who the reviewer was. Record the actual reviewer explicitly:
await loopgrid.recordHumanReview(decisionId, {
approved: true,
reviewer: 'alice@example.com',
reason: 'Duplicate charge verified',
});captureContent defaults to false.
The integration records SHA-256 commitments for model content, provider metadata, tool inputs, tool results, and tool errors. Raw content/provider metadata/error messages are omitted unless explicitly enabled:
const loopgrid = new LoopGridAISDK({ captureContent: true });AI SDK's own telemetry options are also returned with recordInputs: false and recordOutputs: false by default.
AI SDK telemetry callbacks are observational. The integration does not claim telemetry callbacks can enforce or block a tool action.
Transport failures are retained and made inspectable:
await loopgrid.flush(decisionId);
loopgrid.assertHealthy();If your application requires evidence to be persisted before an action may proceed, enforce that requirement in application/control-plane logic, not by assuming an observational telemetry hook is a policy gate.
npm install
npm test
npm run test:privacy
npm run check
npm run e2eThe deterministic E2E uses AI SDK's MockLanguageModelV4; it requires no model API key and moves no real money.
The release gate is:
lifecycle = evidence_complete
applicable coverage = 100%
verification.valid = true
failures = []
See INTEGRATION-CONTRACT.md and VALIDATION.md before publishing.