# AirCoding Provider Capability Matrix V1 Date: 2026-05-27 Status: Canonical provider/model capability contract for V1.0.0 Alpha skeleton This document defines how AirCoding represents provider/model capabilities, selects models, handles conversion limits, and records fallback behavior. AirCoding's internal canonical message format is Anthropic content blocks. Provider adapters own conversion. ## 1. Goals The provider capability matrix must answer: 1. Can this model/tool path execute the requested task? 2. Which capabilities are native vs emulated? 3. What quality/risk tier is acceptable for the task? 4. What conversion or feature loss must be recorded? 5. When should Scheduler force a model vs let an agent choose? ## 2. Provider Identity ```ts type ProviderKind = | "anthropic" | "openai" | "openrouter" | "ollama" | "anthropic_compatible" | "openai_compatible" | "custom" interface ProviderIdentity { provider_id: string provider_kind: ProviderKind display_name: string base_url?: string auth_ref?: string local: boolean } ``` Secrets are referenced by `auth_ref`; they are never embedded in session DB events or artifacts. ## 3. Model Capability Matrix ```ts interface ProviderCapabilityMatrix { provider_id: string provider_kind: ProviderKind model_id: string display_name?: string enabled: boolean quality_tier: "frontier" | "strong" | "standard" | "cheap" | "local" | "unknown" cost_tier: "high" | "medium" | "low" | "free" | "unknown" context_window_tokens?: number max_output_tokens?: number supports: { text_input: boolean text_output: boolean streaming: boolean tool_use: boolean parallel_tool_use: boolean structured_output: boolean json_mode: boolean thinking: boolean prompt_cache: boolean system_prompt: boolean image_input: boolean image_output: boolean audio_input: boolean audio_output: boolean file_input: boolean computer_use: boolean long_context: boolean batch: boolean } conversion: { from_anthropic_canonical: "lossless" | "lossy" | "unsupported" tool_schema: "native" | "converted" | "emulated" | "unsupported" image_input: "native" | "artifact_link" | "unsupported" thinking: "native" | "stripped" | "unsupported" cache_control: "native" | "ignored" | "unsupported" } limits?: { requests_per_minute?: number tokens_per_minute?: number concurrent_requests?: number max_tool_schema_bytes?: number max_image_count?: number max_file_bytes?: number } default_use?: { main?: boolean architecture?: boolean execute?: boolean review?: boolean debug?: boolean compact?: boolean mine_experience?: boolean } notes?: string[] } ``` ## 4. Capability Semantics ### `tool_use` Native model-driven tool invocation. If false, agents may still call deterministic internal tools outside model tool-use, but the model cannot choose tool calls directly in a single turn. This is lower quality for coding execution. ### `parallel_tool_use` Model can request multiple tool calls in one turn. Scheduler/ToolRegistry may still serialize unsafe tools. ### `structured_output` / `json_mode` Used for WorkerResult, review reports, scheduler decisions, and impact assessments. If unavailable, runtime validates best-effort parsed JSON and may retry with stricter prompt. ### `thinking` Model supports a distinct reasoning/thinking channel or equivalent. If converted/stripped, the adapter must ensure hidden reasoning is not persisted as user-visible content. ### `prompt_cache` Provider supports cache-control or equivalent prompt reuse. If unsupported, ContextAssembler still works but cost may be higher. ### `image_input` Required for screenshot/UI analysis, diagram analysis, and image-based debugging. ### `image_output` Required for first-class image generation. If unavailable, `ui-design-assets` falls back to SVG/assets/prompts. ### `computer_use` Post-MVP. V1 uses explicit tools for GUI/screenshot/network rather than opaque computer-use loops. ## 5. Task Capability Requirements ```ts interface ModelRequirement { required: Partial preferred?: Partial min_quality_tier?: "frontier" | "strong" | "standard" | "cheap" | "local" max_cost_tier?: "high" | "medium" | "low" | "free" min_context_window_tokens?: number allow_lossy_conversion?: boolean } ``` Default requirements by task type: | Task type | Required | Preferred | Quality floor | |---|---|---|---| | Main conversation | streaming, tool_use | prompt_cache, long_context | strong | | Architecture Designer | structured_output, long_context | thinking, prompt_cache | frontier/strong | | Executor | tool_use, structured_output | thinking, long_context | frontier/strong | | Reviewer | structured_output | image_input for UI artifacts | strong | | Debugger | tool_use, structured_output | long_context, image_input | strong | | Compactor | long_context or large enough context | prompt_cache | standard | | ExperienceMiner | structured_output | long_context | standard | | UI screenshot analysis | image_input | structured_output | strong | | Image generation | image_output | image editing | provider-specific | ## 6. Scheduler Model Assignment Scheduler chooses one of: ```ts type ModelAssignmentMode = "scheduler_forced" | "agent_select" interface ModelAssignment { mode: ModelAssignmentMode provider_id?: string model_id?: string allowed_models?: Array<{ provider_id: string; model_id: string }> requirement: ModelRequirement reason: string } ``` Guidelines: 1. Use `scheduler_forced` for cross-model review, high-risk tasks, repeated failures, and deterministic comparisons. 2. Use `agent_select` for normal implementation/debug tasks when multiple acceptable models exist. 3. Use strong/frontier models for code-changing tasks where hidden complexity may exist. 4. Use cheaper models for summarization, indexing, and low-risk classification when evidence can be validated. 5. Escalate if no model satisfies required capabilities. ## 7. Provider Adapter Contract ```ts interface ProviderAdapter { provider_id: string list_models(): Promise validate_model(model_id: string): Promise complete(input: ProviderCompletionInput): AsyncIterable count_tokens?(input: unknown): Promise } interface ProviderCompletionInput { model_id: string canonical_format: "anthropic" messages: unknown[] tools?: unknown[] tool_choice?: unknown system?: unknown max_output_tokens?: number temperature?: number metadata?: Record } ``` Adapter responsibilities: 1. Convert Anthropic canonical messages to provider format. 2. Convert provider output back to Anthropic canonical content blocks or RuntimeEvents. 3. Validate tool-call and structured-output compatibility. 4. Record conversion omissions/losses. 5. Never leak credentials into logs, events, artifacts, or model-visible messages. ## 8. Conversion Loss Handling Conversion result: ```ts interface ProviderConversionReport { status: "lossless" | "lossy" | "unsupported" omissions: string[] warnings: string[] required_confirmation?: boolean } ``` Rules: 1. Lossless conversion continues silently. 2. Lossy conversion may continue only if `allow_lossy_conversion` is true and omitted features are not required. 3. Unsupported required feature blocks before model call. 4. Thinking/cache-control stripping is allowed only when not required by task policy. 5. Tool schema truncation or unsupported required tool use blocks. ## 9. Configuration Locations Global provider/model config: ```text ~/.air/models.yaml ``` Project override: ```text /.air/shared/models.yaml ``` Session records store selected `model_provider_id` and `model_id`, but not secrets. Example config shape: ```yaml providers: - provider_id: anthropic-main provider_kind: anthropic display_name: Anthropic auth_ref: env:ANTHROPIC_API_KEY enabled: true models: - model_id: claude-opus-4-7 quality_tier: frontier cost_tier: high default_use: architecture: true execute: true review: true - model_id: claude-sonnet-4-6 quality_tier: strong cost_tier: medium default_use: main: true debug: true compact: true ``` ## 10. Doctor Checks Doctor validates: ```text provider config parseability auth_ref existence without printing secret values base_url reachability when allowed model list/validation where provider supports it required default model coverage by role capability mismatch warnings rate-limit metadata if configured ``` Doctor must not persist or print API keys. ## 11. Fallback Policy Fallback order: 1. Same provider, same quality tier, compatible model. 2. Same provider, higher quality tier if allowed. 3. Different provider with lossless/acceptable conversion. 4. Lower quality tier only for non-code-changing or explicitly allowed tasks. 5. Block and ask Main Agent/user if no safe fallback exists. Fallback must record: ```text original provider/model selected provider/model reason capability differences conversion report ``` ## 12. V1.0.0 Alpha Cut Line V1.0.0 Alpha skeleton must implement: 1. `ProviderCapabilityMatrix` contract. 2. Global/project model config loading. 3. Anthropic and OpenAI-compatible adapter interfaces. 4. Capability-based model selection. 5. Conversion report and omission handling. 6. Scheduler model assignment integration. 7. Doctor provider checks. 8. Session persistence of chosen provider/model IDs. Post-MVP: ```text automatic provider benchmarking cost optimizer multi-provider speculative review batch processing computer-use models native image-generation providers local model quality calibration ```