Finish the Assistant & Patrol settings rename to Pulse Intelligence

Commit cc948b022 fixed the Patrol preflight strings that gated keyless
onboarding; this sweeps the rest. Error messages, readiness checks, and
guidance copy that still pointed at the retired Assistant & Patrol
settings page now name the real surfaces: Pulse Intelligence settings
for the area as a whole, and the Provider & Models settings page for
provider-credential guidance, matching the phrasing cc948b022
established. Pinning tests updated in step, including three
ai_handlers_test.go assertions cc948b022 had already left stale.
This commit is contained in:
rcourtman
2026-07-10 12:04:03 +01:00
parent 0db74c7eab
commit 8d07089eb3
17 changed files with 37 additions and 39 deletions
@@ -406,7 +406,7 @@ describe('AgentProfilesAPI', () => {
const mockResponse = { ok: false, status: 503 } as unknown as Response;
vi.mocked(apiFetch).mockResolvedValueOnce(mockResponse);
vi.mocked(assertAPIResponseOKOrThrowStatus).mockRejectedValueOnce(
new Error('Pulse Intelligence is not available. Please check Assistant & Patrol settings.'),
new Error('Pulse Intelligence is not available. Please check Pulse Intelligence settings.'),
);
await expect(AgentProfilesAPI.suggestProfile({ prompt: 'test' })).rejects.toThrow(
@@ -415,7 +415,7 @@ describe('AgentProfilesAPI', () => {
expect(assertAPIResponseOKOrThrowStatus).toHaveBeenCalledWith(
mockResponse,
503,
'Pulse Intelligence is not available. Please check Assistant & Patrol settings.',
'Pulse Intelligence is not available. Please check Pulse Intelligence settings.',
'Failed to get suggestion: 503',
);
});
@@ -431,7 +431,7 @@ describe('AgentProfilesAPI', () => {
expect(assertAPIResponseOKOrThrowStatus).toHaveBeenCalledWith(
mockResponse,
503,
'Pulse Intelligence is not available. Please check Assistant & Patrol settings.',
'Pulse Intelligence is not available. Please check Pulse Intelligence settings.',
'Failed to get suggestion: 500',
);
});
+1 -1
View File
@@ -243,7 +243,7 @@ describe('AIAPI', () => {
cause: 'provider_auth',
summary: 'The provider rejected the configured credentials or account access.',
recommendation:
'Check the API key or provider authentication in Assistant and Patrol settings, then retry.',
'Check the API key or provider authentication on the Provider & Models settings page, then retry.',
action: 'open_provider_settings',
};
apiFetchJSONMock.mockResolvedValueOnce(diagnostic as any);
+1 -1
View File
@@ -378,7 +378,7 @@ export class AgentProfilesAPI {
await assertAPIResponseOKOrThrowStatus(
response,
503,
'Pulse Intelligence is not available. Please check Assistant & Patrol settings.',
'Pulse Intelligence is not available. Please check Pulse Intelligence settings.',
`Failed to get suggestion: ${response.status}`,
);
@@ -110,13 +110,11 @@ const isGenericAISettingsSaveFailure = (error: unknown): boolean => {
const message = error instanceof Error ? error.message.trim().toLowerCase() : '';
if (!message) return true;
return (
message === 'failed to save assistant & patrol settings' ||
message === 'failed to save pulse intelligence settings' ||
message === 'failed to save provider & models settings' ||
message === 'unable to save assistant & patrol settings.' ||
message === 'unable to save assistant & patrol settings' ||
message === 'unable to save provider & models settings.' ||
message === 'unable to save provider & models settings' ||
message.includes('failed to save assistant & patrol settings') ||
message.includes('failed to save pulse intelligence settings') ||
message.includes('failed to save provider & models settings') ||
message.startsWith('request failed with status')
);
+1 -1
View File
@@ -27,7 +27,7 @@ const (
// ControlToolsDisabledMessage is the stable operator guidance returned when a
// caller attempts to run a control-gated Assistant tool while the shared control
// level is read-only or otherwise not allowed to expose control tools.
const ControlToolsDisabledMessage = "Control tools are disabled. Open Assistant & Patrol settings, then set Pulse Assistant Permissions > Control mode to Controlled before using action tools."
const ControlToolsDisabledMessage = "Control tools are disabled. Open Pulse Intelligence settings, then set Pulse Assistant Permissions > Control mode to Controlled before using action tools."
// DefaultApprovalPolicyDescription returns a concise operator-facing
// explanation for a shared approval-policy value.
+1 -1
View File
@@ -32,7 +32,7 @@ func patrolFindingUsesSyntheticRuntimeResource(f *Finding) bool {
func patrolRuntimeFindingManualActionError(action string) error {
return fmt.Errorf(
"Patrol runtime findings cannot be %s manually; fix Patrol provider configuration in Assistant & Patrol settings and rerun Patrol",
"Patrol runtime findings cannot be %s manually; fix Patrol provider configuration in Pulse Intelligence settings and rerun Patrol",
action,
)
}
@@ -112,8 +112,8 @@ func TestPatrolService_DismissFinding_RejectsPatrolRuntimeFinding(t *testing.T)
if got := err.Error(); !strings.Contains(got, "cannot be dismissed manually") {
t.Fatalf("unexpected error: %q", got)
}
if got := err.Error(); !strings.Contains(got, "Assistant & Patrol settings") {
t.Fatalf("dismissal guidance must point to Assistant & Patrol settings: %q", got)
if got := err.Error(); !strings.Contains(got, "Pulse Intelligence settings") {
t.Fatalf("dismissal guidance must point to Pulse Intelligence settings: %q", got)
}
stored := ps.findings.Get("runtime-1")
@@ -143,7 +143,7 @@ func TestPatrolService_RejectManualActionForRuntimeFindingUsesProviderSettingsGu
t.Fatal("expected Patrol runtime finding manual action to be rejected")
}
got := err.Error()
if !strings.Contains(got, "fix Patrol provider configuration in Assistant & Patrol settings") {
if !strings.Contains(got, "fix Patrol provider configuration in Pulse Intelligence settings") {
t.Fatalf("manual action guidance = %q", got)
}
if strings.Contains(got, "AI settings") {
+2 -2
View File
@@ -118,8 +118,8 @@ func (s *Service) RunPatrolToolPreflight(ctx context.Context, providerName, mode
if cfg == nil {
result.Cause = PatrolFailureCauseSettingsPersistence
result.Title = "Pulse Patrol: Assistant & Patrol settings unavailable"
result.Summary = "Assistant & Patrol settings could not be loaded"
result.Title = "Pulse Patrol: Pulse Intelligence settings unavailable"
result.Summary = "Pulse Intelligence settings could not be loaded"
result.Recommendation = "Confirm Pulse settings persistence is healthy, then re-run preflight."
result.DurationMs = time.Since(started).Milliseconds()
s.recordPatrolPreflight(result, time.Now())
+2 -2
View File
@@ -277,10 +277,10 @@ func TestRunPatrolToolPreflight_SettingsUnavailableUsesAssistantPatrolCopy(t *te
if result.Cause != PatrolFailureCauseSettingsPersistence {
t.Fatalf("unexpected cause %q", result.Cause)
}
if result.Title != "Pulse Patrol: Assistant & Patrol settings unavailable" {
if result.Title != "Pulse Patrol: Pulse Intelligence settings unavailable" {
t.Fatalf("unexpected title %q", result.Title)
}
if result.Summary != "Assistant & Patrol settings could not be loaded" {
if result.Summary != "Pulse Intelligence settings could not be loaded" {
t.Fatalf("unexpected summary %q", result.Summary)
}
}
+1 -1
View File
@@ -48,7 +48,7 @@ type PatrolConfigReadiness struct {
func EvaluatePatrolConfigReadiness(cfg *config.AIConfig) PatrolConfigReadiness {
if cfg == nil {
return patrolConfigReadiness("", "", PatrolReadinessNotReady, PatrolFailureCauseSettingsPersistence, "Assistant & Patrol settings could not be loaded from persistence.")
return patrolConfigReadiness("", "", PatrolReadinessNotReady, PatrolFailureCauseSettingsPersistence, "Pulse Intelligence settings could not be loaded from persistence.")
}
if !cfg.Enabled {
return patrolConfigReadiness("", "", PatrolReadinessNotReady, PatrolFailureCauseAssistantDisabled, "Pulse Intelligence is turned off, so Patrol cannot run.")
+1 -1
View File
@@ -145,7 +145,7 @@ func TestEvaluatePatrolConfigReadiness_NilConfigUsesAssistantPatrolSettingsCopy(
if readiness.Cause != PatrolFailureCauseSettingsPersistence {
t.Fatalf("cause = %q, want %q", readiness.Cause, PatrolFailureCauseSettingsPersistence)
}
if readiness.Summary != "Assistant & Patrol settings could not be loaded from persistence." {
if readiness.Summary != "Pulse Intelligence settings could not be loaded from persistence." {
t.Fatalf("summary = %q", readiness.Summary)
}
}
+3 -3
View File
@@ -10,7 +10,7 @@ import (
)
const patrolRuntimeFailureDetailLimit = 2000
const patrolProviderNotConfiguredReason = "Patrol provider not configured - open Assistant & Patrol provider settings, configure a provider, and choose a Patrol model that supports tools"
const patrolProviderNotConfiguredReason = "Patrol provider not configured - open Pulse Intelligence settings, configure a provider, and choose a Patrol model that supports tools"
var patrolRuntimeFailureDetailRedactors = []struct {
pattern *regexp.Regexp
@@ -181,12 +181,12 @@ func ClassifyProviderConnectionFailure(err error) PatrolRuntimeFailureDiagnostic
diagnostic.Title = "Provider authentication issue"
diagnostic.Summary = "Provider authentication issue"
diagnostic.Description = "The provider rejected the configured credentials or account access."
diagnostic.Recommendation = "Check the API key or provider authentication in Assistant and Patrol settings, then retry."
diagnostic.Recommendation = "Check the API key or provider authentication on the Provider & Models settings page, then retry."
case PatrolFailureCauseProviderNotConfigured, PatrolFailureCauseModelNotSelected, PatrolFailureCauseModelProviderUnconfigured, PatrolFailureCauseAssistantDisabled, PatrolFailureCauseSettingsPersistence:
diagnostic.Title = "Provider not ready"
diagnostic.Summary = "Provider not ready"
diagnostic.Description = "Pulse cannot test this provider because the provider runtime is not ready."
diagnostic.Recommendation = "Open Assistant and Patrol provider settings, complete provider configuration, verify the selected model, and retry."
diagnostic.Recommendation = "Open the Provider & Models settings page, complete provider configuration, verify the selected model, and retry."
}
return diagnostic
+1 -1
View File
@@ -1033,7 +1033,7 @@ func (s *Service) patrolConfigFromAIConfig(cfg *config.AIConfig) PatrolConfig {
patrolCfg := DefaultPatrolConfig()
if cfg == nil {
patrolCfg.Enabled = false
patrolCfg.RuntimeBlockedReason = "Assistant & Patrol settings could not be loaded from persistence."
patrolCfg.RuntimeBlockedReason = "Pulse Intelligence settings could not be loaded from persistence."
patrolCfg.RuntimeBlockedCause = PatrolFailureCauseSettingsPersistence
return patrolCfg
}
+1 -1
View File
@@ -317,7 +317,7 @@ func TestToolRegistry_ExecuteControlToolReadOnlyUsesAssistantAndPatrolGuidance(t
require.Len(t, result.Content, 1)
text := result.Content[0].Text
assert.Equal(t, agentcapabilities.ControlToolsDisabledMessage, text)
assert.Contains(t, text, "Assistant & Patrol settings")
assert.Contains(t, text, "Pulse Intelligence settings")
assert.Contains(t, text, "Pulse Assistant Permissions > Control mode")
assert.NotContains(t, text, "Settings > Pulse Assistant")
}
+8 -8
View File
@@ -2571,8 +2571,8 @@ func (h *AISettingsHandler) HandleGetAISettings(w http.ResponseWriter, r *http.R
ctx := r.Context()
settings, err := h.loadAIConfig(ctx)
if err != nil {
log.Error().Err(err).Msg("Failed to load Assistant & Patrol settings")
http.Error(w, "Failed to load Assistant & Patrol settings", http.StatusInternalServerError)
log.Error().Err(err).Msg("Failed to load Pulse Intelligence settings")
http.Error(w, "Failed to load Pulse Intelligence settings", http.StatusInternalServerError)
return
}
@@ -3029,7 +3029,7 @@ func (h *AISettingsHandler) HandleUpdateAISettings(w http.ResponseWriter, r *htt
// Save settings
if err := h.getPersistence(r.Context()).SaveAIConfig(*settings); err != nil {
log.Error().Err(err).Msg("Failed to save AI settings")
writeErrorResponse(w, http.StatusInternalServerError, "ai_settings_save_failed", "Failed to save Assistant & Patrol settings", nil)
writeErrorResponse(w, http.StatusInternalServerError, "ai_settings_save_failed", "Failed to save Pulse Intelligence settings", nil)
return
}
@@ -3257,8 +3257,8 @@ func newAIProviderTestNotConfiguredResponse(provider string) aiProviderTestRespo
Message: "Provider not configured",
Provider: provider,
Cause: string(ai.PatrolFailureCauseProviderNotConfigured),
Summary: "Pulse cannot test this provider because it is not configured for the current Assistant and Patrol settings.",
Recommendation: "Open Assistant and Patrol provider settings, configure the provider credentials or base URL, choose a model, and retry.",
Summary: "Pulse cannot test this provider because it is not configured for the current Pulse Intelligence settings.",
Recommendation: "Open the Provider & Models settings page, configure the provider credentials or base URL, choose a model, and retry.",
Action: "open_provider_settings",
}
}
@@ -4981,7 +4981,7 @@ func (h *AISettingsHandler) HandleOAuthDisconnect(w http.ResponseWriter, r *http
}
settings, err := h.loadAIConfig(r.Context())
if err != nil {
log.Error().Err(err).Msg("Failed to load Assistant & Patrol settings for OAuth disconnect")
log.Error().Err(err).Msg("Failed to load Pulse Intelligence settings for OAuth disconnect")
http.Error(w, "Failed to load settings", http.StatusInternalServerError)
return
}
@@ -5109,10 +5109,10 @@ func (h *AISettingsHandler) buildPatrolReadiness(ctx context.Context, aiService
cfg, err := h.loadAIConfig(ctx)
if err != nil || cfg == nil {
addCheck("settings", patrolReadinessNotReady, ai.PatrolFailureCauseSettingsPersistence, "Settings persistence", "Assistant & Patrol settings could not be loaded from persistence.", "open_provider_settings")
addCheck("settings", patrolReadinessNotReady, ai.PatrolFailureCauseSettingsPersistence, "Settings persistence", "Pulse Intelligence settings could not be loaded from persistence.", "open_provider_settings")
return summarizePatrolReadiness("", "", checks)
}
addCheck("settings", patrolReadinessReady, ai.PatrolFailureCauseNone, "Settings persistence", "Assistant & Patrol settings are readable.", "")
addCheck("settings", patrolReadinessReady, ai.PatrolFailureCauseNone, "Settings persistence", "Pulse Intelligence settings are readable.", "")
if !cfg.Enabled {
addCheck("enabled", patrolReadinessNotReady, ai.PatrolFailureCauseAssistantDisabled, "Assistant enabled", "Pulse Intelligence is turned off, so Patrol cannot run.", "open_provider_settings")
+3 -3
View File
@@ -414,7 +414,7 @@ func TestAISettingsHandler_PatrolReadinessBranches(t *testing.T) {
wantReady: false,
wantCheckID: "enabled",
wantCheck: patrolReadinessNotReady,
wantSummary: "disabled",
wantSummary: "turned off",
configure: func(aiCfg *config.AIConfig) {
aiCfg.Enabled = false
aiCfg.Model = "ollama:llama3"
@@ -1634,7 +1634,7 @@ func TestAISettingsHandler_TestConnection_NoConfig(t *testing.T) {
assert.False(t, resp.Success)
assert.Equal(t, "Provider not ready", resp.Message)
assert.Equal(t, string(ai.PatrolFailureCauseProviderNotConfigured), resp.Cause)
assert.Contains(t, resp.Recommendation, "provider settings")
assert.Contains(t, resp.Recommendation, "Provider & Models settings page")
}
// ========================================
@@ -1728,7 +1728,7 @@ func TestAISettingsHandler_TestProvider_NoAIConfig(t *testing.T) {
assert.Equal(t, "Provider not configured", resp.Message)
assert.Equal(t, "ollama", resp.Provider)
assert.Equal(t, string(ai.PatrolFailureCauseProviderNotConfigured), resp.Cause)
assert.Contains(t, resp.Recommendation, "provider settings")
assert.Contains(t, resp.Recommendation, "Provider & Models settings page")
assert.Equal(t, "open_provider_settings", resp.Action)
}
@@ -51,7 +51,7 @@ const baseSettings = (): MockAISettings => ({
available_models: [],
});
test.describe("Assistant & Patrol settings provider setup", () => {
test.describe("Pulse Intelligence settings provider setup", () => {
test("OpenRouter setup submits credentials without a hardcoded model and renders backend-selected state", async ({
page,
}, testInfo) => {
@@ -355,7 +355,7 @@ test.describe("Assistant & Patrol settings provider setup", () => {
status: 500,
contentType: "application/json",
body: JSON.stringify({
error: "Unable to save Assistant & Patrol settings.",
error: "Failed to save Pulse Intelligence settings",
}),
});
});
@@ -379,7 +379,7 @@ test.describe("Assistant & Patrol settings provider setup", () => {
await expect.poll(() => updateHits).toBe(1);
const failureMessage = page.getByText(
/OpenRouter provider.*Provider authentication issue.*Unable to save Assistant & Patrol settings/i,
/OpenRouter provider.*Provider authentication issue.*Failed to save Pulse Intelligence settings/i,
);
await expect(failureMessage).toBeVisible();
await expect(failureMessage).toContainText(