Skip to content

Revive ai diagnostics report command - #15169

Open
sharon-wang wants to merge 8 commits into
mainfrom
ai/diagnostics
Open

Revive ai diagnostics report command#15169
sharon-wang wants to merge 8 commits into
mainfrom
ai/diagnostics

Conversation

@sharon-wang

@sharon-wang sharon-wang commented Jul 27, 2026

Copy link
Copy Markdown
Member

Closes #15117
Companion https://github.com/posit-dev/assistant/pull/1904

Summary

Adds an AI: Create Diagnostic Report command that gathers everything needed to debug an AI problem into a single markdown report and opens it in an editor, so the user can read it over before sharing. This replaces the "Positron Assistant: Collect Diagnostics" command that went away when the Positron Assistant extension was removed, and widens it to cover all of today's AI areas: Authentication, Posit Assistant, Posit AI NES, and GitHub Copilot.

The report has these sections:

  • Version Information - application, Positron version and build, Code OSS version, commit, build date, quality, OS, remote. Plus each AI extension's version and activation state (including runtime error counts).
  • AI Features - the ai.enabled main switch, then each feature's own toggle (NES, notebook AI, console Fix & Explain, Copilot chat). When ai.enabled is off the report says outright that everything below it is off regardless. Extension-backed toggles read "Not installed" when their extension is absent, instead of reporting the unregistered setting's default and contradicting the Extensions list.
  • Providers - which providers the user is signed in to, which are turned off, the models each provider actually offers, and the contents of providers.json (redacted, with its path).
  • Configuration Settings - only AI settings whose value differs from the registered default, with secrets redacted.
  • Logs - recent trace/debug from Authentication, Posit Assistant, Posit AI NES, and GitHub Copilot (the last only when Copilot is enabled). Capped at the most recent 500 lines each.
  • Assistant Diagnostics Bundle - optional. When Posit Assistant is installed the command asks up front whether to also produce its bundle; the report itself is always generated.

Getting trace/debug without asking for a repro

The main problem the issue describes is that by the time something goes wrong, the useful trace and debug lines were never written, because the user's log level is higher. The Posit-owned extensions now buffer every entry in memory at all levels, before the output channel's display filter runs, and hand the buffer over on request.

  • NES gets this through a new BufferedLogOutputChannel (a 500-entry circular buffer wrapping its real LogOutputChannel).
  • Each extension exposes its buffer through a bridge command (*.getDiagnosticLogs). The report runs in the workbench, which can't read an extension's activate() exports, so a command invocation is how the data crosses the extension-host boundary. These commands aren't declared in package.json, so they stay out of the command palette. NES and Authentication register theirs first thing in activate(), so the logs are still reachable if the rest of activation stalls.
  • The Posit Assistant side (log bridge and bundle bridge) landed separately in posit-dev/assistant.
  • GitHub Copilot is third-party, so there's no bridge to add. Its log file is read directly through its output channel descriptor.

Model listing

Adds getModelListingDiagnostics() to IHeadlessLanguageModelService. It reports models before the cross-provider de-duplication, plus the list of providers actually queried, so a report can distinguish three cases that otherwise look identical: the provider wasn't queried at all (disabled, or no credentials), it was queried and returned nothing, or its models lost the dedupe to a higher-priority provider.

