Clapilot-Agent Providers and Models
Supported native providers, model routing, limits, and configuration.
The provider layer is how the native runtime turns "run this agent turn" into a concrete upstream model request. It owns the provider catalog, secret resolution, model selection and fallback, per-model context/output limits, and the choice of execution adapter (direct HTTP vs a subscription bridge). Configuration lives in Postgres (agent_provider_configs plus app_settings.native_model_routing); env-based fallback applies only when the DB configuration is empty.
Implementation:
services/clapilot-agent/src/providers/index.mjsservices/clapilot-agent/src/config.mjs
Supported provider types
agent_provider_configs.provider_type currently supports:
openaianthropicaws_bedrockazure_openaiopenai_compatiblegoogle_geminixaiollama
The UI now exposes providers only after an admin explicitly adds them from ClapilotAICore -> Provider & Modelle -> Provider. Older seeded placeholder rows are hidden unless they already carry real config or models.
Provider config shape
Each provider row stores:
sluglabelenabledis_defaultbase_url- encrypted API key material
model_defaultsmodelsfallback_ordermetadata
The runtime reads these rows, decrypts the stored secret, merges inherited app-level secrets, and builds an executable provider catalog.
Provider rows are now fully user-managed from the settings UI:
- add a supported provider explicitly via
Provider - configure secrets / base URLs / models only for the providers you actually want visible
- use the explicit
Use provider for routingswitch to include or exclude a provider from model selection and fallback routing without deleting its credentials or model configuration - remove providers again from the same panel; save deletes the removed rows from
agent_provider_configs
Adding the first model to a newly created provider enables that provider automatically. After that, the saved enabled value is authoritative: saving the provider form never silently derives or changes it from the model list. Both the UI and POST /api/agent-runtime/config reject an enabled provider with no configured models and ask the admin to add a model or disable the provider.
Every persisted provider enable/disable transition is written in the same database transaction to agent_provider_config_audit_events. The event records the provider slug, previous and next state, authenticated admin when available, change source, and model/label context so a provider disappearing from routing can be traced without relying on the provider row's mutable updated_at timestamp.
OpenAI Compatible is intentionally multi-instance now. Admins can add several compatible backends, give each row its own label, and route models against those individual provider slugs instead of one shared openai_compatible/* namespace.
Secret resolution
Secret priority is:
- provider-specific encrypted secret in
agent_provider_configs - inherited secret from
app_settings - environment fallback when DB config is missing
Special case for OpenAI:
codex_auth_jsonis still synchronized into the native Codex auth store so Codex app-server / orchestrator features can use it- new Codex subscription connections use Codex app-server device-code authentication: Clapilot displays OpenAI's one-time code and verification page, polls the managed login, and persists the resulting refreshable credential automatically instead of asking the administrator to copy a localhost redirect URL
- device-code login must be enabled in the personal ChatGPT security settings or by the ChatGPT workspace administrator; OpenAI currently labels this login mode beta
OpenAI-Codexprovider rows remain configurable and can still use Codex OAuth for model discovery and Codex-brokered execution paths- standard native chat model routing can include
OpenAI-Codexrows again, but those rows execute through the Codex bridge instead of the generic OpenAI HTTP adapter - the Codex bridge now registers a Clapilot MCP stdio server inside the private Codex
CODEX_HOME, so Codex-backed GPT runs can call the same Clapilot-native app tools as the direct native runtime path as long as they pass the currentsession_key - embeddings still exclude
OpenAI-Codexrows, so embedding calls only use direct API-key-backed OpenAI providers
Supported auth modes
In practice the runtime currently supports:
| Provider | Auth modes | Execution route |
|---|---|---|
| OpenAI | API key; Codex OAuth | Direct OpenAI chat/embedding calls; Codex bridge for Codex-brokered runs and Codex-backed standard chat selection |
| Anthropic | API key; Claude setup-token | Direct Anthropic Messages API; Claude CLI bridge for subscription-backed rows |
| AWS Bedrock | Bedrock bearer token (AWS_BEARER_TOKEN_BEDROCK-style API key) | Native Bedrock Converse API |
| Azure OpenAI | Azure API key (base URL normalized onto /openai/v1) | OpenAI-compatible v1 data-plane paths |
| OpenAI-compatible | Base URL plus optional API key | OpenAI-like HTTP path |
| Google Gemini | API key | Native generateContent transport with Clapilot tool calling |
| xAI Grok | xAI subscription OAuth; optional API key fallback | xAI Responses API under https://api.x.ai/v1 |
| Ollama | No key for local servers; API key for Ollama Cloud | Native Ollama /api/chat and /api/embed transport |
OpenAI-compatible providers are intentionally tolerant of missing API keys so local or internal compatible endpoints can be used without bearer auth.
During streaming, the native OpenAI-compatible transport recognizes the commonly used reasoning_content, reasoning, and thinking delta fields (plus typed reasoning content parts). It forwards them through the internal stream as a temporary <think>...</think> boundary while keeping the completed assistant text clean. The web and iOS/macOS chats use that boundary only for an unboxed, animated in-progress reasoning line. Explicit reasoning tags emitted inside ordinary model content remain supported, and repeated orphan </think> markers produced by local chat templates are normalized so their intermediate text cannot leak into the final answer or completion notifications.
Ollama is a first-class provider rather than an OpenAI-compatible alias. Local servers use a base URL such as http://host.docker.internal:11434 without authentication; Ollama Cloud uses https://ollama.com with a bearer API key. API keys cover inference and per-request metrics, but Ollama does not expose 5-hour or weekly plan windows through the API-key API. The same provider can therefore retain an encrypted ollama.com browser Cookie header for Subscription Usage. That usage session remains eligible even if no models are routed through the provider, and it is never used for model inference.
For Bedrock, Clapilot stores the encrypted provider secret in the normal secret slot as the raw bearer token. The region stays in provider metadata. Older SigV4-based Bedrock rows are still read for compatibility, but the supported admin configuration path is now bearer token only.
Model catalogs
Each provider has its own models array plus model_defaults.
Providers no longer auto-populate chat models when a row exists but no models were selected. A provider only contributes model refs to routing after models were explicitly added in the UI.
The runtime builds a model catalog of fully qualified model refs keyed by provider slug:
openai-default/<model>openai/gpt-*for GPT models backed by Codex OAuth; legacyopenai-codex-default/<model>refs still resolve for existing saved settingsanthropic-default/<model>claude-default/<model>aws-bedrock-default/<model>azure-openai-default/<model>openai-compatible-default/<model>google-gemini-default/<model>xai-default/<model>ollama-default/<model>- additional OpenAI-compatible rows use their own slug, for example
openai-compatible-2/<model>
The global model-routing list stored in app_settings.native_model_routing is then used as a cross-provider priority chain for the standard native chat path. This list may contain direct API-backed rows, Google Gemini text-chat models, and subscription-backed rows such as OpenAI-Codex or Anthropic-Claude. The settings UI now keeps those rows in the same ordered list but annotates each entry with its access mode (API vs Subscription) and execution route (for example Codex Bridge or Anthropic setup-token).
The same native_model_routing payload also stores the default Clapilot-code profile for non-specialized providers plus separate global provider/model defaults for TTS, STT, and image generation. The unchanged wire value non_specialized_agent_core=native selects Clapilot-code (Assistant), while embedded_pi selects Clapilot-code (Coding) without changing the underlying provider/model transport. A provider row can override that global default through agent_provider_configs.metadata.agent_core; accepted stored values remain native and embedded_pi, while absent, null, or inherit inherits the global setting. Resolution order is explicit request agentCore, explicit request runtimePath, provider metadata.agent_core, global non_specialized_agent_core, then native.
Adaptive model and profile routing
native_model_routing.adaptive_routing adds a policy layer in front of the existing provider resolver. It only considers configured entries from native_model_routing.priority; it does not create a second provider catalog or bypass provider health, authentication, rate-limit cooldowns, fallback rules, or public-channel subscription restrictions.
mode=offdisables decisions.mode=shadowis the default. ClapilotAICore scores and records the recommendation, but executes the normal base model and profile.mode=applymay select another candidate and, whenroute_harness=true, choose Clapilot-code (Coding) for coding/repository work or Clapilot-code (Assistant) for other work.- An explicit request/session model, explicit
agentCore/runtimePath, specialized agent, or Mixture-of-Agents preset is a hard override. The router never changes provider or profile inside an active tool loop. candidate_limit,exploration_rate,min_samples, andswitch_marginbound selection and adaptation. Exploration is capped at 25 percent by the configuration normalizer.
Every shadow or applied decision is stored in agent_adaptive_route_decisions with the task class, candidate scores, protection/decision reason, base/recommended/selected model and profile, and a terminal technical outcome. The first policy version learns from completion/failure, retry/fallback count, tool errors, token counts, and duration over the prior 90 days. It deliberately does not infer user satisfaction from prose. Recent successful session routing is sticky when its score remains within the configured switch margin.
Adaptive routing is configured under Settings → ClapilotAICore → Model Routing, in the "Adaptive model and profile routing (learning)" section below the Routing Models editor. The same page shows the collected decision data: summary counts, aggregated per-task-class outcomes from the 90-day learning window, and the most recent decisions with base model, recommendation, protection/decision reason, and outcome. The former section in the OpenCore models panel now only links to this page.
Adaptive routing and Routing Models are connected: when a route/<slug> Routing Model resolves the base selection, the learned-outcome layer runs inside the member ranking instead of on the global priority list. The static capability/property score stays the primary signal; recorded outcomes may only reorder members whose static scores are within a fixed tie band (1.5 points — less than one capability match, so a configured capability tag can never be overridden). An alternative member needs at least min_samples recorded outcomes for the detected task class and must beat the current member's learned score by switch_margin. In shadow mode the would-be reorder is only recorded; in apply mode the member order (selection plus fallback chain) is actually reordered. Exploration is intentionally not applied inside Routing Models.
Every routing-model request also writes a decision row with routing_model_slug, the static tag-based pick as the base model, and the outcome-based pick as the recommendation, so the settings data view can report per-route agreement between the configured ranking and learned outcomes. The sessions-level adaptive layer never re-switches a routing-model selection; global candidate scoring applies only to non-routing requests.
Model Routing / Routing Models
Routing Models are administrator-defined virtual models with references in the form route/<slug>. Each Routing Model contains an ordered list of member models. A member can be annotated with capabilities and properties so ClapilotAICore can select a suitable model for each request while retaining a deterministic fallback chain.
Model Routing is off by default. Administrators configure it under Settings → ClapilotAICore → Model Routing, where they can enable the feature and optionally choose a default Routing Model. When a default is set, requests without an explicitly selected model are sent through that route. Enabled route/<slug> entries are also available in regular model pickers for explicit selection.
The capability taxonomy is coding, frontend_design, law, taxes, finance, writing, translation, research, math, data_analysis, design_3d, image_understanding, summarization, and general. The property taxonomy is fast, cheap, expensive, high_reasoning, long_context, vision, local_private, tool_use, and creative.
At execution time, ClapilotAICore classifies the request, scores the configured members against the detected capabilities and properties, and picks the highest-scoring member. Member order breaks score ties. The remaining ranked members become the fallback chain, so a failed first choice can continue through the same Routing Model without discarding the classification result. When adaptive routing is not off, recorded technical outcomes can additionally refine this ranking within a bounded tie band; see the adaptive-routing section above for the exact rules.
Management through agent/chat tools is intentionally not exposed in this iteration; Routing Models are managed through the admin web UI only.
Google Gemini provider rows support both media routing and regular text chat. The chat model list filters out obvious Gemini media-only entries such as TTS, Live/Realtime, image, video, embedding, Imagen, and Lyria model ids, while Gemini text/chat models execute through the native generateContent transport with Clapilot tool-calling support.
xAI Grok provider rows are subscription-backed by default. Admins start the xAI OAuth flow from the provider detail dialog, paste the callback URL, and Clapilot stores the refreshable OAuth JSON in agent_provider_configs. The default catalog seeds grok-4.3 for general chat, grok-build-0.1 for coding-oriented runs, and Grok Imagine image/video model ids for media routing. Chat routing filters grok-imagine-* models out of normal conversation priority, while image/video media settings can select them explicitly. The runtime calls xAI's OpenAI-family Responses endpoint (/responses) for chat and refreshes the xAI OAuth token in place when it expires; if xAI rotates the refresh token, the new OAuth JSON is persisted back to the provider row. Direct xAI API keys remain possible by saving the provider with authMode=api_key, but the built-in catalog entry is intended for SuperGrok / X Premium-style subscription access rather than pay-as-you-go API billing.
Ollama provider rows support local and Cloud execution through Ollama's native API. /api/tags supplies the model catalog, /api/chat handles streaming chat, images, structured output, and the native Clapilot tool loop, and /api/embed handles memory and RAG embeddings. Local rows are considered configured when they have a valid base URL; Cloud rows additionally require an API key. Because the web and agent services normally run in Docker, a host-installed Ollama server should use http://host.docker.internal:11434 rather than localhost.
Provider/account capabilities are enforced before chat routing. A Codex OAuth provider backed by a ChatGPT account accepts only OpenAI GPT/Codex model ids; Grok ids must belong to an xai provider. The admin save endpoint rejects incompatible enabled configurations, the settings UI omits them from chat priority, and the native runtime warns about stale incompatible rows at configuration load while excluding those models from its catalog. Normal configured-priority fallbacks remain available, so a stale invalid model reference cannot consume the user turn.
For Anthropic-Claude with a Claude setup-token, model discovery is intentionally catalog-based instead of live-validated. Clapilot now exposes the shipped Claude subscription catalog (latest, claude-opus-5, claude-fable-5, claude-opus-4-8, claude-opus-4-7, claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5-20251001) without probing /v1/models or /v1/messages first, because subscription-backed runs no longer execute through direct Anthropic HTTP transport.
At runtime, those Anthropic subscription rows execute through the local Claude CLI bridge:
- the stored
setup-tokenis injected as runtime auth for theclaudeCLI - chat streaming uses Claude CLI
stream-jsonoutput instead of synthetic word-chunk replay - each Clapilot
session_keynow keeps a hidden resumable Claude bridge session id, so follow-up turns continue the same Claude Code conversation instead of rebuilding a fully stateless CLI run every time - built-in Claude CLI tools such as
Bash,Read,Grep,Glob,WebFetch, andWebSearchcan run when the model chooses them - Clapilot-native tools are exposed to Claude through an MCP stdio bridge, so app tools such as
documents_list,documents_get,calendar_*,aufgaben_*,notizen_*, and other native tool-proxy contracts remain reachable from the same subscription-backed chat run - normal native chat runs do not apply a hard default kill timeout to the Claude CLI bridge anymore; callers may still pass an explicit run timeout when they need one, and
CLAPILOT_AGENT_CLAUDE_CLI_TIMEOUT_MScan restore a bridge-wide default limit - when the Clapilot session model is changed or cleared, that hidden Claude bridge binding is invalidated so the next turn starts a fresh Claude session with the new model context
The dropdown is therefore a shipped subscription catalog, while actual execution happens through the local Claude CLI bridge plus Clapilot MCP exposure.
Selection algorithm
When a run starts, provider selection works like this:
- if no explicit model is requested and
native_model_routing.priorityexists, use its first model - otherwise parse the requested model for provider and model hints
- otherwise fall back to the default provider
- otherwise fall back in order: OpenAI with credentials, Azure OpenAI with credentials, Anthropic with credentials, AWS Bedrock with credentials, then first enabled provider
If a selected model later fails, the runtime retries using fallback model refs:
- first the remaining entries in the global priority list, if the selected model came from that list
- otherwise the selected provider’s own
fallback_order
Context windows and output limits
The native runtime supports per-model limits, mainly to manage history replay and output caps.
Resolved limits come from:
- model-specific metadata maps
- per-model limits embedded in the provider’s saved
modelscatalog entries model_defaults.context_windowmodel_defaults.max_input_tokensmodel_defaults.max_output_tokensmodel_defaults.max_completion_tokens- Clapilot’s shipped fallback model-limit catalog for current OpenAI + Anthropic top-tier models when provider config does not include explicit limits
- only if none of the above exist, the generic native emergency fallback is used (
32,000context /4,096reserved output)
These values are used by:
- prompt budget estimation
- memory flush triggering
- session compaction
- max token values for provider calls
This is the part the Settings UI exposes as per-model context window and output cap.
If no explicit override is stored for a known OpenAI/Anthropic model, the provider settings UI still shows the effective shipped fallback value and labels it as such, so admins can see the real runtime limit without having to save a manual override first.
For OpenAI providers with Codex OAuth, the UI also exposes a per-model 1M-Kontextfenster aktivieren toggle. It is disabled by default and only affects shipped fallback resolution for eligible models; explicit token overrides still take precedence.
For OpenAI providers with stored Codex OAuth, the shipped fallback catalog now distinguishes between:
- the plain OpenAI API fallback profile for raw model IDs such as
gpt-5.6-sol,gpt-5.6-terra,gpt-5.6-luna, andgpt-5.4 - Codex-auth chat defaults such as
openai/latest; the settings dialog loads the live Codex app-server model catalog from the installed Codex CLI so unavailable rollout models do not get added from stale fallbacks.
latest is a Clapilot-owned moving alias, not an upstream model ID. openai/latest resolves to the first concrete model in the enabled Codex OAuth provider catalog, currently gpt-5.6-sol after migration 191, and Claude subscription providers may use <claude-provider-slug>/latest for the first concrete model in the shipped Claude subscription catalog, currently claude-opus-5 after migration 224. Concrete refs such as openai/gpt-5.6-terra, openai/gpt-5.5, claude-default/claude-opus-5, or claude-default/claude-fable-5 remain supported as explicit pins.
The current OpenAI family is role-aware rather than a single replacement slug:
gpt-5.6is the direct-API family alias and routes togpt-5.6-solupstream.gpt-5.6-solis the frontier model.gpt-5.6-terrais the balanced everyday model.gpt-5.6-lunais the efficient high-volume model.gpt-5.3-codex-sparkis Codex-subscription-only and is intentionally excluded from OpenAI API provider defaults.
Direct OpenAI and Azure OpenAI GPT-5.6 runs use the Responses endpoint, including text-only runs, so native reasoning and function tools do not fall into the incompatible Chat Completions default-reasoning combination. Codex OAuth runs continue through the Codex app-server bridge.
Codex OAuth model cards in Settings -> ClapilotAICore -> Model providers expose a per-model reasoning-effort selector. The available levels and the displayed default come from the installed Codex app-server model/list catalog, because support differs by model. Clapilot stores explicit choices in provider metadata as modelReasoningEfforts and applies them to new threads and subsequent turns for standard native chat, channel sessions, interactive Agent Orchestrator sessions, and Codex-backed reference runs. Leaving a model on Codex default lets the installed Codex runtime choose its advertised default. An explicit Agent Orchestrator runtime effort still takes precedence for that session.
This matters because the public GPT-5.4 API docs advertise a larger maximum context window, while Codex-auth chat runs currently use a smaller effective default budget in practice. The native runtime therefore resolves Codex-auth OpenAI chat against its own shipped fallback profile instead of blindly reusing the public API maximums.
If the per-model 1M-Kontextfenster toggle is enabled, the runtime switches that model’s fallback from the Codex-auth profile back to the larger public OpenAI profile.
Current shipped fallback coverage includes the native aliases currently used in this repo, such as:
latestgpt-progpt-5.6gpt-5.6-solgpt-5.6-terragpt-5.6-lunagpt-5.5gpt-5.4gpt-5.4-minigpt-5.3-codex-spark(Codex OAuth only)claude-opus-5claude-fable-5claude-opus-4-8claude-opus-4-7claude-opus-4-6claude-sonnet-4-6claude-haiku-4-5-20251001grok-4.3grok-build-0.1grok-imagine-image-qualitygrok-imagine-imagegrok-imagine-video-1.5grok-imagine-video
Remote model discovery
The runtime can fetch upstream model lists for admin configuration:
- Anthropic via its models endpoint
- AWS Bedrock via the regional
foundation-modelscontrol-plane API - Azure OpenAI via its
v1models endpoint - OpenAI and OpenAI-compatible providers via OpenAI-style models endpoints
- xAI Grok via OpenAI-style
/models; subscription OAuth rows fall back to the saved Grok catalog when model-list scope is unavailable - Ollama via native
/api/tagsfor local servers and Ollama Cloud
Internal API:
GET /internal/provider-models?slug=<provider-slug>GET /internal/provider-status?slug=<provider-slug>
Enabled OpenAI API-key and Codex OAuth rows are write-preflighted when saved or activated. The probe uses the actual Chat Completions and/or Responses endpoint selected by the configured models, requests only one output token, and stores no credential or response content. A 401/403 scope response records the explicit required scopes (model.request, and api.responses.write for Responses), marks the provider unhealthy, and removes it from default/model routing. Runtime auth failures are not replayed against the same provider: the provider is quarantined for the current runtime configuration and the next eligible cross-provider fallback is selected.
Enabled OpenAI-compatible rows also run a one-token Chat Completions capability probe for every configured model when the row is saved or activated. Token-free results are stored in metadata.modelAvailability. Definitive load errors such as Failed to load model mark only the affected model unavailable: the settings UI labels it as not ready, and native model catalogs and default selection exclude it while leaving healthy sibling models usable. Inconclusive network or server failures do not disable a model. If a provider later returns a definitive model-load error during execution, the shared classifier records model_not_found, proceeds through the configured fallback chain, and returns a clear user-facing error when no fallback succeeds.
Clapilot proxies this through the settings UI so admins can populate the provider model list from the upstream API instead of maintaining it manually.
For OpenAI providers, remote model discovery now prefers the stored Codex OAuth access token when present and only falls back to the saved API key if OAuth is unavailable or unusable.
For Codex OAuth providers, each returned model can also include reasoningEfforts / reasoning_efforts and defaultReasoningEffort / default_reasoning_effort, normalized from the model-specific Codex app-server capability record. The settings UI uses these fields to avoid offering unsupported effort levels.
For AWS Bedrock providers, the supported setup path is the Bedrock bearer token / API key. Clapilot tries to load both Bedrock foundation-model ids and available inference profiles from the regional control plane, and stores the profile ARN when Bedrock returns one. If that discovery path is unavailable for the current account/auth scope, manual model entry remains the fallback for Converse model ids, inference profiles, or provisioned-throughput ARNs.
For Azure OpenAI providers, Clapilot normalizes the configured endpoint to /openai/v1 and keeps all Azure data-plane requests under that path. If apiVersion is left at v1, no extra query parameter is added; only preview or date-style Azure API versions are appended as ?api-version=.... For authentication, Clapilot first tries Azure API-key auth and also tolerates OpenAI-style bearer auth with the same stored key for Azure v1 compatibility. Depending on how the Azure resource is set up, the remote list may expose model ids, deployment ids, or both, so manual deployment entry remains available in the settings UI.
For xAI Grok providers, Clapilot uses the current xAI OAuth discovery document under https://auth.x.ai/.well-known/openid-configuration for token refresh and uses https://api.x.ai/v1 for model and response traffic. The provider status card treats a parseable xAI OAuth credential as connected even when the live model list cannot be fetched with the current subscription scope.
For openai_compatible providers, the settings UI also stores a per-model Visionfähig flag in provider metadata. That flag is used by downstream features such as document vision fallback so custom backends only appear in vision selectors when the admin marked them as multimodal-capable.
Provider request building also reads that flag, per attempt, because capability differs per candidate:
- A vision-capable model keeps the attached image inline as image content, unchanged.
- A text-only model does not receive the image binary. Sending it makes the backend reject the whole request (for example
litellm.BadRequestError: ... is not a multimodal model). Instead the image part is dropped and replaced with a note stating that the image is not visible to the model and that the attachment is listed in the turn with its file name and path. The turn's own attachment summary (Anhänge: - Bild: <name> (<size>; Originalpfad-Metadaten: <path>)) is what makes this actionable, so the model can still store the file or hand its path to an image-to-video job rather than failing outright.
The recorded flag is authoritative — gateway aliases such as spark-cluster/deepseek-v4-flash carry no reliable capability signal in the id — and the id heuristic applies only to models with no recorded flag. The selected model is never swapped out because of an attachment; only the form the attachment takes changes.
When the fallback budget runs out, the surfaced error keeps the provider's own message and appends the budget note, so the actionable cause stays visible instead of being replaced by the timer.
The same per-model metadata area now also supports a four-stage Kontextmodus:
Voll: normaler Webchat-Kontext; der native Runtime-Pfad startet trotzdem mit einem kompakten Tool-Familien-Katalog, direkt gerouteten Funktionsschemas und On-Demand-Erweiterung, damit der volle konkrete Tool-Katalog nicht mehr in jeden ersten Request gehtVoll - Compact Tools: expliziter Alias fuer dasselbe kompakte Tool-Catalog-Verhalten mit vollem Chat-/UI-/RAG-KontextLow: weniger injizierter User/UI-Kontext, kleinere Dokument- und RAG-Blöcke,lightContextim nativen Runtime-Pfad und kein doppelt serialisierter Verlauf im appseitigen Extra-SystempromptUltra Low: wieLow, aber im nativen Runtime-Pfad zusätzlichminimalContext, ohne Bootstrap-, Retrieval-, Compaction- und Stored-History-Replay und mit stark reduziertem Tool-Katalog
The compact catalog path is now the default for normal full-context native runs. It exposes core memory/context tools, directly routed concrete schemas for the active request/page, and tool_catalog_search / tool_catalog_expand / tool_execute for on-demand discovery. Bridge-backed Claude/Codex runtimes expose the same idea through lean MCP tools instead of registering every concrete Clapilot tool as a separate MCP function.
This is mainly intended for slower local or self-hosted models where prompt prefill dominates latency; the tradeoff is that long multi-step conversations may retain less context as you move from Voll to Ultra Low.
The same settings UI now also shows two provider-state signals per card:
Konfiguriert: whether the provider has the required stored setup (for example API key, Codex OAuth, or compatible base URL)Verbunden/Auth ok: whether the runtime could validate the saved connection live against the upstream models endpoint, or for OpenAI Codex setups whether a usable OAuth credential is present even when a stale API key would otherwise fail
Provider cards are collapsed by default so the overview stays scannable even with multiple configured backends.
Execution behavior
The native runtime chooses the execution adapter by provider type:
anthropic-> Anthropic Messages API path for direct API-key rows, Claude CLI bridge forsetup-tokensubscription rowsaws_bedrock-> Bedrock Converse API path using the stored Bedrock bearer tokenazure_openai-> Azure OpenAIv1OpenAI-compatible paths under/openai/v1; preview/date-styleapiVersionvalues are added only when configuredopenai/openai_compatible-> OpenAI-like pathxai-> xAI Responses path under/v1/responses, using either refreshed xAI OAuth or a direct xAI API keyollama-> native Ollama/api/chatwith NDJSON streaming, tool calling, vision images, and structured output; embeddings use/api/embedopenai-codex-> Codex-brokered path for subscription-backed Codex chat selection- OpenAI-compatible provider rows can be selected as the global image-generation provider when their model list contains the intended image model.
/api/generated-images/generatecalls the row'sbase_urlat/images/generations;/api/generated-images/editcalls/images/edits. If the row has an API key Clapilot sends it as a bearer token, and local compatible endpoints can also run without one. - OpenAI-Codex can also be selected as the global image-generation provider. In that media path Clapilot keeps the normal provider row (
provider_type = openai,authMode = codex_oauth) but callschatgpt.com/backend-api/codex/responseswith the hostedimage_generationtool, defaulting togpt-image-2and the stored Codex OAuth credential instead ofOPENAI_API_KEY. - xAI Grok can also be selected as the global image-generation provider.
/api/generated-images/generatecalls xAI/images/generationswithgrok-imagine-image-qualityorgrok-imagine-image;/api/generated-images/editcalls/images/editswith JSON data-URI source images. The same OAuth/API credential is reused, refreshed, and persisted through thexaiprovider row. - AI media video generation is separate from image-generation routing.
Settings -> ClapilotAICore -> AI media -> Video generationselects an enabledmedia_generation_provider_configsvideo row such asxai-grok-video. Enabled OpenAI-compatible runtime providers with a configured base URL appear there automatically. Their model field uses the native provider's live/modelsdiscovery catalog rather than only the models already added to the chat-provider row, while remaining editable for exact video aliases that a gateway does not advertise. xAI video rows use the authenticated/video-generation-modelscatalog so newly enabled model IDs appear without a code or migration update. Discovery failures retain the saved list and current selection instead of clearing the default. Compatible providers use multipartPOST /videos,GET /videos/{id}status polling, andGET /videos/{id}/contentdownload. Stored bearer credentials are reused when present and authless local gateways omit authorization. Normal chat video requests usevideos_generate/videos_status, persist jobs ingenerated_videos, and stream ready files from/api/generated-videos/[id]; Live Stream Studio continues to uselivestream_generate_videofor stream assets.videos_generate.image_idandsource_image_pathenable image-to-video for xAI and OpenAI-compatible providers. Grok sends the owned/imported source asimage.url; compatible providers send it asinput_reference.grok-imagine-video-1.5is used with an image; text-only requests fall back to the configuredgrok-imagine-videoentry instead of submitting an unsupported 1.5 text-only request. xAI durations retain the requested whole-second value within the supported 1–15 second range.
Non-specialized agent-core split:
non_specialized_agent_core=nativeselects Clapilot-code (Assistant) for all providers without a specialized bridgenon_specialized_agent_core=embedded_piselects Clapilot-code (Coding), the persistent coding-agent profile with a larger tool-loop budget, on top of the existing provider transportagent_provider_configs.metadata.agent_corecan override that global choice per provider with the samenativeorembedded_piwire values; absent,null, andinheritinherit the global settingopenai-codexand Claude subscription / CLI paths remain specialized runtimes and are not part of this switch- the selected provider row still owns the actual model request transport; Clapilot-code (Coding) (
embedded_pi) changes the session/core profile, prompt contract, and tool-loop budget rather than swapping the provider to Codex
The same provider layer also resolves:
- tool schema translation
- streaming vs non-streaming response normalization
- usage aggregation
- retry/fallback attempts
Request audit logs
Clapilot now persists a dedicated per-request audit ledger in agent_model_request_logs.
This is intentionally separate from agent_runs:
- one native run can fan out into multiple upstream model requests because of tool loops, retries, or embeddings
- bridge-backed execution paths such as Claude CLI and Codex bridge can be logged alongside direct HTTP providers in one table
- the admin
ClapilotAICore -> Logspage can therefore show the real provider traffic instead of only session-level outcomes
Each row records:
- provider label / type / slug and auth mode
- requested and effective model
- request kind (
conversationorembedding) - transport (
http,cli_bridge,orchestrator_bridge) - endpoint family such as
openai.responses,anthropic.messages,aws_bedrock.converse,openai.embeddings,anthropic.claude_cli_bridge, oropenai.codex_bridge - derived input / output / total token counts plus raw
usage_json - estimated prompt-layer token attribution in
prompt_layer_tokens_json, including runtime system prompt, compaction summary, bootstrap prompt files, retrieved memory, approved learning objects, extra system prompt, stored history, current request, tool schemas, message prompt estimate, and provider input estimate - request duration in milliseconds
- success vs failure status and the captured error message when the request failed
- optional links back to
session_keyandagent_runs.id
The metadata JSON also carries robustness breadcrumbs without requiring schema-specific columns:
assistantSanitizationappears only when output normalization changed a completed response and recordsreasoningStripped,salvagedCount,argsRepaired, andsurrogatesStripped- failed native provider requests record
providerErrorReason,providerErrorAction, andproviderErrorRetryablefrom the shared typed error classifier - a compressed-context retry records
contextCompressionRetrywith the provider type and original, compressed, and dropped message counts on the retried request - run-level provider-attempt summaries carry the same classifier reason/action so timeout replay, rate-limit cooldown, quota reset/fallback, configured fallback, and abort decisions can be audited together; quota attempts use
reason: quota_exhausted,status: quota_limited, and includequotaResetAt/retryAfterMswhen known
Provider metadata also accepts tool_schema_compat. Its default "off" value leaves OpenAI, Azure OpenAI, Anthropic, Bedrock, xAI, and generic OpenAI-compatible schemas unchanged. Set it to "strict" for local or llama.cpp-style backends whose JSON-schema-to-grammar converter rejects keywords such as pattern, format, $ref, or combinators. Gemini applies its narrower schema coercion unconditionally because the Gemini function-calling API accepts only a restricted schema subset.
The current instrumentation covers:
- OpenAI Responses requests
- xAI Responses requests
- OpenAI Chat Completions requests
- Anthropic Messages requests
- AWS Bedrock Converse requests
- provider embedding requests
- Claude subscription CLI bridge runs
- Codex bridge runs
Embeddings
Memory embeddings and the document RAG index are resolved through the same provider layer.
Current behavior:
- admins choose the embedding provider and model explicitly in
ClapilotAICore -> Provider & Modelle - supported embedding backends are:
openaivia direct API-key-backedOpenAI-APIrowsazure_openaiopenai_compatibleaws_bedrock
- uses
modelDefaults.embedding_modelwhen the provider row defines one and no explicit model-routing override is stored - otherwise defaults to
text-embedding-3-small
Clapilot stores the selected provider slug and model in native model routing, and both the native memory store and the web-side RAG retrieval/indexer use that same selection.
If no embedding-capable provider is configured, memory falls back to deterministic local hash embeddings instead of blocking the runtime. The document RAG retrieval/indexer will skip provider embeddings until a provider/model is configured.
Realtime
Live/call Realtime routing is stored alongside embeddings, but with its own provider/model pair.
Current behavior:
- admins choose the Realtime provider and model explicitly in
ClapilotAICore -> Live Voice - supported Realtime provider rows are currently:
openaivia direct API-key-backedOpenAI-APIrowsazure_openaiopenai_compatible
google_gemini- the selection is persisted in native model routing under its own
realtime_provider_slug/realtime_modelkeys - Realtime-capable provider rows are available in the standard cross-provider chat priority when they also support the regular text-chat runtime path; Gemini Live/media model ids remain filtered from chat routing
Speech-to-text
Server-side STT routing supports direct OpenAI API-key rows, Gemini rows, and OpenAI-compatible rows. Compatible providers use the configured base URL plus /audio/transcriptions; administrators can enter an exact gateway model alias, and local endpoints may run without a bearer key. Image, TTS, and STT agent tools accept an exact runtime provider_slug plus optional model; omitted routing uses the capability default, while an explicit slug resolves only that enabled provider and never silently falls back. Video generation already follows the same explicit-slug contract through media_generation_provider_configs.
Split provider rows
OpenAI and Anthropic are now intentionally split into separate provider rows by auth mode:
OpenAI-APIuses a direct API keyOpenAI-Codexuses Codex OAuth JSON / stored OAuth credentialsAnthropic-APIuses a direct API keyAnthropic-Claudeuses a Claudesetup-tokenflow; the stored setup-token is persisted as the provider secret and then injected into the local Claude CLI bridge for runtime execution
The old app-level OpenAI / Anthropic key fields remain only as legacy mirrors for compatibility and migration. The source of truth is now ClapilotAICore -> Provider & Modelle.
Environment fallback
If the database has no usable enabled providers, clapilot-agent falls back to env configuration from services/clapilot-agent/src/config.mjs.
Relevant env vars:
CLAPILOT_AGENT_OPENAI_ENABLEDCLAPILOT_AGENT_OPENAI_MODELSCLAPILOT_AGENT_ANTHROPIC_ENABLEDCLAPILOT_AGENT_ANTHROPIC_MODELSCLAPILOT_AGENT_BEDROCK_ENABLEDCLAPILOT_AGENT_BEDROCK_REGIONCLAPILOT_AGENT_BEDROCK_MODELSCLAPILOT_AGENT_BEDROCK_ACCESS_KEY_IDCLAPILOT_AGENT_BEDROCK_SECRET_ACCESS_KEYCLAPILOT_AGENT_BEDROCK_SESSION_TOKENCLAPILOT_AGENT_BEDROCK_BASE_URLCLAPILOT_AGENT_AZURE_OPENAI_ENABLEDCLAPILOT_AGENT_AZURE_OPENAI_BASE_URLCLAPILOT_AGENT_AZURE_OPENAI_MODELSCLAPILOT_AGENT_AZURE_OPENAI_API_KEYCLAPILOT_AGENT_AZURE_OPENAI_API_VERSIONCLAPILOT_AGENT_COMPAT_BASE_URLCLAPILOT_AGENT_COMPAT_MODELSCLAPILOT_AGENT_GEMINI_ENABLEDCLAPILOT_AGENT_GEMINI_MODELSCLAPILOT_AGENT_GEMINI_BASE_URLCLAPILOT_AGENT_GEMINI_API_KEY(falls back toGEMINI_API_KEY/GOOGLE_AI_API_KEY)
This fallback is mainly for bootstrap and recovery. The intended source of truth in normal operation is Postgres.
Operational recommendations
- Keep provider model lists explicit instead of relying on stale defaults.
- Use the global model priority list for cross-provider failover.
- Set context windows and output caps for OpenAI-compatible backends that do not expose limits automatically.
- Treat Codex OAuth as the preferred OpenAI chat path when available, but remember that embedded runtime runs own their own pre-compaction memory flush and session compaction, so the native Clapilot maintenance path is bypassed for those runs.
Related docs:
