Return safe provider preflight diagnostics

Classify Assistant and Patrol provider-test failures through the Patrol runtime failure taxonomy, redact secret-shaped provider evidence, and preserve safe recommendations in the settings shell.

Refs #1463
This commit is contained in:
rcourtman
2026-05-07 20:45:18 +01:00
parent c31e644f33
commit f7992e8e78
17 changed files with 583 additions and 68 deletions
@@ -1111,6 +1111,10 @@ AI handlers add split scoped-trigger fields, recency labels, or trigger-state
transport for Patrol, lifecycle-adjacent setup and fleet surfaces must treat
those payloads as Patrol-only runtime context and must not reinterpret them as
agent install readiness, enrollment health, or fleet-control state.
Provider preflight diagnostics on the same handler remain AI runtime readiness
context as well: lifecycle-adjacent setup and fleet surfaces may not treat
`provider_auth`, `provider_connection`, model-selection, or provider-settings
recommendations as agent registration, updater trust, or fleet-control health.
That same shared AI handler dependency also assumes direct alert-investigation
execution mode is AI/API-owned. Request-scoped `AutonomousMode:false` and
`RequireCommandApproval:true` on `/api/ai/investigate-alert` are Assistant
@@ -59,6 +59,13 @@ runtime cost control, and shared AI transport surfaces.
2. Add or change canonical AI provider config, provider-scoped model selection, or runtime auth/base-URL defaults through `internal/config/ai.go`
3. Add or change Pulse Assistant request flow through `internal/api/ai_handler.go`, `frontend-modern/src/api/ai.ts`, and `frontend-modern/src/api/aiChat.ts`
4. Add or change Patrol, alert-analysis, or remediation transport through `internal/api/ai_handlers.go`, `internal/api/ai_intelligence_handlers.go`, and `frontend-modern/src/api/patrol.ts`
Provider preflight diagnostics returned from `internal/api/ai_handlers.go`
must reuse the Patrol runtime failure classifier in `internal/ai/` and
expose only safe operator-facing cause, summary, recommendation, model, and
action fields. Raw provider response bodies and transport errors may be
logged server-side or attached as redacted internal Patrol evidence where
governed, but they must not be returned through the browser provider-test
contract.
5. Add or change AI usage/cost dashboard presentation through `frontend-modern/src/components/AI/AICostDashboard.tsx` and `frontend-modern/src/utils/aiCostPresentation.ts`
6. Add or change AI provider, control-level, chat/session, or explore-state presentation through `frontend-modern/src/components/AI/Chat/`, `frontend-modern/src/utils/aiProviderPresentation.ts`, `frontend-modern/src/utils/aiProviderHealthPresentation.ts`, `frontend-modern/src/utils/aiControlLevelPresentation.ts`, `frontend-modern/src/utils/aiChatPresentation.ts`, `frontend-modern/src/utils/aiSessionDiffPresentation.ts`, and `frontend-modern/src/utils/aiExplorePresentation.ts`
7. Keep AI chat presentation helpers aligned through `frontend-modern/src/components/AI/Chat/` and the shared `frontend-modern/src/utils/textPresentation.ts`
@@ -217,6 +217,17 @@ product API routes free of maintainer commercial analytics.
runtime-failure boolean needed for drawer/session presentation, and
run-specific fields remain reserved for `patrol_run`.
34. `internal/api/ai_handlers.go` shared with `ai-runtime`: AI settings and remediation handlers are both an AI runtime control surface and a canonical API payload contract boundary.
Provider test responses from `/api/ai/test` and provider-specific
`/api/ai/test/{provider}` preflight responses must return one safe
structured diagnostic envelope: `success`, `message`, optional `model`,
`cause`, `summary`, `recommendation`, and `action`, plus `provider` on the
provider-specific endpoint.
Failure payloads must use the AI runtime's Patrol failure-cause vocabulary
and safe remediation text instead of returning raw upstream provider errors,
while still leaving those raw details available only to server logs or
redacted governed internal Patrol evidence. The frontend API client and
settings shell must treat this payload as the canonical provider health
contract rather than parsing free-form provider error strings.
35. `internal/api/ai_intelligence_handlers.go` shared with `ai-runtime`: AI intelligence handlers are both an AI runtime control surface and a canonical API payload contract boundary.
36. `internal/api/config_setup_handlers.go` shared with `agent-lifecycle`: auto-register and setup handlers are both an agent lifecycle control surface and a canonical API payload contract boundary.
That same shared boundary also owns reachable-host selection truth for canonical Proxmox registration: runtime callers may propose ordered `candidateHosts`, but the API contract must persist and echo the first candidate Pulse can actually reach instead of freezing the caller's rejected first preference into the stored node endpoint.
@@ -732,7 +732,10 @@ frontend primitive boundary.
configuration rather than as a generic `AI Services` shell. Settings-save
feedback must preserve provider-specific preflight failures and successful
save responses that carry Patrol readiness warnings, including the provider,
selected Patrol model, and readiness summary when those fields are present.
selected Patrol model, failure cause, safe recommendation, and readiness
summary when those fields are present. The settings shell may compose that
safe backend diagnostic for display, but it must not infer provider
remediation by parsing raw upstream error strings in the browser.
Runtime controls inside `frontend-modern/src/components/Settings/AIRuntimeControlsSection.tsx`
must likewise describe discovery as workload discovery that supplies
concrete service context to Pulse Assistant and Patrol, not as a generic
@@ -400,7 +400,7 @@ bypass the API fail-closed execution gate.
hosted diagnostics do not collapse into false free-tier behavior.
19. Preserve shipped local security-doc guidance in shared `internal/api/` config/setup helpers so storage- and recovery-adjacent transport surfaces do not reintroduce GitHub `main` security links when the running build already serves its own local security documentation route.
20. Keep shared `internal/api/` Patrol transport and alert-trigger edits feature-isolated: Patrol-specific recency fields, callback fan-out, or alert-bridge wiring changes must not leak into recovery queries, storage links, or recovery-adjacent install/setup flows unless this contract changes in the same slice.
The same adjacency rule applies to AI settings transport in `internal/api/ai_handlers.go`: provider auth state, masked-secret payload fields, and provider-test model selection remain AI/runtime plus API-contract concerns and must not be absorbed into storage/recovery transport ownership just because those handlers live under the shared backend API tree.
The same adjacency rule applies to AI settings transport in `internal/api/ai_handlers.go`: provider auth state, masked-secret payload fields, provider-test model selection, and safe provider preflight diagnostics remain AI/runtime plus API-contract concerns and must not be absorbed into storage/recovery transport ownership just because those handlers live under the shared backend API tree.
Direct alert-investigation execution controls in `internal/api/ai_handlers.go`
follow that same split: request-scoped `AutonomousMode:false` and
`RequireCommandApproval:true` are AI action-governance constraints, not
@@ -2782,6 +2782,12 @@ shared AI/runtime wiring and the poller's provider selection path, but storage
and recovery surfaces must not grow a second recovery-local config transport
or provider-shaped configuration payload just because those reads can inform
operator investigation.
Provider preflight diagnostics returned by shared AI settings handlers are the
same AI runtime readiness context. Storage and recovery surfaces may use the
resulting safe recommendation to direct an operator back to Assistant & Patrol
settings, but they must not reinterpret provider auth, provider connection, or
model-selection causes as recovery-source health, backup readiness, or
storage-control capability.
That bounded projection is the current TrueNAS floor for storage and recovery:
operators can inspect TrueNAS pools, datasets, disks, snapshots, and
replication artifacts through the shared storage and recovery pages plus