@pellux/goodvibes-agent 0.1.117 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176073 -170980
- package/docs/README.md +11 -5
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +29 -15
- package/docs/knowledge-artifacts-and-multimodal.md +91 -0
- package/docs/project-planning.md +79 -0
- package/docs/providers-and-routing.md +46 -0
- package/docs/release-and-publishing.md +44 -9
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +2 -5
- package/src/agent/channel-delivery.ts +201 -0
- package/src/agent/media-generation.ts +159 -0
- package/src/agent/memory-prompt.ts +0 -1
- package/src/agent/note-registry.ts +329 -0
- package/src/agent/operator-actions.ts +343 -0
- package/src/agent/persona-registry.ts +15 -14
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +26 -25
- package/src/agent/routine-registry.ts +13 -12
- package/src/agent/routine-schedule-args.ts +2 -1
- package/src/agent/routine-schedule-format.ts +77 -53
- package/src/agent/routine-schedule-promotion.ts +34 -32
- package/src/agent/routine-schedule-receipts.ts +28 -26
- package/src/agent/runtime-profile-starters.ts +2 -2
- package/src/agent/runtime-profile.ts +18 -17
- package/src/agent/skill-registry.ts +25 -24
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +39 -33
- package/src/cli/agent-knowledge-format.ts +80 -67
- package/src/cli/agent-knowledge-methods.ts +1 -1
- package/src/cli/agent-knowledge-runtime.ts +32 -26
- package/src/cli/bundle-command.ts +13 -8
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +29 -11
- package/src/cli/local-library-command.ts +134 -68
- package/src/cli/management-commands.ts +98 -62
- package/src/cli/management.ts +52 -26
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -24
- package/src/cli/profiles-command.ts +52 -35
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +44 -36
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +46 -121
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-activation.ts +33 -7
- package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
- package/src/input/agent-workspace-basic-command-editors.ts +30 -10
- package/src/input/agent-workspace-categories.ts +276 -64
- package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
- package/src/input/agent-workspace-channel-command-editors.ts +23 -5
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +18 -2
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
- package/src/input/agent-workspace-editors.ts +140 -2
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +2 -2
- package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
- package/src/input/agent-workspace-library-command-editors.ts +2 -2
- package/src/input/agent-workspace-local-operations.ts +218 -0
- package/src/input/agent-workspace-local-selection.ts +75 -0
- package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
- package/src/input/agent-workspace-media-command-editors.ts +27 -0
- package/src/input/agent-workspace-memory-command-editors.ts +1 -1
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +38 -2
- package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
- package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
- package/src/input/agent-workspace-operations-command-editors.ts +80 -3
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
- package/src/input/agent-workspace-search.ts +169 -0
- package/src/input/agent-workspace-setup.ts +22 -11
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
- package/src/input/agent-workspace-snapshot.ts +112 -13
- package/src/input/agent-workspace-task-command-editors.ts +4 -4
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +92 -4
- package/src/input/agent-workspace-voice-media.ts +3 -6
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace.ts +136 -208
- package/src/input/command-registry.ts +4 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +83 -70
- package/src/input/commands/agent-workspace-runtime.ts +23 -7
- package/src/input/commands/brief-runtime.ts +25 -24
- package/src/input/commands/channels-runtime.ts +145 -31
- package/src/input/commands/delegation-runtime.ts +29 -23
- package/src/input/commands/experience-runtime.ts +6 -4
- package/src/input/commands/guidance-runtime.ts +4 -4
- package/src/input/commands/health-runtime.ts +140 -115
- package/src/input/commands/knowledge.ts +57 -56
- package/src/input/commands/local-provider-runtime.ts +36 -18
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +7 -7
- package/src/input/commands/mcp-runtime.ts +56 -35
- package/src/input/commands/notify-runtime.ts +38 -9
- package/src/input/commands/operator-actions-runtime.ts +138 -0
- package/src/input/commands/operator-runtime.ts +6 -17
- package/src/input/commands/personas-runtime.ts +45 -30
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +29 -29
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +45 -6
- package/src/input/commands/recall-bundle.ts +11 -11
- package/src/input/commands/recall-capture.ts +13 -11
- package/src/input/commands/recall-query.ts +29 -21
- package/src/input/commands/recall-review.ts +2 -1
- package/src/input/commands/routines-runtime.ts +59 -43
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +4 -4
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +132 -93
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +32 -17
- package/src/input/commands/subscription-runtime.ts +53 -179
- package/src/input/commands/tasks-runtime.ts +20 -20
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +2 -2
- package/src/input/feed-context-factory.ts +2 -1
- package/src/input/file-picker.ts +3 -2
- package/src/input/handler-command-route.ts +4 -7
- package/src/input/handler-content-actions.ts +89 -1
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -3
- package/src/input/handler-interactions.ts +7 -5
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +24 -80
- package/src/input/handler-shortcuts.ts +15 -4
- package/src/input/handler.ts +47 -17
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +22 -11
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
- package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
- package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
- package/src/input/onboarding/onboarding-wizard.ts +68 -0
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- package/src/input/settings-modal-behavior.ts +0 -3
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +2 -13
- package/src/input/settings-modal.ts +6 -52
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -8
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +2 -2
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +1 -10
- package/src/panels/builtin/session.ts +9 -9
- package/src/panels/builtin/shared.ts +2 -2
- package/src/panels/cost-tracker-panel.ts +1 -1
- package/src/panels/docs-panel.ts +5 -3
- package/src/panels/index.ts +0 -1
- package/src/panels/knowledge-panel.ts +6 -5
- package/src/panels/memory-panel.ts +7 -6
- package/src/panels/panel-list-panel.ts +36 -80
- package/src/panels/project-planning-panel.ts +18 -11
- package/src/panels/provider-account-snapshot.ts +51 -25
- package/src/panels/provider-accounts-panel.ts +33 -18
- package/src/panels/provider-health-domains.ts +45 -4
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +1 -1
- package/src/panels/schedule-panel.ts +9 -17
- package/src/panels/security-panel.ts +8 -8
- package/src/panels/session-browser-panel.ts +10 -10
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +1 -1
- package/src/panels/tasks-panel.ts +20 -13
- package/src/panels/tool-inspector-panel.ts +19 -12
- package/src/panels/work-plan-panel.ts +5 -5
- package/src/planning/project-planning-coordinator.ts +1 -1
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +228 -52
- package/src/renderer/autocomplete-overlay.ts +25 -6
- package/src/renderer/bookmark-modal.ts +19 -4
- package/src/renderer/buffer.ts +4 -2
- package/src/renderer/context-inspector.ts +50 -13
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +19 -6
- package/src/renderer/help-overlay.ts +106 -33
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +164 -50
- package/src/renderer/model-picker-overlay.ts +58 -2
- package/src/renderer/model-workspace.ts +104 -20
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +20 -4
- package/src/renderer/search-overlay.ts +25 -5
- package/src/renderer/selection-modal-overlay.ts +46 -14
- package/src/renderer/session-picker-modal.ts +18 -1
- package/src/renderer/settings-modal-helpers.ts +2 -40
- package/src/renderer/settings-modal.ts +83 -50
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +6 -6
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +9 -7
- package/src/runtime/bootstrap-core.ts +19 -1
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +31 -22
- package/src/runtime/connected-host-auth.ts +7 -2
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -1
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +80 -79
- package/src/runtime/onboarding/derivation.ts +5 -8
- package/src/runtime/onboarding/snapshot.ts +0 -15
- package/src/runtime/onboarding/types.ts +8 -19
- package/src/runtime/onboarding/verify.ts +32 -10
- package/src/runtime/operator-token-cleanup.ts +1 -1
- package/src/runtime/services.ts +91 -22
- package/src/runtime/store/selectors/index.ts +3 -3
- package/src/runtime/store/state.ts +1 -4
- package/src/runtime/surface-feature-flags.ts +41 -6
- package/src/runtime/ui-read-models.ts +3 -4
- package/src/runtime/ui-services.ts +6 -6
- package/src/shell/blocking-input.ts +2 -1
- package/src/shell/ui-openers.ts +3 -13
- package/src/tools/agent-analysis-registry-policy.ts +0 -1
- package/src/tools/agent-channel-send-tool.ts +133 -0
- package/src/tools/agent-context-policy.ts +1 -1
- package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
- package/src/tools/agent-knowledge-tool.ts +170 -0
- package/src/tools/agent-local-registry-tool.ts +269 -69
- package/src/tools/agent-media-generate-tool.ts +133 -0
- package/src/tools/agent-notify-tool.ts +143 -0
- package/src/tools/agent-operator-action-tool.ts +137 -0
- package/src/tools/agent-operator-briefing-tool.ts +217 -0
- package/src/tools/agent-reminder-schedule-tool.ts +237 -0
- package/src/tools/agent-tool-policy-guard.ts +8 -8
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -13
- package/src/panels/panel-picker.ts +0 -105
- package/src/panels/policy-panel.ts +0 -308
- package/src/renderer/panel-picker-overlay.ts +0 -202
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { REASONING_OPTIONS, HITL_MODE_OPTIONS, GUIDANCE_MODE_OPTIONS, PERMISSION_MODE_OPTIONS, SECRET_POLICY_OPTIONS } from './onboarding-wizard-constants.ts';
|
|
2
2
|
import { modelSelectionLabel, normalizeText } from './onboarding-wizard-helpers.ts';
|
|
3
|
-
import { buildAgentKnowledgeStep, buildAutomationStep, buildCommunicationStep, buildDelegationPolicyStep, buildLocalStateStep, buildToolsStep, buildVoiceMediaStep } from './onboarding-wizard-operator-steps.ts';
|
|
3
|
+
import { buildAgentKnowledgeStep, buildAutomationStep, buildCommunicationStep, buildDelegationPolicyStep, buildLocalStateStep, buildResearchStep, buildToolsStep, buildVoiceMediaStep } from './onboarding-wizard-operator-steps.ts';
|
|
4
4
|
import { listAgentRuntimeProfileTemplates } from '../../agent/runtime-profile.ts';
|
|
5
5
|
import type { OnboardingWizardController } from './onboarding-wizard.ts';
|
|
6
6
|
import type { OnboardingWizardActionFieldDefinition, OnboardingWizardFieldDefinition, OnboardingWizardModelPickerFieldDefinition, OnboardingWizardRadioFieldDefinition, OnboardingWizardRadioOption, OnboardingWizardStepDefinition } from './onboarding-wizard-types.ts';
|
|
7
7
|
import type { OnboardingProviderAccountRecord, OnboardingStep1CapabilityId, OnboardingStep1CapabilityItem } from '../../runtime/onboarding/index.ts';
|
|
8
8
|
|
|
9
|
+
const DEFAULT_STARTER_TEMPLATE_ID = 'personal-productivity';
|
|
10
|
+
|
|
11
|
+
function defaultStarterTemplateId(): string {
|
|
12
|
+
const templates = listAgentRuntimeProfileTemplates();
|
|
13
|
+
if (templates.some((template) => template.id === DEFAULT_STARTER_TEMPLATE_ID)) return DEFAULT_STARTER_TEMPLATE_ID;
|
|
14
|
+
return templates[0]?.id ?? 'none';
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
function buildStarterTemplateOptions(): readonly OnboardingWizardRadioOption[] {
|
|
10
18
|
return [
|
|
11
19
|
{
|
|
@@ -30,6 +38,7 @@ export function buildOnboardingWizardSteps(controller: OnboardingWizardControlle
|
|
|
30
38
|
buildDefaultModelStep(controller),
|
|
31
39
|
buildCommunicationStep(),
|
|
32
40
|
buildToolsStep(),
|
|
41
|
+
buildResearchStep(),
|
|
33
42
|
buildAgentKnowledgeStep(),
|
|
34
43
|
buildLocalStateStep(controller.runtimeSnapshot?.localBehaviorDiscovery),
|
|
35
44
|
buildAutomationStep(),
|
|
@@ -139,14 +148,21 @@ function buildReviewReadinessFields(controller: OnboardingWizardController): rea
|
|
|
139
148
|
kind: 'status',
|
|
140
149
|
id: 'review.readiness.knowledge',
|
|
141
150
|
label: 'Agent Knowledge segment',
|
|
142
|
-
hint: 'Ask, search, status, and ingest stay on /api/goodvibes-agent/knowledge/* with no default
|
|
151
|
+
hint: 'Ask, search, status, and ingest stay on /api/goodvibes-agent/knowledge/* with no default knowledge or non-Agent fallback.',
|
|
143
152
|
defaultValue: 'Isolated',
|
|
144
153
|
},
|
|
154
|
+
{
|
|
155
|
+
kind: 'status',
|
|
156
|
+
id: 'review.readiness.research',
|
|
157
|
+
label: 'Research and source triage',
|
|
158
|
+
hint: 'Web research and URL inspection stay in the main conversation; durable source storage requires explicit Agent Knowledge ingest.',
|
|
159
|
+
defaultValue: 'Read-only',
|
|
160
|
+
},
|
|
145
161
|
{
|
|
146
162
|
kind: 'status',
|
|
147
163
|
id: 'review.readiness.local-behavior',
|
|
148
164
|
label: 'Local behavior library',
|
|
149
|
-
hint: localBehavior?.detail ?? 'Agent-local memory, routines, skills, and personas remain local until a stable shared registry exists.',
|
|
165
|
+
hint: localBehavior?.detail ?? 'Agent-local memory, notes, routines, skills, and personas remain local until a stable shared registry exists.',
|
|
150
166
|
defaultValue: localBehavior?.selected ? 'Customized' : 'Starter ready',
|
|
151
167
|
},
|
|
152
168
|
{
|
|
@@ -206,13 +222,13 @@ export function buildAgentSetupStep(controller: OnboardingWizardController): Onb
|
|
|
206
222
|
id: 'agent-setup',
|
|
207
223
|
title: 'Agent setup',
|
|
208
224
|
shortLabel: 'Agent',
|
|
209
|
-
description: 'Set up the Agent operator workspace
|
|
225
|
+
description: 'Set up the Agent operator workspace with local identity, provider access, isolated Agent Knowledge, reusable local behavior, and explicit build delegation.',
|
|
210
226
|
summaryTitle: 'Agent setup posture',
|
|
211
227
|
summaryLines: [
|
|
212
228
|
'Agent owns the operator TUI and local behavior registry.',
|
|
213
229
|
'Optional starter profile: create an isolated Agent home from setup.',
|
|
214
230
|
'Setup here changes only Agent-owned settings and local state.',
|
|
215
|
-
`Secret policy
|
|
231
|
+
`Secret policy ${controller.getStringFieldValue('agent-setup.secret-policy', secretPolicy)}`,
|
|
216
232
|
collectionIssues > 0 ? `${collectionIssues} setup snapshot issue(s)` : 'Setup snapshot collected cleanly',
|
|
217
233
|
],
|
|
218
234
|
fields: [
|
|
@@ -244,7 +260,7 @@ export function buildAgentSetupStep(controller: OnboardingWizardController): Onb
|
|
|
244
260
|
kind: 'text',
|
|
245
261
|
id: 'agent-setup.profile-name',
|
|
246
262
|
label: 'Create starter profile',
|
|
247
|
-
hint: 'Optional
|
|
263
|
+
hint: 'Optional Agent profile name creates an isolated home during setup. Leave blank to keep the current home.',
|
|
248
264
|
placeholder: 'research-desk',
|
|
249
265
|
defaultValue: '',
|
|
250
266
|
},
|
|
@@ -252,23 +268,24 @@ export function buildAgentSetupStep(controller: OnboardingWizardController): Onb
|
|
|
252
268
|
kind: 'radio',
|
|
253
269
|
id: 'agent-setup.profile-template',
|
|
254
270
|
label: 'Starter profile template',
|
|
255
|
-
hint: 'Choose the persona, skills, and routine bundle to seed into the optional new Agent profile.',
|
|
271
|
+
hint: 'Choose the persona, skills, and routine bundle to seed into the optional new Agent profile. Select No profile only when you intentionally want an empty Agent home.',
|
|
256
272
|
options: buildStarterTemplateOptions(),
|
|
257
|
-
defaultValue:
|
|
273
|
+
defaultValue: defaultStarterTemplateId(),
|
|
258
274
|
},
|
|
259
275
|
{
|
|
260
276
|
kind: 'checklist',
|
|
261
277
|
id: 'agent-setup.profile-default',
|
|
262
278
|
label: 'Use created profile by default',
|
|
263
|
-
hint: 'When a starter profile name is provided, make that isolated Agent profile the default for
|
|
279
|
+
hint: 'When a starter profile name is provided, make that isolated Agent profile the default for later plain goodvibes-agent runs.',
|
|
264
280
|
defaultValue: true,
|
|
265
281
|
},
|
|
266
282
|
{
|
|
267
|
-
kind: '
|
|
283
|
+
kind: 'action',
|
|
268
284
|
id: 'agent-setup.profile-guide',
|
|
285
|
+
action: 'open-agent-workspace:profiles',
|
|
269
286
|
label: 'Profile guidance',
|
|
270
|
-
hint: '
|
|
271
|
-
defaultValue: '
|
|
287
|
+
hint: 'Open the Profiles workspace to browse starters, export, customize, import, create, and select isolated Agent profiles.',
|
|
288
|
+
defaultValue: 'Open Profiles',
|
|
272
289
|
},
|
|
273
290
|
],
|
|
274
291
|
};
|
|
@@ -313,8 +330,8 @@ export function buildProviderAccessStep(controller: OnboardingWizardController):
|
|
|
313
330
|
id: 'providers.subscription-sessions',
|
|
314
331
|
label: 'Subscription sessions',
|
|
315
332
|
hint: [
|
|
316
|
-
`active
|
|
317
|
-
`pending
|
|
333
|
+
`active ${formatBoundedList(activeSubscriptionProviders, 'none')}`,
|
|
334
|
+
`pending ${formatBoundedList(pendingSubscriptionProviders, 'none')}`,
|
|
318
335
|
].join(' '),
|
|
319
336
|
defaultValue: `${activeSubscriptions.length} active / ${pendingSubscriptions.length} pending`,
|
|
320
337
|
},
|
|
@@ -330,8 +347,8 @@ export function buildProviderAccessStep(controller: OnboardingWizardController):
|
|
|
330
347
|
id: 'providers.openai-api-key',
|
|
331
348
|
label: 'OpenAI API key quick start',
|
|
332
349
|
hint: openAiApiKeyConfigured
|
|
333
|
-
? 'Optional quick start
|
|
334
|
-
: 'Optional quick start
|
|
350
|
+
? 'Optional quick start already has an OpenAI API key stored. Leave blank to keep it; enter a new key to replace it through the secret manager.'
|
|
351
|
+
: 'Optional quick start can store an OpenAI API key now. Other providers can be configured from the Setup workspace, Tools & MCP workspace, and model picker.',
|
|
335
352
|
placeholder: openAiApiKeyConfigured ? 'already configured' : 'sk-...',
|
|
336
353
|
defaultValue: '',
|
|
337
354
|
},
|
|
@@ -380,10 +397,10 @@ export function buildProviderAccessStep(controller: OnboardingWizardController):
|
|
|
380
397
|
description: 'Review provider and model access for the Agent conversation. Credentials stay masked and provider-specific setup remains configurable.',
|
|
381
398
|
summaryTitle: 'Provider access summary',
|
|
382
399
|
summaryLines: [
|
|
383
|
-
`Default route
|
|
384
|
-
`Provider account routes
|
|
385
|
-
`Subscription sessions
|
|
386
|
-
`Provider credential references
|
|
400
|
+
`Default route ${providerRouteLabel}`,
|
|
401
|
+
`Provider account routes ${configuredAccounts.length}`,
|
|
402
|
+
`Subscription sessions ${activeSubscriptions.length} active / ${pendingSubscriptions.length} pending`,
|
|
403
|
+
`Provider credential references ${providerSecretCount}`,
|
|
387
404
|
],
|
|
388
405
|
fields,
|
|
389
406
|
};
|
|
@@ -419,8 +436,8 @@ export function buildDefaultModelStep(controller: OnboardingWizardController): O
|
|
|
419
436
|
description: 'Choose the default provider, model, and reasoning posture for normal Agent conversation.',
|
|
420
437
|
summaryTitle: 'Default model summary',
|
|
421
438
|
summaryLines: [
|
|
422
|
-
`Main
|
|
423
|
-
`Reasoning
|
|
439
|
+
`Main ${modelSelectionLabel(controller.modelSelectionState.get('main') ?? primarySelectionField.defaultSelection)}`,
|
|
440
|
+
`Reasoning ${controller.getFieldValueLabel(reasoningField)}`,
|
|
424
441
|
],
|
|
425
442
|
fields: [primarySelectionField, reasoningField],
|
|
426
443
|
};
|
|
@@ -434,9 +451,9 @@ export function buildExperienceStep(controller: OnboardingWizardController): Onb
|
|
|
434
451
|
description: 'Tune the Agent conversation style and approval posture for day-to-day operator use.',
|
|
435
452
|
summaryTitle: 'Experience posture',
|
|
436
453
|
summaryLines: [
|
|
437
|
-
`Human-in-the-Loop (HITL)
|
|
438
|
-
`Guidance
|
|
439
|
-
`Permissions
|
|
454
|
+
`Human-in-the-Loop (HITL) ${controller.getStringFieldValue('experience.hitl', controller.runtimeSnapshot?.runtimeDefaults.behavior.hitlMode ?? 'balanced')}`,
|
|
455
|
+
`Guidance ${controller.getStringFieldValue('experience.guidance', controller.runtimeSnapshot?.runtimeDefaults.behavior.guidanceMode ?? 'minimal')}`,
|
|
456
|
+
`Permissions ${controller.getStringFieldValue('experience.permissions', controller.runtimeSnapshot?.runtimeDefaults.permissionsMode ?? 'prompt')}`,
|
|
440
457
|
],
|
|
441
458
|
fields: [
|
|
442
459
|
{
|
|
@@ -500,11 +517,11 @@ export function buildReviewStep(controller: OnboardingWizardController): Onboard
|
|
|
500
517
|
description: 'Review the Agent day-one checklist and apply setup directly from the wizard.',
|
|
501
518
|
summaryTitle: 'Agent day-one readiness',
|
|
502
519
|
summaryLines: [
|
|
503
|
-
`Day-one readiness
|
|
520
|
+
`Day-one readiness ${dayOneReadiness}`,
|
|
504
521
|
unsavedLabel,
|
|
505
522
|
`${controller.buildApplyRequest().operations.length} Agent setting change(s) ready to apply`,
|
|
506
|
-
feedback ? `Last apply
|
|
507
|
-
controller.isEditingTextField() ? `Editing
|
|
523
|
+
feedback ? `Last apply ${feedback.title}` : 'No apply errors reported',
|
|
524
|
+
controller.isEditingTextField() ? `Editing ${controller.editingFieldId}` : 'Ready to apply',
|
|
508
525
|
],
|
|
509
526
|
fields: [
|
|
510
527
|
...feedbackFields,
|
|
@@ -521,7 +538,7 @@ export function buildReviewStep(controller: OnboardingWizardController): Onboard
|
|
|
521
538
|
id: 'review.apply',
|
|
522
539
|
action: 'apply',
|
|
523
540
|
label: 'Apply Agent settings and verify',
|
|
524
|
-
hint: 'Persist Agent-owned settings and verify that setup did not request non-Agent entrypoints, default
|
|
541
|
+
hint: 'Persist Agent-owned settings and verify that setup did not request non-Agent entrypoints, default knowledge access, or non-Agent knowledge setup.',
|
|
525
542
|
defaultValue: 'Ready',
|
|
526
543
|
},
|
|
527
544
|
],
|
|
@@ -17,6 +17,7 @@ export type OnboardingWizardStepId =
|
|
|
17
17
|
| 'agent-communication'
|
|
18
18
|
| 'agent-tools'
|
|
19
19
|
| 'agent-knowledge'
|
|
20
|
+
| 'agent-research'
|
|
20
21
|
| 'agent-local-state'
|
|
21
22
|
| 'agent-automation'
|
|
22
23
|
| 'agent-voice-media'
|
|
@@ -40,7 +41,8 @@ export type OnboardingWizardAction =
|
|
|
40
41
|
| 'apply'
|
|
41
42
|
| 'apply-and-continue'
|
|
42
43
|
| 'start-openai-subscription'
|
|
43
|
-
| 'finish-openai-subscription'
|
|
44
|
+
| 'finish-openai-subscription'
|
|
45
|
+
| `open-agent-workspace:${string}`;
|
|
44
46
|
|
|
45
47
|
export type OnboardingWizardApplyFeedbackSeverity = 'info' | 'warning' | 'error';
|
|
46
48
|
|
|
@@ -621,3 +621,71 @@ export class OnboardingWizardController {
|
|
|
621
621
|
public isFieldDirtyByDefinition(field: OnboardingWizardFieldDefinition): boolean { return isFieldDirtyByDefinitionForController(this, field); }
|
|
622
622
|
public isFieldSatisfied(field: OnboardingWizardFieldDefinition): boolean { return isFieldSatisfiedForController(this, field); }
|
|
623
623
|
}
|
|
624
|
+
|
|
625
|
+
function pushOnboardingPackageText(lines: string[], ...values: readonly (string | undefined)[]): void {
|
|
626
|
+
for (const value of values) {
|
|
627
|
+
const normalized = normalizeText(value);
|
|
628
|
+
if (normalized.length > 0) lines.push(normalized);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
function appendOnboardingFieldPackageText(
|
|
633
|
+
lines: string[],
|
|
634
|
+
wizard: OnboardingWizardController,
|
|
635
|
+
field: OnboardingWizardFieldDefinition,
|
|
636
|
+
): void {
|
|
637
|
+
pushOnboardingPackageText(lines, field.kind, field.id, field.label, field.hint, wizard.getFieldValueLabel(field));
|
|
638
|
+
|
|
639
|
+
if (field.kind === 'text' || field.kind === 'masked') {
|
|
640
|
+
pushOnboardingPackageText(lines, field.placeholder, field.defaultValue);
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (field.kind === 'radio') {
|
|
645
|
+
for (const option of field.options) {
|
|
646
|
+
pushOnboardingPackageText(lines, option.id, option.label, option.hint);
|
|
647
|
+
}
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (field.kind === 'action') {
|
|
652
|
+
pushOnboardingPackageText(lines, field.action, field.defaultValue);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (field.kind === 'acknowledgement') {
|
|
657
|
+
pushOnboardingPackageText(lines, field.reason);
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (field.kind === 'modelPicker') {
|
|
662
|
+
pushOnboardingPackageText(
|
|
663
|
+
lines,
|
|
664
|
+
field.target,
|
|
665
|
+
field.defaultSelection.providerId,
|
|
666
|
+
field.defaultSelection.modelId,
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
export function renderOnboardingWizardPackageText(): string {
|
|
672
|
+
const wizard = new OnboardingWizardController();
|
|
673
|
+
const lines: string[] = ['GoodVibes Agent onboarding wizard'];
|
|
674
|
+
|
|
675
|
+
for (const step of wizard.steps) {
|
|
676
|
+
pushOnboardingPackageText(
|
|
677
|
+
lines,
|
|
678
|
+
step.id,
|
|
679
|
+
step.shortLabel,
|
|
680
|
+
step.title,
|
|
681
|
+
step.description,
|
|
682
|
+
step.summaryTitle,
|
|
683
|
+
...step.summaryLines,
|
|
684
|
+
);
|
|
685
|
+
for (const field of step.fields) {
|
|
686
|
+
appendOnboardingFieldPackageText(lines, wizard, field);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
return lines.join('\n');
|
|
691
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ProfilePickerModal — state management for the
|
|
2
|
+
* ProfilePickerModal — state management for the Agent profile picker modal.
|
|
3
3
|
*
|
|
4
4
|
* Lists profiles from ProfileManager.list(), tracks selected index,
|
|
5
5
|
* and handles load actions.
|
|
@@ -24,20 +24,39 @@ const BEHAVIOR_KEYS: ConfigKey[] = [
|
|
|
24
24
|
'behavior.saveHistory', 'behavior.notifyOnComplete',
|
|
25
25
|
] as const;
|
|
26
26
|
|
|
27
|
+
function configProfileDeletionDisabledMessage(name: string): string {
|
|
28
|
+
return `Config-profile deletion is disabled in Agent for ${name}. Open Agent Workspace -> Profiles for isolated Agent profile homes.`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function configProfileSavingDisabledMessage(name: string): string {
|
|
32
|
+
return `Config-profile saving is disabled in Agent for ${name}. Open Agent Workspace -> Profiles to create isolated Agent homes.`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function renderProfilePickerStatePackageText(): string {
|
|
36
|
+
return [
|
|
37
|
+
'Profile name cannot be empty',
|
|
38
|
+
'Loaded profile',
|
|
39
|
+
'Saved profile',
|
|
40
|
+
'Error',
|
|
41
|
+
configProfileDeletionDisabledMessage('<profile>'),
|
|
42
|
+
configProfileSavingDisabledMessage('<profile>'),
|
|
43
|
+
].join('\n');
|
|
44
|
+
}
|
|
45
|
+
|
|
27
46
|
/**
|
|
28
47
|
* Apply a profile data category to the config manager.
|
|
29
48
|
* Iterates only known/valid keys rather than open-ended Object.entries.
|
|
30
49
|
*/
|
|
31
50
|
function applyProfileCategory(
|
|
32
51
|
cm: ConfigManager,
|
|
33
|
-
data:
|
|
52
|
+
data: object,
|
|
34
53
|
keys: ConfigKey[],
|
|
35
54
|
): void {
|
|
36
55
|
for (const key of keys) {
|
|
37
56
|
const field = key.split('.')[1];
|
|
38
|
-
if (field && Object.
|
|
57
|
+
if (field && Object.hasOwn(data, field)) {
|
|
39
58
|
try {
|
|
40
|
-
cm.setDynamic(key, data
|
|
59
|
+
cm.setDynamic(key, Reflect.get(data, field));
|
|
41
60
|
} catch (e) { logger.debug('applyProfileCategory: key set failed', { key, error: summarizeError(e) }); }
|
|
42
61
|
}
|
|
43
62
|
}
|
|
@@ -114,7 +133,7 @@ export class ProfilePickerModal {
|
|
|
114
133
|
|
|
115
134
|
// Apply display settings using validated key list
|
|
116
135
|
if (data.display) {
|
|
117
|
-
applyProfileCategory(configManager, data.display
|
|
136
|
+
applyProfileCategory(configManager, data.display, DISPLAY_KEYS);
|
|
118
137
|
}
|
|
119
138
|
|
|
120
139
|
// Apply provider settings (model + reasoningEffort only)
|
|
@@ -129,14 +148,14 @@ export class ProfilePickerModal {
|
|
|
129
148
|
|
|
130
149
|
// Apply behavior settings using validated key list
|
|
131
150
|
if (data.behavior) {
|
|
132
|
-
applyProfileCategory(configManager, data.behavior
|
|
151
|
+
applyProfileCategory(configManager, data.behavior, BEHAVIOR_KEYS);
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
configManager.save();
|
|
136
|
-
this.statusMessage = `Loaded profile
|
|
155
|
+
this.statusMessage = `Loaded profile ${profile.name}`;
|
|
137
156
|
return true;
|
|
138
157
|
} catch (e) {
|
|
139
|
-
this.statusMessage = `Error
|
|
158
|
+
this.statusMessage = `Error ${summarizeError(e)}`;
|
|
140
159
|
return false;
|
|
141
160
|
}
|
|
142
161
|
}
|
|
@@ -145,7 +164,7 @@ export class ProfilePickerModal {
|
|
|
145
164
|
const profile = this.getSelected();
|
|
146
165
|
if (!profile) return false;
|
|
147
166
|
this.deleteConfirmationTarget = null;
|
|
148
|
-
this.statusMessage =
|
|
167
|
+
this.statusMessage = configProfileDeletionDisabledMessage(profile.name);
|
|
149
168
|
return false;
|
|
150
169
|
}
|
|
151
170
|
|
|
@@ -158,7 +177,7 @@ export class ProfilePickerModal {
|
|
|
158
177
|
return false;
|
|
159
178
|
}
|
|
160
179
|
void configManager;
|
|
161
|
-
this.statusMessage =
|
|
180
|
+
this.statusMessage = configProfileSavingDisabledMessage(name);
|
|
162
181
|
return false;
|
|
163
182
|
}
|
|
164
183
|
|
|
@@ -182,11 +201,11 @@ export class ProfilePickerModal {
|
|
|
182
201
|
|
|
183
202
|
// Reload list
|
|
184
203
|
this.profiles = this.profileManager.list();
|
|
185
|
-
this.statusMessage = `Saved profile
|
|
204
|
+
this.statusMessage = `Saved profile ${name}`;
|
|
186
205
|
this._clampScroll();
|
|
187
206
|
return true;
|
|
188
207
|
} catch (e) {
|
|
189
|
-
this.statusMessage = `Error
|
|
208
|
+
this.statusMessage = `Error ${summarizeError(e)}`;
|
|
190
209
|
return false;
|
|
191
210
|
}
|
|
192
211
|
}
|
|
@@ -8,6 +8,23 @@
|
|
|
8
8
|
import type { SessionInfo, SessionManager } from '@pellux/goodvibes-sdk/platform/sessions';
|
|
9
9
|
import type { ConversationManager } from '../core/conversation';
|
|
10
10
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
11
|
+
import { readConversationMessageSnapshots } from '../core/conversation-message-snapshot.ts';
|
|
12
|
+
|
|
13
|
+
function sessionLoadedMessage(name: string, messageCount: number): string {
|
|
14
|
+
return `Loaded session ${name} (${messageCount} messages)`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function sessionDeletionCommandRequiredMessage(name: string): string {
|
|
18
|
+
return `Deletion requires an explicit command: /session delete ${name} --yes`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function renderSessionPickerStatePackageText(): string {
|
|
22
|
+
return [
|
|
23
|
+
'Loaded session <session> (<count> messages)',
|
|
24
|
+
'Error',
|
|
25
|
+
sessionDeletionCommandRequiredMessage('<session>'),
|
|
26
|
+
].join('\n');
|
|
27
|
+
}
|
|
11
28
|
|
|
12
29
|
// ---------------------------------------------------------------------------
|
|
13
30
|
// SessionPickerModal
|
|
@@ -78,13 +95,13 @@ export class SessionPickerModal {
|
|
|
78
95
|
try {
|
|
79
96
|
const { meta, messages } = this.sessionManager.load(session.name);
|
|
80
97
|
conversationManager.resetAll();
|
|
81
|
-
conversationManager.fromJSON({ messages: messages
|
|
98
|
+
conversationManager.fromJSON({ messages: readConversationMessageSnapshots(messages) });
|
|
82
99
|
if (meta.title) conversationManager.title = meta.title;
|
|
83
100
|
conversationManager.rebuildHistory();
|
|
84
|
-
this.statusMessage =
|
|
101
|
+
this.statusMessage = sessionLoadedMessage(session.name, messages.length);
|
|
85
102
|
return true;
|
|
86
103
|
} catch (e) {
|
|
87
|
-
this.statusMessage = `Error
|
|
104
|
+
this.statusMessage = `Error ${summarizeError(e)}`;
|
|
88
105
|
return false;
|
|
89
106
|
}
|
|
90
107
|
}
|
|
@@ -93,7 +110,7 @@ export class SessionPickerModal {
|
|
|
93
110
|
const session = this.getSelected();
|
|
94
111
|
if (!session) return false;
|
|
95
112
|
this.deleteConfirmationTarget = null;
|
|
96
|
-
this.statusMessage =
|
|
113
|
+
this.statusMessage = sessionDeletionCommandRequiredMessage(session.name);
|
|
97
114
|
return false;
|
|
98
115
|
}
|
|
99
116
|
|
|
@@ -30,8 +30,5 @@ export function getNumericAdjustmentMeta(setting: ConfigSetting): {
|
|
|
30
30
|
max?: number;
|
|
31
31
|
precision: number;
|
|
32
32
|
} {
|
|
33
|
-
if (setting.key === 'wrfc.scoreThreshold') {
|
|
34
|
-
return { step: 0.1, min: 0, max: 10, precision: 1 };
|
|
35
|
-
}
|
|
36
33
|
return { step: 1, precision: 0 };
|
|
37
34
|
}
|
|
@@ -23,7 +23,7 @@ export function buildSubscriptionEntries(
|
|
|
23
23
|
activeRoute: 'unconfigured',
|
|
24
24
|
authFreshness: 'unconfigured',
|
|
25
25
|
routeReason: 'Built-in subscription adapter is available, but no active subscription session is stored yet.',
|
|
26
|
-
nextActions: [`Open
|
|
26
|
+
nextActions: [`Open Agent Workspace -> Setup -> Start subscription login for ${provider}.`],
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -38,7 +38,7 @@ export function buildSubscriptionEntries(
|
|
|
38
38
|
activeRoute: providers.get(provider)?.activeRoute ?? 'unconfigured',
|
|
39
39
|
authFreshness: providers.get(provider)?.authFreshness ?? 'unconfigured',
|
|
40
40
|
routeReason: providers.get(provider)?.routeReason ?? 'OAuth metadata is configured for this provider.',
|
|
41
|
-
nextActions: providers.get(provider)?.nextActions ?? [`Open
|
|
41
|
+
nextActions: providers.get(provider)?.nextActions ?? [`Open Agent Workspace -> Setup -> Start subscription login for ${provider}.`],
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -51,7 +51,7 @@ export function buildSubscriptionEntries(
|
|
|
51
51
|
activeRoute: 'unconfigured',
|
|
52
52
|
authFreshness: 'pending',
|
|
53
53
|
routeReason: 'OAuth login is pending completion for this provider.',
|
|
54
|
-
nextActions: [`Open
|
|
54
|
+
nextActions: [`Open Agent Workspace -> Setup -> Finish subscription login for ${pending.provider}.`],
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -27,27 +27,16 @@ export type SettingsCategory =
|
|
|
27
27
|
| 'behavior'
|
|
28
28
|
| 'storage'
|
|
29
29
|
| 'permissions'
|
|
30
|
-
| 'orchestration'
|
|
31
|
-
| 'wrfc'
|
|
32
30
|
| 'tools'
|
|
33
31
|
| 'helper'
|
|
34
32
|
| 'tts'
|
|
35
|
-
| 'service'
|
|
36
|
-
| 'controlPlane'
|
|
37
|
-
| 'httpListener'
|
|
38
|
-
| 'web'
|
|
39
|
-
| 'network'
|
|
40
33
|
| 'surfaces'
|
|
41
|
-
| 'batch'
|
|
42
34
|
| 'automation'
|
|
43
|
-
| 'watchers'
|
|
44
|
-
| 'runtime'
|
|
45
35
|
| 'telemetry'
|
|
46
36
|
| 'cache'
|
|
47
37
|
| 'mcp'
|
|
48
38
|
| 'flags'
|
|
49
|
-
| 'release'
|
|
50
|
-
| 'danger';
|
|
39
|
+
| 'release';
|
|
51
40
|
|
|
52
41
|
export type SettingsFocusPane = 'categories' | 'settings';
|
|
53
42
|
|
|
@@ -57,7 +46,7 @@ export const SETTINGS_CATEGORY_GROUPS: ReadonlyArray<{
|
|
|
57
46
|
}> = [
|
|
58
47
|
{ label: 'Agent Experience', categories: ['display', 'ui', 'behavior', 'permissions'] },
|
|
59
48
|
{ label: 'Models and Providers', categories: ['provider', 'subscriptions', 'helper', 'tools', 'tts'] },
|
|
60
|
-
{ label: '
|
|
49
|
+
{ label: 'Agent-local state', categories: ['storage', 'cache', 'telemetry'] },
|
|
61
50
|
{ label: 'Channels and Tools', categories: ['surfaces', 'mcp', 'automation'] },
|
|
62
51
|
{ label: 'Advanced', categories: ['flags', 'release'] },
|
|
63
52
|
];
|
|
@@ -99,12 +99,6 @@ export class SettingsModal {
|
|
|
99
99
|
/** Provider subscription entries (populated when subscriptions tab is active). */
|
|
100
100
|
public subscriptionEntries: SubscriptionEntry[] = [];
|
|
101
101
|
|
|
102
|
-
/**
|
|
103
|
-
* Set after a network-category save that touches controlPlane or httpListener
|
|
104
|
-
* config keys. Renderer reads this to display a transient restart notice.
|
|
105
|
-
* Cleared on next open() or close().
|
|
106
|
-
*/
|
|
107
|
-
public lastSaveTriggeredRestart: 'control-plane' | 'http-listener' | 'web' | null = null;
|
|
108
102
|
public lastSettingEffectMessage: string | null = null;
|
|
109
103
|
|
|
110
104
|
private configManager: ConfigManager | null = null;
|
|
@@ -151,7 +145,6 @@ export class SettingsModal {
|
|
|
151
145
|
this.pendingSettingsPickerAction = null;
|
|
152
146
|
this.mcpAllowAllConfirmationTarget = null;
|
|
153
147
|
this.subscriptionLogoutConfirmationTarget = null;
|
|
154
|
-
this.lastSaveTriggeredRestart = null;
|
|
155
148
|
this.lastSettingEffectMessage = null;
|
|
156
149
|
this.active = true;
|
|
157
150
|
}
|
|
@@ -165,7 +158,6 @@ export class SettingsModal {
|
|
|
165
158
|
this.pendingSettingsPickerAction = null;
|
|
166
159
|
this.mcpAllowAllConfirmationTarget = null;
|
|
167
160
|
this.subscriptionLogoutConfirmationTarget = null;
|
|
168
|
-
this.lastSaveTriggeredRestart = null;
|
|
169
161
|
this.lastSettingEffectMessage = null;
|
|
170
162
|
this.serviceRegistry = null;
|
|
171
163
|
this.secretsManager = null;
|
|
@@ -452,8 +444,9 @@ export class SettingsModal {
|
|
|
452
444
|
/**
|
|
453
445
|
* Toggle the currently selected feature flag.
|
|
454
446
|
*
|
|
455
|
-
* Killed flags cannot be toggled. Non-runtimeToggleable flags
|
|
456
|
-
*
|
|
447
|
+
* Killed flags cannot be toggled. Non-runtimeToggleable flags are saved as
|
|
448
|
+
* overrides for the next Agent launch or owning-host reload; runtimeToggleable
|
|
449
|
+
* flags toggle immediately.
|
|
457
450
|
*/
|
|
458
451
|
toggleSelectedFlag(): void {
|
|
459
452
|
const flagEntry = this.getSelectedFlag();
|
|
@@ -474,7 +467,7 @@ export class SettingsModal {
|
|
|
474
467
|
const { flag } = flagEntry;
|
|
475
468
|
|
|
476
469
|
if (!flag.runtimeToggleable) {
|
|
477
|
-
// Persist to config only
|
|
470
|
+
// Persist to config only; the flag owner applies it on the next run.
|
|
478
471
|
this._persistFlagState(flag.id, newState, flag.defaultState as FlagState);
|
|
479
472
|
flagEntry.state = newState;
|
|
480
473
|
} else {
|
|
@@ -639,9 +632,6 @@ export class SettingsModal {
|
|
|
639
632
|
lockReason: hostOwned ? AGENT_EXTERNAL_HOST_SETTING_LOCK_REASON : resolved?.lockReason,
|
|
640
633
|
};
|
|
641
634
|
if (this.groups.has(cat)) this.groups.get(cat)!.push(entry);
|
|
642
|
-
if ((rawCat === 'controlPlane' || rawCat === 'httpListener' || rawCat === 'web') && this.groups.has('network')) {
|
|
643
|
-
this.groups.get('network')!.push(entry);
|
|
644
|
-
}
|
|
645
635
|
}
|
|
646
636
|
|
|
647
637
|
const uiEntries = this.groups.get('ui');
|
|
@@ -649,8 +639,7 @@ export class SettingsModal {
|
|
|
649
639
|
const uiPriority: Record<string, number> = {
|
|
650
640
|
'ui.systemMessages': 0,
|
|
651
641
|
'ui.operationalMessages': 1,
|
|
652
|
-
'ui.
|
|
653
|
-
'ui.voiceEnabled': 3,
|
|
642
|
+
'ui.voiceEnabled': 2,
|
|
654
643
|
};
|
|
655
644
|
uiEntries.sort((a, b) => (uiPriority[a.setting.key] ?? 99) - (uiPriority[b.setting.key] ?? 99));
|
|
656
645
|
}
|
|
@@ -712,25 +701,7 @@ export class SettingsModal {
|
|
|
712
701
|
/** Returns [] for the flags category (flags use flagEntries instead). */
|
|
713
702
|
private _currentItems(): SettingEntry[] {
|
|
714
703
|
if (this.currentCategory === 'flags' || this.currentCategory === 'mcp' || this.currentCategory === 'subscriptions') return [];
|
|
715
|
-
|
|
716
|
-
if (this.currentCategory === 'network') {
|
|
717
|
-
return items.filter(entry => {
|
|
718
|
-
if (entry.setting.key === 'controlPlane.host') {
|
|
719
|
-
const hostMode = this.configManager?.get('controlPlane.hostMode');
|
|
720
|
-
return hostMode === 'custom';
|
|
721
|
-
}
|
|
722
|
-
if (entry.setting.key === 'httpListener.host') {
|
|
723
|
-
const hostMode = this.configManager?.get('httpListener.hostMode');
|
|
724
|
-
return hostMode === 'custom';
|
|
725
|
-
}
|
|
726
|
-
if (entry.setting.key === 'web.host') {
|
|
727
|
-
const hostMode = this.configManager?.get('web.hostMode');
|
|
728
|
-
return hostMode === 'custom';
|
|
729
|
-
}
|
|
730
|
-
return true;
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
return items;
|
|
704
|
+
return this.groups.get(this.currentCategory) ?? [];
|
|
734
705
|
}
|
|
735
706
|
|
|
736
707
|
private _refreshAllEntries(): void {
|
|
@@ -749,26 +720,9 @@ export class SettingsModal {
|
|
|
749
720
|
this.lastSettingEffectMessage = AGENT_EXTERNAL_HOST_SETTING_LOCK_REASON;
|
|
750
721
|
return;
|
|
751
722
|
}
|
|
752
|
-
// Diff previous value before writing — avoids false restart notices on no-op saves
|
|
753
723
|
const previousValue = this.configManager.get(key);
|
|
754
|
-
const isRestartKey = ['host', 'port', 'hostMode', 'enabled'].includes(key.split('.')[1] ?? '');
|
|
755
724
|
try {
|
|
756
725
|
this.configManager.setDynamic(key, value);
|
|
757
|
-
const rawCat = key.split('.')[0] as string;
|
|
758
|
-
if (rawCat === 'controlPlane') {
|
|
759
|
-
if (isRestartKey && previousValue !== value) {
|
|
760
|
-
this.lastSaveTriggeredRestart = 'control-plane';
|
|
761
|
-
}
|
|
762
|
-
} else if (rawCat === 'httpListener') {
|
|
763
|
-
if (isRestartKey && previousValue !== value) {
|
|
764
|
-
this.lastSaveTriggeredRestart = 'http-listener';
|
|
765
|
-
}
|
|
766
|
-
} else if (rawCat === 'web') {
|
|
767
|
-
if (isRestartKey && previousValue !== value) {
|
|
768
|
-
this.lastSaveTriggeredRestart = 'web';
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
|
|
772
726
|
for (const entries of this.groups.values()) {
|
|
773
727
|
const entry = entries.find((candidate) => candidate.setting.key === key);
|
|
774
728
|
if (entry) {
|