Models
Introduction
Section titled “Introduction”An agent never spells out a model. It names a profile, the profile names a provider and a model id, and the provider names the endpoint and the environment variable that holds the key. Operators manage providers and profiles as files, so a model change never needs a code change.
agent -> runtime.profileId -> profile (model: "provider:model_id", params) -> provider (kind, baseUrl, key variable)Adding a provider
Section titled “Adding a provider”A provider is a named endpoint in .pilotoo/providers/<name>.yaml. The file name is its id.
kind: openai-compatiblebaseUrl: https://api.example.com/openai/v1apiKeyEnv: EXAMPLE_API_KEYsalvageLeakedToolCalls: trueacceptsImages: falseFor the common hosted vendors you need no file: deepseek, openai, anthropic and anthropic-bedrock resolve from environment variables. A file with a built-in’s name replaces it.
Adding a profile
Section titled “Adding a profile”A profile is .pilotoo/profiles/<id>.yaml. Its model is <provider>:<model id>.
name: Reasoningmodel: my-endpoint:my-model-idparams: reasoningEffort: high temperature: 0.2An agent then names it with profileId: reasoning. default.yaml is special: every template names it and the boot requires it. It is the model an agent runs on unless it names another profile. One model can back several profiles with different params.
Tuning parameters
Section titled “Tuning parameters”| Param | Notes |
|---|---|
temperature |
Default 0. |
maxTokens, topP |
Sampling. |
reasoningEffort |
low, medium or high. For openai, openai-compatible, deepseek, and for anthropic-bedrock and claude-subscription, where it is sent as the output effort. |
thinkingBudget |
Tokens, at least 1024. For anthropic, anthropic-bedrock and claude-subscription, and only with an explicit maxTokens above it. |
A param the provider kind cannot honour is a validation error naming the profile and the param. SUPPORTED_PARAMS in packages/agent-runtime/src/model-params.ts is the one table, keyed by kind.
Resolving models in code
Section titled “Resolving models in code”The runner needs a ModelResolver. The simplest one is the provider registry:
import { createProviderRegistry } from '@pilotoo/agent-runtime';
const models = createProviderRegistry({ anthropic: { apiKey: process.env.ANTHROPIC_API_KEY }, openai: { apiKey: process.env.OPENAI_API_KEY, baseUrl: process.env.OPENAI_BASE_URL },});To include file providers, pass them with createDirectoryProviderSource as createProviderRegistry(envConfigs, { providers, env }). In PilotooModule, this is the modelProviders option. Or implement ModelResolver yourself:
| Method | Meaning |
|---|---|
resolveModel(ref, params?) |
Returns a LangChain chat model. Required. |
salvagesLeakedToolCalls?(ref) |
Whether the endpoint leaks tool calls as text. Unanswered is off. |
acceptsImages?(ref) |
Whether the model takes image content. Unanswered is no. |
When files are read
Section titled “When files are read”| What | When |
|---|---|
| Provider files | Once, at boot. Edit one, restart. |
| Profile files | On every call. A profile edit reaches the next run. |
The boot fails on a profile naming a provider that does not exist, on a profile on a claude-subscription provider when the host passes no claudeLogin, on a param its kind cannot honour, and on a system agent or template whose profileId has no profile file.
The key is read from env[apiKeyEnv] each time a model is built, so a variable set after boot is used. A missing one fails the run at its start with an error naming the provider and the variable, never a value.
Options
Section titled “Options”Provider fields
Section titled “Provider fields”The provider file is strict: an unknown field is an error.
| Field | Meaning |
|---|---|
kind |
One of openai-compatible, openai, deepseek, anthropic, anthropic-bedrock, claude-subscription, pilotoo-gateway. |
baseUrl |
https, or http only for localhost, 127.0.0.1 and [::1]. Required for openai-compatible and pilotoo-gateway; otherwise the library default. |
apiKeyEnv |
The name of an environment variable that ends in _KEY, so a pasted key or an unrelated variable such as DATABASE_URL is refused. |
region |
An AWS region code. Required by anthropic-bedrock, rejected by every other kind. |
salvageLeakedToolCalls |
Recover tool calls an endpoint leaks as text. |
acceptsImages |
Whether the endpoint’s models read images. |
| Kind | Builds | Key |
|---|---|---|
openai-compatible |
ChatOpenAI on baseUrl |
apiKeyEnv required |
openai, deepseek, anthropic |
the chat model of that name | apiKeyEnv required |
anthropic-bedrock |
ChatAnthropic on Amazon Bedrock |
apiKeyEnv optional (a Bedrock API key); without it, the AWS credentials |
claude-subscription |
ChatAnthropic on the host’s Claude sign-in |
none; takes no apiKeyEnv or baseUrl |
pilotoo-gateway |
a shared profile on a gateway, see Model gateway | none; needs the gateway’s baseUrl |
Unset, the two capability flags keep what the kind does: openai-compatible salvages leaked tool calls and takes no images; deepseek salvages only off DeepSeek’s own host and takes no images; openai, anthropic, anthropic-bedrock and claude-subscription do not salvage and take images.
Profile fields
Section titled “Profile fields”| Field | Meaning |
|---|---|
name |
Display name. |
model |
<provider>:<model id>. |
params |
A closed schema, see above. |
shared |
true lets a model gateway lend this profile to other hosts. Absent is no. |
Profiles are operator-managed and live only in files. Tenants never write profiles.
What the kit guarantees
Section titled “What the kit guarantees”- An unsupported provider throws
UnknownProviderError; one without an API key throwsProviderNotConfiguredError. The run ends inRUN_ERRORnaming it. - A run carrying attachments on a model that does not accept images ends with
AttachmentsNotSupportedErrorbefore any provider call. - Profile summaries the editor lists report
provider,keyConfigured(whether the variable is set, never its value) andkeyVariable(its name). Paths are written.pilotoo/profiles/<id>.yamlwhateverPILOTOO_CONFIG_DIRis. - A file that fails the schema is not offered as a choice but reported in the optional
invalidarray.
Next steps
Section titled “Next steps”- Point an agent at your profile.
- Lend your models to desktop clients with the model gateway.
- Meter spending with usage.