@memoflowio/memoflow-ai-sdk
v0.1.2
Published
Durable budget and invocation middleware for Vercel AI SDK language models
Readme
@memoflowio/memoflow-ai-sdk
Optional durable language-model middleware for Vercel AI SDK. It wraps each
provider generation with a MemoFlow budget reservation and invocation ledger
entry while keeping ai out of the core SDK install. The adapter targets the
current Language Model V4 middleware contract from AI SDK 7.
Terminal and streaming generation are supported. A stream settles only after
its Language Model V4 finish event; provider errors, early EOF, and consumer
cancellation retain reconciliation liability. Text deltas are forwarded to
best-effort activity output while durable evidence remains digest-only.
Ordinary AI SDK tools are rejected fail-closed. MCP tools can be admitted through a paired bridge so each provider step keeps its own model-call reservation and every tool execution uses the MCP adapter's separate reservation, effect ledger, stable logical key, and protected replay:
const bridge = createMemoFlowAiSdkMcpBridge(mcpClient, {
budget: ({ provider, modelId }) => modelBudget(provider, modelId),
recordedReplayKey: (_call, params) => logicalModelTurnKey(params),
});
const weather = bridge.mcpTool({
name: 'weather.lookup',
inputSchema: jsonSchema({ type: 'object', properties: { city: { type: 'string' } } }),
server: { name: 'weather', version: '2026-07' },
version: 'v1',
budget: { modelCalls: 0, toolCalls: 1, totalTokens: 0 },
replayKey: ({ city }) => `weather-command-${city}`,
});
await generateText({ model: wrapLanguageModel({ model, middleware: bridge.middleware }), tools: { weather } });Each replay key must identify one logical call. The MCP envelope rejects a
changed server/tool/input binding. When recordedReplayKey is configured, a
terminal V4 provider result is stored in protected activity output and bound to
provider, model, prompt, parameters, and tools; an activity retry restores it
before reservation or dispatch. Complete V4 streams use the same binding and
replay their ordered parts only when a terminal finish was recorded. The
protected stream buffer defaults to 16 MiB and can be bounded from 1 byte to
64 MiB with recordedReplayMaxBytes; oversized or partial streams reconcile
instead of producing replay evidence.
