@pellux/goodvibes-agent 0.1.116 → 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 +48 -661
- package/README.md +64 -57
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +199180 -192185
- package/docs/README.md +15 -8
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +59 -0
- package/docs/getting-started.md +61 -50
- 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 +48 -11
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +3 -6
- package/src/agent/behavior-discovery-summary.ts +1 -3
- 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-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +19 -16
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +27 -26
- package/src/agent/routine-registry.ts +54 -14
- 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 +35 -33
- package/src/agent/routine-schedule-receipts.ts +29 -27
- package/src/agent/runtime-profile-starters.ts +5 -5
- package/src/agent/runtime-profile.ts +91 -12
- package/src/agent/skill-registry.ts +210 -32
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +40 -34
- 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 +14 -9
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +54 -29
- package/src/cli/local-library-command.ts +203 -83
- package/src/cli/management-commands.ts +105 -68
- package/src/cli/management.ts +55 -74
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -3
- package/src/cli/profiles-command.ts +166 -31
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +176 -40
- package/src/cli/service-posture.ts +16 -16
- package/src/cli/status.ts +56 -135
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +35 -8
- package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
- package/src/input/agent-workspace-basic-command-editors.ts +502 -9
- package/src/input/agent-workspace-categories.ts +423 -51
- package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
- package/src/input/agent-workspace-channel-command-editors.ts +65 -0
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +41 -3
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +166 -1
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- 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-mcp-command-editor-submission.ts +95 -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-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +81 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
- package/src/input/agent-workspace-operations-command-editors.ts +196 -0
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- package/src/input/agent-workspace-requirements.ts +11 -0
- 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-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +37 -16
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +162 -21
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +212 -4
- package/src/input/agent-workspace-voice-media.ts +4 -7
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +178 -240
- package/src/input/command-registry.ts +5 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
- package/src/input/commands/agent-skills-runtime.ts +149 -72
- package/src/input/commands/agent-workspace-runtime.ts +23 -6
- package/src/input/commands/brief-runtime.ts +55 -25
- package/src/input/commands/channels-runtime.ts +147 -33
- package/src/input/commands/compat-runtime.ts +32 -0
- 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 +149 -126
- package/src/input/commands/knowledge.ts +82 -60
- package/src/input/commands/local-provider-runtime.ts +43 -21
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +10 -20
- package/src/input/commands/mcp-runtime.ts +63 -46
- 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 -76
- package/src/input/commands/personas-runtime.ts +46 -31
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +35 -98
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +50 -9
- 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 +99 -45
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +6 -11
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +134 -104
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +38 -17
- package/src/input/commands/subscription-runtime.ts +54 -185
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +21 -21
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +6 -2
- package/src/input/feed-context-factory.ts +2 -2
- 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 -26
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -5
- package/src/input/handler-interactions.ts +9 -36
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +52 -91
- package/src/input/handler-shortcuts.ts +16 -7
- package/src/input/handler.ts +50 -23
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +27 -16
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
- package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
- package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
- package/src/input/onboarding/onboarding-wizard.ts +87 -2
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- package/src/input/settings-modal-agent-policy.ts +6 -6
- 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 +20 -66
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -10
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +4 -4
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +3 -12
- package/src/panels/builtin/session.ts +32 -24
- package/src/panels/builtin/shared.ts +7 -7
- 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 +19 -12
- 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 +48 -7
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +44 -20
- 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 +6 -6
- package/src/panels/system-messages-panel.ts +3 -3
- package/src/panels/tasks-panel.ts +21 -14
- 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 +3 -3
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +254 -57
- package/src/renderer/autocomplete-overlay.ts +25 -6
- package/src/renderer/block-actions.ts +1 -3
- 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 +112 -34
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +176 -43
- package/src/renderer/model-picker-overlay.ts +58 -3
- package/src/renderer/model-workspace.ts +104 -22
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +21 -5
- 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 +88 -55
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +11 -8
- package/src/runtime/bootstrap-core.ts +23 -65
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +46 -8
- package/src/runtime/bootstrap.ts +36 -46
- package/src/runtime/connected-host-auth.ts +47 -0
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -5
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +288 -74
- package/src/runtime/onboarding/derivation.ts +10 -13
- package/src/runtime/onboarding/snapshot.ts +2 -17
- package/src/runtime/onboarding/types.ts +34 -20
- package/src/runtime/onboarding/verify.ts +105 -4
- package/src/runtime/operator-token-cleanup.ts +3 -3
- package/src/runtime/services.ts +95 -11
- 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/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +17 -38
- 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 +279 -73
- 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 +13 -15
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/docs/connected-services.md +0 -51
- package/src/cli/package-verification.ts +0 -274
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -17
- 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,4 +1,4 @@
|
|
|
1
|
-
import type { KnowledgeService } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
1
|
+
import type { KnowledgeMapResult, KnowledgeService } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
2
2
|
import type { BrowserKnowledgeKind, BrowserKnowledgeSourceKind } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
3
3
|
import type { CommandContext, SlashCommand } from '../command-registry.ts';
|
|
4
4
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
@@ -12,10 +12,14 @@ type KnowledgeAskInput = Parameters<KnowledgeService['ask']>[0];
|
|
|
12
12
|
type KnowledgeAskResult = Awaited<ReturnType<KnowledgeService['ask']>>;
|
|
13
13
|
type KnowledgeAskMode = NonNullable<KnowledgeAskInput['mode']>;
|
|
14
14
|
|
|
15
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
16
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
function requireAgentKnowledgeApi(context: CommandContext) {
|
|
16
20
|
const knowledgeApi = context.clients?.agentKnowledgeApi;
|
|
17
21
|
if (!knowledgeApi) {
|
|
18
|
-
context.print('[knowledge] Agent Knowledge API is not available in this runtime. Refusing to use default
|
|
22
|
+
context.print('[knowledge] Agent Knowledge API is not available in this runtime. Refusing to use default knowledge or non-Agent knowledge fallback.');
|
|
19
23
|
return null;
|
|
20
24
|
}
|
|
21
25
|
return knowledgeApi;
|
|
@@ -48,7 +52,7 @@ function findDisallowedKnowledgeScopeFlag(args: readonly string[]): string | nul
|
|
|
48
52
|
function printScopeFlagRejection(context: CommandContext, flag: string): void {
|
|
49
53
|
context.print([
|
|
50
54
|
`[knowledge] Agent Knowledge is isolated; ${flag} is not accepted.`,
|
|
51
|
-
'[knowledge] GoodVibes Agent must not use default
|
|
55
|
+
'[knowledge] GoodVibes Agent must not use default knowledge or non-Agent product spaces.',
|
|
52
56
|
'[knowledge] Use only /api/goodvibes-agent/knowledge/* Agent-owned routes.',
|
|
53
57
|
].join('\n'));
|
|
54
58
|
}
|
|
@@ -110,10 +114,7 @@ function readJsonObjectFlag(args: string[], name: string): Record<string, unknow
|
|
|
110
114
|
if (!value) return undefined;
|
|
111
115
|
try {
|
|
112
116
|
const parsed = JSON.parse(value) as unknown;
|
|
113
|
-
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
return parsed as Record<string, unknown>;
|
|
117
|
+
return isRecord(parsed) ? parsed : null;
|
|
117
118
|
} catch {
|
|
118
119
|
return null;
|
|
119
120
|
}
|
|
@@ -131,7 +132,7 @@ function requireAgentKnowledgeAsk(context: CommandContext): ((input: KnowledgeAs
|
|
|
131
132
|
const serviceAsk = context.extensions.agentKnowledgeService?.ask?.bind(context.extensions.agentKnowledgeService);
|
|
132
133
|
if (serviceAsk) return serviceAsk;
|
|
133
134
|
|
|
134
|
-
context.print('[knowledge] Agent Knowledge ask is not available in this runtime. Refusing to use default
|
|
135
|
+
context.print('[knowledge] Agent Knowledge ask is not available in this runtime. Refusing to use default knowledge or non-Agent knowledge fallback.');
|
|
135
136
|
return null;
|
|
136
137
|
}
|
|
137
138
|
|
|
@@ -139,11 +140,20 @@ function cleanInline(value: unknown): string {
|
|
|
139
140
|
return typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : '';
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
function formatKnowledgeMap(result: KnowledgeMapResult): string {
|
|
144
|
+
return [
|
|
145
|
+
'Agent Knowledge map',
|
|
146
|
+
` nodes: ${result.nodeCount}${result.totalNodeCount !== undefined && result.totalNodeCount !== result.nodeCount ? ` of ${result.totalNodeCount}` : ''}`,
|
|
147
|
+
` edges: ${result.edgeCount}${result.totalEdgeCount !== undefined && result.totalEdgeCount !== result.edgeCount ? ` of ${result.totalEdgeCount}` : ''}`,
|
|
148
|
+
' route /api/goodvibes-agent/knowledge/map',
|
|
149
|
+
].join('\n');
|
|
150
|
+
}
|
|
151
|
+
|
|
142
152
|
function nodeLabel(node: { readonly kind?: string; readonly title?: string; readonly summary?: string; readonly confidence?: number }): string {
|
|
143
153
|
const kind = cleanInline(node.kind) || 'node';
|
|
144
154
|
const title = cleanInline(node.title) || 'untitled';
|
|
145
155
|
const summary = cleanInline(node.summary);
|
|
146
|
-
const confidence = typeof node.confidence === 'number' ? `
|
|
156
|
+
const confidence = typeof node.confidence === 'number' ? ` confidence ${node.confidence}` : '';
|
|
147
157
|
return summary ? `[${kind}] ${title}${confidence} - ${summary}` : `[${kind}] ${title}${confidence}`;
|
|
148
158
|
}
|
|
149
159
|
|
|
@@ -170,7 +180,7 @@ function renderKnowledgeAskResult(result: KnowledgeAskResult): string {
|
|
|
170
180
|
`[knowledge] ${result.query}`,
|
|
171
181
|
answer.text,
|
|
172
182
|
'',
|
|
173
|
-
`mode
|
|
183
|
+
`mode ${answer.mode} confidence ${answer.confidence} synthesized ${answer.synthesized ? 'yes' : 'no'}`,
|
|
174
184
|
];
|
|
175
185
|
|
|
176
186
|
if (answer.sources.length > 0) {
|
|
@@ -199,16 +209,16 @@ function renderKnowledgeAskResult(result: KnowledgeAskResult): string {
|
|
|
199
209
|
export const knowledgeCommand: SlashCommand = {
|
|
200
210
|
name: 'knowledge',
|
|
201
211
|
aliases: ['know', 'kb'],
|
|
202
|
-
description: 'Agent Knowledge
|
|
212
|
+
description: 'Agent Knowledge: isolated Agent-owned sources, graph, review queue, and compact prompt packets.',
|
|
203
213
|
usage: '<subcommand> [args]',
|
|
204
214
|
argsHint: 'status|ask|ingest-url --yes|ingest-file --yes|import-bookmarks --yes|list|search|get|queue|review-issue --yes',
|
|
205
215
|
handler: async (args: string[], context: CommandContext): Promise<void> => {
|
|
206
|
-
|
|
207
|
-
|
|
216
|
+
if (args.length === 0 && context.openAgentWorkspace) {
|
|
217
|
+
context.openAgentWorkspace('knowledge');
|
|
208
218
|
return;
|
|
209
219
|
}
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
const knowledge = requireAgentKnowledgeApi(context);
|
|
221
|
+
if (!knowledge) {
|
|
212
222
|
return;
|
|
213
223
|
}
|
|
214
224
|
const sub = (args[0] ?? 'status').toLowerCase();
|
|
@@ -321,9 +331,9 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
321
331
|
return;
|
|
322
332
|
}
|
|
323
333
|
const result = await knowledge.ingest.bookmarksFile({ path, sessionId: context.session.runtime.sessionId });
|
|
324
|
-
context.print(`[knowledge] Imported bookmarks
|
|
334
|
+
context.print(`[knowledge] Imported bookmarks ${result.imported} ok, ${result.failed} failed`);
|
|
325
335
|
if (result.errors.length > 0) {
|
|
326
|
-
for (const error of result.errors.slice(0, 10)) context.print(` error
|
|
336
|
+
for (const error of result.errors.slice(0, 10)) context.print(` error ${error}`);
|
|
327
337
|
}
|
|
328
338
|
break;
|
|
329
339
|
}
|
|
@@ -339,9 +349,9 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
339
349
|
return;
|
|
340
350
|
}
|
|
341
351
|
const result = await knowledge.ingest.urlsFile({ path, sessionId: context.session.runtime.sessionId });
|
|
342
|
-
context.print(`[knowledge] Imported URL list
|
|
352
|
+
context.print(`[knowledge] Imported URL list ${result.imported} ok, ${result.failed} failed`);
|
|
343
353
|
if (result.errors.length > 0) {
|
|
344
|
-
for (const error of result.errors.slice(0, 10)) context.print(` error
|
|
354
|
+
for (const error of result.errors.slice(0, 10)) context.print(` error ${error}`);
|
|
345
355
|
}
|
|
346
356
|
break;
|
|
347
357
|
}
|
|
@@ -362,9 +372,9 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
362
372
|
sessionId: context.session.runtime.sessionId,
|
|
363
373
|
});
|
|
364
374
|
context.print(`[knowledge] Imported browser knowledge: ${result.imported} ok, ${result.failed} failed`);
|
|
365
|
-
if (result.profiles.length > 0) context.print(` profiles
|
|
375
|
+
if (result.profiles.length > 0) context.print(` profiles ${result.profiles.length}`);
|
|
366
376
|
if (result.errors.length > 0) {
|
|
367
|
-
for (const error of result.errors.slice(0, 10)) context.print(` error
|
|
377
|
+
for (const error of result.errors.slice(0, 10)) context.print(` error ${error}`);
|
|
368
378
|
}
|
|
369
379
|
break;
|
|
370
380
|
}
|
|
@@ -396,7 +406,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
396
406
|
});
|
|
397
407
|
context.print(`[knowledge] Imported connector input: ${result.imported} ok, ${result.failed} failed`);
|
|
398
408
|
if (result.errors.length > 0) {
|
|
399
|
-
for (const error of result.errors.slice(0, 10)) context.print(` error
|
|
409
|
+
for (const error of result.errors.slice(0, 10)) context.print(` error ${error}`);
|
|
400
410
|
}
|
|
401
411
|
break;
|
|
402
412
|
}
|
|
@@ -410,7 +420,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
410
420
|
context.print('[knowledge] No nodes.');
|
|
411
421
|
return;
|
|
412
422
|
}
|
|
413
|
-
context.print(`[knowledge] ${nodes.length} node(s)
|
|
423
|
+
context.print(`[knowledge] ${nodes.length} node(s)`);
|
|
414
424
|
for (const node of nodes) {
|
|
415
425
|
context.print(` ${node.id} [${node.kind}] ${node.title}`);
|
|
416
426
|
if (node.summary) context.print(` ${node.summary}`);
|
|
@@ -423,7 +433,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
423
433
|
context.print('[knowledge] No issues.');
|
|
424
434
|
return;
|
|
425
435
|
}
|
|
426
|
-
context.print(`[knowledge] ${issues.length} issue(s)
|
|
436
|
+
context.print(`[knowledge] ${issues.length} issue(s)`);
|
|
427
437
|
for (const issue of issues) {
|
|
428
438
|
context.print(` ${issue.id} [${issue.severity}] ${issue.code}`);
|
|
429
439
|
context.print(` ${issue.message}`);
|
|
@@ -435,7 +445,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
435
445
|
context.print('[knowledge] No sources.');
|
|
436
446
|
return;
|
|
437
447
|
}
|
|
438
|
-
context.print(`[knowledge] ${sources.length} source(s)
|
|
448
|
+
context.print(`[knowledge] ${sources.length} source(s)`);
|
|
439
449
|
for (const source of sources) {
|
|
440
450
|
context.print(` ${source.id} [${source.sourceType}/${source.status}] ${source.title ?? source.canonicalUri ?? source.sourceUri ?? 'untitled'}`);
|
|
441
451
|
if (source.summary) context.print(` ${source.summary}`);
|
|
@@ -456,10 +466,10 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
456
466
|
context.print('[knowledge] No results.');
|
|
457
467
|
return;
|
|
458
468
|
}
|
|
459
|
-
context.print(`[knowledge] ${results.length} result(s)
|
|
469
|
+
context.print(`[knowledge] ${results.length} result(s)`);
|
|
460
470
|
for (const result of results) {
|
|
461
471
|
const title = result.source?.title ?? result.source?.canonicalUri ?? result.node?.title ?? result.id;
|
|
462
|
-
context.print(` ${result.id} [${result.kind}] score
|
|
472
|
+
context.print(` ${result.id} [${result.kind}] score ${result.score} ${title}`);
|
|
463
473
|
context.print(` ${result.reason}`);
|
|
464
474
|
}
|
|
465
475
|
break;
|
|
@@ -473,28 +483,28 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
473
483
|
}
|
|
474
484
|
const item = knowledge.graph.items.get(id);
|
|
475
485
|
if (!item) {
|
|
476
|
-
context.print(`[knowledge] Unknown item
|
|
486
|
+
context.print(`[knowledge] Unknown item ${id}`);
|
|
477
487
|
return;
|
|
478
488
|
}
|
|
479
489
|
if (item.source) {
|
|
480
490
|
context.print(`[knowledge] source ${item.source.id}`);
|
|
481
|
-
context.print(` title
|
|
482
|
-
context.print(` uri
|
|
483
|
-
context.print(` status
|
|
484
|
-
if (item.source.summary) context.print(` summary
|
|
491
|
+
context.print(` title ${item.source.title ?? 'untitled'}`);
|
|
492
|
+
context.print(` uri ${item.source.canonicalUri ?? item.source.sourceUri ?? 'n/a'}`);
|
|
493
|
+
context.print(` status ${item.source.status}`);
|
|
494
|
+
if (item.source.summary) context.print(` summary ${item.source.summary}`);
|
|
485
495
|
} else if (item.node) {
|
|
486
496
|
context.print(`[knowledge] node ${item.node.id}`);
|
|
487
|
-
context.print(`
|
|
488
|
-
context.print(` title
|
|
489
|
-
if (item.node.summary) context.print(` summary
|
|
497
|
+
context.print(` type ${item.node.kind}`);
|
|
498
|
+
context.print(` title ${item.node.title}`);
|
|
499
|
+
if (item.node.summary) context.print(` summary ${item.node.summary}`);
|
|
490
500
|
} else if (item.issue) {
|
|
491
501
|
context.print(`[knowledge] issue ${item.issue.id}`);
|
|
492
|
-
context.print(` severity
|
|
493
|
-
context.print(` code
|
|
494
|
-
context.print(` message
|
|
502
|
+
context.print(` severity ${item.issue.severity}`);
|
|
503
|
+
context.print(` code ${item.issue.code}`);
|
|
504
|
+
context.print(` message ${item.issue.message}`);
|
|
495
505
|
}
|
|
496
506
|
if (item.relatedEdges.length > 0) {
|
|
497
|
-
context.print(' relations
|
|
507
|
+
context.print(' relations');
|
|
498
508
|
for (const edge of item.relatedEdges.slice(0, 12)) {
|
|
499
509
|
context.print(` ${edge.fromKind}:${edge.fromId} -[${edge.relation}]-> ${edge.toKind}:${edge.toId}`);
|
|
500
510
|
}
|
|
@@ -502,13 +512,24 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
502
512
|
break;
|
|
503
513
|
}
|
|
504
514
|
|
|
515
|
+
case 'map': {
|
|
516
|
+
const limit = readPositiveIntFlag(rest, '--limit', 50);
|
|
517
|
+
const query = positionalArgs(rest, ['--limit']).join(' ').trim();
|
|
518
|
+
const result = await knowledge.graph.map({
|
|
519
|
+
limit,
|
|
520
|
+
...(query.length > 0 ? { query } : {}),
|
|
521
|
+
});
|
|
522
|
+
context.print(formatKnowledgeMap(result));
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
|
|
505
526
|
case 'lint': {
|
|
506
527
|
const issues = await knowledge.status.lint();
|
|
507
528
|
if (issues.length === 0) {
|
|
508
529
|
context.print('[knowledge] No lint issues.');
|
|
509
530
|
return;
|
|
510
531
|
}
|
|
511
|
-
context.print(`[knowledge] ${issues.length} lint issue(s)
|
|
532
|
+
context.print(`[knowledge] ${issues.length} lint issue(s)`);
|
|
512
533
|
for (const issue of issues) {
|
|
513
534
|
context.print(` ${issue.id} [${issue.severity}] ${issue.code}`);
|
|
514
535
|
context.print(` ${issue.message}`);
|
|
@@ -524,7 +545,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
524
545
|
context.print('Knowledge review queue is empty.');
|
|
525
546
|
return;
|
|
526
547
|
}
|
|
527
|
-
context.print(`[knowledge] Review queue (${issues.length})
|
|
548
|
+
context.print(`[knowledge] Review queue (${issues.length})`);
|
|
528
549
|
for (const issue of issues) {
|
|
529
550
|
context.print(` ${issue.id} [${issue.severity}] ${issue.code}`);
|
|
530
551
|
context.print(` ${issue.message}`);
|
|
@@ -558,11 +579,11 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
558
579
|
});
|
|
559
580
|
context.print([
|
|
560
581
|
`[knowledge] Reviewed issue ${result.issue.id}`,
|
|
561
|
-
` action
|
|
562
|
-
` status
|
|
563
|
-
...(result.node ? [` node
|
|
564
|
-
...(result.source ? [` source
|
|
565
|
-
...(result.appliedFacts ? [` applied facts
|
|
582
|
+
` action ${action}`,
|
|
583
|
+
` status ${result.issue.status}`,
|
|
584
|
+
...(result.node ? [` node ${result.node.id} ${result.node.title}`] : []),
|
|
585
|
+
...(result.source ? [` knowledge source ${result.source.id} ${result.source.title ?? result.source.canonicalUri ?? result.source.sourceUri ?? 'untitled'}`] : []),
|
|
586
|
+
...(result.appliedFacts ? [` applied facts ${Object.keys(result.appliedFacts).join(', ') || 'none'}`] : []),
|
|
566
587
|
].join('\n'));
|
|
567
588
|
} catch (error) {
|
|
568
589
|
context.print(`[knowledge] ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -578,9 +599,9 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
578
599
|
context.print('[knowledge] No consolidation candidates.');
|
|
579
600
|
return;
|
|
580
601
|
}
|
|
581
|
-
context.print(`[knowledge] Consolidation candidates (${candidates.length})
|
|
602
|
+
context.print(`[knowledge] Consolidation candidates (${candidates.length})`);
|
|
582
603
|
for (const candidate of candidates) {
|
|
583
|
-
context.print(` ${candidate.id} [${candidate.status}] score
|
|
604
|
+
context.print(` ${candidate.id} [${candidate.status}] score ${candidate.score} ${candidate.title}`);
|
|
584
605
|
context.print(` ${candidate.candidateType}`);
|
|
585
606
|
}
|
|
586
607
|
break;
|
|
@@ -595,7 +616,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
595
616
|
}
|
|
596
617
|
const report = await knowledge.connectors.doctor(second);
|
|
597
618
|
if (!report) {
|
|
598
|
-
context.print(`[knowledge] Connector doctor report unavailable
|
|
619
|
+
context.print(`[knowledge] Connector doctor report unavailable ${second}`);
|
|
599
620
|
return;
|
|
600
621
|
}
|
|
601
622
|
context.print([
|
|
@@ -610,14 +631,14 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
610
631
|
if (first) {
|
|
611
632
|
const connector = knowledge.connectors.get(first);
|
|
612
633
|
if (!connector) {
|
|
613
|
-
context.print(`[knowledge] Unknown connector
|
|
634
|
+
context.print(`[knowledge] Unknown connector ${first}`);
|
|
614
635
|
return;
|
|
615
636
|
}
|
|
616
637
|
context.print([
|
|
617
638
|
`[knowledge] Connector ${connector.id}`,
|
|
618
|
-
` name
|
|
619
|
-
`
|
|
620
|
-
` description
|
|
639
|
+
` name ${connector.displayName ?? connector.id}`,
|
|
640
|
+
` source type ${connector.sourceType}`,
|
|
641
|
+
` description ${connector.description}`,
|
|
621
642
|
` capabilities: ${connector.capabilities?.join(', ') || 'none'}`,
|
|
622
643
|
].join('\n'));
|
|
623
644
|
return;
|
|
@@ -627,7 +648,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
627
648
|
context.print('[knowledge] No connectors.');
|
|
628
649
|
return;
|
|
629
650
|
}
|
|
630
|
-
context.print(`[knowledge] Connectors (${connectors.length})
|
|
651
|
+
context.print(`[knowledge] Connectors (${connectors.length})`);
|
|
631
652
|
for (const connector of connectors) {
|
|
632
653
|
context.print(` ${connector.id} [${connector.sourceType}] ${connector.displayName ?? connector.id}`);
|
|
633
654
|
context.print(` ${connector.description}`);
|
|
@@ -643,7 +664,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
643
664
|
context.print('[knowledge] No consolidation reports.');
|
|
644
665
|
return;
|
|
645
666
|
}
|
|
646
|
-
context.print(`[knowledge] Consolidation reports (${reports.length})
|
|
667
|
+
context.print(`[knowledge] Consolidation reports (${reports.length})`);
|
|
647
668
|
for (const report of reports) {
|
|
648
669
|
context.print(` ${report.id} [${report.kind}] ${report.title}`);
|
|
649
670
|
context.print(` ${report.summary}`);
|
|
@@ -657,7 +678,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
657
678
|
context.print('[knowledge] No knowledge schedules.');
|
|
658
679
|
return;
|
|
659
680
|
}
|
|
660
|
-
context.print(`[knowledge] Managed schedules (${schedules.length})
|
|
681
|
+
context.print(`[knowledge] Managed schedules (${schedules.length})`);
|
|
661
682
|
for (const schedule of schedules) {
|
|
662
683
|
context.print(` ${schedule.id} [${schedule.enabled ? 'enabled' : 'disabled'}] ${schedule.jobId}`);
|
|
663
684
|
context.print(` ${schedule.label}`);
|
|
@@ -709,10 +730,10 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
709
730
|
const result = await knowledge.status.reindex();
|
|
710
731
|
context.print([
|
|
711
732
|
'[knowledge] Reindex complete',
|
|
712
|
-
` sources
|
|
713
|
-
` nodes
|
|
714
|
-
` edges
|
|
715
|
-
` issues
|
|
733
|
+
` sources ${result.status.sourceCount}`,
|
|
734
|
+
` nodes ${result.status.nodeCount}`,
|
|
735
|
+
` edges ${result.status.edgeCount}`,
|
|
736
|
+
` issues ${result.status.issueCount}`,
|
|
716
737
|
].join('\n'));
|
|
717
738
|
break;
|
|
718
739
|
}
|
|
@@ -743,6 +764,7 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
743
764
|
' list [--kind <sources|nodes|issues>] [--limit <n>]',
|
|
744
765
|
' search <query> [--limit <n>]',
|
|
745
766
|
' get <id>',
|
|
767
|
+
' map [query] [--limit <n>]',
|
|
746
768
|
' queue [limit]',
|
|
747
769
|
' review-issue <issueId> <accept|reject|resolve|reopen|edit|forget> [--reviewer <name>] [--value <json-object>] --yes',
|
|
748
770
|
' candidates [limit]',
|
|
@@ -13,6 +13,14 @@ function isValidProviderName(name: string): boolean {
|
|
|
13
13
|
return /^[a-zA-Z0-9_-]+$/.test(name);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function readDiscoveredModelIds(body: unknown): string[] {
|
|
17
|
+
if (!body || typeof body !== 'object' || !('data' in body) || !Array.isArray(body.data)) return [];
|
|
18
|
+
return body.data
|
|
19
|
+
.filter((model): model is { readonly id: unknown } => Boolean(model) && typeof model === 'object' && 'id' in model)
|
|
20
|
+
.map((model) => String(model.id))
|
|
21
|
+
.filter(Boolean);
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
export function registerLocalProviderRuntimeCommands(registry: CommandRegistry): void {
|
|
17
25
|
registry.register({
|
|
18
26
|
name: 'provider',
|
|
@@ -36,20 +44,26 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
36
44
|
return;
|
|
37
45
|
}
|
|
38
46
|
if (!isValidProviderName(name)) {
|
|
39
|
-
ctx.print(
|
|
47
|
+
ctx.print([
|
|
48
|
+
'Error',
|
|
49
|
+
' message Provider name must contain only letters, numbers, hyphens, and underscores.',
|
|
50
|
+
].join('\n'));
|
|
40
51
|
return;
|
|
41
52
|
}
|
|
42
53
|
let parsedUrl: URL;
|
|
43
54
|
try {
|
|
44
55
|
parsedUrl = new URL(baseURL);
|
|
45
56
|
} catch {
|
|
46
|
-
ctx.print(
|
|
57
|
+
ctx.print([
|
|
58
|
+
'Error',
|
|
59
|
+
` message ${baseURL} is not a valid URL. Example http://192.168.0.85:8001/v1`,
|
|
60
|
+
].join('\n'));
|
|
47
61
|
return;
|
|
48
62
|
}
|
|
49
63
|
const providersDir = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, 'providers');
|
|
50
64
|
const providerFile = join(providersDir, `${name}.json`);
|
|
51
65
|
if (existsSync(providerFile)) {
|
|
52
|
-
ctx.print(`
|
|
66
|
+
ctx.print(`Provider ${name} already exists at ${providerFile}\nRemove it first with /provider remove ${name} --yes`);
|
|
53
67
|
return;
|
|
54
68
|
}
|
|
55
69
|
|
|
@@ -64,12 +78,7 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
64
78
|
clearTimeout(timeoutId);
|
|
65
79
|
if (res.ok) {
|
|
66
80
|
const body = await res.json() as unknown;
|
|
67
|
-
|
|
68
|
-
discoveredModelIds = ((body as { data: unknown[] }).data)
|
|
69
|
-
.filter((m): m is Record<string, unknown> => typeof m === 'object' && m !== null && 'id' in m)
|
|
70
|
-
.map((m) => String(m.id))
|
|
71
|
-
.filter(Boolean);
|
|
72
|
-
}
|
|
81
|
+
discoveredModelIds = readDiscoveredModelIds(body);
|
|
73
82
|
}
|
|
74
83
|
} catch {
|
|
75
84
|
ctx.print(`Could not reach ${baseURL}/models — creating provider with a minimal starter config.`);
|
|
@@ -91,13 +100,13 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
91
100
|
id: defaultModel,
|
|
92
101
|
displayName: defaultModel,
|
|
93
102
|
contextWindow: 8192,
|
|
94
|
-
capabilities: { toolCalling: true, codeEditing:
|
|
103
|
+
capabilities: { toolCalling: true, codeEditing: false, reasoning: false, multimodal: false },
|
|
95
104
|
}]
|
|
96
105
|
: discoveredModelIds.map((id) => ({
|
|
97
106
|
id,
|
|
98
107
|
displayName: id,
|
|
99
108
|
contextWindow: contextWindows[id] ?? 8192,
|
|
100
|
-
capabilities: { toolCalling: true, codeEditing:
|
|
109
|
+
capabilities: { toolCalling: true, codeEditing: false, reasoning: false, multimodal: false },
|
|
101
110
|
}));
|
|
102
111
|
const config: CustomProviderConfig = {
|
|
103
112
|
name,
|
|
@@ -111,10 +120,10 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
111
120
|
mkdirSync(providersDir, { recursive: true });
|
|
112
121
|
await writeFile(providerFile, JSON.stringify(config, null, 2), 'utf-8');
|
|
113
122
|
} catch (e) {
|
|
114
|
-
ctx.print(`Error writing provider file
|
|
123
|
+
ctx.print(`Error writing provider file ${summarizeError(e)}`);
|
|
115
124
|
return;
|
|
116
125
|
}
|
|
117
|
-
ctx.print(`Provider
|
|
126
|
+
ctx.print(`Provider ${name} added with ${models.length} model(s)\n${discoveredModelIds.length > 0 ? discoveredModelIds.map((id) => ` • ${id} (${(contextWindows[id] ?? 8192).toLocaleString()} ctx)`).join('\n') : ` • ${defaultModel} (starter entry)`}\nThe file watcher will auto-register it shortly.`);
|
|
118
127
|
return;
|
|
119
128
|
}
|
|
120
129
|
|
|
@@ -129,19 +138,22 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
129
138
|
return;
|
|
130
139
|
}
|
|
131
140
|
if (!isValidProviderName(name)) {
|
|
132
|
-
ctx.print(
|
|
141
|
+
ctx.print([
|
|
142
|
+
'Error',
|
|
143
|
+
' message Provider name must contain only letters, numbers, hyphens, and underscores.',
|
|
144
|
+
].join('\n'));
|
|
133
145
|
return;
|
|
134
146
|
}
|
|
135
147
|
const providerFile = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, 'providers', `${name}.json`);
|
|
136
148
|
if (!existsSync(providerFile)) {
|
|
137
|
-
ctx.print(`
|
|
149
|
+
ctx.print(`No custom provider ${name} found at ${providerFile}`);
|
|
138
150
|
return;
|
|
139
151
|
}
|
|
140
152
|
try {
|
|
141
153
|
await unlink(providerFile);
|
|
142
|
-
ctx.print(`Provider
|
|
154
|
+
ctx.print(`Provider ${name} removed. The file watcher will deregister it shortly.`);
|
|
143
155
|
} catch (e) {
|
|
144
|
-
ctx.print(`Error removing provider file
|
|
156
|
+
ctx.print(`Error removing provider file ${summarizeError(e)}`);
|
|
145
157
|
}
|
|
146
158
|
return;
|
|
147
159
|
}
|
|
@@ -152,11 +164,12 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
152
164
|
return;
|
|
153
165
|
}
|
|
154
166
|
const providers = requireProviderApi(ctx).listProviderIds();
|
|
155
|
-
ctx.print(['Available providers
|
|
167
|
+
ctx.print(['Available providers', ...providers.map((provider) => ` ${provider === ctx.session.runtime.provider ? '▶' : ' '} ${provider}`)].join('\n'));
|
|
156
168
|
return;
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
const providerName = commandArgs[0];
|
|
172
|
+
const requestedModel = commandArgs[1];
|
|
160
173
|
const providerApi = requireProviderApi(ctx);
|
|
161
174
|
const selectable = await providerApi.listModels({
|
|
162
175
|
providerId: providerName,
|
|
@@ -164,17 +177,26 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
164
177
|
});
|
|
165
178
|
const match = selectable[0];
|
|
166
179
|
if (!match) {
|
|
167
|
-
ctx.print(
|
|
180
|
+
ctx.print([
|
|
181
|
+
`Unknown provider ${providerName}`,
|
|
182
|
+
`available providers ${providerApi.listProviderIds().join(', ')}`,
|
|
183
|
+
].join('\n'));
|
|
168
184
|
return;
|
|
169
185
|
}
|
|
170
186
|
try {
|
|
171
|
-
const
|
|
187
|
+
const registryKey = requestedModel
|
|
188
|
+
? requestedModel.includes(':') ? requestedModel : `${providerName}:${requestedModel}`
|
|
189
|
+
: match.registryKey;
|
|
190
|
+
const selected = await providerApi.selectModel(registryKey);
|
|
172
191
|
ctx.session.runtime.model = selected.registryKey;
|
|
173
192
|
ctx.session.runtime.provider = selected.providerId;
|
|
174
193
|
ctx.platform.configManager.set('provider.model', selected.registryKey);
|
|
175
194
|
ctx.print(`Switched to provider: ${selected.providerId} (model: ${selected.modelId})`);
|
|
176
195
|
} catch (e) {
|
|
177
|
-
ctx.print(
|
|
196
|
+
ctx.print([
|
|
197
|
+
'Error',
|
|
198
|
+
` message ${summarizeError(e)}`,
|
|
199
|
+
].join('\n'));
|
|
178
200
|
}
|
|
179
201
|
},
|
|
180
202
|
});
|