feat: interactive provider wizard (/setup, claw setup, Ctrl+P)#2810
Open
TheArchitectit wants to merge 18 commits into
Open
feat: interactive provider wizard (/setup, claw setup, Ctrl+P)#2810TheArchitectit wants to merge 18 commits into
TheArchitectit wants to merge 18 commits into
Conversation
b1f8451 to
8a117ac
Compare
code-yeongyu
added a commit
that referenced
this pull request
Apr 26, 2026
code-yeongyu
added a commit
that referenced
this pull request
Apr 27, 2026
code-yeongyu
added a commit
that referenced
this pull request
Apr 27, 2026
This was referenced Apr 27, 2026
code-yeongyu
added a commit
to code-yeongyu/claw-code-1
that referenced
this pull request
Apr 28, 2026
code-yeongyu
added a commit
to code-yeongyu/claw-code-1
that referenced
this pull request
Apr 28, 2026
code-yeongyu
added a commit
to code-yeongyu/claw-code-1
that referenced
this pull request
Apr 28, 2026
code-yeongyu
added a commit
to code-yeongyu/claw-code-1
that referenced
this pull request
Apr 29, 2026
itwizardo
pushed a commit
to itwizardo/hackcode
that referenced
this pull request
Apr 30, 2026
When the model API returns a context_window_blocked error (because the request exceeds the model's context window), the CLI now automatically: 1. Compact the session (remove old messages to free up space) 2. Retry the original request with the compacted session 3. Report results to the user This eliminates the need for users to manually run /compact when they hit context limits - the recovery happens automatically. ## Technical Details - Detection: Looks for 'context_window' or 'Context window' in error message - Uses runtime::compact_session() to aggressively compact (max_estimated_tokens=0) - Creates new runtime with compacted session and retries the turn - Reports compaction results and final status to user ## Testing Tested successfully with a request that exceeded model's context: - Auto-compact triggered: 'Messages removed 19, Messages kept 5' - Successfully retried and completed after compaction
…rl+P Adds an interactive setup wizard that lets users configure their provider, API key, base URL, and model without setting environment variables. Configuration is persisted to ~/.claw/settings.json (with 0600 permissions). New features: - `claw setup` CLI subcommand runs the wizard from the terminal - `/setup` slash command runs the wizard inside the REPL (hot-swaps model) - Ctrl+P hotkey in the REPL triggers /setup for in-session provider swap - Stored provider config used as fallback when env vars are absent - Three-tier auth resolution: env var > .env file > stored config - RuntimeProviderConfig struct and validation in settings schema Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ctrl+P now inserts a sentinel char (\x01) that the highlighter renders as a cyan "[Provider Swap]" prompt. User presses Enter to confirm and launch the setup wizard. Returns ReadOutcome::ProviderSwap so the REPL loop can hot-swap the model and reprint the connection line. Also fixes clippy warnings: merged duplicate match arms in provider_config_value, doc_markdown on ProviderKind, map_unwrap_or idioms in setup_wizard.rs, and pre-existing clippy issues in main.rs and commands/lib.rs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously /resume latest only searched the current workspace's fingerprinted session directory. If you started claw from a different directory, it found zero sessions even though sessions existed elsewhere on disk. Changes: - Add global_sessions_root() pointing to ~/.claw/sessions/ - Add scan_global_sessions() to scan all workspace namespaces - Modify latest_session() to fall back to global scan when no workspace-local sessions are found - Add load_session_loose() that skips workspace validation for alias references (latest/last/recent) so cross-workspace resume works while still enforcing workspace check for explicit IDs - Wire load_session_loose() into CLI's load_session_reference() - Add provider field to config validation schema (needed because user's settings.json already has the provider key) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous implementation only scanned ~/.claw/sessions/ for the global fallback, but sessions are actually stored in the project-local <cwd>/.claw/sessions/<fingerprint>/ by SessionStore::from_cwd(). Now scans both the global root and the project-local parent directory (checking all fingerprint subdirs) so /resume latest finds sessions regardless of where they're stored. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously /resume latest returned the most recently created session, which was always the empty one just created on startup. Now it skips sessions with 0 messages and excludes the current session ID, so it finds the previous session with actual conversation history. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ider The setup wizard wrote `model` inside the `provider` object, but `parse_optional_model` reads it from the top level. This caused the model setting to be silently ignored after `claw setup`. Also clean up the top-level `model` key when clearing provider settings.
claw setup now asks for a subagentModel (smaller/cheaper model for Agent subtasks) after the main model prompt. The value is written to ~/.claw/settings.json as subagentModel. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Some OpenAI-compatible providers (e.g., GLM-5) omit the `id` field in streaming and non-streaming responses. Adding #[serde(default)] allows the parser to accept these responses instead of failing with "missing field `id`". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds scripts/install.sh that builds the release binary and links it to ~/.local/bin/claw. Run after code changes to update the CLI. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When a provider returns HTML (e.g., error page, wrong endpoint) instead of JSON in an SSE stream, provide a clear error message instead of hanging or failing with a cryptic parse error. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When a provider returns a JSON error (e.g., {"error":{"message":"..."}})
without SSE framing (no "data:" prefix), the SSE parser was silently
ignoring it and hanging. Now detects and surfaces these errors.
Also handles HTML responses that lack SSE framing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Some providers (GLM, DeepSeek) emit reasoning tokens in `reasoning_content` or nested `thinking.content` fields instead of `content`. Added support for these fields so reasoning models work correctly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The final streaming chunk from some providers contains only finish_reason and usage, with no delta field. Made it optional to prevent parse errors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When preserve_recent_messages == 0, raw_keep_from equals messages.len(), causing index out of bounds when accessing session.messages[k]. Added k >= session.messages.len() check to prevent panic. Reason: Compaction with preserve_recent_messages=0 triggered OOB access when checking for tool-use/tool-result pair preservation at boundary. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5e728d7 to
9f58553
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an interactive provider wizard so users can configure their AI provider, API key, base URL, and model without manually editing config files or setting environment variables. Settings persist across sessions in
~/.claw/settings.json.Three ways to access the wizard:
claw setup— CLI subcommand/setup— slash command inside the REPL[Provider Swap]prompt, press Enter to confirm)Problem this solves
No way to configure providers without environment variables
Before: the only way to set your provider, API key, base URL, or model was via environment variables (
ANTHROPIC_API_KEY,OPENAI_API_KEY,OPENAI_BASE_URL, etc.) or manually editing a settings file. There was no guided setup — users had to read docs, figure out which env vars to set, and hope they got the names right. Switching providers mid-session required exiting, setting new env vars, and restarting.Fix: The interactive wizard walks users through provider selection, API key entry, base URL (for OpenAI-compat), and model name — all with prompts and validation. Settings persist in
~/.claw/settings.json, so they survive across sessions. Ctrl+P enables in-session provider hot-swap without restarting.No persistent auth — re-enter credentials every session
Before: API keys entered as environment variables are lost when the terminal closes. There was no way to save them persistently without editing shell profiles. Users who don't use
.envfiles or shell rc files had to export keys every time.Fix: The wizard saves all settings (including API key) to
~/.claw/settings.jsonwith0o600permissions. Auth resolution follows a three-tier priority: env var >.envfile > stored config. Environment variables always win, so power users aren't blocked.Model written under wrong JSON key
Before:
save_user_provider_settings()wrotemodelnested under theproviderobject insettings.json, but the config reader expected it at the top level. This meant the model selection from the wizard was silently ignored on next startup.Fix:
modelis now written at the top level ofsettings.jsonalongside theproviderblock, matching what the config reader expects.How it works
Three-tier auth resolution
read_env_or_config()checks in order:ANTHROPIC_API_KEY,OPENAI_API_KEY, etc.).envfile in the current directory~/.claw/settings.jsonHow Ctrl+P works
Rustyline cannot chain commands or show popup menus. The implementation:
\x01Highlighterreplaces it with a cyan[Provider Swap]label so the user sees feedbackread_line()returnsReadOutcome::ProviderSwaprun_setup_wizard(), then hot-swaps the model and reprints the connection linePersistence
Settings are stored in
~/.claw/settings.json:{ "provider": { "kind": "xai", "apiKey": "xai-...", "baseUrl": "https://api.x.ai/v1" }, "model": "grok-4" }File is created with
0o600permissions. All provider fields are optional — only set values are written.Files changed
runtime/src/config.rsRuntimeProviderConfigstruct,save_user_provider_settings(),clear_user_provider_settings(), I/O helpers. Model written at top level, not nested under provider.runtime/src/config_validate.rsprovidertop-level field +PROVIDER_FIELDSconstant (kind,apiKey,baseUrl,model) for validationapi/src/providers/mod.rsprovider_config_value(),read_env_or_config()(3-tier fallback),stored_provider_kind(), updateddetect_provider_kind()api/src/providers/anthropic.rsread_env_non_empty()→read_env_or_config()api/src/providers/openai_compat.rscommands/src/lib.rsSlashCommand::Setupvariant, spec, validationrusty-claude-cli/src/setup_wizard.rsrusty-claude-cli/src/input.rsReadOutcome::ProviderSwapvariant, Ctrl+P → sentinel char +[Provider Swap]highlight, Enter to confirmrusty-claude-cli/src/main.rsCliAction::Setup,/setupREPL handler with model hot-swap, Ctrl+P→wizard dispatchTest plan
cargo test --workspace— all tests passcargo clippy --workspace --all-targets -- -D warnings— cleanclaw setup— wizard runs interactively, saves to~/.claw/settings.json/setupin REPL — wizard runs, model hot-swaps, connection line reprints[Provider Swap], Enter launches wizardclaw setuperrors with clear messagemodelfield read correctly from top level of settings.json on startup💘 Generated with Crush