providerId deliberately stays off the feature-facing IAvailableModel. Requests select a model and the service picks the provider, so exposing the provider id to feature code would let something route around that. Only diagnostics, which reports rather than decides, sees it. Models registered with the built-in language model API (where Copilot's live) are merged into the same per-provider listing, since which of the two paths a model arrived through is Positron's plumbing and not something a reader should have to reason about.

Robustness

  • The command has no precondition. It has to work when AI features are off, since "why is this disabled?" is one of the reasons to run it.
  • Every extension activation and bridge call is bounded at 5s, and each model listing at 10s, so a stuck extension can't hang the report. A listing that times out is reported as incomplete rather than as zero models.
  • A progress notification names the step currently running, since the total wait can add up if something is stuck.

Redaction

apiKey, token, secret, and password keys and all customHeaders values are replaced with <redacted>, in both the settings block and providers.json. Everything else is shown as configured, including base URLs, which can name internal endpoints. The report opens with a privacy notice spelling this out and asking the user to read the whole thing before sharing it.

Also in here

Maps extensions/next-edit-suggestions/ to the assistant tag in test-tag-paths-map.json, so NES changes auto-tag the right e2e suite.

Testing

24 new vitest cases in aiDiagnostics.vitest.ts cover the pure report formatter (snapshotted) and each helper: feature-toggle description, sensitive-key detection, providers.json redaction, explicit-value detection, extension status description, and log capping. Two new cases in headlessLanguageModelService.vitest.ts cover the diagnostics accessor, including the de-duplication case.

Known gap: the extension-side logic isn't covered yet. The auth getProviderDiagnostics command and the NES buffered log channel need cases in the authentication and next-edit-suggestions mocha suites. Tracked as a follow-up along with showing the selected model per feature, and routing notebook AI and console Fix & Explain logs into the report.

Release Notes

New Features

Bug Fixes

  • N/A

Validation Steps

@:assistant

  1. Run AI: Create Diagnostic Report from the command palette. With Posit Assistant installed you'll be asked whether to include its diagnostics bundle; either answer should produce the report, and pressing Escape should cancel the whole command.
  2. Check the report opens in an editor and every section is filled in: version info, extensions with activation state, AI features, providers, providers.json, non-default settings, and a log section per AI area.
  3. Confirm the logs include trace and debug lines even though your log level is at the default. Nothing should need reproducing first.
  4. Set ai.enabled to false and run it again. The command should still work, and the AI Features section should say the main switch is off and everything below it is off regardless.
  5. Sign in to at least one provider and confirm it shows under Providers > Authenticated, with its models listed under Available Models. Sign out and confirm the report reflects that.
  6. Set a custom header on a provider and confirm the value reads <redacted> in both the settings block and the providers.json block.
  7. With Copilot disabled (chat.disableAIFeatures on), confirm the report skips the Copilot log section; turn it back on and confirm the section returns.
  8. Uninstall Posit Assistant or NES and confirm their features read "Not installed" rather than "Enabled", and the Extensions list agrees.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:assistant @:positron-notebooks

Why these tags?
Tag Source
@:critical Always runs (required)
@:assistant PR description
@:positron-notebooks Changed files

More on automatic tags from changed files.

readme  valid tags

Adds a command (category "AI") that collects AI diagnostics into a
markdown report opened in the editor: Positron version info, the
providers the user is authenticated with and any disabled in settings,
non-default AI-related settings (secrets redacted), and recent
trace/debug logs from Authentication, Posit Assistant, Posit AI NES,
and GitHub Copilot.

The workbench can't read an extension's activate() exports, so each
Posit-owned extension buffers its logs and exposes them (and provider
state) via bridge commands the command invokes across the extension-host
boundary. NES gains a buffered log channel to match Authentication; the
Posit Assistant bridge lives in its own repo, and the command degrades
gracefully until it ships. Copilot logs are read from its output-channel
file, gated on chat.disableAIFeatures.
Leads each feature's on/off state (with its setting key) after the
extensions list: the ai.enabled main switch, Posit AI NES, notebook AI,
console Fix & Explain, and GitHub Copilot chat. A disabled ai.enabled is
called out since it gates everything. Also groups the authenticated and
disabled provider lists under one Providers heading.
When Posit Assistant is installed, the command offers a two-option quick
pick (Report only / Report and diagnostics bundle). On opt-in it invokes
the posit.assistant.collectDiagnosticsBundle bridge command, fired after
the report opens and not awaited so the Assistant's own reveal/progress
notification doesn't block the report from appearing. Tolerant of the
command's absence, with a warning notification on failure.
Lists Posit Assistant (assistant.enabled) in the AI Features section.
Extension-backed toggles (Posit Assistant, Posit AI NES, GitHub Copilot
chat) now report "Not installed" when their extension is absent, instead
of the setting defaulting to "Enabled" and contradicting the Extensions
list. Notebook AI and console actions are core, so they always show.
Adds the directory to test-tag-paths-map.json so NES changes are tagged
automatically. Uses @:assistant, matching the sibling AI extensions and
the existing tags.ASSISTANT-tagged next-edit-suggestions e2e test.
The provider connection config (base URLs, custom headers, AWS/Snowflake
enablement, model overrides) moved from settings.json to ~/.posit/ai/
providers.json via the provider catalog, so the settings itemization no
longer captured it. Add a Providers > Configuration section that reads
providers.json and shows it verbatim in a JSON fence.

Read the file fresh each run (via getConfigFileUri + IFileService) rather
than the catalog service's warmed snapshot: the snapshot can still be empty
on the first invocation before the node side finishes loading, which showed
up as having to run the command twice before providers appeared.

customHeaders is the one field that can hold a hand-placed token, so
redactProvidersConfig keeps header names but redacts their values (and
redacts any apiKey/token/secret/password key wholesale) while leaving the
rest of the file as-is. Parsed tolerantly; an unparseable file is shown raw.
The report showed what providers.json declares but never what the providers
actually return, which is usually the first question on a support ticket.

Adds an Available Models section listing what each provider offers. Models come
from two places, the provider sweep and the built-in language model API (where
GitHub Copilot's live), merged into one per-provider list: which path a model
arrived through is Positron's plumbing, not something a reader should parse.
Listed before cross-provider de-duplication, so a provider whose models all lose
to a higher-priority one is visible rather than silently absent, and a provider
that was queried and returned nothing says so.

Collection runs under a progress notification naming the current step. The model
listing is the only step that reaches the network, so both sources run together
under their own bound; if it does not come back the report still generates and
says the list may be incomplete, rather than claiming there are no models.

The headless service gains getModelListingDiagnostics() for this.
getAvailableModels() is unchanged: provider identity stays off it so feature
code cannot route by provider, and the test guarding that still passes.
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.

Add a command to collect AI diagnostics

1 participant