@pellux/goodvibes-agent 0.1.117 → 1.0.1
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 +20 -4
- package/README.md +35 -14
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +176093 -171065
- 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 +159 -73
- 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 +59 -39
- 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-knowledge-url-editor.ts +4 -11
- 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-local-library-args.ts +52 -0
- package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
- package/src/input/commands/agent-skills-runtime.ts +87 -99
- 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 +118 -50
- 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 +49 -59
- 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 +63 -72
- 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 +22 -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
|
@@ -9,6 +9,10 @@ import { BUILTIN_SECRET_PROVIDER_SOURCES, describeSecretRef, isSecretRefInput, r
|
|
|
9
9
|
import { requireBookmarkManager, requireProviderApi, requireSecretsManager } from './runtime-services.ts';
|
|
10
10
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
11
11
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
12
|
+
import {
|
|
13
|
+
formatAgentMediaGenerationResult,
|
|
14
|
+
generateAgentMedia,
|
|
15
|
+
} from '../../agent/media-generation.ts';
|
|
12
16
|
|
|
13
17
|
function isGoodVibesSecretRefInput(value: string): boolean {
|
|
14
18
|
const normalized = value.trim();
|
|
@@ -23,7 +27,7 @@ function isMalformedGoodVibesSecretRefInput(value: string): boolean {
|
|
|
23
27
|
function toggleBlocks(typeFilter: string, collapsed: boolean, ctx: CommandContext): void {
|
|
24
28
|
const VALID_TYPES = ['all', 'thinking', 'tool', 'code'] as const;
|
|
25
29
|
if (!VALID_TYPES.includes(typeFilter as typeof VALID_TYPES[number])) {
|
|
26
|
-
ctx.print(`Unknown type
|
|
30
|
+
ctx.print(`Unknown type ${typeFilter}\nValid types ${VALID_TYPES.join(', ')}`);
|
|
27
31
|
return;
|
|
28
32
|
}
|
|
29
33
|
const blockRegistry = ctx.session.conversationManager.getBlockRegistry();
|
|
@@ -49,6 +53,60 @@ function toggleBlocks(typeFilter: string, collapsed: boolean, ctx: CommandContex
|
|
|
49
53
|
ctx.renderRequest();
|
|
50
54
|
}
|
|
51
55
|
|
|
56
|
+
interface MediaGenerateArgs {
|
|
57
|
+
readonly prompt: string;
|
|
58
|
+
readonly providerId?: string;
|
|
59
|
+
readonly modelId?: string;
|
|
60
|
+
readonly outputMimeType?: string;
|
|
61
|
+
readonly yes: boolean;
|
|
62
|
+
readonly errors: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function readFlagValue(args: readonly string[], index: number, flag: string, errors: string[]): string | null {
|
|
66
|
+
const value = args[index + 1];
|
|
67
|
+
if (!value || value.startsWith('--')) {
|
|
68
|
+
errors.push(`${flag} requires a value.`);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parseMediaGenerateArgs(args: readonly string[]): MediaGenerateArgs {
|
|
75
|
+
const parsed = stripYesFlag([...args]);
|
|
76
|
+
const errors: string[] = [];
|
|
77
|
+
const promptParts: string[] = [];
|
|
78
|
+
let providerId: string | undefined;
|
|
79
|
+
let modelId: string | undefined;
|
|
80
|
+
let outputMimeType: string | undefined;
|
|
81
|
+
for (let index = 0; index < parsed.rest.length; index += 1) {
|
|
82
|
+
const arg = parsed.rest[index];
|
|
83
|
+
if (arg === '--provider') {
|
|
84
|
+
providerId = readFlagValue(parsed.rest, index, arg, errors) ?? providerId;
|
|
85
|
+
index += 1;
|
|
86
|
+
} else if (arg === '--model') {
|
|
87
|
+
modelId = readFlagValue(parsed.rest, index, arg, errors) ?? modelId;
|
|
88
|
+
index += 1;
|
|
89
|
+
} else if (arg === '--mime') {
|
|
90
|
+
outputMimeType = readFlagValue(parsed.rest, index, arg, errors) ?? outputMimeType;
|
|
91
|
+
index += 1;
|
|
92
|
+
} else if (arg?.startsWith('--')) {
|
|
93
|
+
errors.push(`Unknown media generation flag ${arg}`);
|
|
94
|
+
} else if (arg) {
|
|
95
|
+
promptParts.push(arg);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const prompt = promptParts.join(' ').trim();
|
|
99
|
+
if (!prompt) errors.push('Media generation prompt is required.');
|
|
100
|
+
return {
|
|
101
|
+
prompt,
|
|
102
|
+
...(providerId ? { providerId } : {}),
|
|
103
|
+
...(modelId ? { modelId } : {}),
|
|
104
|
+
...(outputMimeType ? { outputMimeType } : {}),
|
|
105
|
+
yes: parsed.yes,
|
|
106
|
+
errors,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
52
110
|
export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
53
111
|
registry.register({ name: 'expand', description: 'Expand blocks by type', usage: '[all|thinking|tool|code]', argsHint: '[all|thinking|tool|code]', handler(args, ctx) { toggleBlocks(args[0] || 'all', false, ctx); } });
|
|
54
112
|
registry.register({ name: 'collapse', description: 'Collapse blocks by type', usage: '[all|thinking|tool|code]', argsHint: '[all|thinking|tool|code]', handler(args, ctx) { toggleBlocks(args[0] || 'all', true, ctx); } });
|
|
@@ -130,9 +188,12 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
130
188
|
}
|
|
131
189
|
try {
|
|
132
190
|
const resolved = await resolveSecretRef(refText, { resolveLocalSecret: (key) => mgr.get(key) });
|
|
133
|
-
ctx.print(
|
|
191
|
+
ctx.print([
|
|
192
|
+
`[secrets] ${describeSecretRef(refText)}`,
|
|
193
|
+
` status ${resolved.value ? 'resolved <redacted>' : 'missing'}`,
|
|
194
|
+
].join('\n'));
|
|
134
195
|
} catch (error) {
|
|
135
|
-
ctx.print(`[secrets] ${describeSecretRef(refText)} failed
|
|
196
|
+
ctx.print(`[secrets] ${describeSecretRef(refText)} failed ${summarizeError(error)}`);
|
|
136
197
|
}
|
|
137
198
|
return;
|
|
138
199
|
}
|
|
@@ -190,7 +251,10 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
190
251
|
scope: flags.has('--user') ? 'user' : flags.has('--project') ? 'project' : undefined,
|
|
191
252
|
medium: flags.has('--plaintext') ? 'plaintext' : flags.has('--secure') ? 'secure' : undefined,
|
|
192
253
|
});
|
|
193
|
-
ctx.print(
|
|
254
|
+
ctx.print([
|
|
255
|
+
'[secrets] Deleted',
|
|
256
|
+
` key ${key}`,
|
|
257
|
+
].join('\n'));
|
|
194
258
|
return;
|
|
195
259
|
}
|
|
196
260
|
ctx.print('[secrets] Usage: /secrets set <KEY> <value> [--user|--project] [--secure|--plaintext] --yes | link <KEY> <secret-ref> [--user|--project] [--secure|--plaintext] --yes | get <KEY> | test <secret-ref> | providers | list | delete <KEY> [--user|--project] [--secure|--plaintext] --yes');
|
|
@@ -212,36 +276,42 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
212
276
|
const promptText = args.slice(1).join(' ') || `Attached image: ${rawPath.split('/').pop() ?? rawPath}`;
|
|
213
277
|
const projectRoot = ctx.workspace.shellPaths?.workingDirectory ?? ctx.platform.configManager.getWorkingDirectory();
|
|
214
278
|
if (!projectRoot) {
|
|
215
|
-
ctx.print(
|
|
279
|
+
ctx.print([
|
|
280
|
+
'Error',
|
|
281
|
+
' message working directory is unavailable.',
|
|
282
|
+
].join('\n'));
|
|
216
283
|
return;
|
|
217
284
|
}
|
|
218
285
|
let resolvedPath: string;
|
|
219
286
|
try {
|
|
220
287
|
resolvedPath = resolveAndValidatePath(rawPath, projectRoot);
|
|
221
288
|
} catch (err) {
|
|
222
|
-
ctx.print(
|
|
289
|
+
ctx.print([
|
|
290
|
+
'Error',
|
|
291
|
+
` message ${summarizeError(err)}`,
|
|
292
|
+
].join('\n'));
|
|
223
293
|
return;
|
|
224
294
|
}
|
|
225
295
|
if (!existsSync(resolvedPath)) {
|
|
226
|
-
ctx.print(`File not found
|
|
296
|
+
ctx.print(`File not found ${rawPath}`);
|
|
227
297
|
return;
|
|
228
298
|
}
|
|
229
299
|
const ext = resolvedPath.slice(resolvedPath.lastIndexOf('.')).toLowerCase();
|
|
230
300
|
const mediaType = ({ '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.gif': 'image/gif' } as Record<string, string>)[ext];
|
|
231
301
|
if (!mediaType) {
|
|
232
|
-
ctx.print(`Unsupported image format
|
|
302
|
+
ctx.print(`Unsupported image format ${ext}\nSupported .png, .jpg, .jpeg, .webp, .gif`);
|
|
233
303
|
return;
|
|
234
304
|
}
|
|
235
305
|
const stat = statSync(resolvedPath);
|
|
236
306
|
if (stat.size > 20 * 1024 * 1024) {
|
|
237
|
-
ctx.print(`Image too large (${(stat.size / 1024 / 1024).toFixed(1)}MB). Maximum
|
|
307
|
+
ctx.print(`Image too large (${(stat.size / 1024 / 1024).toFixed(1)}MB). Maximum 20MB`);
|
|
238
308
|
return;
|
|
239
309
|
}
|
|
240
310
|
let data: string;
|
|
241
311
|
try {
|
|
242
312
|
data = (await readFile(resolvedPath)).toString('base64');
|
|
243
313
|
} catch (err) {
|
|
244
|
-
ctx.print(`Failed to read image
|
|
314
|
+
ctx.print(`Failed to read image ${summarizeError(err)}`);
|
|
245
315
|
return;
|
|
246
316
|
}
|
|
247
317
|
const currentModel = await requireProviderApi(ctx).getCurrentModel();
|
|
@@ -253,6 +323,53 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
253
323
|
},
|
|
254
324
|
});
|
|
255
325
|
|
|
326
|
+
registry.register({
|
|
327
|
+
name: 'media',
|
|
328
|
+
description: 'Inspect media providers or generate media through configured providers',
|
|
329
|
+
usage: 'providers | generate [--provider <id>] [--model <id>] [--mime <mime>] <prompt> --yes',
|
|
330
|
+
argsHint: '<providers|generate>',
|
|
331
|
+
async handler(args, ctx) {
|
|
332
|
+
const subcommand = args[0]?.toLowerCase() || 'providers';
|
|
333
|
+
const registry = ctx.platform.mediaProviderRegistry;
|
|
334
|
+
if (!registry) {
|
|
335
|
+
ctx.print('[media] Media providers are not available in this runtime.');
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
if (subcommand === 'providers' || subcommand === 'status' || subcommand === 'list') {
|
|
339
|
+
const statuses = await registry.status();
|
|
340
|
+
ctx.print([
|
|
341
|
+
'[media] Providers:',
|
|
342
|
+
...statuses.map((provider) => ` ${provider.id}: ${provider.state}${provider.configured ? '' : ' (setup needed)'} - ${provider.capabilities.join(', ')}${provider.detail ? ` - ${provider.detail}` : ''}`),
|
|
343
|
+
].join('\n'));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (subcommand !== 'generate') {
|
|
347
|
+
ctx.print('[media] Usage: /media providers | /media generate [--provider <id>] [--model <id>] [--mime <mime>] <prompt> --yes');
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const artifactStore = ctx.platform.artifactStore;
|
|
351
|
+
if (!artifactStore) {
|
|
352
|
+
ctx.print('[media] Artifact storage is not available in this runtime.');
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const parsed = parseMediaGenerateArgs(args.slice(1));
|
|
356
|
+
if (parsed.errors.length > 0) {
|
|
357
|
+
ctx.print(`[media] ${parsed.errors.join('\n[media] ')}`);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!parsed.yes) {
|
|
361
|
+
requireYesFlag(ctx, `generate media for "${parsed.prompt}"`, '/media generate [--provider <id>] [--model <id>] [--mime <mime>] <prompt> --yes');
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
try {
|
|
365
|
+
const result = await generateAgentMedia(registry, artifactStore, parsed);
|
|
366
|
+
ctx.print(formatAgentMediaGenerationResult(result));
|
|
367
|
+
} catch (error) {
|
|
368
|
+
ctx.print(`[media] Generation failed ${summarizeError(error)}`);
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
|
|
256
373
|
registry.register({
|
|
257
374
|
name: 'refresh-models',
|
|
258
375
|
description: 'Refresh model catalog, benchmarks, and token limits',
|
|
@@ -267,15 +384,17 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
267
384
|
catalogOk = true;
|
|
268
385
|
ctx.print(`Model catalog refreshed: ${catalog.modelCount} models from ${catalog.providerCount} providers`);
|
|
269
386
|
} catch (e) {
|
|
270
|
-
ctx.print(`Catalog refresh failed
|
|
387
|
+
ctx.print(`Catalog refresh failed ${summarizeError(e)}`);
|
|
271
388
|
}
|
|
272
389
|
ctx.print('Refreshing benchmarks...');
|
|
273
390
|
try {
|
|
274
391
|
const benchmarkCount = await providerApi.refreshBenchmarks();
|
|
275
392
|
benchmarksOk = true;
|
|
276
|
-
ctx.print(
|
|
393
|
+
ctx.print(benchmarkCount > 0
|
|
394
|
+
? `Benchmarks refreshed: ${benchmarkCount} model records available.`
|
|
395
|
+
: 'Benchmarks refreshed.');
|
|
277
396
|
} catch (e) {
|
|
278
|
-
ctx.print(`Benchmarks refresh failed
|
|
397
|
+
ctx.print(`Benchmarks refresh failed ${summarizeError(e)}`);
|
|
279
398
|
}
|
|
280
399
|
ctx.print('Refreshing token limits...');
|
|
281
400
|
try {
|
|
@@ -283,7 +402,7 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
283
402
|
limitsOk = true;
|
|
284
403
|
ctx.print(`Token limits refreshed: ${count} models updated.`);
|
|
285
404
|
} catch (e) {
|
|
286
|
-
ctx.print(`Token limits refresh failed
|
|
405
|
+
ctx.print(`Token limits refresh failed ${summarizeError(e)}`);
|
|
287
406
|
}
|
|
288
407
|
if (!catalogOk || !benchmarksOk || !limitsOk) ctx.print('Some refreshes failed — see messages above.');
|
|
289
408
|
},
|
|
@@ -308,14 +427,17 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
308
427
|
}
|
|
309
428
|
const favorites = await providerApi.getFavorites();
|
|
310
429
|
if (favorites.pinned.some((entry) => entry.modelId === modelId || entry.registryKey === modelId)) {
|
|
311
|
-
ctx.print(`Model already pinned
|
|
430
|
+
ctx.print(`Model already pinned ${modelId}`);
|
|
312
431
|
return;
|
|
313
432
|
}
|
|
314
433
|
try {
|
|
315
434
|
await providerApi.pinModel(modelId);
|
|
316
435
|
ctx.print(`Pinned: ${modelId}`);
|
|
317
436
|
} catch (e) {
|
|
318
|
-
ctx.print(
|
|
437
|
+
ctx.print([
|
|
438
|
+
'Error',
|
|
439
|
+
` message ${summarizeError(e)}`,
|
|
440
|
+
].join('\n'));
|
|
319
441
|
}
|
|
320
442
|
},
|
|
321
443
|
});
|
|
@@ -13,7 +13,7 @@ export interface SetupReviewSnapshot {
|
|
|
13
13
|
readonly builtinSubscriptionProviderCount: number;
|
|
14
14
|
readonly activeSubscriptionCount: number;
|
|
15
15
|
readonly pendingSubscriptionCount: number;
|
|
16
|
-
readonly
|
|
16
|
+
readonly hostIntegrationIssues: string[];
|
|
17
17
|
readonly skillCount: number;
|
|
18
18
|
readonly pluginCount: number;
|
|
19
19
|
readonly quarantinedPluginCount: number;
|
|
@@ -33,11 +33,11 @@ export async function buildSetupReviewSnapshot(ctx: CommandContext): Promise<Set
|
|
|
33
33
|
const serviceRegistry = requireServiceRegistry(ctx);
|
|
34
34
|
const services = Object.keys(serviceRegistry.getAll()).sort((a, b) => a.localeCompare(b));
|
|
35
35
|
const serviceConfigs = serviceRegistry.getAll();
|
|
36
|
-
const
|
|
36
|
+
const hostIntegrationIssues: string[] = [];
|
|
37
37
|
for (const name of services) {
|
|
38
38
|
const inspection = await serviceRegistry.inspect(name);
|
|
39
39
|
if (!inspection?.hasPrimaryCredential) {
|
|
40
|
-
|
|
40
|
+
hostIntegrationIssues.push(`${name}: missing primary credential`);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -79,13 +79,13 @@ export async function buildSetupReviewSnapshot(ctx: CommandContext): Promise<Set
|
|
|
79
79
|
message: providerCount > 0 ? `${providerCount} model(s) available` : 'no models available',
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
|
-
severity: (services.length === 0 && oauthProviderCount === 0 && builtinSubscriptionProviderCount === 0) ? 'warn' :
|
|
82
|
+
severity: (services.length === 0 && oauthProviderCount === 0 && builtinSubscriptionProviderCount === 0) ? 'warn' : hostIntegrationIssues.length === 0 ? 'pass' : 'warn',
|
|
83
83
|
area: 'host',
|
|
84
84
|
message: (services.length === 0 && oauthProviderCount === 0 && builtinSubscriptionProviderCount === 0)
|
|
85
85
|
? 'no connected host integrations configured'
|
|
86
|
-
:
|
|
86
|
+
: hostIntegrationIssues.length === 0
|
|
87
87
|
? `${services.length} host integration(s), ${oauthProviderCount + builtinSubscriptionProviderCount} oauth provider(s), ${activeSubscriptionCount} active subscription override(s)`
|
|
88
|
-
: `${
|
|
88
|
+
: `${hostIntegrationIssues.length} host integration configuration issue(s)`,
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
severity: quarantinedPluginCount === 0 ? 'pass' : 'warn',
|
|
@@ -111,7 +111,7 @@ export async function buildSetupReviewSnapshot(ctx: CommandContext): Promise<Set
|
|
|
111
111
|
builtinSubscriptionProviderCount,
|
|
112
112
|
activeSubscriptionCount,
|
|
113
113
|
pendingSubscriptionCount,
|
|
114
|
-
|
|
114
|
+
hostIntegrationIssues,
|
|
115
115
|
skillCount: skills.length,
|
|
116
116
|
pluginCount: plugins.length,
|
|
117
117
|
quarantinedPluginCount,
|