Release v1.5.0 - **Multi-provider support** — `Provider` trait (`src/provider/traits.rs`) abstracts over different AI providers; `AnthropicProvider` uses the native Anthropic API, `OpenAiProvider` (`src/provider/openai.rs`) covers OpenAI, DeepSeek, Ollama, LM Studio, and any `/v1/chat/completions` endpoint - **Provider registry** — `ProviderRegistry` (`src/provider/registry.rs`) lazily builds only the providers referenced by the active profile; resolves role bindings to `(provider, model)` pairs - **Profiles** — `[profiles.<name>]` config sections bind four roles (`simple`, `planner`, `executor`, `patcher`) to provider/model pairs; `General.active_profile` selects the active profile - **Routing classifier** — `classify_complexity()` (`src/provider/routing.rs`) routes prompts as `Simple` (single-turn) or `Complex` (agent loop) using heuristic word count + keyword matching, with `hybrid` and `classifier_api` strategies - **Agent loop** — `run_agent_loop()` (`src/provider/agent_loop.rs`) for complex prompts: planner step (produces a numbered plan), plan approval dialog (`[Enter]` approve / `[e]` edit / `[Esc]` cancel), executor loop with tool dispatch - **Prompt templates** — `PLANNER_PREFIX` and `EXECUTOR_PREFIX` (`src/provider/prompts.rs`) prepended to system prompt for planner and executor roles - **`ait profile list`** — prints all configured profiles with their role bindings; active profile marked with `*` - **`ait profile use <name>`** — validates a profile exists (runtime switching via REPL planned) - **Active profile in REPL prompt** — non-default profiles shown as `ait [profile] ~/path> ` - **`profile` and `model` fields on `Message`** — recorded on assistant messages in session JSON - **`[routing]` config section** — `strategy` (`heuristic` / `classifier_api` / `hybrid`), `[routing.heuristic]` with `complex_word_threshold` and `complex_keywords` - **Credential store integration** — API keys are resolved from the system credential store (macOS Keychain, Linux secret-service, Windows Credential Manager) first, falling back to environment variables - **`ait auth set <provider>`** — store an API key securely with validation (lists models to verify the key works) - **`ait auth list`** — show which providers have keys stored (credential store + env vars) - **`ait auth remove <provider>`** — remove a stored key - **`ait model list [--provider <name>]`** — list available models from configured providers - **Agent loop: planner reads files before planning** — planner gets read-only tools (`read_file`, `list_files`, `grep_files`, `cwd`) with no 5KB truncation; gathers context before producing the plan - **Agent loop: file diff status** — `Creating file diff for <path>...` shown while computing diffs in `write_file`/`patch_file` (replaces blank screen after spinner disappears) - **Agent loop: wrap-up with context** — when hitting the turn limit, the model receives the original task, plan, and list of modified files to produce an accurate summary instead of hallucinating - **Agent loop: consecutive error detection** — 3 consecutive tool errors break the loop to avoid infinite retries (e.g. repeated `patch_file` failures) - **`AIT_NO_CREDENTIAL_STORE`** env var — disables credential store lookups for CI/Docker/test environments - Agent loop executor limit increased from 30 to 100 iterations - Agent loop wrap-up fires 2 turns before the limit (with empty tools to force prose) instead of on the last turn - Executor gets a clean session (original prompt + plan only) — no planner tool history, avoids cross-provider tool ID format mismatches - Planner prompt updated: "gather context efficiently in 2-3 tool turns, batch calls, use grep first" - Planner budget hint fires at turn 3 to stop context gathering and produce the plan - Config reload now also checks right before sending AI prompts (not just at REPL loop top) - Ctrl+C now works during proactive rate limit waits - Rate limit countdown display fixed (explicit `write_all` + `flush` per tick) - Terminal line cleared on Ctrl+C to prevent spinner remnants - Fixed UTF-8 panic in OpenAI debug log truncation (multi-byte chars like `─` and `⠹`) - `Config.providers` is now `HashMap<String, ProviderConfig>` (was a single-field `Providers` struct) — supports any number of named providers - `AiContext` uses `ProviderRegistry` instead of direct `AnthropicProvider`; model is resolved per-request from the active profile - `handle_prompt` uses the routing classifier to dispatch simple prompts to the single-turn loop and complex prompts to the agent loop - Default config template updated with `[profiles.default]`, `[routing]`, and multi-provider `[providers.*]` sections - `ait config validate` now checks all configured providers and validates the active profile exists - `AnthropicProvider::complete()` and `stream()` — dead code; streaming will be rewritten for TUI in v2 - `AnthropicProvider::from_config()` — superseded by `new()` used by the registry - `Provider::name()` trait method — unused - Added `async-trait` 0.1 (Provider trait) - Added `keyring` 3.x (system credential store: macOS Keychain, Linux secret-service) - Added `rpassword` 5.x (hidden password input for `ait auth set`)