ai-assistant: Add shared packages, skills, and proactive diagnosis#871
Conversation
6eae6f4 to
8fab864
Compare
722eb47 to
70e5a2b
Compare
|
f9c8c07 to
9de7823
Compare
|
The 3 big commits are now 9 atomic commits (70 → 76 total): Skills → 2 commits: adf95d8 ai-common/skills: Add skill parsing and routing with tests Settings → 5 commits: e04b8f6 Add TermsDialog and ModelSelector with tests Delete → 2 commits: 1008238 Delete source files superseded by @headlamp-k8s/ai-common Also fixed the pre-existing ordering bug: PromptWidthContext is now committed before AIPanelComponent (which imports it), so the TypeScript check passes at every commit. |
|
Split up the docs commits so they are smaller and more atomic. |
ee07ff3 to
4e22bc4
Compare
|
The docs commits were removed from here, and put into separate PRs. |
65a5941 to
6c1cf8a
Compare
|
Added review fixes from part 1 |
96b959f to
e1c2914
Compare
|
In #891 copilot kept finding more and more issues, I would fix and it would report more. 100s found and fixed so far (with tests). Instead I moved to creating more tests, and finding bugs that way locally first. It seems to be a faster way of finding the issues before the review agent runs. The test coverage was around 60% before, and I'll try to get it up to 80%. With some more mock testing things which can be enabled like a mock tool stuff (execution and approvals for example). You can use the mock tools, approvals, and skills from the cli and plugin in developer mode too (which is good for manual and e2e testing). Along the way it found a bunch of user facing issues and some security issues as well... not just edge case error handling bugs. Like sending private keys to AI providers (now redacted) and also issues with tool selection approval bypass and writable tools selection bugs, tools, skills and mcp bugs. The process also helped find some unused code which could be removed. |
Add the headlamp-ai CLI entrypoint. It merges configuration from the Headlamp app data directory, an explicit --config file, and environment variables in priority order. In single-shot mode it prints the response and exits; in interactive mode it starts a readline REPL. Auto-detection discovers available providers when --auto-detect is passed and optionally saves the first result with --save. The e2e tests run the CLI binary via execFileSync with the mock-testing-model provider, exercising config file loading, environment variable resolution, template variable matching, and the --help flag without requiring a live AI service. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…cies Add file: references to the two new sub-packages so the plugin can import from them. Also add js-yaml, jszip, langchain, prismjs, react-markdown, langchain/mcp-adapters, modelcontextprotocol/sdk, types/prismjs, and iconify/react, which the refactored source requires. Update overrides to pin zod for ag-ui/client and ag-ui/core compatibility instead of ws. Keep sanitize-html until LangChainManager.ts is removed. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
The exports map generated by the scaffold commit incorrectly used the folder-per-component path pattern (e.g. ./src/parsing/urlParsing/urlParsing.ts) for flat utility files that were never moved into subdirectories. Fix the 13 affected entries to point to their actual paths. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…ages Add the files that replace the old scattered utility modules. Each new file either re-exports from headlamp-k8s/ai-common or headlamp-k8s/ai-ui, or is a thin wrapper that pre-binds platform-specific dependencies. context/contextGenerator.ts re-exports from ai-common, replacing utils/contextGenerator.ts. headlampLink.ts contains the Headlamp-specific URL resolver for resource and cluster links, keeping it in the plugin where it depends on kinvolk/headlamp-plugin and window. holmesClient.ts re-exports from ai-common and pre-binds clusterRequest so callers do not need to import from headlamp-plugin directly. api/clusterActions.tsx moves the Kubernetes API helpers from helper/apihelper.tsx, adds useTranslation, and switches YAML parsing to js-yaml. kubernetes/EventFetcher.ts moves from utils/EventFetcher.ts and exports RawK8sEvent for external use. prompts/promptGenerator.ts moves from utils/promptGenerator.ts, splits the hook into a pure generatePrompts function and a thin React hook. pluginState.tsx replaces utils.tsx with an updated PluginConfig type (adds previewEnabled, autoDetectDismissedProviders, devOptions) and fixes isUIPanelOpen always initialising to false. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Add thin wrapper components that delegate to headlamp-k8s/ai-ui and inject headlamp-plugin-specific dependencies. components/appbar/HeadlampAIPrompt.tsx wraps ai-ui's AIAssistantToggle, binding the global panel state so the toggle opens and closes the panel. components/appbar/HeadlampEventHandler.tsx is a headless component that registers Headlamp event callbacks (cluster switch, diagnosis triggers) from the plugin's event system, extracted from index.tsx. components/panel/AIPanelComponent.tsx wraps ai-ui's AIPanelComponent, injecting the ClusterChangeNotifier, loading saved provider configs, and passing the main AIPrompt as the panel content. components/settings/Settings.tsx replaces the six individual settings components with a single thin wrapper around ai-ui's SettingsPage, passing through the Holmes service constants from the plugin config. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Replace 'yaml' with 'js-yaml' for YAML parsing (matching the refactored dependency list) and add useTranslation so all user-facing strings in the editor dialog are internationalised. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…api/ useKubernetesToolUI now imports KubernetesToolUICallbacks and KubernetesToolUIState from headlamp-k8s/ai-common/langchain/tools/kubernetes/types instead of the local langchain/tools/kubernetes barrel, and imports handleActualApiRequest from ../api/clusterActions instead of ../helper/apihelper. It also accepts an optional translation function parameter. useClusterChangeNotifier updates its JSDoc to more precisely describe the polling interval and IPC behaviour. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…ai-ui Replace the self-contained ContentRenderer with a thin wrapper that delegates to ContentRendererBase from headlamp-k8s/ai-ui/components/chat/ContentRenderer. The plugin-specific getHeadlampLink function is injected via the LinkRendererSlot prop so the renderer can resolve Headlamp navigation links without the UI package depending on kinvolk/headlamp-plugin. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…i-ui Replace the self-contained TextStreamContainer with a thin wrapper around TextStreamContainerBase from headlamp-k8s/ai-ui/components/chat/TextStreamContainer. All scroll logic, content filter detection, and editor state move into the shared package. The wrapper adds the agentThinkingSteps prop passed from the plugin's LangChain integration. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…n wrappers AIChatContent wraps AIChatContentBase from headlamp-k8s/ai-ui, injecting the plugin's TextStreamContainer and SettingsLink via slot props. AllInputSection wraps AIInputSectionBase from headlamp-k8s/ai-ui, injecting ToolsDialog and ActionButton (from kinvolk/headlamp-plugin) via slot props. Both components drop several hundred lines of self-contained UI logic that now lives in the shared ai-ui package. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Replace all local imports of langchain, AI manager, config, and UI components with imports from headlamp-k8s/ai-common and headlamp-k8s/ai-ui. State is now sourced from pluginState instead of utils. The AIPanelComponent width prop is removed now that panel sizing is handled by the shared component. Local LangChainManager, ProviderConfigManager, ToolConfigManager and all approval/MCP types come from ai-common; all settings and dialog components come from ai-ui. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
…iagnose button Replace the 300-line monolith with a lean plugin registration file. Inline AIPanelComponent, HeadlampAIPrompt, and HeadlampEventHandler definitions are removed; the extracted components from components/appbar/ and components/panel/ are used instead. registerPluginSettings now uses the unified Settings component from components/settings/. New: i18next.init() guard ensures i18n is initialised before the plugin registers. registerResourceTableColumnsProcessor adds an AI diagnose button to the Kubernetes events table. useClusterChangeNotifier and ClusterChangeNotifier are exported for reuse in the app shell. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Remove all local copies of code now provided by packages/ai-ui. Removed: components/assistant/* (AIAssistantHeader, AgentThinkingBlock, ProactiveDiagnosisSection, PromptSuggestions, TestModeInput, ToolsDialog, and the barrel index), components/chat/MCPFormattedMessage, the full components/common tree (ApiConfirmationDialog, InlineToolConfirmation, LogsButton, LogsDialog, YamlDisplay, and index), components/mcpOutput/MCPOutputDisplay, all components/settings flat files (HolmesAgentSettings, MCPConfigEditorDialog, MCPServerEditor, MCPSettings, ModelSelector, TermsDialog, and index), contexts/PromptWidthContext, and hooks/useProactiveDiagnosis. These are now imported from headlamp-k8s/ai-ui in the wiring commits. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Add tests covering the modules that remain in the plugin src/ after the refactoring: agent-mode-default.test.ts verifies the Holmes agent-mode auto-enable logic that runs on first launch. pluginState.test.ts is a regression test for the bug where the AI panel restored its open state from saved config, causing it to open on every page load. hooks/useClusterChangeNotifier.test.ts and hooks/useKubernetesToolUI.test.ts cover the two headlamp-plugin-dependent hooks that bridge the UI to the cluster API. prompts/promptGenerator.test.ts covers the pure generatePrompts function now split from the React hook. components/settings/Settings.test.tsx asserts that Holmes service constants are correctly passed through to the settings page. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Prevent Kubernetes Secret data and common credential formats from being sent to model providers or exposed through tool-result rendering. Redact structured, aggregated, error, and fallback output. Require explicit approval for Kubernetes API calls that access Secret resources, normalize encoded API paths, and add regression coverage for credential formats and Secret payload variants. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Share in-flight MCP initialization, serialize cleanup with pending startup, and reset failed attempts for retry. Replace tool-state files through collision-free temporary siblings, clean up failed writes, log malformed tool-call arguments, and cover concurrent initialization, cleanup, and persistence behavior. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Expose proactive diagnosis progress through a concise translated status announcement without placing interactive task controls inside a live region. Add regression coverage for streamed status changes and prove that raw image and script HTML in markdown remains inert. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Write headlamp-ai.json through a unique temporary sibling so failed updates do not truncate an existing configuration. Enforce owner-only permissions on POSIX systems and use a rollback-safe replacement path on Windows, where confidentiality relies on the current user profile directory ACL. Add regression coverage for both replacement paths. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Explain that HolmesGPT must be installed and running in the selected cluster when the agent cannot be reached. Add installation guidance and connection settings, preserve external-link safety, validate editable service ports with accessible error feedback, and cover the settings behavior. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Check HolmesGPT before enabling agent mode and show setup guidance when the service is unavailable instead of dropping submitted prompts. Sequence overlapping health checks, preserve pending prompts, prevent stale results from changing modes, translate diagnosis progress, focus and label the setup guide, and add direct accessibility and request-gating tests. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Treat Kubernetes Service- and namespace-not-found responses as unavailable while keeping bare Holmes application route 404s reachable. Track inner subscription handles across thread resets so unsubscribe always detaches the current agent registration, and add regression coverage for both health classification and reset behavior. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Add provider configuration types, identity checks, and pure transformations for saving, selecting, and deleting providers. Expose caller-owned configuration operations with terms acceptance and active-provider selection. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com>
…n, and developer settings with tests AIToolsSettings manages the enabled/disabled state of built-in and MCP tools. AutoDetectProvider and DetectedProvidersDialog handle automatic detection of AI providers available in the environment and let users confirm or dismiss detected providers. DeveloperSettings exposes mock-mode and debug-logging toggles. HolmesAgentSettings configures the Holmes agent endpoint URL. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: Ashu Ghildiyal <aghildiyal@microsoft.com> Signed-off-by: Ashu Ghildiyal <aghildiyal@microsoft.com>
Add a Docker-backed KWOK runner and Playwright scenarios for assistant settings, mock chat and agent behavior, MCP, skills, and proactive diagnosis. Run the suite for AI Assistant changes in CI, document local prerequisites, and keep generated screenshots and test results untracked. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: ashu8912 <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Remove the standalone AKS Agent documentation section and related props, story data, and test expectations from the shared settings page. Keep the remaining assistant stream labeling generic so the UI no longer advertises an integration that is configured elsewhere. Signed-off-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: ashu8912 <aghildiyal@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Provider auto-detection invokes local gh and az commands through Headlamp's runCommand adapter, which is available only in the desktop Electron app. Hide Auto Detect, per-provider CLI detection, and the detected-provider dialog in browser mode and while the desktop command runner is unavailable. Update the desktop Storybook scenario and cover browser, runner-not-ready, and runner-ready states. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Resolve GitHub and Azure CLI sentinel credentials in an ephemeral config copy before constructing chat models. Fail clearly when the desktop command runner cannot provide a credential. Keep persisted provider configurations sentinel-based: the resolver never mutates saved input or invokes persistence callbacks. Cover frozen GitHub and Azure configs to prove real credentials remain runtime-only, and reject stale proactive-diagnosis sessions after provider changes. Signed-off-by: ashu8912 <aghildiyal@microsoft.com> Co-authored-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com>
Add a persisted Proactive Diagnosis preview setting that defaults to disabled. Hide manual diagnosis actions and results, reject manager requests, and stop scheduled cycles until the user explicitly enables the feature. Recheck the preference after asynchronous event loading, expose an accessible settings toggle, and cover manager, host, reload-persistence, and E2E behavior. Co-authored-by: René Dudfield <renedudfield@microsoft.com> Co-authored-by: ashu8912 <aghildiyal@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Bump the plugin and lockfile to 0.3.0-alpha. Add Artifact Hub metadata with PR-derived release notes and a snapshot of the plugin README. Co-authored-by: ashu8912 <aghildiyal@microsoft.com> Signed-off-by: René Dudfield <renedudfield@microsoft.com> Signed-off-by: ashu8912 <aghildiyal@microsoft.com>
Summary
This PR separates the AI Assistant into shared runtime and UI packages, adds a standalone CLI, and reduces the Headlamp plugin to its host-specific integrations. The result is less duplicated code, clearer ownership boundaries, broader test coverage, and shared behavior across the UI and command line.
Enhancements
HEADLAMP_CURRENT_CLUSTERcan restart with the correct Kubernetes context.headlamp-aiCLI with one-shot, stdin, and interactive modes, primarily so the shared assistant core, providers, skills, and Kubernetes tools can be tested and debugged outside the Headlamp UI.Skills
Adds configurable skills from GitHub sources with loading, inspection, keyword or embedding routing, and prompt injection, so deployments can extend the assistant with domain-specific guidance without changing application code.
Auto detect provider
So far out of all the different AI providers it auto detects Local llama models, and also GitHub copilot and Azure model foundry ones.
Preview features
Proactive diagnosis
Automatically starts investigating critical Kubernetes events as they occur, so when users open the assistant the investigation is already underway instead of beginning from manually reconstructed event context. Note this is off by default, and can be enabled in the plugin settings.
Accessibility
ai-uicomponent modules, so keyboard and assistive-technology users can operate and understand more of the assistant without relying on pointer interaction or visual context.ai-uitest files plus focused keyboard, accessible-name, ARIA-relationship, focus, and dialog tests, so accessibility regressions are caught during component testing. These checks improve coverage but do not claim full WCAG compliance.Security
Bug fixes
enabledfield remain enabled.Development
@headlamp-k8s/ai-common, so non-UI behavior has a typed, host-independent API that can evolve without Headlamp or React coupling.@headlamp-k8s/ai-ui, so the Headlamp plugin only supplies cluster APIs, persistence, registration, and component slots instead of maintaining duplicate UI logic.Testing
ai-commonand 96.99% line / 87.84% branch coverage inai-ui, so the two extracted packages have measurable protection across core logic and UI behavior. These are separate package-level measurements becauseai-commonuses Istanbul andai-uiuses V8; one newly added UI file remains below the per-file 80% gate.npm run checkscript that runs formatting checks, linting, TypeScript validation, and Vitest, so contributors and CI have one consistent command for catching code-quality, type, and regression failures before submission.Assisted by co pilot and ai-assistant.