@pellux/goodvibes-agent 1.1.7 → 1.3.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 +329 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +138903 -91477
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +58 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +116 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +142 -5
- package/release/release-readiness.json +124 -94
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +294 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +683 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +313 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +217 -0
- package/src/input/agent-workspace-setup.ts +61 -1
- package/src/input/agent-workspace-snapshot.ts +184 -149
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +23 -1
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/input/setup-wizard-live-receipts.ts +76 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +701 -0
- package/src/renderer/agent-workspace.ts +68 -421
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +39 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +199 -5
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +137 -7
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
- package/src/tools/agent-harness-agent-orchestration.ts +791 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +742 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +571 -0
- package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +798 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +373 -0
- package/src/tools/agent-harness-browser-control.ts +346 -0
- package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-device-live-read-models.ts +366 -0
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +385 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +269 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +788 -0
- package/src/tools/agent-harness-local-model-smoke.ts +277 -0
- package/src/tools/agent-harness-local-model-url.ts +78 -0
- package/src/tools/agent-harness-media-posture.ts +223 -2
- package/src/tools/agent-harness-memory-external-providers.ts +796 -0
- package/src/tools/agent-harness-memory-posture.ts +672 -0
- package/src/tools/agent-harness-memory-provider-certification.ts +219 -0
- package/src/tools/agent-harness-memory-refinement.ts +340 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +86 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +283 -0
- package/src/tools/agent-harness-model-readiness.ts +432 -0
- package/src/tools/agent-harness-model-routing-types.ts +327 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +165 -193
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +452 -18
- package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +270 -0
- package/src/tools/agent-harness-personal-ops-operations.ts +225 -0
- package/src/tools/agent-harness-personal-ops-provider-records.ts +358 -0
- package/src/tools/agent-harness-personal-ops-provider-task-records.ts +321 -0
- package/src/tools/agent-harness-personal-ops-records.ts +684 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +240 -0
- package/src/tools/agent-harness-personal-ops.ts +613 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-remote-read-models.ts +541 -0
- package/src/tools/agent-harness-research-briefing.ts +446 -0
- package/src/tools/agent-harness-research-live-read-models.ts +500 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +307 -0
- package/src/tools/agent-harness-research-workflow.ts +395 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +102 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +533 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +142 -7
- package/src/tools/agent-harness-tool-types.ts +83 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +319 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +253 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +735 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runner.ts +367 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +515 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +106 -85
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
import type { MemoryDoctorReport, MemoryEmbeddingProviderStatus, MemoryVectorStats } from '@pellux/goodvibes-sdk/platform/state';
|
|
2
|
+
import type { CommandContext } from '../input/command-registry.ts';
|
|
3
|
+
import { buildAgentWorkspaceRuntimeSnapshot } from '../input/agent-workspace-snapshot.ts';
|
|
4
|
+
import { previewHarnessText } from './agent-harness-text.ts';
|
|
5
|
+
import { EXTERNAL_MEMORY_RECEIPT_FIELDS, EXTERNAL_MEMORY_REQUIRED_CONTRACTS, aggregateExternalProviderLiveRecord, aggregateExternalProviderSetupStatus, externalMemoryLiveProviderRecords, externalMemoryProviderCatalog, externalMemoryReceiptEvidence, externalProviderLiveReady, liveRecordForProvider, receiptEvidenceForProvider, setupStatusFromLiveRecord } from './agent-harness-memory-external-providers.ts';
|
|
6
|
+
import type { ExternalMemoryProviderCatalogEntry, MemoryExternalProviderContractCheck, MemoryExternalProviderContractStatus, MemoryExternalProviderLiveRecord, MemoryExternalProviderReceiptContract, MemoryExternalProviderReceiptEvidence, MemoryExternalProviderRoute, MemoryExternalProviderSetupGuide, MemoryExternalProviderStatus, MemoryPostureProvider, MemoryProviderResolution } from './agent-harness-memory-external-providers.ts';
|
|
7
|
+
|
|
8
|
+
type MemoryPostureStatus = 'ready' | 'needs-review' | 'empty' | 'unavailable';
|
|
9
|
+
type MemoryVectorPostureStatus = 'ready' | 'attention' | 'disabled' | 'unavailable';
|
|
10
|
+
interface AgentHarnessMemoryPostureArgs {
|
|
11
|
+
readonly providerId?: unknown;
|
|
12
|
+
readonly target?: unknown;
|
|
13
|
+
readonly query?: unknown;
|
|
14
|
+
readonly includeParameters?: unknown;
|
|
15
|
+
readonly limit?: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function readString(value: unknown): string {
|
|
19
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function readLimit(value: unknown, fallback: number): number {
|
|
23
|
+
const parsed = typeof value === 'string' && value.trim() ? Number(value) : value;
|
|
24
|
+
if (typeof parsed !== 'number' || !Number.isFinite(parsed)) return fallback;
|
|
25
|
+
return Math.max(1, Math.min(200, Math.trunc(parsed)));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function memoryApi(context: CommandContext): {
|
|
29
|
+
readonly vectorStats?: () => MemoryVectorStats;
|
|
30
|
+
readonly doctor?: () => Promise<MemoryDoctorReport>;
|
|
31
|
+
} | null {
|
|
32
|
+
return context.clients?.agentKnowledgeApi?.memory ?? null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function readMemoryDoctor(context: CommandContext): Promise<MemoryDoctorReport | null> {
|
|
36
|
+
const memory = memoryApi(context);
|
|
37
|
+
if (!memory || typeof memory.doctor !== 'function') return null;
|
|
38
|
+
try {
|
|
39
|
+
return await memory.doctor();
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function readVectorStats(context: CommandContext, doctor: MemoryDoctorReport | null): MemoryVectorStats | null {
|
|
46
|
+
if (doctor?.vector) return doctor.vector;
|
|
47
|
+
const memory = memoryApi(context);
|
|
48
|
+
if (!memory || typeof memory.vectorStats !== 'function') return null;
|
|
49
|
+
try {
|
|
50
|
+
return memory.vectorStats();
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function memoryStatus(snapshot: ReturnType<typeof buildAgentWorkspaceRuntimeSnapshot>, memoryAvailable: boolean): MemoryPostureStatus {
|
|
57
|
+
if (!memoryAvailable) return 'unavailable';
|
|
58
|
+
if (snapshot.localMemoryCount === 0) return 'empty';
|
|
59
|
+
if (snapshot.localMemoryPromptActiveCount > 0) return 'ready';
|
|
60
|
+
return 'needs-review';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function vectorStatus(vector: MemoryVectorStats | null): MemoryVectorPostureStatus {
|
|
64
|
+
if (!vector) return 'unavailable';
|
|
65
|
+
if (!vector.enabled) return 'disabled';
|
|
66
|
+
if (vector.available && !vector.error) return 'ready';
|
|
67
|
+
return 'attention';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function describeEmbeddingProvider(
|
|
71
|
+
provider: MemoryEmbeddingProviderStatus,
|
|
72
|
+
activeProviderId: string | undefined,
|
|
73
|
+
includeParameters: boolean,
|
|
74
|
+
): MemoryPostureProvider {
|
|
75
|
+
return {
|
|
76
|
+
id: provider.id,
|
|
77
|
+
label: provider.label,
|
|
78
|
+
kind: 'embedding',
|
|
79
|
+
status: provider.state,
|
|
80
|
+
summary: previewHarnessText(provider.detail ?? `${provider.configured ? 'configured' : 'not configured'} memory embedding provider`, includeParameters ? 180 : 96),
|
|
81
|
+
modelRoute: `memory action:"provider" providerId:"${provider.id}"`,
|
|
82
|
+
setupRoute: `settings action:"set" key:"provider.embeddingProvider" value:"${provider.id}" confirm:true explicitUserRequest:"..."`,
|
|
83
|
+
configured: provider.configured,
|
|
84
|
+
active: provider.id === activeProviderId,
|
|
85
|
+
dimensions: provider.dimensions,
|
|
86
|
+
...(typeof provider.deterministic === 'boolean' ? { deterministic: provider.deterministic } : {}),
|
|
87
|
+
...(includeParameters ? { metadata: provider.metadata } : {}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function externalProviderNextRoutes(
|
|
92
|
+
provider: ExternalMemoryProviderCatalogEntry,
|
|
93
|
+
liveRecord: MemoryExternalProviderLiveRecord | null = null,
|
|
94
|
+
): readonly MemoryExternalProviderRoute[] {
|
|
95
|
+
const liveRoutes: MemoryExternalProviderRoute[] = [];
|
|
96
|
+
if (liveRecord?.readRoute) {
|
|
97
|
+
liveRoutes.push({
|
|
98
|
+
id: 'read-provider-memory',
|
|
99
|
+
label: 'Read provider memory',
|
|
100
|
+
modelRoute: liveRecord.readRoute,
|
|
101
|
+
effect: 'read-only',
|
|
102
|
+
why: 'Uses the daemon-published bounded read/search route with provider redaction and provenance policy.',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (liveRecord?.writeRoute) {
|
|
106
|
+
liveRoutes.push({
|
|
107
|
+
id: 'write-provider-memory',
|
|
108
|
+
label: 'Write provider memory',
|
|
109
|
+
modelRoute: liveRecord.writeRoute,
|
|
110
|
+
effect: 'confirmed',
|
|
111
|
+
why: 'External memory writes require explicit user request, confirmation, and a durable provider receipt.',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (liveRecord?.syncRoute) {
|
|
115
|
+
liveRoutes.push({
|
|
116
|
+
id: 'sync-provider-memory',
|
|
117
|
+
label: 'Sync provider memory',
|
|
118
|
+
modelRoute: liveRecord.syncRoute,
|
|
119
|
+
effect: 'confirmed',
|
|
120
|
+
why: 'Provider sync/import/export crosses a boundary and needs confirmation plus durable receipt evidence.',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (liveRecord?.forgetRoute) {
|
|
124
|
+
liveRoutes.push({
|
|
125
|
+
id: 'forget-provider-memory',
|
|
126
|
+
label: 'Forget provider memory',
|
|
127
|
+
modelRoute: liveRecord.forgetRoute,
|
|
128
|
+
effect: 'confirmed',
|
|
129
|
+
why: 'Provider forget/delete/disable effects require explicit user request and durable receipt evidence.',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return [
|
|
133
|
+
...liveRoutes,
|
|
134
|
+
{
|
|
135
|
+
id: 'inspect-provider-contract',
|
|
136
|
+
label: 'Inspect provider contract',
|
|
137
|
+
modelRoute: `memory action:"provider" providerId:"${provider.id}" includeParameters:true`,
|
|
138
|
+
effect: 'read-only',
|
|
139
|
+
why: 'Shows the current SDK/daemon contract checklist, missing receipt fields, credential boundary, and local fallback.',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 'inspect-host-capability',
|
|
143
|
+
label: 'Inspect host capability',
|
|
144
|
+
modelRoute: `host action:"capability" query:"${provider.id} memory provider"`,
|
|
145
|
+
effect: 'read-only',
|
|
146
|
+
why: 'Checks whether the connected GoodVibes host publishes a provider capability record for Agent to consume.',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: 'inspect-mcp-server',
|
|
150
|
+
label: 'Inspect MCP server',
|
|
151
|
+
modelRoute: `agent_harness mode:"mcp_servers" query:"${provider.id}"`,
|
|
152
|
+
effect: 'read-only',
|
|
153
|
+
why: 'Finds a matching MCP connector without reading secrets or invoking provider writes.',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: 'inspect-memory-settings',
|
|
157
|
+
label: 'Inspect memory settings',
|
|
158
|
+
modelRoute: 'settings action:"list" query:"memory" includeHidden:true',
|
|
159
|
+
effect: 'read-only',
|
|
160
|
+
why: 'Shows safe setting keys and secret-ref posture before any memory-provider configuration change.',
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function externalProviderContractChecklist(
|
|
166
|
+
provider: ExternalMemoryProviderCatalogEntry,
|
|
167
|
+
receipts: readonly MemoryExternalProviderReceiptEvidence[] = [],
|
|
168
|
+
liveRecord: MemoryExternalProviderLiveRecord | null = null,
|
|
169
|
+
): readonly MemoryExternalProviderContractCheck[] {
|
|
170
|
+
const providerQuery = `${provider.id} memory provider`;
|
|
171
|
+
const hasReceipts = receipts.length > 0;
|
|
172
|
+
const liveInspectRoute = liveRecord?.inspectRoute ?? `host action:"capability" query:"${providerQuery}"`;
|
|
173
|
+
const providerCertificationPublished: MemoryExternalProviderContractStatus = liveRecord?.certification?.schemaStatus === 'certified'
|
|
174
|
+
&& liveRecord.certification.missingSignals.length === 0
|
|
175
|
+
? 'published'
|
|
176
|
+
: 'missing';
|
|
177
|
+
const statusRecordStatus: MemoryExternalProviderContractStatus = liveRecord ? 'published' : 'missing';
|
|
178
|
+
const credentialStatus: MemoryExternalProviderContractStatus = liveRecord && (liveRecord.credentialState !== null || liveRecord.configured !== null) ? 'published' : 'missing';
|
|
179
|
+
const readStatus: MemoryExternalProviderContractStatus = liveRecord?.readReady === true || liveRecord?.readRoute ? 'published' : 'missing';
|
|
180
|
+
const writeStatus: MemoryExternalProviderContractStatus = liveRecord?.writeReady === true || liveRecord?.writeRoute ? 'published' : 'missing';
|
|
181
|
+
const forgetStatus: MemoryExternalProviderContractStatus = liveRecord && (liveRecord.forgetReady !== null || liveRecord.forgetRoute) ? 'published' : 'missing';
|
|
182
|
+
const syncStatus: MemoryExternalProviderContractStatus = liveRecord?.syncReady === true || liveRecord?.syncRoute || liveRecord?.receiptRoute || liveRecord?.receiptIds.length
|
|
183
|
+
? 'published'
|
|
184
|
+
: hasReceipts ? 'artifact-evidence-found' : 'missing';
|
|
185
|
+
const promptPolicyStatus: MemoryExternalProviderContractStatus = liveRecord && liveRecord.promptEligible !== null ? 'published' : 'missing';
|
|
186
|
+
return [
|
|
187
|
+
{
|
|
188
|
+
id: 'certified-provider-contract',
|
|
189
|
+
label: 'Certified provider schema/publication evidence',
|
|
190
|
+
status: providerCertificationPublished,
|
|
191
|
+
requiredFor: 'Treat provider readiness as release-grade instead of a legacy host hint.',
|
|
192
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
193
|
+
inspectRoute: liveInspectRoute,
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: 'status-record',
|
|
197
|
+
label: 'Provider status/readiness record',
|
|
198
|
+
status: statusRecordStatus,
|
|
199
|
+
requiredFor: 'Show whether the provider is configured, reachable, and safe to use.',
|
|
200
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
201
|
+
inspectRoute: liveInspectRoute,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: 'credential-reference',
|
|
205
|
+
label: 'Credential reference without raw secret values',
|
|
206
|
+
status: credentialStatus,
|
|
207
|
+
requiredFor: 'Let the user repair auth without exposing API keys or memory payloads.',
|
|
208
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
209
|
+
inspectRoute: liveRecord?.setupRoute ?? 'settings action:"list" query:"memory" includeHidden:true',
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
id: 'bounded-read-search',
|
|
213
|
+
label: 'Bounded read/search route',
|
|
214
|
+
status: readStatus,
|
|
215
|
+
requiredFor: 'Review external memories with redaction, provenance, and source limits before prompt use.',
|
|
216
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
217
|
+
inspectRoute: liveRecord?.readRoute ?? `agent_harness mode:"mcp_servers" query:"${provider.id}"`,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: 'confirmed-write-upsert',
|
|
221
|
+
label: 'Confirmed write/upsert/import route',
|
|
222
|
+
status: writeStatus,
|
|
223
|
+
requiredFor: 'Write external memories only after explicit user request and confirmation.',
|
|
224
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
225
|
+
inspectRoute: liveRecord?.writeRoute ?? `host action:"capability" query:"${providerQuery}"`,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: 'forget-contract',
|
|
229
|
+
label: 'Forget/delete or explicit not-supported contract',
|
|
230
|
+
status: forgetStatus,
|
|
231
|
+
requiredFor: 'Prove provider memory can be removed or that removal is explicitly unsupported before the provider is relied on.',
|
|
232
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
233
|
+
inspectRoute: liveRecord?.forgetRoute ?? liveInspectRoute,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: 'sync-receipts',
|
|
237
|
+
label: 'Sync/import/export receipts',
|
|
238
|
+
status: syncStatus,
|
|
239
|
+
requiredFor: 'Prove what crossed the provider boundary, when it happened, and what failed.',
|
|
240
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
241
|
+
inspectRoute: liveRecord?.receiptRoute ?? liveRecord?.syncRoute ?? (hasReceipts
|
|
242
|
+
? receipts[0]!.inspectRoute
|
|
243
|
+
: `memory action:"provider" providerId:"${provider.id}" includeParameters:true`),
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: 'prompt-eligibility-policy',
|
|
247
|
+
label: 'Prompt eligibility policy',
|
|
248
|
+
status: promptPolicyStatus,
|
|
249
|
+
requiredFor: 'Prevent external provider records from silently entering the Agent prompt.',
|
|
250
|
+
owner: 'goodvibes-sdk-or-daemon',
|
|
251
|
+
inspectRoute: 'context action:"prompt" includeParameters:true',
|
|
252
|
+
},
|
|
253
|
+
];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function externalProviderReceiptContract(
|
|
257
|
+
providerId = '<provider-id>',
|
|
258
|
+
receipts: readonly MemoryExternalProviderReceiptEvidence[] = [],
|
|
259
|
+
liveRecord: MemoryExternalProviderLiveRecord | null = null,
|
|
260
|
+
): MemoryExternalProviderReceiptContract {
|
|
261
|
+
const liveReceiptsPublished = Boolean(liveRecord && (liveRecord.receiptIds.length > 0 || liveRecord.receiptRoute || liveRecord.syncReady === true || liveRecord.syncRoute));
|
|
262
|
+
const liveReceiptCertified = liveRecord?.certification?.schemaStatus === 'certified' && liveRecord.certification.missingSignals.length === 0;
|
|
263
|
+
const artifactReceiptCertified = receipts.some((receipt) => receipt.certification?.schemaStatus === 'certified' && receipt.certification.missingSignals.length === 0);
|
|
264
|
+
return {
|
|
265
|
+
status: liveReceiptsPublished && liveReceiptCertified ? 'published' : receipts.length > 0 && artifactReceiptCertified ? 'artifact-evidence-found' : 'missing',
|
|
266
|
+
appliesTo: ['status', 'read', 'write', 'upsert', 'import', 'export', 'sync', 'forget'],
|
|
267
|
+
requiredFields: EXTERNAL_MEMORY_RECEIPT_FIELDS,
|
|
268
|
+
nextWhenPublished: `memory action:"provider" providerId:"${providerId}" includeParameters:true should expose latest receipts and exact follow-up routes.`,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function externalProviderSetupGuide(
|
|
273
|
+
provider: ExternalMemoryProviderCatalogEntry,
|
|
274
|
+
receipts: readonly MemoryExternalProviderReceiptEvidence[] = [],
|
|
275
|
+
liveRecord: MemoryExternalProviderLiveRecord | null = null,
|
|
276
|
+
): MemoryExternalProviderSetupGuide {
|
|
277
|
+
const latestReceipt = receipts[0] ?? null;
|
|
278
|
+
const liveSetupStatus = setupStatusFromLiveRecord(liveRecord);
|
|
279
|
+
const readiness = liveRecord
|
|
280
|
+
? [
|
|
281
|
+
`status ${liveRecord.status}`,
|
|
282
|
+
liveRecord.configured === null ? '' : `configured ${liveRecord.configured}`,
|
|
283
|
+
liveRecord.reachable === null ? '' : `reachable ${liveRecord.reachable}`,
|
|
284
|
+
liveRecord.readReady === null ? '' : `read ${liveRecord.readReady}`,
|
|
285
|
+
liveRecord.writeReady === null ? '' : `write ${liveRecord.writeReady}`,
|
|
286
|
+
liveRecord.syncReady === null ? '' : `sync ${liveRecord.syncReady}`,
|
|
287
|
+
liveRecord.forgetReady === null ? '' : `forget ${liveRecord.forgetReady}`,
|
|
288
|
+
liveRecord.promptEligible === null ? '' : `promptEligible ${liveRecord.promptEligible}`,
|
|
289
|
+
].filter(Boolean).join(', ')
|
|
290
|
+
: '';
|
|
291
|
+
const liveInspectRoutes = liveRecord
|
|
292
|
+
? [
|
|
293
|
+
liveRecord.inspectRoute,
|
|
294
|
+
liveRecord.readRoute,
|
|
295
|
+
liveRecord.writeRoute,
|
|
296
|
+
liveRecord.syncRoute,
|
|
297
|
+
liveRecord.forgetRoute,
|
|
298
|
+
liveRecord.receiptRoute,
|
|
299
|
+
].filter((route): route is string => Boolean(route))
|
|
300
|
+
: [];
|
|
301
|
+
return {
|
|
302
|
+
status: liveSetupStatus ?? (latestReceipt ? 'receipt-evidence-found' : 'contract-needed'),
|
|
303
|
+
userOutcome: liveRecord
|
|
304
|
+
? `Use ${provider.label} as an external memory backend through the daemon-published read model, with bounded reads visible before prompt use and every write/sync/forget route treated as confirmed external provider effect.`
|
|
305
|
+
: `Use ${provider.label} as an external memory backend only after the SDK/daemon publishes provider setup, status, read, write, and receipt contracts for Agent to consume.`,
|
|
306
|
+
currentState: liveRecord
|
|
307
|
+
? `Live ${provider.label} provider record from ${liveRecord.source} reports ${readiness || liveRecord.status}.${latestReceipt ? ` Latest durable receipt artifact ${latestReceipt.artifactId} reports ${latestReceipt.operation} ${latestReceipt.status}.` : ''}`
|
|
308
|
+
: latestReceipt
|
|
309
|
+
? `Latest durable ${provider.label} receipt artifact ${latestReceipt.artifactId} reports ${latestReceipt.operation} ${latestReceipt.status}; live provider status/read/write records are still not published by the current SDK/daemon contract.`
|
|
310
|
+
: `No concrete ${provider.label} provider record is published by the current SDK/daemon contract.`,
|
|
311
|
+
safeFirstStep: liveRecord
|
|
312
|
+
? `Inspect the live ${provider.label} record and use only the published bounded read route until the user explicitly confirms any write, sync, import/export, forget/delete, or prompt-eligibility change.`
|
|
313
|
+
: latestReceipt
|
|
314
|
+
? `Review ${latestReceipt.artifactId}, then keep Agent-local memory as the active prompt path until a ready provider record and prompt-eligibility policy exist.`
|
|
315
|
+
: `Inspect connected-host and MCP setup for ${provider.label}; keep Agent-local memory as the active path until a ready provider record exists.`,
|
|
316
|
+
inspectRoutes: [...new Set([
|
|
317
|
+
`memory action:"provider" providerId:"${provider.id}" includeParameters:true`,
|
|
318
|
+
...liveInspectRoutes,
|
|
319
|
+
`host action:"capability" query:"${provider.id} memory provider"`,
|
|
320
|
+
`agent_harness mode:"mcp_servers" query:"${provider.id}"`,
|
|
321
|
+
'settings action:"list" query:"memory" includeHidden:true',
|
|
322
|
+
])],
|
|
323
|
+
nextRoutes: externalProviderNextRoutes(provider, liveRecord),
|
|
324
|
+
contractChecklist: externalProviderContractChecklist(provider, receipts, liveRecord),
|
|
325
|
+
receiptContract: externalProviderReceiptContract(provider.id, receipts, liveRecord),
|
|
326
|
+
...(latestReceipt ? { latestReceipt, receiptHistory: receipts.slice(0, 5) } : {}),
|
|
327
|
+
requiredHostContracts: EXTERNAL_MEMORY_REQUIRED_CONTRACTS,
|
|
328
|
+
credentialPolicy: 'Provider credentials must use secret refs or connected-host auth state; raw API keys, tokens, and user memory payloads are never returned by posture inspection.',
|
|
329
|
+
confirmationPolicy: 'External memory writes, sync, import, export, forget/delete, and prompt-eligibility changes require explicit user request, confirmation, and durable receipts.',
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function describeExternalProvider(
|
|
334
|
+
provider: ExternalMemoryProviderCatalogEntry,
|
|
335
|
+
includeParameters: boolean,
|
|
336
|
+
receipts: readonly MemoryExternalProviderReceiptEvidence[] = [],
|
|
337
|
+
liveRecord: MemoryExternalProviderLiveRecord | null = null,
|
|
338
|
+
): MemoryPostureProvider {
|
|
339
|
+
const latestReceipt = receipts[0] ?? null;
|
|
340
|
+
const status: MemoryExternalProviderStatus = liveRecord?.status ?? (latestReceipt ? 'receipt-evidence-found' : 'not-published');
|
|
341
|
+
const liveSummary = liveRecord
|
|
342
|
+
? `Live external memory provider record from ${liveRecord.source} reports ${liveRecord.status}; configured ${liveRecord.configured ?? 'unknown'}, read ${liveRecord.readReady ?? 'unknown'}, write ${liveRecord.writeReady ?? 'unknown'}, sync ${liveRecord.syncReady ?? 'unknown'}.`
|
|
343
|
+
: '';
|
|
344
|
+
return {
|
|
345
|
+
id: provider.id,
|
|
346
|
+
label: provider.label,
|
|
347
|
+
kind: 'external-memory',
|
|
348
|
+
status,
|
|
349
|
+
summary: previewHarnessText(liveRecord
|
|
350
|
+
? liveSummary
|
|
351
|
+
: latestReceipt
|
|
352
|
+
? `Durable external memory receipt ${latestReceipt.artifactId} reports ${latestReceipt.operation} ${latestReceipt.status}; live provider records are still not published.`
|
|
353
|
+
: 'External memory backend records are not published by the current GoodVibes SDK/daemon contract.', includeParameters ? 180 : 96),
|
|
354
|
+
modelRoute: `memory action:"provider" providerId:"${provider.id}"`,
|
|
355
|
+
setupRoute: 'host action:"capability" query:"memory provider"',
|
|
356
|
+
configured: liveRecord?.configured ?? (liveRecord ? externalProviderLiveReady(liveRecord) : latestReceipt ? latestReceipt.status === 'succeeded' : false),
|
|
357
|
+
...(includeParameters && liveRecord ? { liveRecord } : {}),
|
|
358
|
+
...(latestReceipt ? { latestReceipt } : {}),
|
|
359
|
+
...(includeParameters && receipts.length > 0 ? { receiptEvidence: receipts.slice(0, 5) } : {}),
|
|
360
|
+
...(includeParameters ? { setupGuide: externalProviderSetupGuide(provider, receipts, liveRecord) } : {}),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function providerSearchText(provider: MemoryPostureProvider): string {
|
|
365
|
+
return [
|
|
366
|
+
provider.id,
|
|
367
|
+
provider.label,
|
|
368
|
+
provider.kind,
|
|
369
|
+
provider.status,
|
|
370
|
+
provider.summary,
|
|
371
|
+
provider.modelRoute,
|
|
372
|
+
provider.setupRoute ?? '',
|
|
373
|
+
provider.liveRecord ? [
|
|
374
|
+
provider.liveRecord.providerId,
|
|
375
|
+
provider.liveRecord.label ?? '',
|
|
376
|
+
provider.liveRecord.status,
|
|
377
|
+
provider.liveRecord.source,
|
|
378
|
+
provider.liveRecord.credentialState ?? '',
|
|
379
|
+
provider.liveRecord.readRoute ?? '',
|
|
380
|
+
provider.liveRecord.writeRoute ?? '',
|
|
381
|
+
provider.liveRecord.syncRoute ?? '',
|
|
382
|
+
provider.liveRecord.receiptIds.join('\n'),
|
|
383
|
+
provider.liveRecord.certification ? [
|
|
384
|
+
provider.liveRecord.certification.schemaStatus,
|
|
385
|
+
provider.liveRecord.certification.schemaVersion ?? '',
|
|
386
|
+
provider.liveRecord.certification.publicationGuarantee ?? '',
|
|
387
|
+
provider.liveRecord.certification.publisher ?? '',
|
|
388
|
+
provider.liveRecord.certification.provenance?.join('\n') ?? '',
|
|
389
|
+
provider.liveRecord.certification.receiptIds?.join('\n') ?? '',
|
|
390
|
+
provider.liveRecord.certification.missingSignals.join('\n'),
|
|
391
|
+
].join('\n') : '',
|
|
392
|
+
].join('\n') : '',
|
|
393
|
+
provider.latestReceipt ? [
|
|
394
|
+
provider.latestReceipt.artifactId,
|
|
395
|
+
provider.latestReceipt.operation,
|
|
396
|
+
provider.latestReceipt.status,
|
|
397
|
+
provider.latestReceipt.nextRoute,
|
|
398
|
+
provider.latestReceipt.certification ? [
|
|
399
|
+
provider.latestReceipt.certification.schemaStatus,
|
|
400
|
+
provider.latestReceipt.certification.schemaVersion ?? '',
|
|
401
|
+
provider.latestReceipt.certification.publicationGuarantee ?? '',
|
|
402
|
+
provider.latestReceipt.certification.publisher ?? '',
|
|
403
|
+
provider.latestReceipt.certification.provenance?.join('\n') ?? '',
|
|
404
|
+
provider.latestReceipt.certification.receiptIds?.join('\n') ?? '',
|
|
405
|
+
provider.latestReceipt.certification.missingSignals.join('\n'),
|
|
406
|
+
].join('\n') : '',
|
|
407
|
+
].join('\n') : '',
|
|
408
|
+
provider.setupGuide ? [
|
|
409
|
+
provider.setupGuide.status,
|
|
410
|
+
provider.setupGuide.userOutcome,
|
|
411
|
+
provider.setupGuide.currentState,
|
|
412
|
+
provider.setupGuide.safeFirstStep,
|
|
413
|
+
provider.setupGuide.inspectRoutes.join('\n'),
|
|
414
|
+
provider.setupGuide.nextRoutes.map((route) => `${route.id} ${route.label} ${route.modelRoute} ${route.effect} ${route.why}`).join('\n'),
|
|
415
|
+
provider.setupGuide.contractChecklist.map((check) => `${check.id} ${check.label} ${check.status} ${check.requiredFor} ${check.inspectRoute}`).join('\n'),
|
|
416
|
+
provider.setupGuide.receiptContract.appliesTo.join('\n'),
|
|
417
|
+
provider.setupGuide.receiptContract.requiredFields.join('\n'),
|
|
418
|
+
provider.setupGuide.receiptContract.nextWhenPublished,
|
|
419
|
+
provider.setupGuide.latestReceipt ? [
|
|
420
|
+
provider.setupGuide.latestReceipt.artifactId,
|
|
421
|
+
provider.setupGuide.latestReceipt.operation,
|
|
422
|
+
provider.setupGuide.latestReceipt.status,
|
|
423
|
+
].join('\n') : '',
|
|
424
|
+
provider.setupGuide.requiredHostContracts.join('\n'),
|
|
425
|
+
provider.setupGuide.credentialPolicy,
|
|
426
|
+
provider.setupGuide.confirmationPolicy,
|
|
427
|
+
].join('\n') : '',
|
|
428
|
+
].join('\n').toLowerCase();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function compactProvider(provider: MemoryPostureProvider, includeParameters: boolean): Record<string, unknown> {
|
|
432
|
+
return {
|
|
433
|
+
id: provider.id,
|
|
434
|
+
label: provider.label,
|
|
435
|
+
kind: provider.kind,
|
|
436
|
+
status: provider.status,
|
|
437
|
+
summary: provider.summary,
|
|
438
|
+
modelRoute: provider.modelRoute,
|
|
439
|
+
...(provider.setupRoute ? { setupRoute: provider.setupRoute } : {}),
|
|
440
|
+
...(includeParameters && typeof provider.configured === 'boolean' ? { configured: provider.configured } : {}),
|
|
441
|
+
...(includeParameters && typeof provider.active === 'boolean' ? { active: provider.active } : {}),
|
|
442
|
+
...(includeParameters && typeof provider.dimensions === 'number' ? { dimensions: provider.dimensions } : {}),
|
|
443
|
+
...(includeParameters && typeof provider.deterministic === 'boolean' ? { deterministic: provider.deterministic } : {}),
|
|
444
|
+
...(includeParameters && provider.metadata ? { metadata: provider.metadata } : {}),
|
|
445
|
+
...(includeParameters && provider.liveRecord ? { liveRecord: provider.liveRecord } : {}),
|
|
446
|
+
...(provider.latestReceipt ? { latestReceipt: provider.latestReceipt } : {}),
|
|
447
|
+
...(includeParameters && provider.receiptEvidence ? { receiptEvidence: provider.receiptEvidence } : {}),
|
|
448
|
+
...(includeParameters && provider.setupGuide ? { setupGuide: provider.setupGuide } : {}),
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async function buildProviderRecords(
|
|
453
|
+
context: CommandContext,
|
|
454
|
+
args: AgentHarnessMemoryPostureArgs,
|
|
455
|
+
): Promise<{
|
|
456
|
+
readonly doctor: MemoryDoctorReport | null;
|
|
457
|
+
readonly vector: MemoryVectorStats | null;
|
|
458
|
+
readonly providers: readonly MemoryPostureProvider[];
|
|
459
|
+
readonly receiptEvidence: readonly MemoryExternalProviderReceiptEvidence[];
|
|
460
|
+
readonly liveRecords: readonly MemoryExternalProviderLiveRecord[];
|
|
461
|
+
}> {
|
|
462
|
+
const includeParameters = args.includeParameters === true;
|
|
463
|
+
const doctor = await readMemoryDoctor(context);
|
|
464
|
+
const vector = readVectorStats(context, doctor);
|
|
465
|
+
const receiptEvidence = externalMemoryReceiptEvidence(context);
|
|
466
|
+
const liveRecords = await externalMemoryLiveProviderRecords(context);
|
|
467
|
+
const embeddingProviders = (doctor?.embeddings.providers ?? []).map((provider) => (
|
|
468
|
+
describeEmbeddingProvider(provider, doctor?.embeddings.activeProviderId, includeParameters)
|
|
469
|
+
));
|
|
470
|
+
const externalProviders = externalMemoryProviderCatalog(liveRecords, receiptEvidence).map((provider) => (
|
|
471
|
+
describeExternalProvider(
|
|
472
|
+
provider,
|
|
473
|
+
includeParameters,
|
|
474
|
+
receiptEvidenceForProvider(receiptEvidence, provider.id),
|
|
475
|
+
liveRecordForProvider(liveRecords, provider.id),
|
|
476
|
+
)
|
|
477
|
+
));
|
|
478
|
+
return {
|
|
479
|
+
doctor,
|
|
480
|
+
vector,
|
|
481
|
+
providers: [...embeddingProviders, ...externalProviders],
|
|
482
|
+
receiptEvidence,
|
|
483
|
+
liveRecords,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function nextActions(
|
|
488
|
+
snapshot: ReturnType<typeof buildAgentWorkspaceRuntimeSnapshot>,
|
|
489
|
+
memoryStatusValue: MemoryPostureStatus,
|
|
490
|
+
vectorStatusValue: MemoryVectorPostureStatus,
|
|
491
|
+
doctor: MemoryDoctorReport | null,
|
|
492
|
+
): readonly string[] {
|
|
493
|
+
const actions: string[] = [];
|
|
494
|
+
if (memoryStatusValue === 'empty') actions.push('Create one durable non-secret Agent memory only after the user asks to remember it.');
|
|
495
|
+
if (memoryStatusValue === 'needs-review') actions.push('Review or stale memory candidates before relying on them in the prompt.');
|
|
496
|
+
if (snapshot.localMemoryReviewQueueCount > 0) actions.push('Use learning_curator or memory review routes to clear the memory review queue.');
|
|
497
|
+
if (vectorStatusValue === 'attention') actions.push('Run memory vector doctor, then rebuild the vector index if the reported issue is fixed.');
|
|
498
|
+
if (doctor?.embeddings.warnings.length) actions.push('Inspect the active embedding provider warning before semantic recall or rebuild work.');
|
|
499
|
+
actions.push('Inspect memory action:"provider" for one external backend to see the exact SDK/daemon setup contracts Agent can consume before use.');
|
|
500
|
+
return actions.slice(0, 6);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function compactVector(vector: MemoryVectorStats | null): Record<string, unknown> {
|
|
504
|
+
if (!vector) {
|
|
505
|
+
return {
|
|
506
|
+
status: 'unavailable',
|
|
507
|
+
summary: 'Memory vector stats are not exposed in this runtime.',
|
|
508
|
+
modelRoute: 'memory action:"status"',
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
status: vectorStatus(vector),
|
|
513
|
+
backend: vector.backend,
|
|
514
|
+
enabled: vector.enabled,
|
|
515
|
+
available: vector.available,
|
|
516
|
+
indexedRecords: vector.indexedRecords,
|
|
517
|
+
dimensions: vector.dimensions,
|
|
518
|
+
embeddingProviderId: vector.embeddingProviderId,
|
|
519
|
+
embeddingProviderLabel: vector.embeddingProviderLabel,
|
|
520
|
+
...(vector.error ? { error: previewHarnessText(vector.error, 160) } : {}),
|
|
521
|
+
modelRoute: 'agent_harness mode:"workspace_action" actionId:"memory-vector-status"',
|
|
522
|
+
doctorRoute: 'agent_harness mode:"workspace_action" actionId:"memory-vector-doctor"',
|
|
523
|
+
rebuildRoute: 'agent_harness mode:"run_workspace_action" actionId:"memory-vector-rebuild" confirm:true explicitUserRequest:"..."',
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export async function memoryPostureCatalogStatus(context: CommandContext): Promise<Record<string, unknown>> {
|
|
528
|
+
const snapshot = buildAgentWorkspaceRuntimeSnapshot(context);
|
|
529
|
+
const doctor = await readMemoryDoctor(context);
|
|
530
|
+
const vector = readVectorStats(context, doctor);
|
|
531
|
+
const receiptEvidence = externalMemoryReceiptEvidence(context);
|
|
532
|
+
const liveRecords = await externalMemoryLiveProviderRecords(context);
|
|
533
|
+
const status = memoryStatus(snapshot, Boolean(memoryApi(context)));
|
|
534
|
+
const vectorState = vectorStatus(vector);
|
|
535
|
+
return {
|
|
536
|
+
modes: ['memory_posture', 'memory_provider'],
|
|
537
|
+
modelRoute: 'memory action:"status"',
|
|
538
|
+
status,
|
|
539
|
+
localMemories: snapshot.localMemoryCount,
|
|
540
|
+
reviewQueue: snapshot.localMemoryReviewQueueCount,
|
|
541
|
+
promptActive: snapshot.localMemoryPromptActiveCount,
|
|
542
|
+
vector: vectorState,
|
|
543
|
+
embeddingProviders: doctor?.embeddings.providers.length ?? 0,
|
|
544
|
+
externalProviders: externalMemoryProviderCatalog(liveRecords, receiptEvidence).length,
|
|
545
|
+
externalProviderRecordsPublished: liveRecords.length > 0,
|
|
546
|
+
externalProviderLiveRecordCount: liveRecords.length,
|
|
547
|
+
externalProviderReceiptEvidenceFound: receiptEvidence.length > 0,
|
|
548
|
+
externalProviderReceiptEvidenceCount: receiptEvidence.length,
|
|
549
|
+
externalProviderSetupGuideStatus: aggregateExternalProviderSetupStatus(liveRecords, receiptEvidence),
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
export async function memoryPostureSummary(context: CommandContext, args: AgentHarnessMemoryPostureArgs): Promise<Record<string, unknown>> {
|
|
554
|
+
const includeParameters = args.includeParameters === true;
|
|
555
|
+
const limit = readLimit(args.limit, 100);
|
|
556
|
+
const query = readString(args.query).toLowerCase();
|
|
557
|
+
const snapshot = buildAgentWorkspaceRuntimeSnapshot(context);
|
|
558
|
+
const { doctor, vector, providers, receiptEvidence, liveRecords } = await buildProviderRecords(context, args);
|
|
559
|
+
const status = memoryStatus(snapshot, Boolean(memoryApi(context)));
|
|
560
|
+
const vectorState = vectorStatus(vector);
|
|
561
|
+
const aggregateLiveRecord = aggregateExternalProviderLiveRecord(liveRecords);
|
|
562
|
+
const filteredProviders = providers
|
|
563
|
+
.filter((provider) => !query || providerSearchText(provider).includes(query))
|
|
564
|
+
.slice(0, limit)
|
|
565
|
+
.map((provider) => compactProvider(provider, includeParameters));
|
|
566
|
+
return {
|
|
567
|
+
status,
|
|
568
|
+
localMemory: {
|
|
569
|
+
total: snapshot.localMemoryCount,
|
|
570
|
+
reviewQueue: snapshot.localMemoryReviewQueueCount,
|
|
571
|
+
promptActive: snapshot.localMemoryPromptActiveCount,
|
|
572
|
+
sessionMemory: snapshot.sessionMemoryCount,
|
|
573
|
+
policy: 'Only reviewed, high-confidence Agent-local memories are prompt-active. Fresh/stale/setup-blocked behavior stays visible for review.',
|
|
574
|
+
routes: {
|
|
575
|
+
list: 'memory action:"list"',
|
|
576
|
+
search: 'memory action:"search" query:"..."',
|
|
577
|
+
reviewQueue: 'memory action:"curator" query:"memory review"',
|
|
578
|
+
create: 'memory action:"create" summary:"..." explicitUserRequest:"..."',
|
|
579
|
+
curator: 'memory action:"curator"',
|
|
580
|
+
},
|
|
581
|
+
},
|
|
582
|
+
vector: compactVector(vector),
|
|
583
|
+
embeddings: {
|
|
584
|
+
activeProviderId: doctor?.embeddings.activeProviderId ?? vector?.embeddingProviderId ?? snapshot.embeddingProvider,
|
|
585
|
+
warnings: doctor?.embeddings.warnings.map((warning) => previewHarnessText(warning, includeParameters ? 180 : 96)) ?? [],
|
|
586
|
+
syncProviders: doctor?.embeddings.syncProviders ?? [],
|
|
587
|
+
asyncProviders: doctor?.embeddings.asyncProviders ?? [],
|
|
588
|
+
},
|
|
589
|
+
providers: filteredProviders,
|
|
590
|
+
returned: filteredProviders.length,
|
|
591
|
+
totalProviders: providers.length,
|
|
592
|
+
externalMemory: {
|
|
593
|
+
status: aggregateLiveRecord?.status ?? (receiptEvidence.length > 0 ? 'receipt-evidence-found' : 'not-published'),
|
|
594
|
+
providerRecordsPublished: liveRecords.length > 0,
|
|
595
|
+
liveProviderRecordCount: liveRecords.length,
|
|
596
|
+
latestLiveProviderRecords: liveRecords.slice(0, 5),
|
|
597
|
+
receiptEvidenceFound: receiptEvidence.length > 0,
|
|
598
|
+
receiptEvidenceCount: receiptEvidence.length,
|
|
599
|
+
latestReceipts: receiptEvidence.slice(0, 5),
|
|
600
|
+
setupGuideStatus: aggregateExternalProviderSetupStatus(liveRecords, receiptEvidence),
|
|
601
|
+
checkedProviders: externalMemoryProviderCatalog(liveRecords, receiptEvidence).map((provider) => provider.id),
|
|
602
|
+
requiredHostContracts: EXTERNAL_MEMORY_REQUIRED_CONTRACTS,
|
|
603
|
+
contractChecklist: externalProviderContractChecklist({ id: '<provider-id>', label: 'External memory provider' }, receiptEvidence, aggregateLiveRecord),
|
|
604
|
+
receiptContract: externalProviderReceiptContract('<provider-id>', receiptEvidence, aggregateLiveRecord),
|
|
605
|
+
nextRoutes: [
|
|
606
|
+
{
|
|
607
|
+
id: 'inspect-one-provider',
|
|
608
|
+
label: 'Inspect one provider contract',
|
|
609
|
+
modelRoute: 'memory action:"provider" providerId:"<id>" includeParameters:true',
|
|
610
|
+
effect: 'read-only',
|
|
611
|
+
why: 'Shows provider-specific missing SDK/daemon contracts, receipt requirements, credential policy, and next routes.',
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
id: 'inspect-host-memory-capability',
|
|
615
|
+
label: 'Inspect host memory capability',
|
|
616
|
+
modelRoute: 'host action:"capability" query:"memory provider"',
|
|
617
|
+
effect: 'read-only',
|
|
618
|
+
why: 'Checks whether the connected host exposes a provider-backed memory capability.',
|
|
619
|
+
},
|
|
620
|
+
],
|
|
621
|
+
next: liveRecords.length > 0
|
|
622
|
+
? 'Inspect the matching live provider record before any provider read; keep write, sync, import/export, forget/delete, and prompt-eligibility changes on confirmed routes with durable receipts.'
|
|
623
|
+
: receiptEvidence.length > 0
|
|
624
|
+
? 'Review the latest external-memory receipt artifact, then keep Agent-local memory as the active prompt path until live provider status/read/write records are published.'
|
|
625
|
+
: 'Use Agent-local memory now. Inspect one external provider for the required SDK/daemon setup/status/read/write/receipt contracts Agent can consume before provider use.',
|
|
626
|
+
inspectRoute: 'host action:"capability" query:"memory provider"',
|
|
627
|
+
providerLookup: 'memory action:"provider" providerId:"<id>" includeParameters:true',
|
|
628
|
+
},
|
|
629
|
+
nextActions: nextActions(snapshot, status, vectorState, doctor),
|
|
630
|
+
policy: 'Memory posture is read-only. Memory edits, vector rebuilds, and embedding-provider changes stay on existing confirmed Agent-local routes.',
|
|
631
|
+
...(includeParameters ? {
|
|
632
|
+
checkedAt: doctor?.checkedAt ?? null,
|
|
633
|
+
providerLookup: 'memory action:"provider" providerId:"<id>"',
|
|
634
|
+
} : {}),
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export async function describeMemoryProvider(context: CommandContext, args: AgentHarnessMemoryPostureArgs): Promise<MemoryProviderResolution> {
|
|
639
|
+
const input = readString(args.providerId) || readString(args.target) || readString(args.query);
|
|
640
|
+
if (!input) {
|
|
641
|
+
return {
|
|
642
|
+
status: 'missing_lookup',
|
|
643
|
+
usage: 'memory action:"provider" requires providerId, target, or query. Use memory action:"status" to inspect available provider ids.',
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
const includeParameters = args.includeParameters !== false;
|
|
647
|
+
const { providers } = await buildProviderRecords(context, { ...args, includeParameters });
|
|
648
|
+
const normalized = input.toLowerCase();
|
|
649
|
+
const exact = providers.find((provider) => provider.id === input || provider.id.toLowerCase() === normalized);
|
|
650
|
+
if (exact) return { status: 'found', provider: compactProvider(exact, true) };
|
|
651
|
+
const label = providers.find((provider) => provider.label.toLowerCase() === normalized);
|
|
652
|
+
if (label) return { status: 'found', provider: compactProvider(label, true) };
|
|
653
|
+
const matches = providers.filter((provider) => providerSearchText(provider).includes(normalized));
|
|
654
|
+
if (matches.length === 1) return { status: 'found', provider: compactProvider(matches[0]!, true) };
|
|
655
|
+
if (matches.length > 1) {
|
|
656
|
+
return {
|
|
657
|
+
status: 'ambiguous',
|
|
658
|
+
input,
|
|
659
|
+
candidates: matches.slice(0, 10).map((provider) => ({
|
|
660
|
+
providerId: provider.id,
|
|
661
|
+
label: provider.label,
|
|
662
|
+
kind: provider.kind,
|
|
663
|
+
status: provider.status,
|
|
664
|
+
modelRoute: provider.modelRoute,
|
|
665
|
+
})),
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
return {
|
|
669
|
+
status: 'missing_lookup',
|
|
670
|
+
usage: `Unknown memory provider ${input}. Use memory action:"status" to inspect available provider ids.`,
|
|
671
|
+
};
|
|
672
|
+
}
|