Skip to content

Fix fabricated tool narration + codicon empty states (#101) - #116

Merged
hellodk merged 13 commits into
masterfrom
fix/hallucination-and-icons
Aug 24, 2026
Merged

Fix fabricated tool narration + codicon empty states (#101)#116
hellodk merged 13 commits into
masterfrom
fix/hallucination-and-icons

Conversation

@hellodk

@hellodk hellodk commented Aug 24, 2026

Copy link
Copy Markdown
Owner

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 remains
  • Regression tests for parseToolCallsFromText, extractPreToolText, extractTextContent, hasFabricatedNarration
  • Webview robustness: lazy VS Code API acquisition (fixes blank webview from double acquireVsCodeApi()), status-bar reset after turns/errors, loading provider broadcast, deferred playwright chromium import

Verification

  • 170 files / 1526 tests passed on this branch at time of writing
  • pnpm run check-types and pnpm run lint clean

hellodk added 13 commits July 18, 2026 00:16
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.
Both correct prompt-based tool calling from complementary angles:
narration-without-tool-calls gets the #101 corrective turn, malformed
argument JSON gets #106 feedback. Browser SSRF import and lazy
playwright load coexist; version takes 1.6.170 pending release bump.
@hellodk
hellodk merged commit dfa5bc9 into master Aug 24, 2026
4 of 6 checks passed
@hellodk
hellodk deleted the fix/hallucination-and-icons branch August 27, 2026 18:37
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.

Prompt-based tool mode: model narrates fake tool results without emitting <tool_call> XML

1 participant