Providers

Thin adapters that translate Shiro requests into vendor model APIs.

Providers

A provider adapts a model vendor to Shiro’s request/response contract. It should stay small: accept messages and options, return text / tool requests / usage, and map vendor errors into Shiro errors.

Everything else — tools, approvals, memory, Studio — stays outside the adapter.

Why providers are isolated#

Vendor APIs change. Runtime behavior should not. If tools or Studio imported OpenAI types directly, every SDK bump would ripple through the product. Providers absorb that churn.

Agent (provider: "openai")


Engine plugin registers OpenAIProvider


Runner calls provider.generate / provider.stream

Installing OpenAI#

import { Engine } from "@shiro-sdk/core";
import { OpenAIPlugin } from "@shiro-sdk/openai";

const engine = new Engine();
engine.use(
  new OpenAIPlugin({
    apiKey: process.env.OPENAI_API_KEY!,
    model: "gpt-5",
  })
);

OpenAIPlugin registers an OpenAIProvider under the id "openai". Agents select it:

const agent = new Agent({
  name: "support",
  instructions: "...",
  provider: "openai",
});

You can also pass a provider instance instead of a string id when you need a one-off configuration.

What providers should not own#

  • Memory persistence
  • Approval decisions
  • Tool execution
  • Studio rendering
  • Handoff policy

If you find those concerns inside a provider, they belong on the engine / runner instead. See Plugins for the install surface.

Streaming#

Providers may expose streaming at the adapter level (provider.stream). Application-facing “stream the whole run” is better modeled as runtime events (tool started, approval requested, run completed) via the engine event bus — that is what Studio consumes. Do not assume provider token deltas are the only progress signal.

Best practices#

  • Configure providers at startup through plugins
  • Normalize errors at the adapter boundary
  • Record usage and latency for traces
  • Avoid leaking vendor-specific response objects into tools

Common mistakes#

  • Calling the vendor SDK from a tool after adopting Shiro
  • Installing the package but forgetting engine.use(new OpenAIPlugin(...))
  • Selecting provider: "openai" when no plugin registered that id