Skip to content

feat: Provider UI consolidation — two-level selector, multi-provider support, skill UX fixes#20

Merged
MarcelRoozekrans merged 43 commits intomainfrom
feat/provider-ui-consolidation
Mar 26, 2026
Merged

feat: Provider UI consolidation — two-level selector, multi-provider support, skill UX fixes#20
MarcelRoozekrans merged 43 commits intomainfrom
feat/provider-ui-consolidation

Conversation

@MarcelRoozekrans
Copy link
Copy Markdown
Contributor

Summary

  • Unified provider + model selector — replaces the old single-level model picker with a two-level ProviderModelSelector: Level 1 lists providers (●/○ dot, ✓/! config status, ⚙ gear), Level 2 shows that provider's models with search and per-million pricing
  • Consolidated status bar — merges the two separate status bar items (inline completion spinner + auth/cost) into one dynamic item that reflects the active provider name and loading state
  • Multi-provider support — OpenRouter, Anthropic (native), and NVIDIA NIM all routable from the UI; ProviderRegistry gains setOverride(), getProvider(), isConfigured()
  • Skill capability filtering — uses supported_parameters.includes('tools') instead of a model-name allowlist to decide whether to show workflow skills
  • Price formatting fixProviderModelSelector now shows per-million-token rates ($3.00 · $15.00 /1M) matching the old ModelSelector
  • Skill badge in YOU message — skill names are stored on the user message and rendered as ⚡ /skill-name chips so sent skills are visible in history
  • Skill-only send blocked — sending with only a skill chip and no body is now disabled on all models (previously only blocked for workflow-capable models)
  • Minor UX fixes(free) suffix stripped from model names (pricing row already says free); model list height tightened; thinking badge stays visible on hover/selected rows
  • VS Code debug config.vscode/launch.json + tasks.json so F5 launches Extension Development Host
  • Docs + marketing updated — getting-started, model-selection, LLM Providers developer doc, marketing feature cards all updated for multi-provider world

Test plan

  • Build extension with npm run build — no TypeScript errors
  • F5 in VS Code → Extension Development Host opens
  • Provider selector opens two-level picker; switching provider repopulates model list
  • Status bar shows active provider name + cost; spinner appears during inline completion
  • Selecting Nemotron (no tool support) hides claude/marketplace skills in picker
  • Attaching a skill chip without body text keeps Send button disabled
  • Skill chip shows as ⚡ /skill-name badge in YOU message after sending
  • Model prices show as $X.XX · $Y.YY /1M (not raw per-token values)
  • Free models show free label, not (free) in the name
  • All 487 unit tests pass: npm test

🤖 Generated with Claude Code

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 26, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
lucent-code 399247f Commit Preview URL

Branch Preview URL
Mar 26 2026, 05:40 PM

MarcelRoozekrans and others added 29 commits March 26, 2026 18:39
Covers ILLMProvider interface, OpenRouter/Anthropic/NVIDIA NIM providers,
provider registry with auto-detect, settings, error normalization, and
Anthropic tool format translation details.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
13-task TDD plan covering ILLMProvider interface, OpenRouter/Anthropic/NVIDIA
NIM providers, ProviderRegistry with auto-detect, settings, MessageHandler
wiring, and provider badge UI.

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

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace direct OpenRouterClient dependency in MessageHandler with the
ILLMProvider abstraction. Updates chatStream, listModels, and
getAccountBalance call sites; rewrites chat() usages for compaction and
auto-title to use chatStream; maps ProviderModel to OpenRouterModel shape
for backward-compat webview serialization; updates error handling to
LLMError with string codes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace OpenRouterClient dependency in InlineCompletionProvider with
ILLMProvider interface, switching from chat() to chatStream() to
accumulate delta content. Update message-handler.test.ts and
inline-provider.test.ts to mock ILLMProvider instead of OpenRouterClient,
fix mockModels to use ProviderModel shape (contextLength), and update
compactConversation/autoTitle tests to use chatStream mocks.

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

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves the active provider (Anthropic, OpenRouter, NVIDIA NIM) via
ProviderRegistry.resolve() and displays it as a subtle muted badge next
to the model name in the ModelSelector toggle button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix type errors across source and test files:
- remove unknown definitions field from CodeContext mock
- cast mock.calls for filter callbacks
- add non-null assertions for .find() results
- type mock functions with correct return types
- cast response.json() returns and use FileSystemWatcher type
- cast proposed-API onDidWriteTerminalData
- add tsconfig.test.json with esnext module for top-level await

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s message types

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

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

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

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MarcelRoozekrans and others added 14 commits March 26, 2026 18:39
… providersLoaded on ready

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gs; wire in App.tsx

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the single-level ModelSelector with a two-level dropdown:
Level 1 shows providers with ●/○ active indicator, ✓/! config status,
and a gear icon to open provider settings. Level 2 shows a searchable
model list with pricing, selected check, warning banner, and back button.
ChatInput and App.tsx updated to wire all new props from the chat store.

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

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

Use the model's explicit supported_parameters metadata to determine
tool-use capability, with a name-based allowlist as fallback for
providers that don't expose this field (e.g. local/custom models).

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

Raw per-token values (e.g. $0.000003) were displayed instead of the
human-readable per-million-token format used in ModelSelector.
Free models now show "free" instead of "$0.00 · $0.00 /1M".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l-2 list height

- Model names like "NVIDIA: Nemotron 3 Nano (free)" had "(free)" in both
  the name and the pricing row. Strip the suffix from the display name
  since the pricing row already shows "free".
- Add overflow:hidden to .model-list-level2 and reduce inner list
  max-height to 220px so the dropdown is more compact on small viewports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Marketing:
- CoreFeaturesGrid: "Any model via OpenRouter" → "Any model, any provider"
  (mentions OpenRouter, Anthropic native, NVIDIA NIM)
- AdvancedFeaturesGrid: add "Native provider support" card

Docs:
- getting-started: restructured around provider choice; table comparing
  OpenRouter / Anthropic / NVIDIA NIM with setup instructions for each
- model-selection: full rewrite for two-level ProviderModelSelector;
  explains all three providers; adds native-provider tip (Anthropic for
  full Claude features, NIM for Nemotron without a proxy hop)
- openrouter-integration → LLM Providers: expanded to cover all three
  providers, ILLMProvider interface, error normalisation, tool-use
  capability detection, and provider switching flow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Marketing AdvancedFeaturesGrid referenced "TDD" (not a builtin) and
omitted most of the actual skills. Updated to list the real set.

Skills doc now opens with a quick-reference table of all 10 built-in
slash commands, including a note about tool-use model filtering.

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

- ChatMessage.ChatMessage: add skills?: string[] field (display-only)
- sendMessage: record skill names alongside the user message so the
  YOU bubble always shows which skills were active
- ChatMessage: render ⚡ /skill-name chips above message text for user
  messages that had skills attached
- ChatInput: remove isWorkflowCapableModel() guard from skill-only send
  check — skills always need a body message (the workflow needs user
  intent to kick off), regardless of model capability
- Send button disabled state updated to match the guard change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- .vscode/launch.json + tasks.json: F5 launches Extension Development Host
- .vscodeignore: exclude docs-site/ from packaged extension
- src/markdown.d.ts: type declaration for markdown imports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MarcelRoozekrans MarcelRoozekrans force-pushed the feat/provider-ui-consolidation branch from 666ec10 to 399247f Compare March 26, 2026 17:40
@MarcelRoozekrans MarcelRoozekrans merged commit 791d394 into main Mar 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant