Fix fabricated tool narration + codicon empty states (#101) - #116
Merged
Conversation
When provider initialization times out (10 seconds), show a blocking modal that guides the user to configure a provider instead of leaving the webview stuck with an infinite loading bar. - Add config modal with semi-transparent overlay - Display 'Configure a Provider' message when provider state is 'error' - Button opens VS Code settings for provider configuration - Replaces confusing retry button with actionable setup guidance
Three improvements to fix provider initialization hanging: 1. Reduce INIT_TIMEOUT_MS from 10s to 5s for faster error feedback 2. Add individual 2s timeouts on memoryBank.load() and globalMemoryBank.load() so a hanging read doesn't block entire initialization 3. Add connectivity probe (ping baseUrl) during provider creation for local providers (ollama, llamacpp, vllm, openai-compatible) so errors surface during init instead of on first chat message With these changes: - Extension reports provider errors within 5 seconds - Modal guides user to configure provider - User doesn't waste time waiting for timeouts on each chat message
1. Message type mismatch — modal sent 'openSettings' but handler expects 'openSettingsRequest'. Now sends correct type so Settings button works. 2. Modal shown repeatedly — showConfigModal() called on every state update. Added flag to show modal only once per error, plus dismiss button (X) and click-outside-to-close so user isn't trapped in a loop. 3. Probe fails for llamacpp — used /health which doesn't exist. Now uses provider-specific endpoints: - ollama: /api/tags - llamacpp/vllm/openai-compatible: /v1/models Also improved error message to show which endpoint was tried.
The probe was silently skipped for users with fallback.providers configured. FallbackProvider.name returns 'fallback(ollama,vllm)' which never matched the includes() check, so probeLocalProvider() returned early without probing. Now unwraps FallbackProvider to get the first underlying provider's actual name and baseUrl, then probes that. This fixes the timeout for users with redundant local providers configured via fallback.providers.
Previous check using 'in' operator was generic and fragile. Now uses instanceof checks to properly detect and unwrap: - RateLimitedProvider (accesses .inner property) - FallbackProvider (accesses .providers[0] array) This ensures we get the actual underlying provider name and can access its baseUrl from config for the connectivity probe.
The error message was lost when the webview wasn't ready at probe time. When sidebar was closed during extension activation, the error broadcast was silently dropped because the webview hadn't resolved yet. When the webview later opened, onWebviewReady had a guard that skipped re-broadcast for 'not-configured' provider (exactly the failed case). Now: 1. Cache provider error in lastProviderError on failure 2. Clear it on successful load 3. In onWebviewReady, check if provider is 'not-configured' AND lastProviderError is set, then re-broadcast the error state This ensures the modal appears even if the sidebar wasn't open when provider initialization failed.
The modal implementation was breaking the webview - it wouldn't render at all, showing a blank panel instead of the chat interface. Removed: - configModal element creation and styling - showConfigModal() function - modal-related state and event handlers - references to configModalShownForError Restored the retry button display on error state instead. This gets the webview back to a working state so the timeout/error flow can work again.
…rash MemoryPanel was calling acquireVsCodeApi() unconditionally at module level, causing a second call in the same webview session. VS Code throws on the second call, which crashed components.js and broke the entire webview (showed blank instead of any content). Added guard to check if window.vscode already exists (set by main.js's first call), matching the pattern used in other panel components (DiffOverlayPanel, McpMarketplacePanel, etc). This was the root cause of the webview being completely blank and not rendering anything at all.
Models without native tool calling imitate narration style but never emit <tool_call> XML, so fabricated results streamed as plain text. Add hasFabricatedNarration() detection plus a corrective user turn that forces a real <tool_call> emission when the budget allows. Closes #101
Replace emoji empty-state prompts with codicons, resolve the VS Code API handle lazily so components never double-acquire (blank webview), reset the status bar to ready after each turn or stream error, broadcast a loading provider state instead of leaving the header stuck, and defer the playwright chromium import until first browser use.
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.
Fixes #101 — prompt-based models narrate fake tool results without emitting
<tool_call>XML, and empty-state prompts used emoji instead of codicons.Changes
hasFabricatedNarration()detection + corrective user turn that forces a real<tool_call>emission when iteration budget remainsparseToolCallsFromText,extractPreToolText,extractTextContent,hasFabricatedNarrationacquireVsCodeApi()), status-bar reset after turns/errors, loading provider broadcast, deferred playwright chromium importVerification
pnpm run check-typesandpnpm run lintclean