@talosjs/ai component is a multi-provider AI toolkit. It exposes a single, consistent API for text generation, streaming, structured output, and function calling across 300+ models (OpenAI, Anthropic, Google, Groq, Ollama, and more) through OpenRouter.
You build three kinds of classes (chats, tools, and middleware), register them with a decorator, and resolve them from the container.
What you get
Switching providers is a matter of changing theprovider/model string passed to getModel(); nothing else moves. Chats, tools, and middleware are all dependency-injected classes you compose as you like, with TypeScript types throughout, schema-validated tool inputs, and structured run output. Tool and function calling, streaming events, and the agentic loop are supported directly. For operations, the component gives you structured exceptions, input validation, and lifecycle hooks you can use for auditing and metrics.
How it works
A chat is the unit you run. When you callrun() or stream(), the component:
- Builds the message list from your system prompts, history, and the new prompt.
- Resolves the chat’s tool and middleware classes from the container.
- Creates an OpenRouter adapter from
getModel(). - Runs the agentic loop. The model may call tools, whose results feed back into the conversation.
- Returns the final text, a validated structured object, or a stream of events.
Environment variables
The core API talks to OpenRouter; the bundled tools read their own provider keys from the app environment. Keys are read lazily, so a missing key fails when the tool is called rather than at startup.Decorators and usage
@decorator.chat()
Registers a Chat subclass with the container. You implement four getters: the model, the system prompts, the tools, and the middleware.
provider/model form, for example anthropic/claude-sonnet-4.5, openai/gpt-4.1, or google/gemini-2.5-pro.
@decorator.tool()
Registers a tool the model can call. Implement getName() (snake_case, the name the model sees), getDescription() (tells the model when to call it), getInputSchema() (validated before your handler runs), and handler().
getTools():
getTools() to use them.
@decorator.middleware()
Registers middleware that observes the run through lifecycle hooks. Implement only the hooks you need.
setup → onConfig → onStart → onBeforeModel → streaming (onChunk) → onToolPhaseComplete → onUsage, then one terminal hook (onFinish, onError, or onAbort). Add the class to a chat’s getMiddlewares().
Running chats
Structured output
Pass a schema and the run returns a validated object instead of free text.Streaming
Context, history, and sampling
Exceptions
The component throwsAiException for AI-specific failures: a tool handler error, an invalid response, a missing key, or a failed run. It carries a machine-readable key, a human-readable message, and a frozen data object.
key:
Working effectively
Keep model selection ingetModel() rather than at the call site, so a single edit swaps providers for every caller of that chat. A tool’s getName() and getDescription() are how the model decides when to call it, so write them for the model: be specific about when to call the tool and what it returns. Because getInputSchema() runs before your handler, you can narrow the input type inside the handler without re-validating.
Favor single-purpose tools. One tool does one job and the model composes them, which works better than a single multi-mode tool. Cross-cutting concerns (logging, metrics, auditing, per-iteration tweaks) belong in middleware, not inside tools or chats. Pass per-run data through context instead of globals; it reaches every tool and middleware while keeping them stateless. When you throw AiException, keep the key stable so callers can branch on it, and put the variable detail in data. For results a program will consume, an outputSchema beats parsing free text.
CLI commands
Scaffold each building block with its generator. Each command creates the class and a matching test file under the target module, and installs@talosjs/ai if it is missing.
See ai:chat:create, ai:tool:create, and ai:middleware:create for full command references.
Use with Claude and Codex
Each generator ships a matching skill that runs the scaffold and then guides your AI agent through completing the class: the chat’s model, prompts, tools, and middleware; a tool’s description, schema, and handler; or a middleware’s lifecycle hooks. Initialize the skills once for your agent:- Claude
- Codex
Prompt
ai:chat:create --name=Support, then generates the matching ai:tool:create --name=WebSearch and ai:middleware:create --name=Audit classes and wires them into the chat.