Revive ai diagnostics report command - #15169
Open
sharon-wang wants to merge 8 commits into
Open
Conversation
|
E2E Tests 🚀 Why these tags?
More on automatic tags from changed files. |
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.
sharon-wang
force-pushed
the
ai/diagnostics
branch
from
July 30, 2026 14:28
83dc10c to
1d8c44d
Compare
sharon-wang
marked this pull request as ready for review
July 30, 2026 17:33
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.
Closes #15117
Companion https://github.com/posit-dev/assistant/pull/1904
Summary
Adds an
AI: Create Diagnostic Reportcommand 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:
ai.enabledmain switch, then each feature's own toggle (NES, notebook AI, console Fix & Explain, Copilot chat). Whenai.enabledis 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.json(redacted, with its path).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.
BufferedLogOutputChannel(a 500-entry circular buffer wrapping its realLogOutputChannel).*.getDiagnosticLogs). The report runs in the workbench, which can't read an extension'sactivate()exports, so a command invocation is how the data crosses the extension-host boundary. These commands aren't declared inpackage.json, so they stay out of the command palette. NES and Authentication register theirs first thing inactivate(), so the logs are still reachable if the rest of activation stalls.posit-dev/assistant.Model listing
Adds
getModelListingDiagnostics()toIHeadlessLanguageModelService. 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.providerIddeliberately stays off the feature-facingIAvailableModel. 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
Redaction
apiKey,token,secret, andpasswordkeys and allcustomHeadersvalues are replaced with<redacted>, in both the settings block andproviders.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 intest-tag-paths-map.json, so NES changes auto-tag the right e2e suite.Testing
24 new vitest cases in
aiDiagnostics.vitest.tscover the pure report formatter (snapshotted) and each helper: feature-toggle description, sensitive-key detection,providers.jsonredaction, explicit-value detection, extension status description, and log capping. Two new cases inheadlessLanguageModelService.vitest.tscover the diagnostics accessor, including the de-duplication case.Known gap: the extension-side logic isn't covered yet. The auth
getProviderDiagnosticscommand and the NES buffered log channel need cases in theauthenticationandnext-edit-suggestionsmocha 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
Validation Steps
@:assistant
providers.json, non-default settings, and a log section per AI area.traceanddebuglines even though your log level is at the default. Nothing should need reproducing first.ai.enabledtofalseand 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.<redacted>in both the settings block and theproviders.jsonblock.chat.disableAIFeatureson), confirm the report skips the Copilot log section; turn it back on and confirm the section returns.