Dexby

Frameworks

Give a session's tools to your agent framework or model API, in its own format.

Pick a provider when you create the client. session.tools() then returns tools in that framework's own type, ready to pass in. No casts.

agent.ts
const dexby = new Dexby({ provider: new AiSdkProvider() })

const tools = await dexby
	.createSession({ userId: 'user_123', connectors: ['slack'] })
	.andThen((session) => session.tools())
if (tools.isErr()) throw new Error(tools.error.message)

// tools.value is an AI SDK ToolSet

Agent frameworks

The framework calls each tool through Dexby with the user's connected accounts. Install the framework next to @dexby.ai/sdk. Allow several steps: the model searches for a tool before it runs it.

ai-sdk.ts
import { openai } from '@ai-sdk/openai'
import { Dexby } from '@dexby.ai/sdk'
import { AiSdkProvider } from '@dexby.ai/sdk/providers/ai-sdk'
import { generateText, stepCountIs } from 'ai'

const dexby = new Dexby({ userId: 'user_123', provider: new AiSdkProvider() })
const tools = await dexby.createSession({ connectors: ['slack'] }).andThen((s) => s.tools())
if (tools.isErr()) throw new Error(tools.error.message)

const { text } = await generateText({
	model: openai('gpt-5'),
	tools: tools.value,
	stopWhen: stepCountIs(8),
	prompt: 'Post "Deploy finished" to #general'
})

Frameworks that take AI SDK tools, such as Cloudflare's Agents SDK, use AiSdkProvider.

Model APIs

These providers return plain tool definitions without a framework dependency. Install the model client package used by your application. Your code runs each tool call with session.call(name, input) and sends the result back.

The snippets below show only tool dispatch. The comments mark where your application must send results back to the model and continue the loop; these are not complete agent runs.

anthropic.ts
import Anthropic from '@anthropic-ai/sdk'
import { Dexby } from '@dexby.ai/sdk'
import { AnthropicProvider } from '@dexby.ai/sdk/providers/anthropic'

const anthropic = new Anthropic()
const dexby = new Dexby({ userId: 'user_123', provider: new AnthropicProvider() })
const created = await dexby.createSession({ connectors: ['slack'] })
if (created.isErr()) throw new Error(created.error.message)
const session = created.value
const tools = await session.tools()
if (tools.isErr()) throw new Error(tools.error.message)

const message = await anthropic.messages.create({
	model: 'claude-sonnet-4-5',
	max_tokens: 1024,
	tools: tools.value,
	messages: [{ role: 'user', content: 'Post "Deploy finished" to #general' }]
})
for (const block of message.content) {
	if (block.type !== 'tool_use') continue
	const outcome = await session.call(block.name, block.input)
	if (outcome.isErr()) throw new Error(outcome.error.message)
	// Send back { type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(outcome.value) }
}

Good to know

  • A tool returns { ok: true, result } or { ok: false, error }. The model reads both. A refusal, such as an app that is not connected, is not an exception. See Errors.
  • Stopping a run cancels the Dexby call, except in LlamaIndex (no abort signal for tools) and Genkit's generate (does not pass its signal to tools).
  • Mastra, LangChain and Genkit check tool input against the schema first. Mastra hands a mismatch back to the model; LangChain and Genkit throw.
  • Each framework is an optional dependency, loaded only by its own provider import.
  • Another format? Implement ToolProvider from @dexby.ai/sdk/contracts. See the SDK reference.

On this page