@pellux/goodvibes-agent 1.0.34 → 1.0.36
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 +28 -13
- package/README.md +11 -8
- package/dist/package/main.js +1592 -921
- package/docs/README.md +6 -5
- package/docs/channels-remote-and-api.md +3 -3
- package/docs/connected-host.md +3 -3
- package/docs/getting-started.md +20 -12
- package/docs/knowledge-artifacts-and-multimodal.md +9 -4
- package/docs/project-planning.md +3 -3
- package/docs/providers-and-routing.md +2 -2
- package/docs/release-and-publishing.md +8 -8
- package/docs/tools-and-commands.md +34 -17
- package/docs/voice-and-live-tts.md +1 -1
- package/package.json +1 -1
- package/release/live-verification/live-verification.json +15 -15
- package/release/live-verification/live-verification.md +19 -21
- package/release/release-notes.md +6 -6
- package/release/release-readiness.json +64 -64
- package/src/agent/harness-control.ts +35 -9
- package/src/agent/reminder-schedule-format.ts +2 -5
- package/src/agent/reminder-schedule.ts +4 -11
- package/src/agent/routine-schedule-format.ts +3 -6
- package/src/agent/routine-schedule-promotion.ts +5 -14
- package/src/agent/routine-schedule-receipts.ts +4 -9
- package/src/cli/agent-knowledge-command.ts +6 -11
- package/src/cli/agent-knowledge-format.ts +4 -9
- package/src/cli/agent-knowledge-runtime.ts +7 -14
- package/src/cli/external-runtime.ts +3 -46
- package/src/cli/help.ts +2 -2
- package/src/cli/status.ts +6 -7
- package/src/input/agent-workspace-categories.ts +23 -23
- package/src/input/agent-workspace-channels.ts +3 -3
- package/src/input/agent-workspace-operations-command-editors.ts +1 -1
- package/src/input/command-registry.ts +1 -1
- package/src/input/commands/compat-runtime.ts +1 -1
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/runtime-services.ts +1 -1
- package/src/input/mcp-workspace.ts +1 -1
- package/src/input/submission-router.ts +1 -1
- package/src/panels/builtin/shared.ts +1 -1
- package/src/panels/project-planning-panel.ts +4 -4
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/conversation-overlays.ts +1 -0
- package/src/runtime/bootstrap-command-parts.ts +1 -1
- package/src/runtime/bootstrap-core.ts +3 -1
- package/src/runtime/bootstrap-hook-bridge.ts +1 -1
- package/src/runtime/bootstrap-shell.ts +1 -1
- package/src/runtime/bootstrap.ts +7 -4
- package/src/runtime/context.ts +2 -2
- package/src/runtime/index.ts +88 -5
- package/src/runtime/store/state.ts +1 -1
- package/src/tools/agent-channel-send-tool.ts +1 -1
- package/src/tools/agent-harness-channel-metadata.ts +36 -25
- package/src/tools/agent-harness-cli-metadata.ts +19 -1
- package/src/tools/agent-harness-command-catalog.ts +15 -4
- package/src/tools/agent-harness-connected-host-status.ts +7 -6
- package/src/tools/agent-harness-delegation-posture.ts +15 -4
- package/src/tools/agent-harness-keybinding-metadata.ts +67 -16
- package/src/tools/agent-harness-mcp-metadata.ts +11 -3
- package/src/tools/agent-harness-media-posture.ts +25 -14
- package/src/tools/agent-harness-metadata.ts +140 -37
- package/src/tools/agent-harness-mode-catalog.ts +258 -0
- package/src/tools/agent-harness-model-routing.ts +18 -3
- package/src/tools/agent-harness-model-tool-catalog.ts +85 -7
- package/src/tools/agent-harness-notification-metadata.ts +30 -19
- package/src/tools/agent-harness-operator-methods.ts +15 -10
- package/src/tools/agent-harness-pairing-posture.ts +17 -5
- package/src/tools/agent-harness-panel-metadata.ts +10 -4
- package/src/tools/agent-harness-provider-account-metadata.ts +46 -35
- package/src/tools/agent-harness-release-evidence.ts +31 -3
- package/src/tools/agent-harness-release-readiness.ts +30 -0
- package/src/tools/agent-harness-security-posture.ts +18 -4
- package/src/tools/agent-harness-service-posture.ts +9 -2
- package/src/tools/agent-harness-session-metadata.ts +24 -8
- package/src/tools/agent-harness-setup-posture.ts +32 -21
- package/src/tools/agent-harness-text.ts +6 -0
- package/src/tools/agent-harness-tool-schema.ts +1 -1
- package/src/tools/agent-harness-tool.ts +38 -36
- package/src/tools/agent-harness-ui-surface-metadata.ts +105 -101
- package/src/tools/agent-harness-workspace-actions.ts +64 -3
- package/src/tools/agent-knowledge-ingest-tool.ts +1 -1
- package/src/tools/agent-knowledge-tool.ts +1 -1
- package/src/tools/agent-media-generate-tool.ts +2 -2
- package/src/tools/agent-notify-tool.ts +1 -1
- package/src/tools/agent-reminder-schedule-tool.ts +1 -1
- package/src/tools/tool-definition-compaction.ts +76 -0
- package/src/version.ts +2 -8
|
@@ -25,9 +25,9 @@ function scheduleValue(preview: ReminderSchedulePreview): string {
|
|
|
25
25
|
function formatReminderScheduleFailureKind(kind: string): string {
|
|
26
26
|
if (kind === 'auth_required') return 'authorization required';
|
|
27
27
|
if (kind === 'connected_host_unavailable') return 'connected host unavailable';
|
|
28
|
+
if (kind === 'connected_host_incompatible') return 'connected host incompatible';
|
|
28
29
|
if (kind === 'connected_host_route_unavailable') return 'connected host route unavailable';
|
|
29
30
|
if (kind === 'connected_host_error') return 'connected host error';
|
|
30
|
-
if (kind === 'version_mismatch') return 'version mismatch';
|
|
31
31
|
return kind.replace(/[_-]+/g, ' ');
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -68,16 +68,13 @@ export function formatReminderScheduleFailure(failure: ReminderScheduleFailure):
|
|
|
68
68
|
` ${failure.error}`,
|
|
69
69
|
failure.baseUrl ? ` connected host ${failure.baseUrl}` : null,
|
|
70
70
|
` route ${REMINDER_SCHEDULE_METHOD} ${failure.route}`,
|
|
71
|
-
failure.kind === 'version_mismatch' && failure.connectedHostVersion && failure.expectedSdkVersion
|
|
72
|
-
? ` versions connected host ${failure.connectedHostVersion}; expected ${failure.expectedSdkVersion}`
|
|
73
|
-
: null,
|
|
74
71
|
failure.kind === 'auth_required'
|
|
75
72
|
? ' next pair/authenticate with the connected GoodVibes host, then retry with --yes.'
|
|
76
73
|
: null,
|
|
77
74
|
failure.kind === 'connected_host_unavailable'
|
|
78
75
|
? ' next make the connected GoodVibes host available outside Agent, then retry.'
|
|
79
76
|
: null,
|
|
80
|
-
failure.kind === '
|
|
77
|
+
failure.kind === 'connected_host_incompatible' || failure.kind === 'connected_host_route_unavailable'
|
|
81
78
|
? ' next update the connected GoodVibes host so public schedules.create is available.'
|
|
82
79
|
: null,
|
|
83
80
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
@@ -2,7 +2,6 @@ import { createBrowserGoodVibesSdk } from '@pellux/goodvibes-sdk/browser';
|
|
|
2
2
|
import type { OperatorMethodInput, OperatorMethodOutput } from '@pellux/goodvibes-sdk/contracts';
|
|
3
3
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
4
|
import { getModelIdFromProviderModel, getProviderIdFromModel } from '../config/provider-model.ts';
|
|
5
|
-
import { SDK_VERSION } from '../version.ts';
|
|
6
5
|
import {
|
|
7
6
|
resolveAgentConnectedHostConnection,
|
|
8
7
|
ROUTINE_SCHEDULE_METHOD,
|
|
@@ -59,14 +58,12 @@ export interface ReminderScheduleFailure {
|
|
|
59
58
|
| 'confirmation_required'
|
|
60
59
|
| 'auth_required'
|
|
61
60
|
| 'connected_host_unavailable'
|
|
62
|
-
| '
|
|
61
|
+
| 'connected_host_incompatible'
|
|
63
62
|
| 'connected_host_route_unavailable'
|
|
64
63
|
| 'connected_host_error';
|
|
65
64
|
readonly error: string;
|
|
66
65
|
readonly route: typeof REMINDER_SCHEDULE_ROUTE;
|
|
67
66
|
readonly baseUrl?: string;
|
|
68
|
-
readonly connectedHostVersion?: string;
|
|
69
|
-
readonly expectedSdkVersion?: string;
|
|
70
67
|
}
|
|
71
68
|
|
|
72
69
|
export type ReminderScheduleResult = ReminderScheduleSuccess | ReminderScheduleFailure;
|
|
@@ -440,17 +437,13 @@ async function classifyReminderScheduleError(
|
|
|
440
437
|
}
|
|
441
438
|
if (lower.includes('404') || lower.includes('not found')) {
|
|
442
439
|
const connectedHost = await fetchConnectedHostStatus(connection);
|
|
443
|
-
|
|
444
|
-
const connectedHostVersion = readString(record, 'version') ?? 'unknown';
|
|
445
|
-
if (connectedHost.ok && connectedHostVersion !== SDK_VERSION) {
|
|
440
|
+
if (connectedHost.ok) {
|
|
446
441
|
return {
|
|
447
442
|
ok: false,
|
|
448
|
-
kind: '
|
|
449
|
-
error:
|
|
443
|
+
kind: 'connected_host_incompatible',
|
|
444
|
+
error: 'Connected GoodVibes host compatibility does not satisfy Agent schedule requirements; schedules.create is unavailable.',
|
|
450
445
|
route: REMINDER_SCHEDULE_ROUTE,
|
|
451
446
|
baseUrl: connection.baseUrl,
|
|
452
|
-
connectedHostVersion,
|
|
453
|
-
expectedSdkVersion: SDK_VERSION,
|
|
454
447
|
};
|
|
455
448
|
}
|
|
456
449
|
return { ok: false, kind: 'connected_host_route_unavailable', error: message, route: REMINDER_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
|
|
@@ -41,9 +41,9 @@ function formatDeliveryTarget(target: {
|
|
|
41
41
|
function formatRoutineScheduleFailureKind(kind: string): string {
|
|
42
42
|
if (kind === 'auth_required') return 'authorization required';
|
|
43
43
|
if (kind === 'connected_host_unavailable') return 'connected host unavailable';
|
|
44
|
+
if (kind === 'connected_host_incompatible') return 'connected host incompatible';
|
|
44
45
|
if (kind === 'connected_host_route_unavailable') return 'connected host route unavailable';
|
|
45
46
|
if (kind === 'connected_host_error') return 'connected host error';
|
|
46
|
-
if (kind === 'version_mismatch') return 'version mismatch';
|
|
47
47
|
return kind.replace(/[_-]+/g, ' ');
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -140,7 +140,7 @@ export function formatRoutineScheduleCorrelation(result: RoutineScheduleCorrelat
|
|
|
140
140
|
result.kind === 'connected_host_unavailable'
|
|
141
141
|
? ' next make the connected GoodVibes host available outside Agent, then retry.'
|
|
142
142
|
: null,
|
|
143
|
-
result.kind === '
|
|
143
|
+
result.kind === 'connected_host_incompatible' || result.kind === 'connected_host_route_unavailable'
|
|
144
144
|
? ' next update the connected GoodVibes host so public schedules.list is available.'
|
|
145
145
|
: null,
|
|
146
146
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
@@ -186,16 +186,13 @@ export function formatRoutineScheduleFailure(failure: RoutineSchedulePromotionFa
|
|
|
186
186
|
` ${failure.error}`,
|
|
187
187
|
failure.baseUrl ? ` connected host ${failure.baseUrl}` : null,
|
|
188
188
|
` route ${ROUTINE_SCHEDULE_METHOD} ${failure.route}`,
|
|
189
|
-
failure.kind === 'version_mismatch' && failure.connectedHostVersion && failure.expectedSdkVersion
|
|
190
|
-
? ` versions connected host ${failure.connectedHostVersion}; expected ${failure.expectedSdkVersion}`
|
|
191
|
-
: null,
|
|
192
189
|
failure.kind === 'auth_required'
|
|
193
190
|
? ' next pair/authenticate with the connected GoodVibes host, then retry with --yes.'
|
|
194
191
|
: null,
|
|
195
192
|
failure.kind === 'connected_host_unavailable'
|
|
196
193
|
? ' next make the connected GoodVibes host available outside Agent, then retry.'
|
|
197
194
|
: null,
|
|
198
|
-
failure.kind === '
|
|
195
|
+
failure.kind === 'connected_host_incompatible' || failure.kind === 'connected_host_route_unavailable'
|
|
199
196
|
? ' next update the connected GoodVibes host so public schedules.create is available.'
|
|
200
197
|
: null,
|
|
201
198
|
].filter((line): line is string => Boolean(line)).join('\n');
|
|
@@ -4,7 +4,6 @@ import { createBrowserGoodVibesSdk } from '@pellux/goodvibes-sdk/browser';
|
|
|
4
4
|
import type { OperatorMethodInput, OperatorMethodOutput } from '@pellux/goodvibes-sdk/contracts';
|
|
5
5
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
6
6
|
import { getModelIdFromProviderModel, getProviderIdFromModel } from '../config/provider-model.ts';
|
|
7
|
-
import { SDK_VERSION } from '../version.ts';
|
|
8
7
|
import { formatAgentRecordReviewState } from './record-labels.ts';
|
|
9
8
|
import type { AgentRoutineRecord } from './routine-registry.ts';
|
|
10
9
|
|
|
@@ -108,14 +107,12 @@ export interface RoutineSchedulePromotionFailure {
|
|
|
108
107
|
| 'confirmation_required'
|
|
109
108
|
| 'auth_required'
|
|
110
109
|
| 'connected_host_unavailable'
|
|
111
|
-
| '
|
|
110
|
+
| 'connected_host_incompatible'
|
|
112
111
|
| 'connected_host_route_unavailable'
|
|
113
112
|
| 'connected_host_error';
|
|
114
113
|
readonly error: string;
|
|
115
114
|
readonly route: typeof ROUTINE_SCHEDULE_ROUTE;
|
|
116
115
|
readonly baseUrl?: string;
|
|
117
|
-
readonly connectedHostVersion?: string;
|
|
118
|
-
readonly expectedSdkVersion?: string;
|
|
119
116
|
}
|
|
120
117
|
|
|
121
118
|
export type RoutineSchedulePromotionResult =
|
|
@@ -194,14 +191,12 @@ export interface RoutineScheduleCorrelationFailure {
|
|
|
194
191
|
readonly kind:
|
|
195
192
|
| 'auth_required'
|
|
196
193
|
| 'connected_host_unavailable'
|
|
197
|
-
| '
|
|
194
|
+
| 'connected_host_incompatible'
|
|
198
195
|
| 'connected_host_route_unavailable'
|
|
199
196
|
| 'connected_host_error';
|
|
200
197
|
readonly error: string;
|
|
201
198
|
readonly route: typeof ROUTINE_SCHEDULE_ROUTE;
|
|
202
199
|
readonly baseUrl?: string;
|
|
203
|
-
readonly connectedHostVersion?: string;
|
|
204
|
-
readonly expectedSdkVersion?: string;
|
|
205
200
|
}
|
|
206
201
|
|
|
207
202
|
export type RoutineScheduleCorrelationResult =
|
|
@@ -389,17 +384,13 @@ async function classifyScheduleError(
|
|
|
389
384
|
}
|
|
390
385
|
if (lower.includes('404') || lower.includes('not found')) {
|
|
391
386
|
const connectedHost = await fetchConnectedHostStatus(connection);
|
|
392
|
-
|
|
393
|
-
const connectedHostVersion = readString(record, 'version') ?? 'unknown';
|
|
394
|
-
if (connectedHost.ok && connectedHostVersion !== SDK_VERSION) {
|
|
387
|
+
if (connectedHost.ok) {
|
|
395
388
|
return {
|
|
396
389
|
ok: false,
|
|
397
|
-
kind: '
|
|
398
|
-
error:
|
|
390
|
+
kind: 'connected_host_incompatible',
|
|
391
|
+
error: 'Connected GoodVibes host compatibility does not satisfy Agent schedule requirements; schedules.create is unavailable.',
|
|
399
392
|
route: ROUTINE_SCHEDULE_ROUTE,
|
|
400
393
|
baseUrl: connection.baseUrl,
|
|
401
|
-
connectedHostVersion,
|
|
402
|
-
expectedSdkVersion: SDK_VERSION,
|
|
403
394
|
};
|
|
404
395
|
}
|
|
405
396
|
return { ok: false, kind: 'connected_host_route_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
|
|
@@ -6,7 +6,6 @@ import { formatEveryInterval } from '@pellux/goodvibes-sdk/platform/automation';
|
|
|
6
6
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
7
7
|
import type { ShellPathService } from '@/runtime/index.ts';
|
|
8
8
|
import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
|
|
9
|
-
import { SDK_VERSION } from '../version.ts';
|
|
10
9
|
import { isRoutineScheduleDeliverySurfaceKind } from './routine-schedule-args.ts';
|
|
11
10
|
import {
|
|
12
11
|
ROUTINE_SCHEDULE_LIST_METHOD,
|
|
@@ -83,7 +82,7 @@ function redactedDeliveryTargets(delivery: ScheduleDeliveryInput | undefined): r
|
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
function normalizeFailureKind(value: unknown): RoutineScheduleReceipt['failureKind'] {
|
|
86
|
-
if (value === 'confirmation_required' || value === 'auth_required' || value === '
|
|
85
|
+
if (value === 'confirmation_required' || value === 'auth_required' || value === 'connected_host_incompatible') return value;
|
|
87
86
|
if (value === 'connected_host_unavailable' || value === 'connected_host_route_unavailable' || value === 'connected_host_error') return value;
|
|
88
87
|
if (value === 'daemon_unavailable') return 'connected_host_unavailable';
|
|
89
88
|
if (value === 'daemon_route_unavailable') return 'connected_host_route_unavailable';
|
|
@@ -450,17 +449,13 @@ async function classifyScheduleListError(
|
|
|
450
449
|
}
|
|
451
450
|
if (lower.includes('404') || lower.includes('not found')) {
|
|
452
451
|
const connectedHost = await fetchConnectedHostStatus(connection);
|
|
453
|
-
|
|
454
|
-
const connectedHostVersion = readString(record, 'version') ?? 'unknown';
|
|
455
|
-
if (connectedHost.ok && connectedHostVersion !== SDK_VERSION) {
|
|
452
|
+
if (connectedHost.ok) {
|
|
456
453
|
return {
|
|
457
454
|
ok: false,
|
|
458
|
-
kind: '
|
|
459
|
-
error:
|
|
455
|
+
kind: 'connected_host_incompatible',
|
|
456
|
+
error: 'Connected GoodVibes host compatibility does not satisfy Agent schedule requirements; schedules.list is unavailable.',
|
|
460
457
|
route: ROUTINE_SCHEDULE_ROUTE,
|
|
461
458
|
baseUrl: connection.baseUrl,
|
|
462
|
-
connectedHostVersion,
|
|
463
|
-
expectedSdkVersion: SDK_VERSION,
|
|
464
459
|
};
|
|
465
460
|
}
|
|
466
461
|
return { ok: false, kind: 'connected_host_route_unavailable', error: message, route: ROUTINE_SCHEDULE_ROUTE, baseUrl: connection.baseUrl };
|
|
@@ -484,23 +484,19 @@ export async function handleCompatCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
484
484
|
const connection = resolveConnectedHostConnection(runtime);
|
|
485
485
|
const metadata = readPackageMetadata();
|
|
486
486
|
const connectedHost = await fetchConnectedHostStatus(connection);
|
|
487
|
-
const connectedHostRecord = isRecord(connectedHost.body) ? connectedHost.body : {};
|
|
488
|
-
const connectedHostVersion = readString(connectedHostRecord, 'version') ?? 'unknown';
|
|
489
|
-
const versionCompatible = connectedHost.ok && connectedHostVersion === metadata.sdkVersion;
|
|
490
487
|
const knowledgeRoute = await runKnowledgeCall(runtime, AGENT_KNOWLEDGE_METHODS.status, async (routeConnection) => (
|
|
491
488
|
await createAgentSdk(routeConnection).knowledge.status()
|
|
492
489
|
));
|
|
493
490
|
const knowledgeRouteReady = knowledgeRoute.ok;
|
|
491
|
+
const hostCompatible = connectedHost.ok && knowledgeRouteReady;
|
|
494
492
|
const value = {
|
|
495
|
-
ok:
|
|
493
|
+
ok: hostCompatible && knowledgeRouteReady,
|
|
496
494
|
packageVersion: metadata.version,
|
|
497
|
-
sdkPin: metadata.sdkVersion,
|
|
498
495
|
connectedHost: {
|
|
499
496
|
baseUrl: connection.baseUrl,
|
|
500
497
|
status: connectedHost.status,
|
|
501
|
-
version: connectedHostVersion,
|
|
502
498
|
reachable: connectedHost.ok,
|
|
503
|
-
compatible:
|
|
499
|
+
compatible: hostCompatible,
|
|
504
500
|
},
|
|
505
501
|
auth: {
|
|
506
502
|
tokenPresent: Boolean(connection.token),
|
|
@@ -515,12 +511,11 @@ export async function handleCompatCommand(runtime: CliCommandRuntime): Promise<C
|
|
|
515
511
|
const text = [
|
|
516
512
|
'GoodVibes Agent compatibility',
|
|
517
513
|
` package ${metadata.version}`,
|
|
518
|
-
`
|
|
519
|
-
`
|
|
520
|
-
` version compatible ${yesNo(versionCompatible)}`,
|
|
514
|
+
` connected host ${connection.baseUrl} (${connectedHost.ok ? 'reachable' : 'unreachable'})`,
|
|
515
|
+
` host compatible ${yesNo(hostCompatible)}`,
|
|
521
516
|
` operator token ${connection.token ? 'present' : 'missing'} (${connection.tokenPath})`,
|
|
522
517
|
` Agent Knowledge route ${knowledgeRouteReady ? 'ready' : `not ready (${knowledgeRoute.ok ? 'unknown' : formatAgentKnowledgeFailureKind(knowledgeRoute.kind)})`}`,
|
|
523
|
-
...(
|
|
518
|
+
...(hostCompatible ? [] : [' next update the connected GoodVibes host so its public Agent routes are compatible.']),
|
|
524
519
|
].join('\n');
|
|
525
520
|
return {
|
|
526
521
|
output: runtime.cli.flags.outputFormat === 'json' ? JSON.stringify(value, null, 2) : text,
|
|
@@ -6,8 +6,6 @@ export interface AgentKnowledgeFailureLike {
|
|
|
6
6
|
readonly error: string;
|
|
7
7
|
readonly baseUrl: string;
|
|
8
8
|
readonly route: string;
|
|
9
|
-
readonly connectedHostVersion?: string;
|
|
10
|
-
readonly expectedSdkVersion?: string;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
export function isRecord(value: unknown): value is JsonRecord {
|
|
@@ -45,10 +43,10 @@ function yesNo(value: boolean): string {
|
|
|
45
43
|
export function formatAgentKnowledgeFailureKind(kind: string): string {
|
|
46
44
|
if (kind === 'auth_required') return 'authorization required';
|
|
47
45
|
if (kind === 'connected_host_unavailable') return 'connected host unavailable';
|
|
46
|
+
if (kind === 'connected_host_incompatible') return 'connected host incompatible';
|
|
48
47
|
if (kind === 'connected_host_route_unavailable') return 'connected host route unavailable';
|
|
49
48
|
if (kind === 'connected_host_error') return 'connected host error';
|
|
50
49
|
if (kind === 'scope_contamination') return 'scope contamination';
|
|
51
|
-
if (kind === 'version_mismatch') return 'version mismatch';
|
|
52
50
|
return kind.replace(/[_-]+/g, ' ');
|
|
53
51
|
}
|
|
54
52
|
|
|
@@ -384,14 +382,11 @@ export function formatFailure(failure: AgentKnowledgeFailureLike, json: boolean)
|
|
|
384
382
|
` ${failure.error}`,
|
|
385
383
|
` connected host ${failure.baseUrl}`,
|
|
386
384
|
` route ${failure.route}`,
|
|
387
|
-
failure.kind === '
|
|
388
|
-
?
|
|
389
|
-
: null,
|
|
390
|
-
failure.kind === 'version_mismatch'
|
|
391
|
-
? ' next update the connected GoodVibes host so /status matches the Agent SDK pin.'
|
|
385
|
+
failure.kind === 'connected_host_incompatible'
|
|
386
|
+
? ' next update the connected GoodVibes host so its public Agent routes are compatible.'
|
|
392
387
|
: null,
|
|
393
388
|
failure.kind === 'connected_host_route_unavailable'
|
|
394
|
-
? ' next update the connected GoodVibes host
|
|
389
|
+
? ' next update the connected GoodVibes host so Agent Knowledge routes are available.'
|
|
395
390
|
: null,
|
|
396
391
|
failure.kind === 'scope_contamination'
|
|
397
392
|
? ' next update the connected GoodVibes host so Agent Knowledge routes return only Agent-owned scope data.'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createBrowserAgentSdk } from '@pellux/goodvibes-sdk/browser/agent';
|
|
2
2
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
3
|
-
import {
|
|
3
|
+
import { VERSION } from '../version.ts';
|
|
4
4
|
import { readConnectedHostOperatorToken } from '../runtime/connected-host-auth.ts';
|
|
5
5
|
import type { ConnectedHostCallMethod } from './agent-knowledge-methods.ts';
|
|
6
6
|
|
|
@@ -24,15 +24,13 @@ export interface AgentKnowledgeFailure {
|
|
|
24
24
|
readonly kind:
|
|
25
25
|
| 'connected_host_unavailable'
|
|
26
26
|
| 'auth_required'
|
|
27
|
-
| '
|
|
27
|
+
| 'connected_host_incompatible'
|
|
28
28
|
| 'connected_host_route_unavailable'
|
|
29
29
|
| 'connected_host_error'
|
|
30
30
|
| 'scope_contamination';
|
|
31
31
|
readonly error: string;
|
|
32
32
|
readonly baseUrl: string;
|
|
33
33
|
readonly route: string;
|
|
34
|
-
readonly connectedHostVersion?: string;
|
|
35
|
-
readonly expectedSdkVersion?: string;
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
export interface AgentKnowledgeSuccess<TData> {
|
|
@@ -53,8 +51,8 @@ export function readString(record: JsonRecord | null, key: string): string | nul
|
|
|
53
51
|
return typeof value === 'string' ? value : null;
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
export function readPackageMetadata(): { readonly version: string
|
|
57
|
-
return { version: VERSION
|
|
54
|
+
export function readPackageMetadata(): { readonly version: string } {
|
|
55
|
+
return { version: VERSION };
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
export function resolveConnectedHostConnection(runtime: AgentKnowledgeConnectionRuntime): AgentKnowledgeConnection {
|
|
@@ -90,19 +88,14 @@ export async function classifyKnowledgeError(error: unknown, connection: AgentKn
|
|
|
90
88
|
return { ok: false, kind: 'auth_required', error: message, baseUrl: connection.baseUrl, route };
|
|
91
89
|
}
|
|
92
90
|
if (lower.includes('404') || lower.includes('not found')) {
|
|
93
|
-
const metadata = readPackageMetadata();
|
|
94
91
|
const connectedHost = await fetchConnectedHostStatus(connection);
|
|
95
|
-
|
|
96
|
-
const connectedHostVersion = readString(connectedHostRecord, 'version') ?? 'unknown';
|
|
97
|
-
if (connectedHost.ok && connectedHostVersion !== metadata.sdkVersion) {
|
|
92
|
+
if (connectedHost.ok) {
|
|
98
93
|
return {
|
|
99
94
|
ok: false,
|
|
100
|
-
kind: '
|
|
101
|
-
error: `Connected GoodVibes host
|
|
95
|
+
kind: 'connected_host_incompatible',
|
|
96
|
+
error: `Connected GoodVibes host compatibility does not satisfy Agent Knowledge requirements; Agent Knowledge route is unavailable.`,
|
|
102
97
|
baseUrl: connection.baseUrl,
|
|
103
98
|
route,
|
|
104
|
-
connectedHostVersion,
|
|
105
|
-
expectedSdkVersion: metadata.sdkVersion,
|
|
106
99
|
};
|
|
107
100
|
}
|
|
108
101
|
return { ok: false, kind: 'connected_host_route_unavailable', error: message, baseUrl: connection.baseUrl, route };
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
2
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
3
|
-
import { SDK_VERSION } from '../version.ts';
|
|
4
3
|
import { readConnectedHostOperatorToken } from '../runtime/connected-host-auth.ts';
|
|
5
4
|
|
|
6
|
-
type JsonRecord = Record<string, unknown>;
|
|
7
|
-
|
|
8
5
|
export interface CliExternalRuntimeInspectionOptions {
|
|
9
6
|
readonly configManager: Pick<ConfigManager, 'get'>;
|
|
10
7
|
readonly homeDirectory: string;
|
|
@@ -15,8 +12,6 @@ export interface CliExternalRuntimeSnapshot {
|
|
|
15
12
|
readonly baseUrl: string;
|
|
16
13
|
readonly statusCode: number | null;
|
|
17
14
|
readonly reachable: boolean;
|
|
18
|
-
readonly version: string;
|
|
19
|
-
readonly expectedVersion: string;
|
|
20
15
|
readonly compatible: boolean;
|
|
21
16
|
readonly operatorToken: {
|
|
22
17
|
readonly present: boolean;
|
|
@@ -25,21 +20,12 @@ export interface CliExternalRuntimeSnapshot {
|
|
|
25
20
|
readonly agentKnowledge: {
|
|
26
21
|
readonly route: '/api/goodvibes-agent/knowledge/status';
|
|
27
22
|
readonly ready: boolean;
|
|
28
|
-
readonly kind: 'ok' | 'auth_required' | 'connected_host_unavailable' | '
|
|
23
|
+
readonly kind: 'ok' | 'auth_required' | 'connected_host_unavailable' | 'connected_host_incompatible' | 'connected_host_route_unavailable' | 'connected_host_error';
|
|
29
24
|
readonly statusCode: number | null;
|
|
30
25
|
};
|
|
31
26
|
readonly error: string | null;
|
|
32
27
|
}
|
|
33
28
|
|
|
34
|
-
function isRecord(value: unknown): value is JsonRecord {
|
|
35
|
-
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function readString(record: JsonRecord | null, key: string): string | null {
|
|
39
|
-
const value = record?.[key];
|
|
40
|
-
return typeof value === 'string' ? value : null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
29
|
function resolveBaseUrl(configManager: Pick<ConfigManager, 'get'>): string {
|
|
44
30
|
const host = String(configManager.get('controlPlane.host') ?? '127.0.0.1');
|
|
45
31
|
const port = Number(configManager.get('controlPlane.port') ?? 3421);
|
|
@@ -83,17 +69,12 @@ export async function inspectCliExternalRuntime(
|
|
|
83
69
|
|
|
84
70
|
try {
|
|
85
71
|
const status = await fetchJson(`${baseUrl}/status`, token.token, timeoutMs);
|
|
86
|
-
const statusRecord = isRecord(status.body) ? status.body : {};
|
|
87
|
-
const version = readString(statusRecord, 'version') ?? 'unknown';
|
|
88
|
-
const compatible = status.ok && version === SDK_VERSION;
|
|
89
72
|
|
|
90
73
|
if (!status.ok) {
|
|
91
74
|
return {
|
|
92
75
|
baseUrl,
|
|
93
76
|
statusCode: status.status,
|
|
94
77
|
reachable: false,
|
|
95
|
-
version,
|
|
96
|
-
expectedVersion: SDK_VERSION,
|
|
97
78
|
compatible: false,
|
|
98
79
|
operatorToken: { present: Boolean(token.token), path: token.path },
|
|
99
80
|
agentKnowledge: {
|
|
@@ -111,9 +92,7 @@ export async function inspectCliExternalRuntime(
|
|
|
111
92
|
baseUrl,
|
|
112
93
|
statusCode: status.status,
|
|
113
94
|
reachable: true,
|
|
114
|
-
|
|
115
|
-
expectedVersion: SDK_VERSION,
|
|
116
|
-
compatible,
|
|
95
|
+
compatible: false,
|
|
117
96
|
operatorToken: { present: false, path: token.path },
|
|
118
97
|
agentKnowledge: {
|
|
119
98
|
route,
|
|
@@ -125,32 +104,12 @@ export async function inspectCliExternalRuntime(
|
|
|
125
104
|
};
|
|
126
105
|
}
|
|
127
106
|
|
|
128
|
-
if (!compatible) {
|
|
129
|
-
return {
|
|
130
|
-
baseUrl,
|
|
131
|
-
statusCode: status.status,
|
|
132
|
-
reachable: true,
|
|
133
|
-
version,
|
|
134
|
-
expectedVersion: SDK_VERSION,
|
|
135
|
-
compatible: false,
|
|
136
|
-
operatorToken: { present: true, path: token.path },
|
|
137
|
-
agentKnowledge: {
|
|
138
|
-
route,
|
|
139
|
-
ready: false,
|
|
140
|
-
kind: 'version_mismatch',
|
|
141
|
-
statusCode: null,
|
|
142
|
-
},
|
|
143
|
-
error: null,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
107
|
const knowledge = await fetchJson(`${baseUrl}${route}`, token.token, timeoutMs);
|
|
108
|
+
const compatible = knowledge.ok;
|
|
148
109
|
return {
|
|
149
110
|
baseUrl,
|
|
150
111
|
statusCode: status.status,
|
|
151
112
|
reachable: true,
|
|
152
|
-
version,
|
|
153
|
-
expectedVersion: SDK_VERSION,
|
|
154
113
|
compatible,
|
|
155
114
|
operatorToken: { present: true, path: token.path },
|
|
156
115
|
agentKnowledge: {
|
|
@@ -172,8 +131,6 @@ export async function inspectCliExternalRuntime(
|
|
|
172
131
|
baseUrl,
|
|
173
132
|
statusCode: null,
|
|
174
133
|
reachable: false,
|
|
175
|
-
version: 'unknown',
|
|
176
|
-
expectedVersion: SDK_VERSION,
|
|
177
134
|
compatible: false,
|
|
178
135
|
operatorToken: { present: Boolean(token.token), path: token.path },
|
|
179
136
|
agentKnowledge: {
|
package/src/cli/help.ts
CHANGED
|
@@ -56,7 +56,7 @@ export function renderGoodVibesHelp(binary = 'goodvibes-agent'): string {
|
|
|
56
56
|
' memory Manage Agent-owned durable memory records',
|
|
57
57
|
' routines Inspect local routines and explicitly promote one to a connected schedule',
|
|
58
58
|
' auth Inspect Agent auth posture and connection token state',
|
|
59
|
-
' compat Inspect
|
|
59
|
+
' compat Inspect connected-host compatibility and Agent Knowledge route readiness',
|
|
60
60
|
' knowledge Use isolated Agent Knowledge routes',
|
|
61
61
|
' ask|search Shortcuts for isolated Agent Knowledge ask/search',
|
|
62
62
|
' delegate Explicitly delegate build/fix/review work to GoodVibes TUI',
|
|
@@ -296,7 +296,7 @@ const COMMAND_HELP: Record<string, CommandHelp> = {
|
|
|
296
296
|
},
|
|
297
297
|
compat: {
|
|
298
298
|
usage: ['compat', 'compat --json'],
|
|
299
|
-
summary: 'Inspect
|
|
299
|
+
summary: 'Inspect connected-host compatibility and Agent-specific knowledge route readiness.',
|
|
300
300
|
examples: ['compat', 'compat --json'],
|
|
301
301
|
},
|
|
302
302
|
knowledge: {
|
package/src/cli/status.ts
CHANGED
|
@@ -114,13 +114,13 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
114
114
|
});
|
|
115
115
|
} else if (!options.externalRuntime.compatible) {
|
|
116
116
|
findings.push({
|
|
117
|
-
id: 'external-runtime-
|
|
117
|
+
id: 'external-runtime-incompatible',
|
|
118
118
|
area: 'runtime',
|
|
119
119
|
severity: 'warning',
|
|
120
|
-
summary: 'Connected GoodVibes host
|
|
121
|
-
cause:
|
|
122
|
-
impact: 'Agent-only routes, especially isolated Agent Knowledge, may be
|
|
123
|
-
action: 'Update the owning GoodVibes host so
|
|
120
|
+
summary: 'Connected GoodVibes host compatibility does not satisfy Agent readiness.',
|
|
121
|
+
cause: 'Connected host is reachable, but at least one public Agent route is unavailable or incompatible.',
|
|
122
|
+
impact: 'Agent-only routes, especially isolated Agent Knowledge, may be unavailable.',
|
|
123
|
+
action: 'Update the owning GoodVibes host so its public Agent routes are compatible.',
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -144,7 +144,7 @@ export function buildCliDoctorFindings(options: CliStatusOptions): readonly CliD
|
|
|
144
144
|
summary: 'Isolated Agent Knowledge route is not ready.',
|
|
145
145
|
cause: `${options.externalRuntime.agentKnowledge.route} returned ${options.externalRuntime.agentKnowledge.kind}${options.externalRuntime.agentKnowledge.statusCode === null ? '' : ` (${options.externalRuntime.agentKnowledge.statusCode})`}.`,
|
|
146
146
|
impact: 'Agent Knowledge ask/search will not use default or non-Agent knowledge fallback; it will fail closed until the Agent route is available.',
|
|
147
|
-
action: 'Update the connected GoodVibes host
|
|
147
|
+
action: 'Update the connected GoodVibes host so public Agent routes are compatible, then verify goodvibes-agent compat.',
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -283,7 +283,6 @@ export function renderCliStatus(options: CliStatusOptions): string {
|
|
|
283
283
|
...(externalRuntime ? [
|
|
284
284
|
` baseUrl: ${externalRuntime.baseUrl}`,
|
|
285
285
|
` reachable: ${yesNo(externalRuntime.reachable)}${externalRuntime.statusCode === null ? '' : ` (HTTP ${externalRuntime.statusCode})`}`,
|
|
286
|
-
` sdk: ${externalRuntime.version} expected ${externalRuntime.expectedVersion}`,
|
|
287
286
|
` compatible: ${yesNo(externalRuntime.compatible)}`,
|
|
288
287
|
` access token: ${externalRuntime.operatorToken.present ? 'present' : 'missing'} (${externalRuntime.operatorToken.path})`,
|
|
289
288
|
` Agent Knowledge: ${externalRuntime.agentKnowledge.ready ? 'ready' : `not ready (${formatAgentKnowledgeFailureKind(externalRuntime.agentKnowledge.kind)})`}`,
|