@pellux/goodvibes-agent 0.1.47 → 0.1.49
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 +18 -10
- package/README.md +3 -23
- package/docs/README.md +0 -2
- package/package.json +1 -3
- package/src/cli/completion.ts +0 -1
- package/src/cli/help.ts +0 -12
- package/src/cli/management.ts +0 -6
- package/src/cli/package-verification.ts +0 -1
- package/src/cli/parser.ts +0 -4
- package/src/cli/types.ts +0 -1
- package/src/input/agent-workspace-channels.ts +214 -0
- package/src/input/agent-workspace-setup.ts +121 -0
- package/src/input/agent-workspace.ts +75 -210
- package/src/input/commands/experience-runtime.ts +2 -25
- package/src/input/commands/remote-runtime.ts +5 -5
- package/src/input/commands.ts +0 -2
- package/src/input/onboarding/onboarding-wizard-steps.ts +7 -7
- package/src/panels/builtin/knowledge.ts +3 -3
- package/src/panels/builtin/shared.ts +3 -0
- package/src/panels/knowledge-panel.ts +80 -9
- package/src/panels/provider-health-domains.ts +1 -1
- package/src/panels/remote-panel.ts +2 -2
- package/src/renderer/agent-workspace.ts +39 -10
- package/src/runtime/bootstrap-core.ts +2 -0
- package/src/runtime/bootstrap-shell.ts +1 -0
- package/src/runtime/bootstrap.ts +1 -0
- package/src/tools/agent-context-policy.ts +2 -2
- package/src/tools/agent-local-registry-tool.ts +341 -0
- package/src/verification/live-verifier.ts +0 -15
- package/src/version.ts +1 -1
- package/docs/operator-capability-benchmark.md +0 -106
- package/src/cli/capabilities-command.ts +0 -173
- package/src/config/goodvibes-home-audit.ts +0 -465
- package/src/input/commands/capabilities-runtime.ts +0 -102
- package/src/operator/capability-benchmark.ts +0 -244
- package/src/operator/daemon-capability-audit.ts +0 -1534
|
@@ -5,18 +5,29 @@ import { AgentPersonaRegistry } from '../agent/persona-registry.ts';
|
|
|
5
5
|
import { AgentRoutineRegistry } from '../agent/routine-registry.ts';
|
|
6
6
|
import { AgentSkillRegistry } from '../agent/skill-registry.ts';
|
|
7
7
|
import { getAgentRuntimeProfilesRoot, listAgentRuntimeProfiles, listAgentRuntimeProfileTemplates } from '../agent/runtime-profile.ts';
|
|
8
|
+
import {
|
|
9
|
+
buildAgentWorkspaceChannels,
|
|
10
|
+
type AgentWorkspaceChannelStatus,
|
|
11
|
+
} from './agent-workspace-channels.ts';
|
|
12
|
+
import {
|
|
13
|
+
buildAgentWorkspaceSetupChecklist,
|
|
14
|
+
type AgentWorkspaceSetupChecklistItem,
|
|
15
|
+
} from './agent-workspace-setup.ts';
|
|
16
|
+
|
|
17
|
+
export type { AgentWorkspaceChannelRisk, AgentWorkspaceChannelStatus } from './agent-workspace-channels.ts';
|
|
8
18
|
|
|
9
19
|
export const AGENT_WORKSPACE_MODAL_NAME = 'agentWorkspace';
|
|
10
20
|
|
|
11
21
|
export type AgentWorkspaceFocusPane = 'categories' | 'actions';
|
|
12
22
|
|
|
13
|
-
export type AgentWorkspaceActionKind = 'command' | 'guidance';
|
|
23
|
+
export type AgentWorkspaceActionKind = 'command' | 'guidance' | 'workspace';
|
|
14
24
|
|
|
15
25
|
export interface AgentWorkspaceAction {
|
|
16
26
|
readonly id: string;
|
|
17
27
|
readonly label: string;
|
|
18
28
|
readonly detail: string;
|
|
19
29
|
readonly command?: string;
|
|
30
|
+
readonly targetCategoryId?: string;
|
|
20
31
|
readonly kind: AgentWorkspaceActionKind;
|
|
21
32
|
readonly safety: 'safe' | 'read-only' | 'delegates' | 'blocked';
|
|
22
33
|
}
|
|
@@ -32,20 +43,6 @@ export interface AgentWorkspaceCategory {
|
|
|
32
43
|
|
|
33
44
|
export type AgentWorkspaceCommandDispatcher = (command: string) => void;
|
|
34
45
|
|
|
35
|
-
export type AgentWorkspaceChannelRisk = 'dm' | 'group' | 'public' | 'webhook' | 'bridge';
|
|
36
|
-
|
|
37
|
-
export interface AgentWorkspaceChannelStatus {
|
|
38
|
-
readonly id: string;
|
|
39
|
-
readonly label: string;
|
|
40
|
-
readonly enabled: boolean;
|
|
41
|
-
readonly ready: boolean;
|
|
42
|
-
readonly missingConfigCount: number;
|
|
43
|
-
readonly defaultTarget: 'configured' | 'missing' | 'not-required';
|
|
44
|
-
readonly delivery: 'disabled' | 'blocked' | 'explicit-target' | 'default-ready';
|
|
45
|
-
readonly risk: AgentWorkspaceChannelRisk;
|
|
46
|
-
readonly riskLabel: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
46
|
export type AgentWorkspaceActionResultKind = 'guidance' | 'blocked' | 'dispatched' | 'refreshed' | 'error';
|
|
50
47
|
|
|
51
48
|
export interface AgentWorkspaceActionResult {
|
|
@@ -100,139 +97,10 @@ export interface AgentWorkspaceRuntimeSnapshot {
|
|
|
100
97
|
readonly runtimeStarterTemplateCount: number;
|
|
101
98
|
readonly localStarterTemplateCount: number;
|
|
102
99
|
readonly configProfileCount: number;
|
|
100
|
+
readonly setupChecklist: readonly AgentWorkspaceSetupChecklistItem[];
|
|
103
101
|
readonly warnings: readonly string[];
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
interface AgentWorkspaceChannelSpec {
|
|
107
|
-
readonly id: string;
|
|
108
|
-
readonly label: string;
|
|
109
|
-
readonly enabledKey: string;
|
|
110
|
-
readonly requiredKeys: readonly string[];
|
|
111
|
-
readonly defaultTargetKeys: readonly string[];
|
|
112
|
-
readonly risk: AgentWorkspaceChannelRisk;
|
|
113
|
-
readonly riskLabel: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const AGENT_WORKSPACE_CHANNEL_SPECS: readonly AgentWorkspaceChannelSpec[] = [
|
|
117
|
-
{
|
|
118
|
-
id: 'slack',
|
|
119
|
-
label: 'Slack',
|
|
120
|
-
enabledKey: 'surfaces.slack.enabled',
|
|
121
|
-
requiredKeys: ['surfaces.slack.botToken', 'surfaces.slack.signingSecret'],
|
|
122
|
-
defaultTargetKeys: ['surfaces.slack.defaultChannel'],
|
|
123
|
-
risk: 'group',
|
|
124
|
-
riskLabel: 'workspace/group channel',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
id: 'discord',
|
|
128
|
-
label: 'Discord',
|
|
129
|
-
enabledKey: 'surfaces.discord.enabled',
|
|
130
|
-
requiredKeys: ['surfaces.discord.botToken', 'surfaces.discord.publicKey', 'surfaces.discord.applicationId'],
|
|
131
|
-
defaultTargetKeys: ['surfaces.discord.defaultChannelId'],
|
|
132
|
-
risk: 'group',
|
|
133
|
-
riskLabel: 'server/channel delivery',
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
id: 'telegram',
|
|
137
|
-
label: 'Telegram',
|
|
138
|
-
enabledKey: 'surfaces.telegram.enabled',
|
|
139
|
-
requiredKeys: ['surfaces.telegram.botToken'],
|
|
140
|
-
defaultTargetKeys: ['surfaces.telegram.defaultChatId'],
|
|
141
|
-
risk: 'dm',
|
|
142
|
-
riskLabel: 'bot DM/group delivery',
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
id: 'ntfy',
|
|
146
|
-
label: 'ntfy',
|
|
147
|
-
enabledKey: 'surfaces.ntfy.enabled',
|
|
148
|
-
requiredKeys: ['surfaces.ntfy.baseUrl', 'surfaces.ntfy.chatTopic', 'surfaces.ntfy.agentTopic'],
|
|
149
|
-
defaultTargetKeys: ['surfaces.ntfy.topic'],
|
|
150
|
-
risk: 'public',
|
|
151
|
-
riskLabel: 'topic-based public/private feed',
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
id: 'googleChat',
|
|
155
|
-
label: 'Google Chat',
|
|
156
|
-
enabledKey: 'surfaces.googleChat.enabled',
|
|
157
|
-
requiredKeys: ['surfaces.googleChat.webhookUrl', 'surfaces.googleChat.verificationToken'],
|
|
158
|
-
defaultTargetKeys: ['surfaces.googleChat.spaceId'],
|
|
159
|
-
risk: 'group',
|
|
160
|
-
riskLabel: 'space delivery',
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
id: 'signal',
|
|
164
|
-
label: 'Signal',
|
|
165
|
-
enabledKey: 'surfaces.signal.enabled',
|
|
166
|
-
requiredKeys: ['surfaces.signal.bridgeUrl', 'surfaces.signal.account'],
|
|
167
|
-
defaultTargetKeys: ['surfaces.signal.defaultRecipient'],
|
|
168
|
-
risk: 'bridge',
|
|
169
|
-
riskLabel: 'private bridge delivery',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
id: 'whatsapp',
|
|
173
|
-
label: 'WhatsApp',
|
|
174
|
-
enabledKey: 'surfaces.whatsapp.enabled',
|
|
175
|
-
requiredKeys: ['surfaces.whatsapp.accessToken', 'surfaces.whatsapp.verifyToken', 'surfaces.whatsapp.phoneNumberId'],
|
|
176
|
-
defaultTargetKeys: ['surfaces.whatsapp.defaultRecipient'],
|
|
177
|
-
risk: 'dm',
|
|
178
|
-
riskLabel: 'phone-number delivery',
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
id: 'imessage',
|
|
182
|
-
label: 'iMessage',
|
|
183
|
-
enabledKey: 'surfaces.imessage.enabled',
|
|
184
|
-
requiredKeys: ['surfaces.imessage.bridgeUrl', 'surfaces.imessage.account'],
|
|
185
|
-
defaultTargetKeys: ['surfaces.imessage.defaultChatId'],
|
|
186
|
-
risk: 'bridge',
|
|
187
|
-
riskLabel: 'Apple bridge delivery',
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
id: 'bluebubbles',
|
|
191
|
-
label: 'BlueBubbles',
|
|
192
|
-
enabledKey: 'surfaces.bluebubbles.enabled',
|
|
193
|
-
requiredKeys: ['surfaces.bluebubbles.serverUrl', 'surfaces.bluebubbles.password'],
|
|
194
|
-
defaultTargetKeys: ['surfaces.bluebubbles.defaultChatGuid'],
|
|
195
|
-
risk: 'bridge',
|
|
196
|
-
riskLabel: 'iMessage bridge delivery',
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
id: 'msteams',
|
|
200
|
-
label: 'Microsoft Teams',
|
|
201
|
-
enabledKey: 'surfaces.msteams.enabled',
|
|
202
|
-
requiredKeys: ['surfaces.msteams.appId', 'surfaces.msteams.appPassword'],
|
|
203
|
-
defaultTargetKeys: ['surfaces.msteams.defaultConversationId', 'surfaces.msteams.defaultChannelId'],
|
|
204
|
-
risk: 'group',
|
|
205
|
-
riskLabel: 'tenant/channel delivery',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
id: 'mattermost',
|
|
209
|
-
label: 'Mattermost',
|
|
210
|
-
enabledKey: 'surfaces.mattermost.enabled',
|
|
211
|
-
requiredKeys: ['surfaces.mattermost.baseUrl', 'surfaces.mattermost.botToken'],
|
|
212
|
-
defaultTargetKeys: ['surfaces.mattermost.defaultChannelId'],
|
|
213
|
-
risk: 'group',
|
|
214
|
-
riskLabel: 'team/channel delivery',
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
id: 'matrix',
|
|
218
|
-
label: 'Matrix',
|
|
219
|
-
enabledKey: 'surfaces.matrix.enabled',
|
|
220
|
-
requiredKeys: ['surfaces.matrix.homeserverUrl', 'surfaces.matrix.accessToken'],
|
|
221
|
-
defaultTargetKeys: ['surfaces.matrix.defaultRoomId'],
|
|
222
|
-
risk: 'group',
|
|
223
|
-
riskLabel: 'room delivery',
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
id: 'webhook',
|
|
227
|
-
label: 'Webhook',
|
|
228
|
-
enabledKey: 'surfaces.webhook.enabled',
|
|
229
|
-
requiredKeys: ['surfaces.webhook.defaultTarget'],
|
|
230
|
-
defaultTargetKeys: ['surfaces.webhook.defaultTarget'],
|
|
231
|
-
risk: 'webhook',
|
|
232
|
-
riskLabel: 'external HTTP delivery',
|
|
233
|
-
},
|
|
234
|
-
];
|
|
235
|
-
|
|
236
104
|
function readConfigString(context: CommandContext, key: string, fallback: string): string {
|
|
237
105
|
try {
|
|
238
106
|
const configManager = context.platform?.configManager as unknown as AgentWorkspaceConfigReader | undefined;
|
|
@@ -270,48 +138,6 @@ function readConfigBoolean(context: CommandContext, key: string, fallback: boole
|
|
|
270
138
|
}
|
|
271
139
|
}
|
|
272
140
|
|
|
273
|
-
function hasConfigValue(context: CommandContext, key: string): boolean {
|
|
274
|
-
try {
|
|
275
|
-
const configManager = context.platform?.configManager as unknown as AgentWorkspaceConfigReader | undefined;
|
|
276
|
-
const value = configManager?.get(key);
|
|
277
|
-
if (typeof value === 'string') return value.trim().length > 0;
|
|
278
|
-
if (typeof value === 'number') return Number.isFinite(value);
|
|
279
|
-
if (typeof value === 'boolean') return value;
|
|
280
|
-
return value !== null && value !== undefined;
|
|
281
|
-
} catch {
|
|
282
|
-
return false;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function buildChannelStatus(context: CommandContext, spec: AgentWorkspaceChannelSpec): AgentWorkspaceChannelStatus {
|
|
287
|
-
const enabled = readConfigBoolean(context, spec.enabledKey, false);
|
|
288
|
-
const missingConfigCount = spec.requiredKeys.filter((key) => !hasConfigValue(context, key)).length;
|
|
289
|
-
const defaultTarget = spec.defaultTargetKeys.length === 0
|
|
290
|
-
? 'not-required'
|
|
291
|
-
: spec.defaultTargetKeys.some((key) => hasConfigValue(context, key))
|
|
292
|
-
? 'configured'
|
|
293
|
-
: 'missing';
|
|
294
|
-
const ready = enabled && missingConfigCount === 0;
|
|
295
|
-
const delivery = !enabled
|
|
296
|
-
? 'disabled'
|
|
297
|
-
: !ready
|
|
298
|
-
? 'blocked'
|
|
299
|
-
: defaultTarget === 'configured'
|
|
300
|
-
? 'default-ready'
|
|
301
|
-
: 'explicit-target';
|
|
302
|
-
return {
|
|
303
|
-
id: spec.id,
|
|
304
|
-
label: spec.label,
|
|
305
|
-
enabled,
|
|
306
|
-
ready,
|
|
307
|
-
missingConfigCount,
|
|
308
|
-
defaultTarget,
|
|
309
|
-
delivery,
|
|
310
|
-
risk: spec.risk,
|
|
311
|
-
riskLabel: spec.riskLabel,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
141
|
function inferActiveRuntimeProfile(homeDirectory: string): string {
|
|
316
142
|
const marker = `${sep}.goodvibes${sep}agent${sep}profile-homes${sep}`;
|
|
317
143
|
return homeDirectory.includes(marker) ? basename(homeDirectory) : '(default home)';
|
|
@@ -408,6 +234,24 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
408
234
|
const ttsVoice = readConfigString(context, 'tts.voice', '(voice default)');
|
|
409
235
|
const ttsLlmProvider = readConfigString(context, 'tts.llmProvider', '');
|
|
410
236
|
const ttsLlmModel = readConfigString(context, 'tts.llmModel', '');
|
|
237
|
+
const daemonBaseUrl = `http://${host}:${port}`;
|
|
238
|
+
const channels = buildAgentWorkspaceChannels(context);
|
|
239
|
+
const setupChecklist = buildAgentWorkspaceSetupChecklist({
|
|
240
|
+
provider,
|
|
241
|
+
model,
|
|
242
|
+
daemonBaseUrl,
|
|
243
|
+
sessionMemoryCount,
|
|
244
|
+
routineCount: routineSnapshot.count,
|
|
245
|
+
enabledRoutineCount: routineSnapshot.enabled,
|
|
246
|
+
skillCount: skillSnapshot.count,
|
|
247
|
+
enabledSkillCount: skillSnapshot.enabled,
|
|
248
|
+
activePersonaName: personaSnapshot.activeName,
|
|
249
|
+
readyChannelCount: channels.filter((channel) => channel.ready).length,
|
|
250
|
+
voiceProviderCount: voiceProviders.length,
|
|
251
|
+
mediaProviderCount: mediaProviders.length,
|
|
252
|
+
runtimeProfileCount: runtimeProfiles.length,
|
|
253
|
+
runtimeStarterTemplateCount: runtimeStarterTemplates.length,
|
|
254
|
+
});
|
|
411
255
|
|
|
412
256
|
return {
|
|
413
257
|
provider,
|
|
@@ -416,7 +260,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
416
260
|
sessionId: context.session?.runtime?.sessionId ?? 'unknown',
|
|
417
261
|
workingDirectory: context.workspace?.shellPaths?.workingDirectory ?? 'unavailable',
|
|
418
262
|
homeDirectory: context.workspace?.shellPaths?.homeDirectory ?? 'unavailable',
|
|
419
|
-
daemonBaseUrl
|
|
263
|
+
daemonBaseUrl,
|
|
420
264
|
daemonOwnership: 'external',
|
|
421
265
|
sessionMemoryCount,
|
|
422
266
|
localRoutineCount: routineSnapshot.count,
|
|
@@ -429,7 +273,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
429
273
|
knowledgeIsolation: 'agent-only',
|
|
430
274
|
executionPolicy: 'serial-proactive',
|
|
431
275
|
wrfcPolicy: 'explicit-build-delegation-only',
|
|
432
|
-
channels
|
|
276
|
+
channels,
|
|
433
277
|
voiceProviderCount: voiceProviders.length,
|
|
434
278
|
voiceStreamingProviderCount: voiceProviders.filter((entry) => entry.capabilities.includes('tts-stream')).length,
|
|
435
279
|
voiceSttProviderCount: voiceProviders.filter((entry) => entry.capabilities.includes('stt')).length,
|
|
@@ -449,6 +293,7 @@ export function buildAgentWorkspaceRuntimeSnapshot(context: CommandContext): Age
|
|
|
449
293
|
runtimeStarterTemplateCount: runtimeStarterTemplates.length,
|
|
450
294
|
localStarterTemplateCount: runtimeStarterTemplates.filter((template) => template.source === 'local').length,
|
|
451
295
|
configProfileCount,
|
|
296
|
+
setupChecklist,
|
|
452
297
|
warnings,
|
|
453
298
|
};
|
|
454
299
|
}
|
|
@@ -463,6 +308,11 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
463
308
|
actions: [
|
|
464
309
|
{ id: 'chat', label: 'Continue assistant chat', detail: 'Close this workspace and type a normal message. Agent work stays serial in the main conversation.', kind: 'guidance', safety: 'safe' },
|
|
465
310
|
{ id: 'model', label: 'Choose model', detail: 'Open the model/provider workspace for the Agent chat route.', command: '/model', kind: 'command', safety: 'safe' },
|
|
311
|
+
{ id: 'setup-home', label: 'Setup checklist', detail: 'Jump to the first-run checklist for provider, knowledge, personas, skills, routines, memory, channels, and voice/media.', targetCategoryId: 'setup', kind: 'workspace', safety: 'safe' },
|
|
312
|
+
{ id: 'knowledge-home', label: 'Agent Knowledge', detail: 'Jump to isolated Agent Knowledge status, ingest, search, and review flows.', targetCategoryId: 'knowledge', kind: 'workspace', safety: 'read-only' },
|
|
313
|
+
{ id: 'memory-home', label: 'Memory, skills, routines', detail: 'Jump to local memory, persona, skill, and routine setup. These are core Agent product features.', targetCategoryId: 'memory', kind: 'workspace', safety: 'safe' },
|
|
314
|
+
{ id: 'channels-home', label: 'Channels', detail: 'Jump to companion pairing and channel readiness without changing daemon lifecycle.', targetCategoryId: 'channels', kind: 'workspace', safety: 'read-only' },
|
|
315
|
+
{ id: 'voice-home', label: 'Voice and media', detail: 'Jump to voice, TTS, image input, browser, and node posture setup.', targetCategoryId: 'voice-media', kind: 'workspace', safety: 'safe' },
|
|
466
316
|
{ id: 'help', label: 'Browse commands', detail: 'Open registry-driven command help.', command: '/help', kind: 'command', safety: 'safe' },
|
|
467
317
|
{ id: 'health', label: 'Review health', detail: 'Show the local health review surface without starting or mutating daemon services.', command: '/health review', kind: 'command', safety: 'read-only' },
|
|
468
318
|
],
|
|
@@ -476,28 +326,19 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
476
326
|
actions: [
|
|
477
327
|
{ id: 'config', label: 'Open config workspace', detail: 'Use the TUI-derived fullscreen settings workspace.', command: '/config', kind: 'command', safety: 'safe' },
|
|
478
328
|
{ id: 'onboarding', label: 'Open setup wizard', detail: 'Review Agent runtime settings in the fullscreen setup flow.', command: '/onboarding', kind: 'command', safety: 'safe' },
|
|
329
|
+
{ id: 'setup-provider-model', label: 'Provider and model', detail: 'Choose the provider/model route for normal assistant chat.', command: '/model', kind: 'command', safety: 'safe' },
|
|
330
|
+
{ id: 'setup-agent-knowledge', label: 'Agent Knowledge', detail: 'Inspect the isolated Agent Knowledge store before ingesting source-backed material.', command: '/knowledge status', kind: 'command', safety: 'read-only' },
|
|
331
|
+
{ id: 'setup-runtime-profiles', label: 'Runtime profiles', detail: 'Browse starter templates for isolated Agent homes and operator identities.', command: '/agent-profile templates', kind: 'command', safety: 'read-only' },
|
|
332
|
+
{ id: 'setup-personas', label: 'Personas', detail: 'Create or select the active local Agent persona.', command: '/personas', kind: 'command', safety: 'safe' },
|
|
333
|
+
{ id: 'setup-skills', label: 'Skills', detail: 'Create, review, and enable reusable local Agent skills.', command: '/agent-skills', kind: 'command', safety: 'safe' },
|
|
334
|
+
{ id: 'setup-routines', label: 'Routines', detail: 'Create, review, and enable local Agent routines before any explicit schedule promotion.', command: '/routines', kind: 'command', safety: 'safe' },
|
|
335
|
+
{ id: 'setup-memory', label: 'Local memory', detail: 'Inspect local/session memory; secrets stay rejected or redacted.', command: '/memory', kind: 'command', safety: 'read-only' },
|
|
336
|
+
{ id: 'setup-channels', label: 'Channels', detail: 'Open companion pairing and channel readiness setup.', command: '/pair', kind: 'command', safety: 'safe' },
|
|
337
|
+
{ id: 'setup-voice-media', label: 'Voice and media', detail: 'Open TTS/media settings for voice and image-capable Agent flows.', command: '/config tts', kind: 'command', safety: 'safe' },
|
|
479
338
|
{ id: 'provider', label: 'Provider status', detail: 'Review provider/model posture.', command: '/provider', kind: 'command', safety: 'read-only' },
|
|
480
339
|
{ id: 'auth', label: 'Auth review', detail: 'Review authentication posture without printing token values.', command: '/auth review', kind: 'command', safety: 'read-only' },
|
|
481
340
|
],
|
|
482
341
|
},
|
|
483
|
-
{
|
|
484
|
-
id: 'capabilities',
|
|
485
|
-
group: 'SETUP',
|
|
486
|
-
label: 'Capabilities',
|
|
487
|
-
summary: 'OpenClaw/Hermes benchmark and live daemon coverage.',
|
|
488
|
-
detail: 'Use this area to measure both layers: what GoodVibes Agent makes usable, and what the externally owned GoodVibes daemon actually exposes through public routes. Agent Knowledge is checked only through /api/goodvibes-agent/knowledge/*.',
|
|
489
|
-
actions: [
|
|
490
|
-
{ id: 'capabilities-benchmark', label: 'Benchmark report', detail: 'Show the OpenClaw/Hermes parity benchmark with Agent posture, setup commands, usage paths, and remaining product gaps.', command: '/capabilities', kind: 'command', safety: 'read-only' },
|
|
491
|
-
{ id: 'capabilities-daemon', label: 'Live daemon audit', detail: 'Inspect the public daemon method catalog plus isolated Agent Knowledge route coverage. Does not query default Knowledge/Wiki or HomeGraph.', command: '/capabilities daemon', kind: 'command', safety: 'read-only' },
|
|
492
|
-
{ id: 'capabilities-daemon-gaps', label: 'Daemon gap plan', detail: 'Classify live daemon coverage into platform gaps, Agent route gaps, route-risk reviews, and Agent UX work without querying default Knowledge/Wiki or HomeGraph.', command: '/capabilities daemon gaps', kind: 'command', safety: 'read-only' },
|
|
493
|
-
{ id: 'capabilities-daemon-risk', label: 'Route risk review', detail: 'Inspect daemon read-only, mutating, dangerous, and authenticated route metadata for approval-center planning.', command: '/capabilities daemon risk', kind: 'command', safety: 'read-only' },
|
|
494
|
-
{ id: 'capabilities-daemon-inventory', label: 'Full method inventory', detail: 'List every public daemon method by category, HTTP posture, access, and dangerous flag without querying default Knowledge/Wiki or HomeGraph.', command: '/capabilities daemon inventory', kind: 'command', safety: 'read-only' },
|
|
495
|
-
{ id: 'capabilities-daemon-coverage', label: 'UX coverage matrix', detail: 'Map every public daemon method to Agent UX coverage: usable, read-only, explicit confirmation, blocked, or not surfaced.', command: '/capabilities daemon coverage', kind: 'command', safety: 'read-only' },
|
|
496
|
-
{ id: 'capabilities-daemon-knowledge', label: 'Knowledge coverage', detail: 'Filter the live daemon audit to the isolated Agent Knowledge segment.', command: '/capabilities daemon knowledge', kind: 'command', safety: 'read-only' },
|
|
497
|
-
{ id: 'capabilities-daemon-channels', label: 'Channel coverage', detail: 'Filter the live daemon audit to channel and delivery gateway route coverage.', command: '/capabilities daemon channels', kind: 'command', safety: 'read-only' },
|
|
498
|
-
{ id: 'capabilities-daemon-automation', label: 'Automation coverage', detail: 'Filter the live daemon audit to automation, schedule, run, and capacity route coverage.', command: '/capabilities daemon automation', kind: 'command', safety: 'read-only' },
|
|
499
|
-
],
|
|
500
|
-
},
|
|
501
342
|
{
|
|
502
343
|
id: 'channels',
|
|
503
344
|
group: 'SETUP',
|
|
@@ -532,7 +373,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
532
373
|
group: 'SETUP',
|
|
533
374
|
label: 'Voice, Media & Nodes',
|
|
534
375
|
summary: 'Voice, TTS, image input, browser surface, and node/remote posture.',
|
|
535
|
-
detail: '
|
|
376
|
+
detail: 'Voice, media, browser, and node surfaces are first-class operator surfaces. Agent uses the GoodVibes voice/media/provider/browser/remote bones while keeping daemon ownership external and side effects explicit.',
|
|
536
377
|
actions: [
|
|
537
378
|
{ id: 'tts-config', label: 'Configure live TTS', detail: 'Open the TUI-derived config workspace at the TTS settings group.', command: '/config tts', kind: 'command', safety: 'safe' },
|
|
538
379
|
{ id: 'tts-provider', label: 'Choose TTS provider', detail: 'Open provider/model routing for spoken responses through the settings flow.', command: '/config tts.provider', kind: 'command', safety: 'safe' },
|
|
@@ -548,7 +389,7 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
548
389
|
group: 'SETUP',
|
|
549
390
|
label: 'Profiles & Portability',
|
|
550
391
|
summary: 'Isolated Agent homes, config profiles, and setup bundles.',
|
|
551
|
-
detail: '
|
|
392
|
+
detail: 'Profiles isolate agent state. GoodVibes Agent exposes named runtime homes, config profile pickers, profile-sync bundles, setup transfer bundles, and support bundles while keeping the daemon external.',
|
|
552
393
|
actions: [
|
|
553
394
|
{ id: 'profiles-open', label: 'Open config profiles', detail: 'Open the TUI-derived config profile picker for display/provider/behavior profile files.', command: '/profiles', kind: 'command', safety: 'safe' },
|
|
554
395
|
{ id: 'runtime-profile-guide', label: 'Starter authoring guide', detail: 'Open the Agent-local starter authoring flow inside the TUI command surface.', command: '/agent-profile guide', kind: 'command', safety: 'safe' },
|
|
@@ -584,7 +425,6 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
|
|
|
584
425
|
{ id: 'workplan', label: 'Open work plan', detail: 'Open the workspace-scoped work plan panel.', command: '/workplan panel', kind: 'command', safety: 'read-only' },
|
|
585
426
|
{ id: 'workplan-list', label: 'List work plan', detail: 'Print a concise work plan summary.', command: '/workplan list', kind: 'command', safety: 'read-only' },
|
|
586
427
|
{ id: 'approvals', label: 'Review approvals', detail: 'Open/read approval posture. This workspace does not approve or deny requests.', command: '/approval open', kind: 'command', safety: 'read-only' },
|
|
587
|
-
{ id: 'approval-risk', label: 'Route risk review', detail: 'Inspect daemon route risk and dangerous method metadata without approving, denying, or mutating requests.', command: '/approval risk', kind: 'command', safety: 'read-only' },
|
|
588
428
|
],
|
|
589
429
|
},
|
|
590
430
|
{
|
|
@@ -741,6 +581,31 @@ export class AgentWorkspace {
|
|
|
741
581
|
const action = this.selectedAction;
|
|
742
582
|
if (!action) return;
|
|
743
583
|
if (action.kind === 'guidance' || !action.command) {
|
|
584
|
+
if (action.kind === 'workspace' && action.targetCategoryId) {
|
|
585
|
+
const targetIndex = this.categories.findIndex((category) => category.id === action.targetCategoryId);
|
|
586
|
+
if (targetIndex >= 0) {
|
|
587
|
+
this.selectedCategoryIndex = targetIndex;
|
|
588
|
+
this.selectedActionIndex = 0;
|
|
589
|
+
this.focusActions();
|
|
590
|
+
this.status = `Opened ${this.selectedCategory.label}.`;
|
|
591
|
+
this.lastActionResult = {
|
|
592
|
+
kind: 'refreshed',
|
|
593
|
+
title: `Opened ${this.selectedCategory.label}`,
|
|
594
|
+
detail: action.detail,
|
|
595
|
+
safety: action.safety,
|
|
596
|
+
};
|
|
597
|
+
this.clampSelection();
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
this.status = `Workspace area unavailable: ${action.targetCategoryId}.`;
|
|
601
|
+
this.lastActionResult = {
|
|
602
|
+
kind: 'error',
|
|
603
|
+
title: 'Workspace area unavailable',
|
|
604
|
+
detail: `No Agent workspace category exists for ${action.targetCategoryId}.`,
|
|
605
|
+
safety: action.safety,
|
|
606
|
+
};
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
744
609
|
this.status = action.detail;
|
|
745
610
|
this.lastActionResult = {
|
|
746
611
|
kind: 'guidance',
|
|
@@ -4,13 +4,6 @@ import type { CommandRegistry } from '../command-registry.ts';
|
|
|
4
4
|
import { requirePanelManager, requireShellPaths } from './runtime-services.ts';
|
|
5
5
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
6
6
|
import { resolveAgentDaemonConnection } from '../../agent/routine-schedule-promotion.ts';
|
|
7
|
-
import {
|
|
8
|
-
buildDaemonCapabilityRouteRiskReport,
|
|
9
|
-
fetchLiveDaemonCapabilityAudit,
|
|
10
|
-
filterDaemonCapabilityRouteRiskAreas,
|
|
11
|
-
renderDaemonCapabilityFailure,
|
|
12
|
-
renderDaemonCapabilityRouteRisk,
|
|
13
|
-
} from '../../operator/daemon-capability-audit.ts';
|
|
14
7
|
|
|
15
8
|
interface VoiceBundle {
|
|
16
9
|
readonly version: 1;
|
|
@@ -186,7 +179,7 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
|
|
|
186
179
|
name: 'approval',
|
|
187
180
|
aliases: ['approvals'],
|
|
188
181
|
description: 'Review action-specific approval classes and the specialized security UX matrix',
|
|
189
|
-
usage: '[matrix|
|
|
182
|
+
usage: '[matrix|review <kind>]',
|
|
190
183
|
async handler(args, ctx) {
|
|
191
184
|
const sub = (args[0] ?? 'matrix').toLowerCase();
|
|
192
185
|
if (sub === 'open' || sub === 'panel') {
|
|
@@ -213,25 +206,9 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
|
|
|
213
206
|
ctx.print([
|
|
214
207
|
'Approval Matrix',
|
|
215
208
|
...matrix.map(([kind, summary]) => ` ${kind.padEnd(10)} ${summary}`),
|
|
216
|
-
'',
|
|
217
|
-
'Live daemon route risk: /approval risk',
|
|
218
209
|
].join('\n'));
|
|
219
210
|
return;
|
|
220
211
|
}
|
|
221
|
-
if (sub === 'risk' || sub === 'route-risk') {
|
|
222
|
-
const shellPaths = requireShellPaths(ctx);
|
|
223
|
-
const connection = resolveAgentDaemonConnection(ctx.platform.configManager, shellPaths.homeDirectory);
|
|
224
|
-
const audit = await fetchLiveDaemonCapabilityAudit(connection);
|
|
225
|
-
if (!audit.ok) {
|
|
226
|
-
ctx.print(renderDaemonCapabilityFailure(audit));
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
const report = buildDaemonCapabilityRouteRiskReport(audit);
|
|
230
|
-
const query = args.slice(1).join(' ').trim() || undefined;
|
|
231
|
-
const areas = filterDaemonCapabilityRouteRiskAreas(report.areas, query);
|
|
232
|
-
ctx.print(renderDaemonCapabilityRouteRisk(report, areas));
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
212
|
if (sub === 'review') {
|
|
236
213
|
const kind = (args[1] ?? '').toLowerCase();
|
|
237
214
|
const entry = matrix.find(([id]) => id === kind);
|
|
@@ -246,7 +223,7 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
|
|
|
246
223
|
].join('\n'));
|
|
247
224
|
return;
|
|
248
225
|
}
|
|
249
|
-
ctx.print('Usage: /approval [open|matrix|
|
|
226
|
+
ctx.print('Usage: /approval [open|matrix|review <kind>]');
|
|
250
227
|
},
|
|
251
228
|
});
|
|
252
229
|
|
|
@@ -46,7 +46,7 @@ export function registerRemoteRuntimeCommands(registry: CommandRegistry): void {
|
|
|
46
46
|
name: 'remote',
|
|
47
47
|
aliases: [],
|
|
48
48
|
description: 'Inspect, dispatch, and review self-hosted remote runners and artifacts',
|
|
49
|
-
usage: '[list | show [agentId] | supervisor [runnerId] |
|
|
49
|
+
usage: '[list | show [agentId] | supervisor [runnerId] | support [runnerId] | recover [runnerId] | setup [export <path> --yes] | env [export <path> --yes] | tunnel [review|export <path> --yes] | bootstrap [export <path> --yes|inspect <path>] | session <export|inspect|import> <path> [--yes] | pool <list|show|create|assign|unassign> ... | dispatch [template] <description> | dispatch-pool <pool> [template] <description> | contract [agentId] | cancel <agentId> | export <agentId> [path] --yes | artifact list | artifact show <id> | artifact export <id> [path] --yes | review <id> | rerun-local <id> | import <path> --yes]',
|
|
50
50
|
async handler(args, ctx) {
|
|
51
51
|
if (args.length === 0) {
|
|
52
52
|
if (ctx.openRemotePanel) {
|
|
@@ -131,7 +131,7 @@ export function registerRemoteRuntimeCommands(registry: CommandRegistry): void {
|
|
|
131
131
|
` messageCount: ${selected.messageCount}`,
|
|
132
132
|
` errorCount: ${selected.errorCount}`,
|
|
133
133
|
...(selected.lastError ? [` lastError: ${selected.lastError}`] : []),
|
|
134
|
-
'
|
|
134
|
+
' runner support:',
|
|
135
135
|
...selected.capabilities.map((capability) => ` ${capability.id}: ${capability.supported ? 'yes' : 'no'} (${capability.detail})`),
|
|
136
136
|
' recovery:',
|
|
137
137
|
...selected.recovery.map((action) => ` ${action.command} — ${action.reason}`),
|
|
@@ -139,7 +139,7 @@ export function registerRemoteRuntimeCommands(registry: CommandRegistry): void {
|
|
|
139
139
|
return;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
if (subcommand === '
|
|
142
|
+
if (subcommand === 'support') {
|
|
143
143
|
const snapshot = peerSnapshot.supervisor;
|
|
144
144
|
const runnerId = args[1];
|
|
145
145
|
const selected = runnerId
|
|
@@ -150,14 +150,14 @@ export function registerRemoteRuntimeCommands(registry: CommandRegistry): void {
|
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
152
152
|
ctx.print([
|
|
153
|
-
`Remote
|
|
153
|
+
`Remote Support ${selected.runnerId}`,
|
|
154
154
|
` label: ${selected.label}`,
|
|
155
155
|
` transport: ${selected.transportState}`,
|
|
156
156
|
` executionProtocol: ${selected.negotiation.executionProtocol}`,
|
|
157
157
|
` reviewMode: ${selected.negotiation.reviewMode}`,
|
|
158
158
|
` communicationLane: ${selected.negotiation.communicationLane}`,
|
|
159
159
|
` trustClass: ${selected.negotiation.trustClass}`,
|
|
160
|
-
'
|
|
160
|
+
' runner support:',
|
|
161
161
|
...selected.capabilities.map((capability) => (
|
|
162
162
|
` ${capability.id}: ${capability.supported ? 'supported' : 'missing'} — ${capability.detail}`
|
|
163
163
|
)),
|
package/src/input/commands.ts
CHANGED
|
@@ -59,7 +59,6 @@ import { registerDelegationRuntimeCommands } from './commands/delegation-runtime
|
|
|
59
59
|
import { registerPersonasRuntimeCommands } from './commands/personas-runtime.ts';
|
|
60
60
|
import { registerAgentSkillsRuntimeCommands } from './commands/agent-skills-runtime.ts';
|
|
61
61
|
import { registerRoutinesRuntimeCommands } from './commands/routines-runtime.ts';
|
|
62
|
-
import { registerCapabilitiesRuntimeCommands } from './commands/capabilities-runtime.ts';
|
|
63
62
|
|
|
64
63
|
/**
|
|
65
64
|
* registerBuiltinCommands - Register all built-in slash commands into the registry.
|
|
@@ -69,7 +68,6 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
|
|
|
69
68
|
registerShellCoreCommands(registry);
|
|
70
69
|
registerAgentWorkspaceRuntimeCommands(registry);
|
|
71
70
|
registerAgentRuntimeProfileRuntimeCommands(registry);
|
|
72
|
-
registerCapabilitiesRuntimeCommands(registry);
|
|
73
71
|
registerPersonasRuntimeCommands(registry);
|
|
74
72
|
registerAgentSkillsRuntimeCommands(registry);
|
|
75
73
|
registerRoutinesRuntimeCommands(registry);
|
|
@@ -114,7 +114,7 @@ export function buildCapabilitiesStep(controller: OnboardingWizardController): O
|
|
|
114
114
|
kind: 'action',
|
|
115
115
|
id: 'capabilities.select-all',
|
|
116
116
|
action: 'select-all-capabilities',
|
|
117
|
-
label: 'Review external-daemon
|
|
117
|
+
label: 'Review external-daemon surfaces',
|
|
118
118
|
hint: 'Review browser, LAN, webhooks/events, and external app surfaces without letting Agent own daemon lifecycle.',
|
|
119
119
|
defaultValue: 'Action',
|
|
120
120
|
},
|
|
@@ -123,17 +123,17 @@ export function buildCapabilitiesStep(controller: OnboardingWizardController): O
|
|
|
123
123
|
id: 'capabilities.clear',
|
|
124
124
|
action: 'clear-capabilities',
|
|
125
125
|
label: 'Keep Agent local-only',
|
|
126
|
-
hint: 'Clear external-daemon
|
|
126
|
+
hint: 'Clear external-daemon surfaces and keep Agent work in this terminal conversation.',
|
|
127
127
|
defaultValue: 'Action',
|
|
128
128
|
},
|
|
129
129
|
];
|
|
130
130
|
|
|
131
131
|
return {
|
|
132
132
|
id: 'capabilities',
|
|
133
|
-
title: 'Choose GoodVibes
|
|
133
|
+
title: 'Choose GoodVibes surfaces',
|
|
134
134
|
shortLabel: 'Capabilities',
|
|
135
|
-
description: 'Choose what Agent should prepare locally. Daemon-backed
|
|
136
|
-
summaryTitle: 'Selected
|
|
135
|
+
description: 'Choose what Agent should prepare locally. Daemon-backed surfaces are reviewed as external dependencies; Agent does not enable service mode or autostart.',
|
|
136
|
+
summaryTitle: 'Selected surfaces',
|
|
137
137
|
summaryLines: [
|
|
138
138
|
`${selectedCount}/${capabilities.length} option(s) selected`,
|
|
139
139
|
`Mode: ${controller.mode === 'edit' ? 'edit existing shell state' : controller.mode === 'reopen' ? 'reopen review flow' : 'new setup'}`,
|
|
@@ -327,7 +327,7 @@ export function buildExternalServicesStep(controller: OnboardingWizardController
|
|
|
327
327
|
id: 'external-services.clear',
|
|
328
328
|
action: 'clear-external-surfaces',
|
|
329
329
|
label: 'Clear all external surfaces',
|
|
330
|
-
hint: 'Hide all external surface setup screens. The HTTP listener can still be enabled separately by webhook/event
|
|
330
|
+
hint: 'Hide all external surface setup screens. The HTTP listener can still be enabled separately by webhook/event settings.',
|
|
331
331
|
defaultValue: 'Action',
|
|
332
332
|
},
|
|
333
333
|
{
|
|
@@ -705,7 +705,7 @@ export function buildAccountsStep(controller: OnboardingWizardController): Onboa
|
|
|
705
705
|
? 'An existing local auth admin user was detected and will be kept.'
|
|
706
706
|
: controller.hasLocalAuthUser()
|
|
707
707
|
? 'Existing local auth users were detected and will be kept.'
|
|
708
|
-
: 'No server-backed
|
|
708
|
+
: 'No server-backed surface is selected, so local auth is not required.',
|
|
709
709
|
defaultValue: needsAuthBootstrap
|
|
710
710
|
? controller.hasBootstrapCredentialPresent() ? 'Bootstrap replacement required' : 'Local admin required'
|
|
711
711
|
: controller.hasAdminAuthUser() ? 'Admin detected' : controller.hasLocalAuthUser() ? 'Local auth detected' : 'Not required',
|
|
@@ -6,14 +6,14 @@ import type { ResolvedBuiltinPanelDeps } from './shared.ts';
|
|
|
6
6
|
export function registerKnowledgePanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
|
|
7
7
|
if (!deps.memoryRegistry) return;
|
|
8
8
|
|
|
9
|
-
const { memoryRegistry } = deps;
|
|
9
|
+
const { agentKnowledgeService, memoryRegistry } = deps;
|
|
10
10
|
manager.registerType({
|
|
11
11
|
id: 'knowledge',
|
|
12
12
|
name: 'Knowledge',
|
|
13
13
|
icon: 'K',
|
|
14
14
|
category: 'agent',
|
|
15
|
-
description: '
|
|
16
|
-
factory: () => new KnowledgePanel(memoryRegistry),
|
|
15
|
+
description: 'Isolated Agent Knowledge plus local non-secret memory review',
|
|
16
|
+
factory: () => new KnowledgePanel(memoryRegistry, agentKnowledgeService ?? null),
|
|
17
17
|
});
|
|
18
18
|
manager.registerType({
|
|
19
19
|
id: 'memory',
|
|
@@ -21,6 +21,7 @@ import type { SessionMemoryStore } from '@pellux/goodvibes-sdk/platform/core';
|
|
|
21
21
|
import type { ExecutionPlanManager } from '@pellux/goodvibes-sdk/platform/core';
|
|
22
22
|
import type { AdaptivePlanner } from '@pellux/goodvibes-sdk/platform/core';
|
|
23
23
|
import type { ProjectPlanningService } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
24
|
+
import type { KnowledgeService } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
24
25
|
import type { ApiTokenAuditor } from '@pellux/goodvibes-sdk/platform/security';
|
|
25
26
|
import type { ComponentHealthMonitor } from '../../runtime/perf/panel-health-monitor.ts';
|
|
26
27
|
import type { WorktreeRegistry } from '@/runtime/index.ts';
|
|
@@ -65,6 +66,8 @@ export interface BuiltinPanelDeps {
|
|
|
65
66
|
evalRegistry?: import('../eval-panel.ts').EvalRegistry;
|
|
66
67
|
/** MemoryRegistry for the Memory panel. */
|
|
67
68
|
memoryRegistry?: MemoryRegistry;
|
|
69
|
+
/** Isolated Agent Knowledge service for the Agent Knowledge panel. */
|
|
70
|
+
agentKnowledgeService?: Pick<KnowledgeService, 'getStatus'>;
|
|
68
71
|
/** Shared policy runtime state for governance/policy diagnostics. */
|
|
69
72
|
policyRuntimeState?: import('@/runtime/index.ts').PolicyRuntimeState;
|
|
70
73
|
/** Approval broker for control-plane/operator panels. */
|