AI SDK
Add credit billing to your agent with TrackedToolLoopAgent.
Replace ToolLoopAgent with TrackedToolLoopAgent. Pass your existing agent settings and a wallet identity. The class checks access before each model step and priced tool execution, then bills completed usage.
import { TrackedToolLoopAgent } from "@orbytelabs/credit/ai-sdk";
const agent = new TrackedToolLoopAgent(existingAgentOptions, {
identity: "customer_123",
});
const result = await agent.generate({ prompt: "What's the weather?" });Telemetry, prepareStep, and final billing error checks are automatic. Your existing prepareStep, prepareCall, telemetry integrations, and step callbacks still run. The class preserves AI SDK's typed tools, call options, and structured output.
For direct control over checks and telemetry, see advanced mode.
Set up
This integration uses AI SDK 6 and requires Node.js 24+. Automatic inference billing requires an AI Gateway model that returns providerMetadata.gateway.cost.
Complete the SDK setup first. Keep ORBYTE_API_KEY and AI_GATEWAY_API_KEY on the server. Credit uses https://api.orbytelabs.com automatically. Your billing key selects the Credit application; your Gateway key authenticates model requests. See AI Gateway setup for Gateway credentials.
pnpm add @orbytelabs/credit ai@^6 zodDefine your agent
Use the same settings you would pass to ToolLoopAgent. Put tool prices in metadata.orbyte.cost.
import { tool } from "ai";
import { z } from "zod";
import { TrackedToolLoopAgent } from "@orbytelabs/credit/ai-sdk";
export function createAgent(identity: string) {
return new TrackedToolLoopAgent(
{
model: "openai/gpt-5.4-mini",
instructions:
"Use the weather tool when asked about weather. Explain that its results are demo data.",
tools: {
weather: tool({
description: "Get demo weather conditions for a location",
metadata: { orbyte: { cost: "0.02" } },
inputSchema: z.object({ location: z.string() }),
execute: async ({ location }) => ({
location,
temperature: 28,
condition: "sunny",
}),
}),
},
},
{ identity },
);
}The weather tool costs 0.02 credits per successful call. metadata.orbyte.cost accepts a decimal string or number. Tools without this metadata and tools priced at zero need no tool access check and produce no tool charge. Failed tool calls produce no tool charge. A denied check prevents the priced tool from executing; AI SDK receives a tool error.
Use a customer identity from your authenticated server context. Each generate() or stream() call creates separate billing telemetry and a fresh run ID, so you can reuse an instance for the same customer. Create another instance for a different customer.
Deploy the agent's catalog
aiSdkBilling reads the agent's tool metadata and creates the credit and feature declarations.
import { aiSdkBilling } from "@orbytelabs/credit/ai-sdk";
import { createAgent } from "./src/agent.js";
export default aiSdkBilling(createAgent("catalog"));Loading this config does not run the model, execute tools, or create a wallet for catalog. Keep generation and top-ups outside modules that the config imports.
pnpm exec orbyte deploy --dry-run
pnpm exec orbyte deployUse a setup key with catalog read and write permissions. The CLI reference covers configuration options, generated keys, and Production deployment.
| Entry | Configuration |
|---|---|
| Credit type | agent-credit, named Agent credit. |
inference feature | One credit per 1_000_000_000 nanodollars of Gateway cost, equal to one credit per USD. |
weather feature | 0.02 credits per successful call. |
inference is reserved for model usage. Do not give a priced tool this name. The helper uses tool names as feature keys and includes only tools with a positive metadata.orbyte.cost. It sets no usage-period deduplication. Redeploy after changing tool prices.
This catalog uses fixed nanodollar pricing for inference. The general quickstart uses callback pricing for that same feature key. Choose this catalog for the agent recipe. If an application already uses the quickstart catalog, update every inference caller to send nanodollar quantities before switching catalogs.
To choose a different inference rate, define your own pricing configuration with the same inference feature and nanodollar quantity unit. Telemetry sends quantities; the deployed catalog sets the charge.
Fund the wallet
Fund the agent-credit balance before running paid work.
import { credit, topup } from "@orbytelabs/credit";
await topup("customer_123", credit("agent-credit")(10), {
idempotencyKey: "agent_credit_purchase_123",
});Run this when granting or selling credits, using the same key when retrying that deposit. Do not top up on every agent request. See wallets and top-ups.
Generate a response
import { createAgent } from "./agent.js";
export async function reply(identity: string, prompt: string) {
const result = await createAgent(identity).generate({ prompt });
return result.text;
}A denied inference check prevents the model step. A failed charge stops the next model step and rejects generate(), including failures on the final step. You do not need a separate BillingTelemetry, using declaration, or final assert().
Stream a response
import { createAgent } from "./agent.js";
export async function streamReply(identity: string, prompt: string) {
const result = await createAgent(identity).stream({ prompt });
return result.toTextStreamResponse();
}Billing stays active until the stream finishes. Result promises such as result.text reject billing failures. Stream consumers and HTTP response streams also receive those failures. Content already sent to a client cannot be recalled if the final charge fails.
An interrupted model step may not return the cost metadata needed for billing. The adapter records completed steps for which Gateway supplies a cost; it cannot reconstruct missing provider costs after an interrupted stream.
Access checks and tracked usage
Before each model step, the class checks inference with a default quantity of 1_000_000 nanodollars, or $0.001. With this catalog, that threshold costs 0.001 credits. Change the threshold in the second constructor argument:
const agent = new TrackedToolLoopAgent(existingAgentOptions, {
identity: "customer_123",
inferenceQuantity: 5_000_000,
});The threshold tests the starting balance. It does not estimate or limit the next model call's actual cost. check does not reserve funds. A larger actual cost or concurrent usage can still cause the later charge to fail. If you add plan allowances, checks also evaluate their limits and subscription state.
After each completed model step, telemetry reads the Gateway USD cost, rounds it up to a whole nanodollar, and tracks that quantity against inference. Zero-cost steps produce no event. Missing or invalid cost metadata rejects the run; the adapter does not estimate charges from token counts.
Before each priced local tool executes, the class checks access for its feature key. After a successful call, telemetry tracks quantity 1 against the tool name. Do not manually track the same model or tool usage again, or attach another BillingTelemetry to a tracked agent.
Each invocation gets a fresh UUID run ID. Model events use {runId}:{stepNumber} and tool events use {runId}-{toolCallId}. These IDs keep transport retries from charging the same event twice. Running the agent again starts new work and creates new event IDs.
Direct provider calls without Gateway cost metadata are not supported by this automatic inference adapter. Use check and track with your own measured quantities or callback pricing when your application calculates the cost itself. For custom run IDs, telemetry error modes, or generateText and streamText, use advanced mode.