Search

Search the documentation

Protobox

Framework Adapters

Hand integration tools to OpenAI, Anthropic, or the Vercel AI SDK in one line.

An adapter converts an integration's tools into a provider's tool-calling format and runs the model's tool-calls back through the platform. Get one with forLLM(provider, options) — on the SDK, or on an entity to scope execution to a user.

const gh = protobox.entity('user_123').forLLM('anthropic', { integrationId: 'github' });

Every adapter exposes .tools() (fetch the provider-formatted tools) and a run method that executes the model's tool-calls and returns provider-shaped results.

Anthropic

import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic();

const gh = user.forLLM('anthropic', { integrationId: 'github' });
const tools = await gh.tools(); // [{ name, description, input_schema }]

let message = await anthropic.messages.create({
  model: 'claude-sonnet-5',
  max_tokens: 1024,
  tools,
  messages,
});

// Execute any tool_use blocks and feed the results back
const toolResults = await gh.run(message.content); // [{ type: 'tool_result', tool_use_id, content }]
messages.push({ role: 'assistant', content: message.content });
messages.push({ role: 'user', content: toolResults });

OpenAI

import OpenAI from 'openai';
const openai = new OpenAI();

const gh = user.forLLM('openai', { integrationId: 'github' });
const tools = await gh.tools(); // ChatCompletionTool[]

const res = await openai.chat.completions.create({ model: 'gpt-4o', messages, tools });
const toolMessages = await gh.run(res.choices[0].message.tool_calls ?? []);
// toolMessages are role:'tool' messages — append them and continue the loop
messages.push(res.choices[0].message, ...toolMessages);

Vercel AI SDK

import { generateText } from 'ai';

const gh = user.forLLM('vercel', { integrationId: 'github' });
const tools = await gh.tools(); // { [name]: { description, parameters, inputSchema, execute } }

const { text } = await generateText({ model, prompt, tools, maxSteps: 5 });

The Vercel tool set includes both parameters (AI SDK v4) and inputSchema (AI SDK v5), each holding the tool's JSON Schema. If your AI SDK version validates the schema type, wrap it with jsonSchema() from the ai package: tool({ description: t.description, inputSchema: jsonSchema(t.inputSchema), execute: t.execute }).

Error handling inside the loop

Adapter run methods never throw for tool-level failures — they encode the error in the provider's result shape so the model can react:

  • OpenAI / Anthropic — the tool message/tool_result content is { "error": "..." } (Anthropic also sets is_error: true).
  • Vercelexecute resolves to { error: "..." }.

For connection problems specifically, a direct execute() call exposes result.authRequired — see Managed auth.

On this page