@pellux/goodvibes-agent 1.1.7 → 1.2.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 +170 -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 +132577 -91483
- 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 +56 -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 +114 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +130 -5
- package/release/release-readiness.json +120 -90
- 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 +296 -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-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +447 -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 +262 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +198 -0
- package/src/input/agent-workspace-setup.ts +34 -1
- package/src/input/agent-workspace-snapshot.ts +162 -147
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +18 -0
- 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/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +686 -0
- package/src/renderer/agent-workspace.ts +30 -419
- 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.ts +703 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +560 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +794 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
- package/src/tools/agent-harness-browser-control.ts +338 -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-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 +382 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -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 +199 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
- package/src/tools/agent-harness-media-posture.ts +208 -2
- package/src/tools/agent-harness-memory-posture.ts +556 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +84 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +186 -0
- package/src/tools/agent-harness-model-readiness.ts +406 -0
- package/src/tools/agent-harness-model-routing-types.ts +266 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +137 -190
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +431 -18
- 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 +204 -0
- package/src/tools/agent-harness-personal-ops-records.ts +732 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +222 -0
- package/src/tools/agent-harness-personal-ops.ts +606 -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-research-briefing.ts +427 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +295 -0
- package/src/tools/agent-harness-research-workflow.ts +322 -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 +101 -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 +508 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +120 -7
- package/src/tools/agent-harness-tool-types.ts +78 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +311 -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 +214 -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 +722 -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-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +687 -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
|
@@ -104,8 +104,8 @@ function itemSearchText(item: Record<string, unknown>): string {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
function releaseReadinessModelRoute(item?: Record<string, unknown>): string {
|
|
107
|
-
if (item) return '
|
|
108
|
-
return '
|
|
107
|
+
if (item) return 'audit action:"item"';
|
|
108
|
+
return 'audit action:"readiness" or action:"item"';
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function releaseReadinessPolicy(): Record<string, unknown> {
|
|
@@ -153,8 +153,9 @@ function summarizeItem(item: Record<string, unknown>, options: { readonly includ
|
|
|
153
153
|
...(options.includeQuality ? {
|
|
154
154
|
policy: releaseReadinessPolicy(),
|
|
155
155
|
modelAccess: {
|
|
156
|
-
listItems: '
|
|
157
|
-
inspectItem: `
|
|
156
|
+
listItems: 'audit action:"readiness"',
|
|
157
|
+
inspectItem: `audit action:"item" itemId:"${readString(item.id)}"`,
|
|
158
|
+
lowerLevelItem: `agent_harness mode:"release_readiness_item" itemId:"${readString(item.id)}" includeParameters:true`,
|
|
158
159
|
},
|
|
159
160
|
} : {}),
|
|
160
161
|
};
|
|
@@ -230,8 +231,9 @@ export function releaseReadinessSummary(args: ReleaseReadinessArgs): Record<stri
|
|
|
230
231
|
policy: loaded.root.policy,
|
|
231
232
|
operatorAuditPolicy: releaseReadinessPolicy(),
|
|
232
233
|
modelAccess: {
|
|
233
|
-
listItems: '
|
|
234
|
-
inspectItem: '
|
|
234
|
+
listItems: 'audit action:"readiness"',
|
|
235
|
+
inspectItem: 'audit action:"item" with itemId, target, or query',
|
|
236
|
+
lowerLevelItem: 'agent_harness mode:"release_readiness_item" itemId:"..." includeParameters:true',
|
|
235
237
|
},
|
|
236
238
|
totals: {
|
|
237
239
|
items: items.length,
|
|
@@ -245,7 +247,7 @@ export function releaseReadinessSummary(args: ReleaseReadinessArgs): Record<stri
|
|
|
245
247
|
},
|
|
246
248
|
sources: includeQuality ? sources : sources.map(summarizeSource),
|
|
247
249
|
items: filtered.slice(0, limit).map((item) => summarizeItem(item, { includeQuality })),
|
|
248
|
-
itemLookup: 'Use
|
|
250
|
+
itemLookup: 'Use audit action:"item" with itemId, target, or query to inspect one readiness item; lower-level agent_harness mode:"release_readiness_item" remains available.',
|
|
249
251
|
};
|
|
250
252
|
}
|
|
251
253
|
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import type { ArtifactDescriptor } from '@pellux/goodvibes-sdk/platform/artifacts';
|
|
2
|
+
import type { CommandContext } from '../input/command-registry.ts';
|
|
3
|
+
import {
|
|
4
|
+
AgentResearchRunRegistry,
|
|
5
|
+
researchRunLogTail,
|
|
6
|
+
type AgentResearchRunRecord,
|
|
7
|
+
type AgentResearchRunStatus,
|
|
8
|
+
} from '../agent/research-run-registry.ts';
|
|
9
|
+
import {
|
|
10
|
+
AgentResearchSourceRegistry,
|
|
11
|
+
researchSourceReportLine,
|
|
12
|
+
type AgentResearchSourceRecord,
|
|
13
|
+
} from '../agent/research-source-registry.ts';
|
|
14
|
+
import { browserControlPosture } from './agent-harness-browser-control.ts';
|
|
15
|
+
import { previewHarnessText } from './agent-harness-text.ts';
|
|
16
|
+
|
|
17
|
+
interface AgentHarnessResearchBriefingArgs {
|
|
18
|
+
readonly query?: unknown;
|
|
19
|
+
readonly target?: unknown;
|
|
20
|
+
readonly includeParameters?: unknown;
|
|
21
|
+
readonly limit?: unknown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ResearchBriefingItem {
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly kind: 'run' | 'source' | 'report' | 'workflow' | 'browser';
|
|
27
|
+
readonly priority: number;
|
|
28
|
+
readonly label: string;
|
|
29
|
+
readonly status: string;
|
|
30
|
+
readonly summary: string;
|
|
31
|
+
readonly next: string;
|
|
32
|
+
readonly routes: Record<string, string>;
|
|
33
|
+
readonly confirmationBoundary: string;
|
|
34
|
+
readonly relatedIds?: readonly string[];
|
|
35
|
+
readonly detail?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type ArtifactListStore = {
|
|
39
|
+
readonly list?: (limit?: number) => readonly ArtifactDescriptor[];
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function readString(value: unknown): string {
|
|
43
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function readLimit(value: unknown, fallback: number): number {
|
|
47
|
+
const parsed = typeof value === 'string' && value.trim() ? Number(value) : value;
|
|
48
|
+
if (typeof parsed !== 'number' || !Number.isFinite(parsed)) return fallback;
|
|
49
|
+
return Math.max(1, Math.min(50, Math.trunc(parsed)));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function routeString(value: string): string {
|
|
53
|
+
return JSON.stringify(value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function fallbackTitle(question: string): string {
|
|
57
|
+
const normalized = question.replace(/\s+/g, ' ').trim();
|
|
58
|
+
if (!normalized) return 'Deep research run';
|
|
59
|
+
return normalized.length <= 72 ? normalized : `${normalized.slice(0, 69).trimEnd()}...`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function runPriority(status: AgentResearchRunStatus, progress: number): number {
|
|
63
|
+
if (status === 'blocked') return 98;
|
|
64
|
+
if (status === 'running') return 94 + Math.min(4, Math.round(progress / 25));
|
|
65
|
+
if (status === 'paused') return 88;
|
|
66
|
+
if (status === 'planned') return 82;
|
|
67
|
+
if (status === 'failed') return 70;
|
|
68
|
+
if (status === 'completed') return 58;
|
|
69
|
+
return 30;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isMutableRun(status: AgentResearchRunStatus): boolean {
|
|
73
|
+
return status !== 'cancelled' && status !== 'completed' && status !== 'failed';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function runSearchText(run: AgentResearchRunRecord): string {
|
|
77
|
+
return [
|
|
78
|
+
run.id,
|
|
79
|
+
run.title,
|
|
80
|
+
run.question,
|
|
81
|
+
run.goal,
|
|
82
|
+
run.status,
|
|
83
|
+
run.phase,
|
|
84
|
+
run.note ?? '',
|
|
85
|
+
run.error ?? '',
|
|
86
|
+
run.reportArtifactId ?? '',
|
|
87
|
+
...run.plan,
|
|
88
|
+
...run.nextSteps,
|
|
89
|
+
...run.sourceIds,
|
|
90
|
+
].join('\n').toLowerCase();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function sourceSearchText(source: AgentResearchSourceRecord): string {
|
|
94
|
+
return [
|
|
95
|
+
source.id,
|
|
96
|
+
source.question,
|
|
97
|
+
source.title,
|
|
98
|
+
source.url ?? '',
|
|
99
|
+
source.publisher ?? '',
|
|
100
|
+
source.summary,
|
|
101
|
+
source.evidence ?? '',
|
|
102
|
+
source.credibility,
|
|
103
|
+
source.status,
|
|
104
|
+
source.note ?? '',
|
|
105
|
+
...source.tags,
|
|
106
|
+
].join('\n').toLowerCase();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function artifactSearchText(artifact: ArtifactDescriptor): string {
|
|
110
|
+
return [
|
|
111
|
+
artifact.id,
|
|
112
|
+
artifact.kind,
|
|
113
|
+
artifact.mimeType,
|
|
114
|
+
artifact.filename ?? '',
|
|
115
|
+
artifact.sourceUri ?? '',
|
|
116
|
+
JSON.stringify(artifact.metadata ?? {}),
|
|
117
|
+
].join('\n').toLowerCase();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function reportArtifacts(context: CommandContext, query: string): readonly ArtifactDescriptor[] {
|
|
121
|
+
const store = context.platform?.artifactStore as ArtifactListStore | undefined;
|
|
122
|
+
const artifacts = store?.list?.(100) ?? [];
|
|
123
|
+
const normalized = query.toLowerCase();
|
|
124
|
+
return artifacts.filter((artifact) => {
|
|
125
|
+
const metadata = artifact.metadata ?? {};
|
|
126
|
+
const purpose = typeof metadata.purpose === 'string' ? metadata.purpose : '';
|
|
127
|
+
const source = typeof metadata.source === 'string' ? metadata.source : '';
|
|
128
|
+
const sourceKind = typeof metadata.sourceKind === 'string' ? metadata.sourceKind : '';
|
|
129
|
+
const isResearchReport = [purpose, source, sourceKind].some((value) => value.toLowerCase().includes('agent-research-report'));
|
|
130
|
+
return isResearchReport && (!normalized || artifactSearchText(artifact).includes(normalized));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function matchingSources(
|
|
135
|
+
sources: readonly AgentResearchSourceRecord[],
|
|
136
|
+
runs: readonly AgentResearchRunRecord[],
|
|
137
|
+
query: string,
|
|
138
|
+
): readonly AgentResearchSourceRecord[] {
|
|
139
|
+
const normalized = query.toLowerCase();
|
|
140
|
+
const sourceIds = new Set(runs.flatMap((run) => run.sourceIds).map((id) => id.toLowerCase()));
|
|
141
|
+
return sources.filter((source) => (
|
|
142
|
+
!normalized
|
|
143
|
+
|| sourceIds.has(source.id.toLowerCase())
|
|
144
|
+
|| sourceSearchText(source).includes(normalized)
|
|
145
|
+
|| runs.some((run) => run.question.toLowerCase() === source.question.toLowerCase())
|
|
146
|
+
));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function runItem(run: AgentResearchRunRecord, includeParameters: boolean): ResearchBriefingItem {
|
|
150
|
+
const mutable = isMutableRun(run.status);
|
|
151
|
+
const routes: Record<string, string> = {
|
|
152
|
+
inspect: `research action:"run" runId:${routeString(run.id)}`,
|
|
153
|
+
workflow: `research action:"plan" runId:${routeString(run.id)}`,
|
|
154
|
+
search: `research action:"search" runId:${routeString(run.id)} maxResults:5`,
|
|
155
|
+
sources: `research action:"sources" query:${routeString(run.question)}`,
|
|
156
|
+
report: `research action:"report" question:${routeString(run.question)} sources:[...] visualReport:true requireCitationCoverage:true confirm:true explicitUserRequest:"..."`,
|
|
157
|
+
};
|
|
158
|
+
if (mutable) {
|
|
159
|
+
routes.checkpoint = `research action:"checkpoint" id:${routeString(run.id)} phase:"reading" progress:${Math.max(run.progress, 25)} note:"..." sourceIds:["..."] confirm:true explicitUserRequest:"..."`;
|
|
160
|
+
routes.cancel = `research action:"cancel" id:${routeString(run.id)} note:"..." confirm:true explicitUserRequest:"..."`;
|
|
161
|
+
}
|
|
162
|
+
if (run.status === 'paused' || run.status === 'planned' || run.status === 'blocked') {
|
|
163
|
+
routes.resume = `research action:"resume" id:${routeString(run.id)} confirm:true explicitUserRequest:"..."`;
|
|
164
|
+
}
|
|
165
|
+
if (run.reportArtifactId) {
|
|
166
|
+
routes.reportArtifact = `research action:"report_artifact" artifactId:${routeString(run.reportArtifactId)}`;
|
|
167
|
+
routes.promoteKnowledge = `agent_knowledge_ingest sourceKind:"artifact" artifactId:${routeString(run.reportArtifactId)} confirm:true explicitUserRequest:"..."`;
|
|
168
|
+
}
|
|
169
|
+
const next = run.status === 'completed'
|
|
170
|
+
? 'Review the saved report artifact, then promote it to Agent Knowledge only if the user wants durable knowledge.'
|
|
171
|
+
: run.status === 'blocked'
|
|
172
|
+
? 'Resolve the blocker, checkpoint the decision, or cancel with a clear note.'
|
|
173
|
+
: run.status === 'paused'
|
|
174
|
+
? 'Resume only when the user wants the research to continue.'
|
|
175
|
+
: run.status === 'planned'
|
|
176
|
+
? 'Start or checkpoint this visible run before collecting more sources.'
|
|
177
|
+
: 'Checkpoint progress, source ids, and next steps before switching tasks or saving a report.';
|
|
178
|
+
return {
|
|
179
|
+
id: `run:${run.id}`,
|
|
180
|
+
kind: 'run',
|
|
181
|
+
priority: runPriority(run.status, run.progress),
|
|
182
|
+
label: run.title,
|
|
183
|
+
status: run.status,
|
|
184
|
+
summary: previewHarnessText(run.question, includeParameters ? 220 : 120),
|
|
185
|
+
next,
|
|
186
|
+
routes,
|
|
187
|
+
confirmationBoundary: mutable ? 'Run state changes require confirm:true and explicitUserRequest; this briefing is read-only.' : 'Terminal run inspection is read-only; replacement runs require explicit confirmation.',
|
|
188
|
+
relatedIds: run.sourceIds,
|
|
189
|
+
...(includeParameters ? {
|
|
190
|
+
detail: {
|
|
191
|
+
runId: run.id,
|
|
192
|
+
phase: run.phase,
|
|
193
|
+
progress: run.progress,
|
|
194
|
+
goal: run.goal,
|
|
195
|
+
plan: run.plan,
|
|
196
|
+
nextSteps: run.nextSteps,
|
|
197
|
+
sourceIds: run.sourceIds,
|
|
198
|
+
logTail: researchRunLogTail(run, 5),
|
|
199
|
+
reportArtifactId: run.reportArtifactId ?? null,
|
|
200
|
+
},
|
|
201
|
+
} : {}),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function sourcePriority(source: AgentResearchSourceRecord): number {
|
|
206
|
+
if (source.status === 'candidate') return 90;
|
|
207
|
+
if (source.status === 'reviewed') return 84 + Math.min(10, Math.round(source.score / 10));
|
|
208
|
+
if (source.status === 'used') return 54;
|
|
209
|
+
return 24;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function sourceItem(source: AgentResearchSourceRecord, includeParameters: boolean): ResearchBriefingItem {
|
|
213
|
+
const routes: Record<string, string> = {
|
|
214
|
+
inspect: `research action:"source" sourceId:${routeString(source.id)}`,
|
|
215
|
+
sources: `research action:"sources" query:${routeString(source.question)}`,
|
|
216
|
+
};
|
|
217
|
+
if (source.status === 'candidate' || source.status === 'rejected') {
|
|
218
|
+
routes.review = `research action:"review_source" id:${routeString(source.id)} credibility:"high|medium|mixed|low" score:80 note:"..." confirm:true explicitUserRequest:"..."`;
|
|
219
|
+
}
|
|
220
|
+
if (source.status !== 'rejected') {
|
|
221
|
+
routes.reject = `research action:"reject_source" id:${routeString(source.id)} note:"..." confirm:true explicitUserRequest:"..."`;
|
|
222
|
+
}
|
|
223
|
+
if (source.status === 'reviewed' || source.status === 'used') {
|
|
224
|
+
routes.bundle = `research action:"bundle" query:${routeString(source.question)} includeReportLines:true`;
|
|
225
|
+
routes.report = `research action:"report" question:${routeString(source.question)} sources:[...] visualReport:true requireCitationCoverage:true confirm:true explicitUserRequest:"..."`;
|
|
226
|
+
routes.ingest = 'agent_knowledge_ingest sourceKind:"url" url:"..." confirm:true explicitUserRequest:"..."';
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
id: `source:${source.id}`,
|
|
230
|
+
kind: 'source',
|
|
231
|
+
priority: sourcePriority(source),
|
|
232
|
+
label: source.title,
|
|
233
|
+
status: source.status,
|
|
234
|
+
summary: previewHarnessText(source.summary, includeParameters ? 220 : 120),
|
|
235
|
+
next: source.status === 'candidate'
|
|
236
|
+
? 'Review credibility, score, and citation value before using this source.'
|
|
237
|
+
: source.status === 'reviewed'
|
|
238
|
+
? 'Bundle reviewed sources and save a citation-covered report artifact.'
|
|
239
|
+
: source.status === 'used'
|
|
240
|
+
? 'Inspect the report that used this source before ingesting durable knowledge.'
|
|
241
|
+
: 'Leave rejected unless the user provides new evidence.',
|
|
242
|
+
routes,
|
|
243
|
+
confirmationBoundary: 'Source review, rejection, report save, and Knowledge ingest are separate confirmed effects.',
|
|
244
|
+
relatedIds: [source.id],
|
|
245
|
+
...(includeParameters ? {
|
|
246
|
+
detail: {
|
|
247
|
+
sourceId: source.id,
|
|
248
|
+
credibility: source.credibility,
|
|
249
|
+
score: source.score,
|
|
250
|
+
publisher: source.publisher ?? null,
|
|
251
|
+
url: source.url ?? null,
|
|
252
|
+
reportLine: researchSourceReportLine(source),
|
|
253
|
+
evidence: source.evidence ?? null,
|
|
254
|
+
},
|
|
255
|
+
} : {}),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function reportItem(artifact: ArtifactDescriptor, includeParameters: boolean): ResearchBriefingItem {
|
|
260
|
+
const routes = {
|
|
261
|
+
inspect: `research action:"report_artifact" artifactId:${routeString(artifact.id)}`,
|
|
262
|
+
export: `agent_artifacts mode:"export" artifactId:${routeString(artifact.id)} destinationPath:"exports/${artifact.filename ?? `${artifact.id}.md`}" confirm:true explicitUserRequest:"..."`,
|
|
263
|
+
archive: `agent_artifacts mode:"archive" artifactIds:[${routeString(artifact.id)}] destinationPath:"exports/research-report.zip" confirm:true explicitUserRequest:"..."`,
|
|
264
|
+
promoteKnowledge: `agent_knowledge_ingest sourceKind:"artifact" artifactId:${routeString(artifact.id)} confirm:true explicitUserRequest:"..."`,
|
|
265
|
+
};
|
|
266
|
+
return {
|
|
267
|
+
id: `report:${artifact.id}`,
|
|
268
|
+
kind: 'report',
|
|
269
|
+
priority: 76,
|
|
270
|
+
label: artifact.filename ?? artifact.id,
|
|
271
|
+
status: 'saved-report',
|
|
272
|
+
summary: previewHarnessText(`Saved research report artifact ${artifact.id}.`, includeParameters ? 220 : 120),
|
|
273
|
+
next: 'Inspect the report, then export, archive, share, or promote to Agent Knowledge only after review.',
|
|
274
|
+
routes,
|
|
275
|
+
confirmationBoundary: 'Report inspection is read-only; export, archive, share, and Knowledge ingest stay confirmed.',
|
|
276
|
+
relatedIds: [artifact.id],
|
|
277
|
+
...(includeParameters ? {
|
|
278
|
+
detail: {
|
|
279
|
+
artifactId: artifact.id,
|
|
280
|
+
mimeType: artifact.mimeType,
|
|
281
|
+
sizeBytes: artifact.sizeBytes,
|
|
282
|
+
createdAt: artifact.createdAt,
|
|
283
|
+
metadata: artifact.metadata,
|
|
284
|
+
},
|
|
285
|
+
} : {}),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function workflowItem(query: string, includeParameters: boolean): ResearchBriefingItem {
|
|
290
|
+
const question = query || 'Research question goes here';
|
|
291
|
+
const title = fallbackTitle(question);
|
|
292
|
+
return {
|
|
293
|
+
id: 'workflow:new-run',
|
|
294
|
+
kind: 'workflow',
|
|
295
|
+
priority: query ? 80 : 34,
|
|
296
|
+
label: query ? `Start visible research: ${title}` : 'Start visible research',
|
|
297
|
+
status: query ? 'needs-visible-run' : 'waiting-for-question',
|
|
298
|
+
summary: query
|
|
299
|
+
? previewHarnessText(question, includeParameters ? 220 : 120)
|
|
300
|
+
: 'Provide a research question before creating run state or collecting sources.',
|
|
301
|
+
next: query
|
|
302
|
+
? 'Create a visible run, collect bounded public sources, review them, then save a sourced visual report.'
|
|
303
|
+
: 'Ask the user for the research question, success criteria, and any source constraints.',
|
|
304
|
+
routes: {
|
|
305
|
+
plan: `research action:"plan" query:${routeString(question)}`,
|
|
306
|
+
createRun: `research action:"create_run" title:${routeString(title)} question:${routeString(question)} plan:["Search bounded public web sources","Capture candidate sources","Review credibility","Save sourced report"] confirm:true explicitUserRequest:"..."`,
|
|
307
|
+
search: `research action:"search" query:${routeString(question)} maxResults:5`,
|
|
308
|
+
sources: `research action:"sources" query:${routeString(question)}`,
|
|
309
|
+
},
|
|
310
|
+
confirmationBoundary: 'Creating run state and source queue writes are separate confirmed actions; this briefing does not search or write.',
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function browserItem(context: CommandContext, includeParameters: boolean): ResearchBriefingItem {
|
|
315
|
+
const browser = browserControlPosture(context);
|
|
316
|
+
return {
|
|
317
|
+
id: 'browser:research-runner',
|
|
318
|
+
kind: 'browser',
|
|
319
|
+
priority: browser.configured ? 60 : 28,
|
|
320
|
+
label: 'Browser-backed research runner',
|
|
321
|
+
status: browser.configured ? 'ready-with-confirmation' : 'setup-needed',
|
|
322
|
+
summary: browser.configured
|
|
323
|
+
? 'Browser or desktop control is configured; use it only when public web/fetch is insufficient.'
|
|
324
|
+
: 'Browser-backed research needs setup before live browser execution should be promised.',
|
|
325
|
+
next: browser.configured
|
|
326
|
+
? 'Use browser-backed research only after the user confirms authenticated or interactive scope.'
|
|
327
|
+
: 'Use bounded public search now, or inspect browser setup if live browser state is required.',
|
|
328
|
+
routes: {
|
|
329
|
+
runner: 'research action:"runner"',
|
|
330
|
+
setup: browser.setupRoute,
|
|
331
|
+
recommended: browser.recommendedRoute,
|
|
332
|
+
fallback: browser.fallbackRoutes[0] ?? 'research action:"search"',
|
|
333
|
+
},
|
|
334
|
+
confirmationBoundary: 'This briefing never opens the browser; browser handoff stays on confirmed computer/browser routes.',
|
|
335
|
+
...(includeParameters ? {
|
|
336
|
+
detail: {
|
|
337
|
+
configured: browser.configured,
|
|
338
|
+
needsReview: browser.needsReview,
|
|
339
|
+
fallbackRoutes: browser.fallbackRoutes,
|
|
340
|
+
},
|
|
341
|
+
} : {}),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export function researchBriefingCatalogStatus(context: CommandContext): Record<string, unknown> {
|
|
346
|
+
const shellPaths = context.workspace?.shellPaths;
|
|
347
|
+
const runs = shellPaths ? AgentResearchRunRegistry.fromShellPaths(shellPaths).snapshot() : null;
|
|
348
|
+
const sources = shellPaths ? AgentResearchSourceRegistry.fromShellPaths(shellPaths).snapshot() : null;
|
|
349
|
+
const reports = reportArtifacts(context, '');
|
|
350
|
+
return {
|
|
351
|
+
modes: ['research_briefing'],
|
|
352
|
+
status: shellPaths ? 'ready' : 'unavailable',
|
|
353
|
+
activeRuns: (runs?.planned.length ?? 0) + (runs?.running.length ?? 0) + (runs?.paused.length ?? 0) + (runs?.blocked.length ?? 0),
|
|
354
|
+
candidateSources: sources?.candidates.length ?? 0,
|
|
355
|
+
reviewedSources: sources?.reviewed.length ?? 0,
|
|
356
|
+
savedReports: reports.length,
|
|
357
|
+
readOnly: true,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export function researchBriefingSummary(context: CommandContext, args: AgentHarnessResearchBriefingArgs): Record<string, unknown> {
|
|
362
|
+
const includeParameters = args.includeParameters === true;
|
|
363
|
+
const query = readString(args.query) || readString(args.target);
|
|
364
|
+
const shellPaths = context.workspace?.shellPaths;
|
|
365
|
+
const runs = shellPaths ? AgentResearchRunRegistry.fromShellPaths(shellPaths).list() : [];
|
|
366
|
+
const sources = shellPaths ? AgentResearchSourceRegistry.fromShellPaths(shellPaths).list() : [];
|
|
367
|
+
const normalized = query.toLowerCase();
|
|
368
|
+
const matchedRuns = runs.filter((run) => !normalized || runSearchText(run).includes(normalized));
|
|
369
|
+
const matchedSources = matchingSources(sources, matchedRuns, query);
|
|
370
|
+
const reports = reportArtifacts(context, query);
|
|
371
|
+
const activeRuns = matchedRuns.filter((run) => isMutableRun(run.status));
|
|
372
|
+
const candidateSources = matchedSources.filter((source) => source.status === 'candidate');
|
|
373
|
+
const reviewedSources = matchedSources.filter((source) => source.status === 'reviewed');
|
|
374
|
+
const items = [
|
|
375
|
+
...activeRuns.map((run) => runItem(run, includeParameters)),
|
|
376
|
+
...matchedRuns.filter((run) => !isMutableRun(run.status) && run.reportArtifactId).map((run) => runItem(run, includeParameters)),
|
|
377
|
+
...candidateSources.map((source) => sourceItem(source, includeParameters)),
|
|
378
|
+
...reviewedSources.map((source) => sourceItem(source, includeParameters)),
|
|
379
|
+
...reports.map((artifact) => reportItem(artifact, includeParameters)),
|
|
380
|
+
...(query && matchedRuns.length === 0 ? [workflowItem(query, includeParameters)] : []),
|
|
381
|
+
browserItem(context, includeParameters),
|
|
382
|
+
]
|
|
383
|
+
.sort((left, right) => right.priority - left.priority || left.label.localeCompare(right.label));
|
|
384
|
+
const limit = readLimit(args.limit, includeParameters ? 20 : 8);
|
|
385
|
+
const status = !shellPaths
|
|
386
|
+
? 'unavailable'
|
|
387
|
+
: candidateSources.length > 0
|
|
388
|
+
? 'needs-source-review'
|
|
389
|
+
: reviewedSources.length > 0
|
|
390
|
+
? 'ready-to-report'
|
|
391
|
+
: activeRuns.length > 0
|
|
392
|
+
? 'active'
|
|
393
|
+
: reports.length > 0
|
|
394
|
+
? 'report-ready'
|
|
395
|
+
: query
|
|
396
|
+
? 'needs-visible-run'
|
|
397
|
+
: 'empty';
|
|
398
|
+
return {
|
|
399
|
+
status,
|
|
400
|
+
query: query || null,
|
|
401
|
+
summary: {
|
|
402
|
+
runs: matchedRuns.length,
|
|
403
|
+
activeRuns: activeRuns.length,
|
|
404
|
+
candidateSources: candidateSources.length,
|
|
405
|
+
reviewedSources: reviewedSources.length,
|
|
406
|
+
savedReports: reports.length,
|
|
407
|
+
browserReady: browserControlPosture(context).configured,
|
|
408
|
+
},
|
|
409
|
+
queue: items.slice(0, limit),
|
|
410
|
+
returned: Math.min(items.length, limit),
|
|
411
|
+
total: items.length,
|
|
412
|
+
routes: {
|
|
413
|
+
plan: query ? `research action:"plan" query:${routeString(query)}` : 'research action:"plan" query:"..."',
|
|
414
|
+
search: query ? `research action:"search" query:${routeString(query)} maxResults:5` : 'research action:"search" query:"..." maxResults:5',
|
|
415
|
+
runner: 'research action:"runner"',
|
|
416
|
+
runs: 'research action:"runs"',
|
|
417
|
+
sources: query ? `research action:"sources" query:${routeString(query)}` : 'research action:"sources"',
|
|
418
|
+
reports: query ? `research action:"reports" query:${routeString(query)}` : 'research action:"reports"',
|
|
419
|
+
saveReport: query ? `research action:"report" question:${routeString(query)} sources:[...] visualReport:true requireCitationCoverage:true confirm:true explicitUserRequest:"..."` : 'research action:"report" question:"..." sources:[...] visualReport:true requireCitationCoverage:true confirm:true explicitUserRequest:"..."',
|
|
420
|
+
},
|
|
421
|
+
nextActions: items
|
|
422
|
+
.filter((item) => item.kind !== 'browser')
|
|
423
|
+
.slice(0, includeParameters ? 6 : 4)
|
|
424
|
+
.map((item) => `${item.label}: ${item.next}`),
|
|
425
|
+
policy: 'Research briefing is read-only. It does not search the web, open a browser, create run state, save sources, write reports, ingest Knowledge, export artifacts, archive artifacts, or send messages; each returned effect route requires its own confirmation boundary.',
|
|
426
|
+
};
|
|
427
|
+
}
|