Provider Protocols and Model Interfaces
Anyy v0.1.107 implements five native conversation protocol families. Shared behavior follows fixed Pi v1.2.0, commit 06a466935536f8c9bcacb2d5efc0fc021be1bdff. This is a protocol and interface scope, not a promise that every provider endpoint, account, or authentication variant has been tested live.
Conversation Protocols
Anyy api_mode | Corresponding Pi API | Request family |
|---|---|---|
openai-compatible | openai-completions | OpenAI-style Chat Completions, including compatible local services |
openai-responses | openai-responses | OpenAI Responses |
codex-responses | openai-codex-responses | Codex subscription Responses and its transport/session behavior |
anthropic-messages | anthropic-messages | Anthropic Messages |
google-gemini | google-generative-ai | Gemini Generative AI |
Provider brands can offer several endpoint contracts; choosing a brand does not make the contracts interchangeable. Ollama and Ollama Cloud use the existing OpenAI-compatible family. Ollama /api/tags only discovers models.
The five additional Pi APIs azure-openai-responses, bedrock-converse-stream, google-vertex, mistral-conversations, and pi-messages have no independent native implementation or qualification in this release. A compatible gateway may use one of the five implemented families if it actually implements that contract; this does not add the service's distinct native API. Blocked setup choices, including native Azure and Bedrock paths, remain unavailable.
Endpoint and Authentication Details
Use the API root expected by the selected endpoint. Native Anthropic Messages appends /v1/messages?beta=true to the supplied Base URL without removing an existing prefix. For Anthropic's direct service, the root is https://api.anthropic.com; do not add /v1 again. Custom proxies must expose the resulting path.
Anyy resolves credentials before preparing a provider request. Native Anthropic authentication follows the effective key and native header/beta rules; auth_transport is not a switch to force a different native Messages scheme. OAuth/subscription setup remains endpoint-specific. Codex uses its own subscription credential and sends Anyy's client identity (originator: anyy by default), rather than claiming to be the provider's client. Configured model headers are applied before request headers; a request header can override or delete that marker. Anyy still manages authentication and its truthful User-Agent.
Typed Model Catalog
The model catalog separates operations by type:
| Type | Purpose | Boundary |
|---|---|---|
chat | Conversation and tool-calling model | Default when type is omitted; main/fallback chat selections use this type |
image | Typed image generation | Used by models.generateImages() |
classifier | Structured choice, score, and boolean classification | Used by models.classify() |
A model ID is resolved with provider and type. The same ID may exist in different types; an image or classifier record cannot silently become a chat model. Catalog descriptors carry API, input/output modalities, limits, costs, compatibility metadata, and configured sampling controls. Those declarations describe a route; they do not probe remote service availability.
Advanced providers[].models[] fields include type, api, base_url, input, output, headers, input_limits, sampling_params, sampling_params_by_thinking_level, compat, capabilities, and cost. Use the declared wire contract and the service's documented parameters. Native sampling merges model defaults, effective-thinking-level parameters, then request parameters; later fields override earlier fields. These controls do not introduce a new protocol family or guarantee that a remote endpoint accepts arbitrary options.
Codemode Models Helpers
When Models helpers are available in Codemode, these asynchronous functions use the same configured catalog and credentials:
| Function | Result |
|---|---|
models.getModelsOfType(type, provider?) | Catalog records for chat, image, or classifier |
models.getAvailableOfType(type, provider?) | Records filtered by provider enablement and resolvable credentials |
models.getModelOfType(type, provider, id) | Exact record, or undefined if absent |
models.classify(model, context) | Typed classification result |
models.generateImages(model, context) | Typed image result |
“Available” is a local credential/enablement check, not a live inference test. Scripts receive catalog descriptors without configured headers. Execution resolves the original configured model again; editing a returned descriptor does not redirect the operation to another endpoint.
The implemented image API is openrouter-images. Classifier APIs are typesafe-system-one, cloudflare-workers-ai-system-one, llama-cpp-classify, and openai-decisions. Their local request/result checks do not qualify every external deployment or account.
For example, inside Codemode:
const candidates = await models.getAvailableOfType("image");
if (!candidates.length) throw new Error("Configure an image model first");
const result = await models.generateImages(candidates[0], {
input: [{ type: "text", text: "A landscape watercolor of a quiet lake" }],
});
if (result.stopReason !== "stop") throw new Error(result.errorMessage);
for (const block of result.output) {
if (block.type === "image") image(block);
}
generateImages accepts text and optional base64 image reference blocks. classify accepts state, questions, and optional images supported by the model; question types are choice, score, and bool. Native failures remain typed error/aborted results. Check stopReason before using output. These helpers do not add a generic models.chat() interface.
Classifier contexts require an object state and a nonempty questions object. Each question has type, instructions, and criteria:
| Question type | criteria shape |
|---|---|
choice | Nonempty object mapping labels to string meanings |
score | Nonempty array of string descriptions, from lowest to highest |
bool | Object with true and false meanings |
Optional images uses { type: "image", data: "<base64>", mimeType: "image/png" } blocks and requires an image-capable classifier. The classification output is in answers; image output is in output, with usage present when the backend supplies it.
The product Image Generation tool is separate: it currently uses OpenAI Responses and persists a conversation attachment. Its Dashboard route does not configure openrouter-images or classifier records.
Retry, Fallback, and Virtual Routing
These mechanisms have different owners:
| Mechanism | What it controls |
|---|---|
| Session auto-retry | Reattempts a retryable assistant error; default enabled, 3 retries, exponential delay starting at 2,000 ms and capped at 60,000 ms |
| Provider SDK retry | Retries eligible initial transport/HTTP failures according to retry.provider; it does not replay an already-streamed response body |
| Configured fallback | Tries an ordered compatible provider/model when the error policy permits |
| Virtual model callback | Resolves a registered virtual selection to a physical catalog model and effective thinking level |
The initial request is not one of the Session retries. Billing/account-limit errors are not ordinary transient retries, and context overflow follows context recovery rather than that retry path. Cancelling ends retry waiting. retry.enabled: false disables Session auto-retry; it does not disable every provider's SDK behavior or configured fallback.
Advanced Profile settings use the exact camelCase keys:
retry:
enabled: true
maxRetries: 3
baseDelayMs: 2000
maxAgentDelayMs: 60000
provider:
maxRetries: 0
maxRetryDelayMs: 60000
httpIdleTimeoutMs: 300000
retry.provider.timeoutMs is an optional provider request timeout. httpIdleTimeoutMs defaults to 300,000 ms; 0 or disabled disables the idle timer. Media routes have their own limits. Session retries, SDK attempts, fallback attempts, and Codex's native transport recovery are separate, so one setting is not a total request-count or elapsed-time limit.
Virtual models use the internal pi-virtual registration/callback interface. They are not a sixth remote inference protocol, and v0.1.107 has no YAML virtual-router declaration, CLI wizard, or Dashboard router editor. A registered callback receives user/continuation/retry/direct context and may retain branch route state, but must return a physical catalog model with usable credentials. It cannot route to an unregistered model or recursively to another virtual model. A configured fallback list does not itself register such a callback.
For everyday setup, use Configuring Models and Dashboard Models.