Davemaina1/iroh_ locks to Anthropic-only, gates extended thinking to Opus

Two commits remove multi-provider routing entirely and replace the model picker with a Quick/Deep/Draft mode selector. If you're evaluating this fork, the provider lock is the defining constraint to know about upfront.

chat-uiinfrastructure

The cleanup in 1f973e7d operates at every layer. gemini.ts gets @ts-nocheck and a throw at the top of both streamGemini and completeGeminiText - dead code kept in place but never reachable. llm/index.ts removes the providerForModel dispatch and replaces it with a toClaudeParams() helper that coerces any non-Claude model to QUICK_MODEL and nulls out user-supplied API keys (the backend uses process.env.ANTHROPIC_API_KEY instead). chatTools.ts does the same with a model.startsWith("claude") check. userSettings.ts drops the Gemini branch from resolveTitleModel.

Three model constants live in backend/src/lib/llm/models.ts:

  • QUICK_MODEL = "claude-haiku-4-5-20251001"
  • DEEP_MODEL = "claude-opus-4-7"
  • DRAFT_MODEL = "claude-opus-4-7"

A modeToModel() helper maps "deep" and "draft" to Opus, everything else to Haiku. The frontend swaps the ModelToggle dropdown for a ModeToggle 3-button segment (quick/deep/draft), with a useSelectedMode hook and a mode field on MikeMessage. The account models page is replaced with an Iroh notice. Draft mode injects DRAFT_SYSTEM_PROMPT_EXTRA into the system prompt and skips getUserApiKeys.

4fbd7517 gates extended thinking. Haiku and Sonnet reject the thinking parameter - only Opus supports it. The fix is selectedModel.startsWith("claude-opus") in chatTools.ts, and a secondary guard in claude.ts that checks both the enableThinking flag and the model name before passing thinking: { type: "adaptive" } and output_config: { effort: "high" }. The stream.on("thinking") listener is also gated the same way.

The Opus-thinking guard is a real hardening that applies regardless of whether you use Davemaina1's mode system. The ModeToggle UX is cleaner than a raw model picker for most legal-AI users. But both come packaged with the single-vendor lock: user API keys are bypassed at the toClaudeParams layer, so there's no path to swap providers without reworking llm/index.ts.

So what Worth a look if you're already committed to Anthropic and want the Quick/Deep/Draft mode pattern or the Opus-gated thinking guard. Skip if you need multi-provider support - the lock is enforced in four separate places and restoring it requires more than reverting a single file.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

2 commits from Davemaina1/iroh_, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
1f973e7d fix: force all chat to Claude - runtime guards + remove Gemini fallback in resolveTitleModel Davemaina1 2026-05-12 ↗ GitHub
commit body
- gemini.ts: throw [Iroh] guard at top of streamGemini and completeGeminiText; add @ts-nocheck since dead code is preserved for later removal
- llm/index.ts: toClaudeParams uses QUICK_MODEL explicitly and console.warns on coercion; completeText same
- chatTools.ts: runLLMStream guards selectedModel with startsWith("claude") check + QUICK_MODEL fallback, warns if coerced; imports QUICK_MODEL directly
- models.ts: add QUICK_MODEL/DEEP_MODEL/DRAFT_MODEL constants, modeToModel(), update defaults to Claude
- userSettings.ts: resolveTitleModel always returns QUICK_MODEL - drop Gemini branch entirely
- chat.ts / projectChat.ts: read mode from request body, compute model via modeToModel(), inject DRAFT_SYSTEM_PROMPT_EXTRA for draft mode, remove getUserApiKeys calls
- Frontend: replace ModelToggle dropdown with ModeToggle 3-button segment (Quick/Deep/Draft); useSelectedMode hook; mode field on MikeMessage; account/models page disabled with Iroh notice

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4fbd7517 fix: gate extended thinking to Opus models only Davemaina1 2026-05-12 ↗ GitHub
commit body
Haiku (and Sonnet) reject the thinking parameter - only claude-opus-*
supports adaptive thinking. Guard at two layers:
- chatTools.ts: derive enableThinking from selectedModel.startsWith("claude-opus")
  so the flag is false for Quick (Haiku) and true for Deep/Draft (Opus)
- claude.ts: secondary guard on both the flag and model name so a
  misconfigured caller can never send thinking to a non-Opus model;
  same guard on the stream.on("thinking") listener for consistency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-376.md from inside the repo you want the changes in.

⬇ Download capture-thread-376.md