@pellux/goodvibes-agent 1.1.6 → 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.
Files changed (256) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/README.md +46 -30
  3. package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
  4. package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
  5. package/dist/package/main.js +132662 -91399
  6. package/docs/README.md +14 -7
  7. package/docs/channels-remote-and-api.md +8 -5
  8. package/docs/connected-host.md +14 -12
  9. package/docs/getting-started.md +56 -30
  10. package/docs/knowledge-artifacts-and-multimodal.md +7 -5
  11. package/docs/project-planning.md +2 -2
  12. package/docs/providers-and-routing.md +11 -3
  13. package/docs/tools-and-commands.md +114 -45
  14. package/docs/voice-and-live-tts.md +3 -1
  15. package/package.json +3 -2
  16. package/release/release-notes.md +130 -5
  17. package/release/release-readiness.json +120 -90
  18. package/src/agent/assistant-cockpit.ts +247 -0
  19. package/src/agent/autonomy-schedule-format.ts +96 -0
  20. package/src/agent/autonomy-schedule.ts +514 -0
  21. package/src/agent/channel-delivery-receipts.ts +292 -0
  22. package/src/agent/competitive-feature-inventory.ts +296 -0
  23. package/src/agent/document-registry-types.ts +106 -0
  24. package/src/agent/document-registry.ts +734 -0
  25. package/src/agent/harness-control.ts +2 -2
  26. package/src/agent/memory-prompt.ts +2 -2
  27. package/src/agent/operator-actions.ts +50 -6
  28. package/src/agent/persona-registry.ts +8 -0
  29. package/src/agent/project-context-files.ts +273 -0
  30. package/src/agent/prompt-context-receipts.ts +502 -0
  31. package/src/agent/reminder-schedule-format.ts +16 -2
  32. package/src/agent/research-run-registry.ts +582 -0
  33. package/src/agent/research-source-registry.ts +441 -0
  34. package/src/agent/routine-registry.ts +19 -3
  35. package/src/agent/routine-schedule-format.ts +27 -2
  36. package/src/agent/runtime-profile-starters.ts +7 -0
  37. package/src/agent/runtime-profile.ts +106 -4
  38. package/src/agent/schedule-edit-format.ts +129 -0
  39. package/src/agent/schedule-edit.ts +496 -0
  40. package/src/agent/schedule-next-routes.ts +42 -0
  41. package/src/agent/setup-wizard-checkpoint.ts +140 -0
  42. package/src/agent/setup-wizard.ts +447 -0
  43. package/src/agent/skill-registry-types.ts +102 -0
  44. package/src/agent/skill-registry.ts +81 -107
  45. package/src/agent/vibe-confirmation-routes.ts +62 -0
  46. package/src/agent/vibe-file.ts +285 -0
  47. package/src/cli/agent-knowledge-command.ts +45 -2
  48. package/src/cli/help.ts +3 -0
  49. package/src/cli/profiles-command.ts +25 -11
  50. package/src/config/agent-settings-policy.ts +1 -18
  51. package/src/input/agent-workspace-activation.ts +53 -0
  52. package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
  53. package/src/input/agent-workspace-artifact-metadata.ts +17 -0
  54. package/src/input/agent-workspace-basic-command-editors.ts +5 -1
  55. package/src/input/agent-workspace-categories.ts +153 -155
  56. package/src/input/agent-workspace-channel-triage.ts +481 -0
  57. package/src/input/agent-workspace-channels.ts +263 -0
  58. package/src/input/agent-workspace-command-editor.ts +152 -0
  59. package/src/input/agent-workspace-context-snapshot.ts +349 -0
  60. package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
  61. package/src/input/agent-workspace-document-editor.ts +502 -0
  62. package/src/input/agent-workspace-document-ops-editor.ts +523 -0
  63. package/src/input/agent-workspace-host-category.ts +1 -1
  64. package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
  65. package/src/input/agent-workspace-model-compare-editor.ts +376 -0
  66. package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
  67. package/src/input/agent-workspace-model-compare-types.ts +82 -0
  68. package/src/input/agent-workspace-model-compare-utils.ts +35 -0
  69. package/src/input/agent-workspace-onboarding-categories.ts +141 -0
  70. package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
  71. package/src/input/agent-workspace-operations-command-editors.ts +22 -0
  72. package/src/input/agent-workspace-research-report-editor.ts +212 -0
  73. package/src/input/agent-workspace-research-run-editor.ts +144 -0
  74. package/src/input/agent-workspace-research-source-editor.ts +167 -0
  75. package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
  76. package/src/input/agent-workspace-review-packet-utils.ts +265 -0
  77. package/src/input/agent-workspace-settings.ts +262 -30
  78. package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
  79. package/src/input/agent-workspace-setup-snapshot.ts +198 -0
  80. package/src/input/agent-workspace-setup.ts +34 -1
  81. package/src/input/agent-workspace-snapshot.ts +162 -147
  82. package/src/input/agent-workspace-types.ts +287 -2
  83. package/src/input/agent-workspace.ts +18 -0
  84. package/src/input/command-registry.ts +9 -2
  85. package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
  86. package/src/input/commands/channels-runtime.ts +102 -114
  87. package/src/input/commands/delegation-runtime.ts +87 -24
  88. package/src/input/commands/knowledge-browser-flags.ts +12 -0
  89. package/src/input/commands/knowledge.ts +28 -14
  90. package/src/input/commands/operator-actions-runtime.ts +6 -3
  91. package/src/input/commands/schedule-runtime.ts +71 -14
  92. package/src/input/commands/session-content.ts +2 -2
  93. package/src/input/commands/shell-core.ts +2 -0
  94. package/src/input/commands/vibe-runtime.ts +140 -0
  95. package/src/input/commands.ts +2 -0
  96. package/src/input/connected-host-routes.ts +123 -0
  97. package/src/input/settings-modal-types.ts +14 -0
  98. package/src/main.ts +15 -15
  99. package/src/panels/qr-panel.ts +2 -2
  100. package/src/renderer/agent-workspace-context-lines.ts +686 -0
  101. package/src/renderer/agent-workspace.ts +30 -419
  102. package/src/renderer/settings-modal-helpers.ts +12 -0
  103. package/src/renderer/settings-modal.ts +12 -0
  104. package/src/runtime/bootstrap-command-context.ts +11 -1
  105. package/src/runtime/bootstrap-command-parts.ts +14 -3
  106. package/src/runtime/bootstrap-core.ts +43 -1
  107. package/src/runtime/bootstrap-shell.ts +6 -0
  108. package/src/runtime/bootstrap.ts +113 -30
  109. package/src/runtime/connected-host-auth.ts +3 -2
  110. package/src/runtime/execution-ledger.ts +231 -0
  111. package/src/runtime/services.ts +88 -10
  112. package/src/runtime/tool-permission-safety.ts +287 -0
  113. package/src/shell/session-continuity-hints.ts +39 -0
  114. package/src/tools/agent-artifacts-tool.ts +606 -0
  115. package/src/tools/agent-audit-tool.ts +155 -0
  116. package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
  117. package/src/tools/agent-autonomy-tool.ts +140 -0
  118. package/src/tools/agent-channel-send-tool.ts +24 -2
  119. package/src/tools/agent-channels-tool.ts +140 -0
  120. package/src/tools/agent-computer-tool.ts +168 -0
  121. package/src/tools/agent-context-policy.ts +267 -10
  122. package/src/tools/agent-context-tool.ts +143 -0
  123. package/src/tools/agent-delegation-tool.ts +128 -0
  124. package/src/tools/agent-device-tool.ts +240 -0
  125. package/src/tools/agent-documents-tool.ts +684 -0
  126. package/src/tools/agent-execution-tool.ts +230 -0
  127. package/src/tools/agent-harness-agent-orchestration.ts +703 -0
  128. package/src/tools/agent-harness-autonomy-intake.ts +785 -0
  129. package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
  130. package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
  131. package/src/tools/agent-harness-autonomy-queue.ts +560 -0
  132. package/src/tools/agent-harness-background-processes-types.ts +35 -0
  133. package/src/tools/agent-harness-background-processes.ts +794 -0
  134. package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
  135. package/src/tools/agent-harness-browser-control.ts +338 -0
  136. package/src/tools/agent-harness-channel-metadata.ts +168 -10
  137. package/src/tools/agent-harness-cli-command-policy.ts +110 -0
  138. package/src/tools/agent-harness-command-catalog.ts +4 -2
  139. package/src/tools/agent-harness-command-runner.ts +42 -0
  140. package/src/tools/agent-harness-connected-host-status.ts +7 -4
  141. package/src/tools/agent-harness-delegation-posture.ts +234 -19
  142. package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
  143. package/src/tools/agent-harness-document-ops-types.ts +72 -0
  144. package/src/tools/agent-harness-document-ops.ts +671 -0
  145. package/src/tools/agent-harness-execution-history.ts +489 -0
  146. package/src/tools/agent-harness-execution-posture.ts +382 -0
  147. package/src/tools/agent-harness-file-recovery.ts +135 -0
  148. package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
  149. package/src/tools/agent-harness-learning-curator-common.ts +102 -0
  150. package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
  151. package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
  152. package/src/tools/agent-harness-learning-curator-types.ts +151 -0
  153. package/src/tools/agent-harness-learning-curator.ts +417 -0
  154. package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
  155. package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
  156. package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
  157. package/src/tools/agent-harness-media-posture.ts +208 -2
  158. package/src/tools/agent-harness-memory-posture.ts +556 -0
  159. package/src/tools/agent-harness-metadata.ts +100 -168
  160. package/src/tools/agent-harness-mode-catalog.ts +84 -33
  161. package/src/tools/agent-harness-model-catalog.ts +162 -0
  162. package/src/tools/agent-harness-model-provider-health.ts +186 -0
  163. package/src/tools/agent-harness-model-readiness.ts +406 -0
  164. package/src/tools/agent-harness-model-routing-types.ts +266 -0
  165. package/src/tools/agent-harness-model-routing-utils.ts +30 -0
  166. package/src/tools/agent-harness-model-routing.ts +137 -190
  167. package/src/tools/agent-harness-operator-methods.ts +115 -133
  168. package/src/tools/agent-harness-pairing-posture.ts +431 -18
  169. package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
  170. package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
  171. package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
  172. package/src/tools/agent-harness-personal-ops-records.ts +732 -0
  173. package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
  174. package/src/tools/agent-harness-personal-ops-types.ts +222 -0
  175. package/src/tools/agent-harness-personal-ops.ts +606 -0
  176. package/src/tools/agent-harness-project-context.ts +144 -0
  177. package/src/tools/agent-harness-prompt-context.ts +589 -0
  178. package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
  179. package/src/tools/agent-harness-release-evidence.ts +9 -7
  180. package/src/tools/agent-harness-release-readiness.ts +9 -7
  181. package/src/tools/agent-harness-research-briefing.ts +427 -0
  182. package/src/tools/agent-harness-research-queue.ts +250 -0
  183. package/src/tools/agent-harness-research-runs.ts +295 -0
  184. package/src/tools/agent-harness-research-workflow.ts +322 -0
  185. package/src/tools/agent-harness-security-posture.ts +2 -2
  186. package/src/tools/agent-harness-service-posture.ts +9 -9
  187. package/src/tools/agent-harness-session-metadata.ts +3 -3
  188. package/src/tools/agent-harness-setup-connected-host.ts +501 -0
  189. package/src/tools/agent-harness-setup-describe.ts +557 -0
  190. package/src/tools/agent-harness-setup-handoffs.ts +502 -0
  191. package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
  192. package/src/tools/agent-harness-setup-plan.ts +253 -0
  193. package/src/tools/agent-harness-setup-posture-types.ts +218 -0
  194. package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
  195. package/src/tools/agent-harness-setup-posture.ts +449 -221
  196. package/src/tools/agent-harness-setup-smoke.ts +508 -0
  197. package/src/tools/agent-harness-sudo-posture.ts +114 -0
  198. package/src/tools/agent-harness-tool-schema.ts +120 -7
  199. package/src/tools/agent-harness-tool-types.ts +78 -0
  200. package/src/tools/agent-harness-tool-utils.ts +43 -0
  201. package/src/tools/agent-harness-tool.ts +311 -370
  202. package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
  203. package/src/tools/agent-harness-ui-surface-types.ts +46 -0
  204. package/src/tools/agent-harness-vibe-health.ts +105 -0
  205. package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
  206. package/src/tools/agent-harness-workspace-actions.ts +114 -8
  207. package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
  208. package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
  209. package/src/tools/agent-host-tool.ts +159 -0
  210. package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
  211. package/src/tools/agent-learning-consolidation-core.ts +327 -0
  212. package/src/tools/agent-learning-consolidation-tool.ts +758 -0
  213. package/src/tools/agent-memory-tool.ts +214 -0
  214. package/src/tools/agent-model-compare-export.ts +315 -0
  215. package/src/tools/agent-model-compare-handoff.ts +592 -0
  216. package/src/tools/agent-model-compare-judgment.ts +633 -0
  217. package/src/tools/agent-model-compare-run.ts +722 -0
  218. package/src/tools/agent-model-compare-tool.ts +698 -0
  219. package/src/tools/agent-model-compare-types.ts +191 -0
  220. package/src/tools/agent-model-compare-utils.ts +93 -0
  221. package/src/tools/agent-models-tool.ts +208 -0
  222. package/src/tools/agent-operator-action-tool.ts +1 -1
  223. package/src/tools/agent-operator-method-tool.ts +643 -0
  224. package/src/tools/agent-personal-ops-tool.ts +197 -0
  225. package/src/tools/agent-policy-explanation.ts +415 -0
  226. package/src/tools/agent-research-report-tool.ts +608 -0
  227. package/src/tools/agent-research-runs-tool.ts +434 -0
  228. package/src/tools/agent-research-sources-tool.ts +443 -0
  229. package/src/tools/agent-research-tool.ts +687 -0
  230. package/src/tools/agent-review-packet-presets-core.ts +757 -0
  231. package/src/tools/agent-review-packet-presets-tool.ts +466 -0
  232. package/src/tools/agent-review-packet-share-tool.ts +305 -0
  233. package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
  234. package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
  235. package/src/tools/agent-route-planner-candidates-work.ts +251 -0
  236. package/src/tools/agent-route-planner-helpers.ts +667 -0
  237. package/src/tools/agent-route-planner.ts +185 -0
  238. package/src/tools/agent-route-tool.ts +105 -0
  239. package/src/tools/agent-schedule-edit-tool.ts +210 -0
  240. package/src/tools/agent-schedule-tool.ts +282 -0
  241. package/src/tools/agent-security-tool.ts +145 -0
  242. package/src/tools/agent-sessions-tool.ts +122 -0
  243. package/src/tools/agent-settings-import-tool.ts +104 -0
  244. package/src/tools/agent-settings-tool.ts +176 -0
  245. package/src/tools/agent-setup-tool.ts +226 -0
  246. package/src/tools/agent-support-tool.ts +122 -0
  247. package/src/tools/agent-terminal-process-tools.ts +167 -0
  248. package/src/tools/agent-tool-policy-guard-types.ts +77 -0
  249. package/src/tools/agent-tool-policy-guard.ts +110 -89
  250. package/src/tools/agent-vibe-tool.ts +297 -0
  251. package/src/tools/agent-work-plan-tool.ts +265 -6
  252. package/src/tools/agent-workspace-tool.ts +305 -0
  253. package/src/tools/artifact-archive.ts +169 -0
  254. package/src/tools/tool-definition-compaction.ts +36 -0
  255. package/src/tools/tool-execution-safety.ts +41 -0
  256. package/src/version.ts +1 -1
@@ -0,0 +1,143 @@
1
+ import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
2
+ import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
3
+ import type { CommandContext, CommandRegistry } from '../input/command-registry.ts';
4
+ import { createAgentHarnessTool } from './agent-harness-tool.ts';
5
+
6
+ type AgentContextAction =
7
+ | 'status'
8
+ | 'files'
9
+ | 'file'
10
+ | 'prompt'
11
+ | 'receipts'
12
+ | 'receipt';
13
+
14
+ interface AgentContextToolArgs {
15
+ readonly action?: unknown;
16
+ readonly mode?: unknown;
17
+ readonly contextFileId?: unknown;
18
+ readonly receiptId?: unknown;
19
+ readonly turnId?: unknown;
20
+ readonly outcomeStatus?: unknown;
21
+ readonly target?: unknown;
22
+ readonly query?: unknown;
23
+ readonly includeParameters?: unknown;
24
+ readonly limit?: unknown;
25
+ }
26
+
27
+ interface AgentContextToolDeps {
28
+ readonly commandRegistry: CommandRegistry;
29
+ readonly commandContext: CommandContext;
30
+ readonly toolRegistry: ToolRegistry;
31
+ readonly harnessTool?: Tool;
32
+ }
33
+
34
+ function readString(value: unknown): string {
35
+ return typeof value === 'string' ? value.trim() : '';
36
+ }
37
+
38
+ function normalizeContextAction(value: unknown): AgentContextAction | null {
39
+ const action = readString(value).toLowerCase().replace(/-/g, '_');
40
+ if (!action) return null;
41
+ if (action === 'status' || action === 'summary' || action === 'context' || action === 'current') return 'status';
42
+ if (action === 'files' || action === 'project' || action === 'project_context' || action === 'instructions') return 'files';
43
+ if (action === 'file' || action === 'show' || action === 'project_context_file' || action === 'instruction') return 'file';
44
+ if (action === 'prompt' || action === 'prompt_context' || action === 'composition' || action === 'budget') return 'prompt';
45
+ if (action === 'receipts' || action === 'turns' || action === 'outcomes') return 'receipts';
46
+ if (action === 'receipt' || action === 'turn' || action === 'outcome') return 'receipt';
47
+ return null;
48
+ }
49
+
50
+ function readAction(args: AgentContextToolArgs): AgentContextAction {
51
+ const explicit = normalizeContextAction(args.action) ?? normalizeContextAction(args.mode);
52
+ if (explicit) return explicit;
53
+ if (readString(args.receiptId) || readString(args.turnId) || readString(args.outcomeStatus)) return 'receipt';
54
+ if (readString(args.contextFileId)) return 'file';
55
+ if (readString(args.target) || readString(args.query)) return 'files';
56
+ return 'status';
57
+ }
58
+
59
+ function compactArgs(entries: Record<string, unknown>): Record<string, unknown> {
60
+ return Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== undefined && value !== ''));
61
+ }
62
+
63
+ export function createAgentContextTool(deps: AgentContextToolDeps): Tool {
64
+ const harnessTool = deps.harnessTool ?? createAgentHarnessTool({
65
+ commandRegistry: deps.commandRegistry,
66
+ commandContext: deps.commandContext,
67
+ toolRegistry: deps.toolRegistry,
68
+ });
69
+
70
+ return {
71
+ definition: {
72
+ name: 'context',
73
+ description: 'Inspect project instructions and prompt context.',
74
+ parameters: {
75
+ type: 'object',
76
+ properties: {
77
+ action: {
78
+ type: 'string',
79
+ enum: ['status', 'files', 'file', 'prompt', 'receipts', 'receipt'],
80
+ description: 'Read project files, prompt context, or receipt history.',
81
+ },
82
+ mode: { type: 'string', description: 'Alias for action.' },
83
+ contextFileId: { type: 'string', description: 'Project context file id.' },
84
+ receiptId: { type: 'string', description: 'Prompt context receipt id.' },
85
+ turnId: { type: 'string', description: 'Prompt context turn id.' },
86
+ outcomeStatus: { type: 'string', enum: ['completed', 'error', 'cancelled', 'pending'], description: 'Prompt receipt outcome filter.' },
87
+ target: { type: 'string', description: 'Target file path or context lookup text.' },
88
+ query: { type: 'string', description: 'Search text for context files.' },
89
+ includeParameters: { type: 'boolean', description: 'Include bounded bodies and receipt detail.' },
90
+ limit: { type: 'number', description: 'Maximum prompt receipts to return.' },
91
+ },
92
+ additionalProperties: false,
93
+ },
94
+ sideEffects: [],
95
+ concurrency: 'parallel',
96
+ },
97
+ execute: async (rawArgs: unknown) => {
98
+ const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentContextToolArgs;
99
+ const action = readAction(args);
100
+
101
+ if (action === 'files') {
102
+ return harnessTool.execute(compactArgs({
103
+ mode: 'project_context',
104
+ target: args.target,
105
+ query: args.query,
106
+ includeParameters: args.includeParameters,
107
+ }));
108
+ }
109
+ if (action === 'file') {
110
+ return harnessTool.execute(compactArgs({
111
+ mode: 'project_context_file',
112
+ contextFileId: args.contextFileId,
113
+ target: args.target,
114
+ query: args.query,
115
+ includeParameters: args.includeParameters,
116
+ }));
117
+ }
118
+ if (action === 'receipt' || action === 'receipts') {
119
+ return harnessTool.execute(compactArgs({
120
+ mode: 'prompt_context',
121
+ receiptId: args.receiptId,
122
+ turnId: args.turnId,
123
+ outcomeStatus: args.outcomeStatus,
124
+ limit: args.limit,
125
+ includeParameters: action === 'receipt' ? args.includeParameters ?? true : args.includeParameters,
126
+ }));
127
+ }
128
+ return harnessTool.execute(compactArgs({
129
+ mode: 'prompt_context',
130
+ limit: args.limit,
131
+ includeParameters: args.includeParameters,
132
+ }));
133
+ },
134
+ };
135
+ }
136
+
137
+ export function registerAgentContextTool(
138
+ registry: ToolRegistry,
139
+ commandRegistry: CommandRegistry,
140
+ commandContext: CommandContext,
141
+ ): void {
142
+ if (!registry.has('context')) registry.register(createAgentContextTool({ commandRegistry, commandContext, toolRegistry: registry }));
143
+ }
@@ -0,0 +1,128 @@
1
+ import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
2
+ import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
3
+ import type { CommandContext, CommandRegistry } from '../input/command-registry.ts';
4
+ import { createAgentHarnessTool } from './agent-harness-tool.ts';
5
+
6
+ type AgentDelegationAction = 'status' | 'routes' | 'route';
7
+
8
+ interface AgentDelegationToolArgs {
9
+ readonly action?: unknown;
10
+ readonly mode?: unknown;
11
+ readonly id?: unknown;
12
+ readonly delegationRouteId?: unknown;
13
+ readonly target?: unknown;
14
+ readonly query?: unknown;
15
+ readonly includeParameters?: unknown;
16
+ readonly limit?: unknown;
17
+ }
18
+
19
+ interface AgentDelegationToolDeps {
20
+ readonly commandRegistry: CommandRegistry;
21
+ readonly commandContext: CommandContext;
22
+ readonly toolRegistry: ToolRegistry;
23
+ readonly harnessTool?: Tool;
24
+ }
25
+
26
+ function error(message: string): { readonly success: false; readonly error: string } {
27
+ return { success: false, error: message };
28
+ }
29
+
30
+ function readString(value: unknown): string {
31
+ return typeof value === 'string' ? value.trim() : '';
32
+ }
33
+
34
+ function normalizeDelegationAction(value: unknown): AgentDelegationAction | null {
35
+ const action = readString(value).toLowerCase().replace(/-/g, '_');
36
+ if (!action) return null;
37
+ if (action === 'status' || action === 'summary' || action === 'overview' || action === 'policy' || action === 'decision' || action === 'decisions' || action === 'delegation_posture') return 'status';
38
+ if (action === 'routes' || action === 'list' || action === 'catalog' || action === 'posture') return 'routes';
39
+ if (action === 'route' || action === 'item' || action === 'card' || action === 'show' || action === 'inspect' || action === 'delegation_route') return 'route';
40
+ return null;
41
+ }
42
+
43
+ function readAction(args: AgentDelegationToolArgs): AgentDelegationAction {
44
+ const explicit = normalizeDelegationAction(args.action) ?? normalizeDelegationAction(args.mode);
45
+ if (explicit) return explicit;
46
+ if (readString(args.delegationRouteId) || readString(args.id)) return 'route';
47
+ return 'status';
48
+ }
49
+
50
+ function compactArgs(entries: Record<string, unknown>): Record<string, unknown> {
51
+ return Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== undefined && value !== ''));
52
+ }
53
+
54
+ function routeId(args: AgentDelegationToolArgs): string {
55
+ return readString(args.delegationRouteId) || readString(args.id);
56
+ }
57
+
58
+ function postureArgs(args: AgentDelegationToolArgs): Record<string, unknown> {
59
+ return compactArgs({
60
+ mode: 'delegation_posture',
61
+ query: args.query ?? args.target,
62
+ limit: args.limit,
63
+ includeParameters: args.includeParameters,
64
+ });
65
+ }
66
+
67
+ function routeArgs(args: AgentDelegationToolArgs): Record<string, unknown> {
68
+ const delegationRouteId = routeId(args);
69
+ return compactArgs({
70
+ mode: 'delegation_route',
71
+ delegationRouteId,
72
+ target: delegationRouteId ? undefined : args.target,
73
+ query: delegationRouteId ? undefined : args.query,
74
+ includeParameters: args.includeParameters,
75
+ });
76
+ }
77
+
78
+ export function createAgentDelegationTool(deps: AgentDelegationToolDeps): Tool {
79
+ const harnessTool = deps.harnessTool ?? createAgentHarnessTool({
80
+ commandRegistry: deps.commandRegistry,
81
+ commandContext: deps.commandContext,
82
+ toolRegistry: deps.toolRegistry,
83
+ });
84
+
85
+ return {
86
+ definition: {
87
+ name: 'delegation',
88
+ description: 'Inspect build delegation routes and policy.',
89
+ parameters: {
90
+ type: 'object',
91
+ properties: {
92
+ action: {
93
+ type: 'string',
94
+ enum: ['status', 'routes', 'route'],
95
+ description: 'Read-only delegation status, route catalog, or single route inspection.',
96
+ },
97
+ mode: { type: 'string', description: 'Alias for action.' },
98
+ id: { type: 'string', description: 'Alias for delegationRouteId.' },
99
+ delegationRouteId: { type: 'string', description: 'Delegation route id.' },
100
+ target: { type: 'string', description: 'Lookup target or route search text.' },
101
+ query: { type: 'string', description: 'Route search text.' },
102
+ includeParameters: { type: 'boolean', description: 'Include required fields, evidence, and confirmed handoff routes.' },
103
+ limit: { type: 'number', description: 'Maximum route rows returned.' },
104
+ },
105
+ additionalProperties: false,
106
+ },
107
+ sideEffects: [],
108
+ concurrency: 'parallel',
109
+ },
110
+ execute: async (rawArgs: unknown) => {
111
+ const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentDelegationToolArgs;
112
+ const action = readAction(args);
113
+
114
+ if (action === 'status' || action === 'routes') return harnessTool.execute(postureArgs(args));
115
+ if (action === 'route') return harnessTool.execute(routeArgs(args));
116
+
117
+ return error('Unknown delegation action. Use action:"status" for policy or action:"route" for one delegation route.');
118
+ },
119
+ };
120
+ }
121
+
122
+ export function registerAgentDelegationTool(
123
+ registry: ToolRegistry,
124
+ commandRegistry: CommandRegistry,
125
+ commandContext: CommandContext,
126
+ ): void {
127
+ if (!registry.has('delegation')) registry.register(createAgentDelegationTool({ commandRegistry, commandContext, toolRegistry: registry }));
128
+ }
@@ -0,0 +1,240 @@
1
+ import type { Tool } from '@pellux/goodvibes-sdk/platform/types';
2
+ import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
3
+ import type { CommandContext, CommandRegistry } from '../input/command-registry.ts';
4
+ import { createAgentHarnessTool } from './agent-harness-tool.ts';
5
+
6
+ type AgentDeviceAction =
7
+ | 'status'
8
+ | 'capability'
9
+ | 'browser'
10
+ | 'open_browser'
11
+ | 'control'
12
+ | 'voice'
13
+ | 'provider'
14
+ | 'open_tts_provider'
15
+ | 'open_tts_voice';
16
+
17
+ interface AgentDeviceToolArgs {
18
+ readonly action?: unknown;
19
+ readonly mode?: unknown;
20
+ readonly id?: unknown;
21
+ readonly capabilityId?: unknown;
22
+ readonly routeId?: unknown;
23
+ readonly pairingRouteId?: unknown;
24
+ readonly mediaProviderId?: unknown;
25
+ readonly providerId?: unknown;
26
+ readonly target?: unknown;
27
+ readonly query?: unknown;
28
+ readonly includeParameters?: unknown;
29
+ readonly limit?: unknown;
30
+ readonly confirm?: unknown;
31
+ readonly explicitUserRequest?: unknown;
32
+ }
33
+
34
+ interface AgentDeviceToolDeps {
35
+ readonly commandRegistry: CommandRegistry;
36
+ readonly commandContext: CommandContext;
37
+ readonly toolRegistry: ToolRegistry;
38
+ readonly harnessTool?: Tool;
39
+ }
40
+
41
+ function error(message: string): { readonly success: false; readonly error: string } {
42
+ return { success: false, error: message };
43
+ }
44
+
45
+ function readString(value: unknown): string {
46
+ return typeof value === 'string' ? value.trim() : '';
47
+ }
48
+
49
+ function normalizeDeviceAction(value: unknown): AgentDeviceAction | null {
50
+ const action = readString(value).toLowerCase().replace(/-/g, '_');
51
+ if (!action) return null;
52
+ if (action === 'status' || action === 'map' || action === 'capabilities' || action === 'device' || action === 'devices' || action === 'mobile' || action === 'phone' || action === 'pairing') return 'status';
53
+ if (action === 'capability' || action === 'route' || action === 'pairing_route' || action === 'show' || action === 'inspect') return 'capability';
54
+ if (action === 'browser' || action === 'pwa' || action === 'cockpit' || action === 'browser_cockpit' || action === 'web') return 'browser';
55
+ if (action === 'open' || action === 'open_browser' || action === 'open_pwa' || action === 'open_cockpit' || action === 'open_browser_cockpit') return 'open_browser';
56
+ if (action === 'control' || action === 'browser_control' || action === 'desktop' || action === 'desktop_control' || action === 'computer_use') return 'control';
57
+ if (action === 'voice' || action === 'media' || action === 'voice_media' || action === 'workflows') return 'voice';
58
+ if (action === 'provider' || action === 'media_provider' || action === 'voice_provider') return 'provider';
59
+ if (action === 'open_tts_provider' || action === 'tts_provider_picker') return 'open_tts_provider';
60
+ if (action === 'open_tts_voice' || action === 'tts_voice_picker') return 'open_tts_voice';
61
+ return null;
62
+ }
63
+
64
+ function readAction(args: AgentDeviceToolArgs): AgentDeviceAction {
65
+ const explicit = normalizeDeviceAction(args.action) ?? normalizeDeviceAction(args.mode);
66
+ if (explicit) return explicit;
67
+ if (readString(args.mediaProviderId) || readString(args.providerId)) return 'provider';
68
+ if (readString(args.capabilityId) || readString(args.routeId) || readString(args.pairingRouteId)) return 'capability';
69
+ return 'status';
70
+ }
71
+
72
+ function compactArgs(entries: Record<string, unknown>): Record<string, unknown> {
73
+ return Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== undefined && value !== ''));
74
+ }
75
+
76
+ function capabilityLookup(args: AgentDeviceToolArgs): string {
77
+ return readString(args.pairingRouteId)
78
+ || readString(args.capabilityId)
79
+ || readString(args.routeId)
80
+ || readString(args.id);
81
+ }
82
+
83
+ function providerLookup(args: AgentDeviceToolArgs): string {
84
+ return readString(args.mediaProviderId)
85
+ || readString(args.providerId)
86
+ || readString(args.id);
87
+ }
88
+
89
+ function confirmedArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
90
+ return compactArgs({
91
+ confirm: args.confirm,
92
+ explicitUserRequest: args.explicitUserRequest,
93
+ });
94
+ }
95
+
96
+ function statusArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
97
+ return compactArgs({
98
+ mode: 'pairing_posture',
99
+ query: args.query ?? args.target ?? 'device',
100
+ includeParameters: args.includeParameters,
101
+ limit: args.limit,
102
+ });
103
+ }
104
+
105
+ function capabilityArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
106
+ const pairingRouteId = capabilityLookup(args);
107
+ return compactArgs({
108
+ mode: 'pairing_route',
109
+ pairingRouteId,
110
+ target: pairingRouteId ? undefined : args.target,
111
+ query: pairingRouteId ? undefined : args.query,
112
+ includeParameters: args.includeParameters,
113
+ });
114
+ }
115
+
116
+ function browserArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
117
+ return compactArgs({
118
+ mode: 'ui_surface',
119
+ surfaceId: 'connected-browser-cockpit',
120
+ includeParameters: args.includeParameters ?? true,
121
+ });
122
+ }
123
+
124
+ function openBrowserArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
125
+ return compactArgs({
126
+ mode: 'open_ui_surface',
127
+ surfaceId: 'connected-browser-cockpit',
128
+ ...confirmedArgs(args),
129
+ });
130
+ }
131
+
132
+ function controlArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
133
+ return compactArgs({
134
+ mode: 'execution_route',
135
+ executionRouteId: 'browser-or-desktop-control',
136
+ includeParameters: args.includeParameters ?? true,
137
+ });
138
+ }
139
+
140
+ function voiceArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
141
+ return compactArgs({
142
+ mode: 'media_posture',
143
+ query: args.query ?? args.target ?? 'voice',
144
+ includeParameters: args.includeParameters,
145
+ limit: args.limit,
146
+ });
147
+ }
148
+
149
+ function providerArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
150
+ const mediaProviderId = providerLookup(args);
151
+ return compactArgs({
152
+ mode: 'media_provider',
153
+ mediaProviderId,
154
+ target: mediaProviderId ? undefined : args.target,
155
+ query: mediaProviderId ? undefined : args.query,
156
+ includeParameters: args.includeParameters,
157
+ });
158
+ }
159
+
160
+ function openTtsProviderArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
161
+ return compactArgs({
162
+ mode: 'open_ui_surface',
163
+ surfaceId: 'tts-provider-picker',
164
+ ...confirmedArgs(args),
165
+ });
166
+ }
167
+
168
+ function openTtsVoiceArgs(args: AgentDeviceToolArgs): Record<string, unknown> {
169
+ return compactArgs({
170
+ mode: 'open_ui_surface',
171
+ surfaceId: 'tts-voice-picker',
172
+ target: readString(args.providerId) || readString(args.mediaProviderId) || args.target,
173
+ ...confirmedArgs(args),
174
+ });
175
+ }
176
+
177
+ export function createAgentDeviceTool(deps: AgentDeviceToolDeps): Tool {
178
+ const harnessTool = deps.harnessTool ?? createAgentHarnessTool({
179
+ commandRegistry: deps.commandRegistry,
180
+ commandContext: deps.commandContext,
181
+ toolRegistry: deps.toolRegistry,
182
+ });
183
+
184
+ return {
185
+ definition: {
186
+ name: 'device',
187
+ description: 'Inspect/open device, voice, and browser routes.',
188
+ parameters: {
189
+ type: 'object',
190
+ properties: {
191
+ action: {
192
+ type: 'string',
193
+ enum: ['status', 'capability', 'browser', 'open_browser', 'control', 'voice', 'provider', 'open_tts_provider', 'open_tts_voice'],
194
+ description: 'Read device/browser/voice posture; confirm visible open actions.',
195
+ },
196
+ mode: { type: 'string', description: 'Alias for action.' },
197
+ id: { type: 'string', description: 'Capability, route, or provider id alias.' },
198
+ capabilityId: { type: 'string', description: 'Device capability id.' },
199
+ routeId: { type: 'string', description: 'Pairing route id alias.' },
200
+ pairingRouteId: { type: 'string', description: 'Pairing route id.' },
201
+ mediaProviderId: { type: 'string', description: 'Voice/media provider id.' },
202
+ providerId: { type: 'string', description: 'Voice/media provider id alias.' },
203
+ target: { type: 'string', description: 'Lookup or provider target.' },
204
+ query: { type: 'string', description: 'Search text.' },
205
+ includeParameters: { type: 'boolean', description: 'Include detailed route contracts.' },
206
+ limit: { type: 'number', description: 'Maximum rows.' },
207
+ confirm: { type: 'boolean', description: 'Required true for visible open actions.' },
208
+ explicitUserRequest: { type: 'string', description: 'User request authorizing visible open actions.' },
209
+ },
210
+ additionalProperties: false,
211
+ },
212
+ sideEffects: ['state'],
213
+ concurrency: 'serial',
214
+ },
215
+ execute: async (rawArgs: unknown) => {
216
+ const args = (rawArgs && typeof rawArgs === 'object' && !Array.isArray(rawArgs) ? rawArgs : {}) as AgentDeviceToolArgs;
217
+ const action = readAction(args);
218
+
219
+ if (action === 'status') return harnessTool.execute(statusArgs(args));
220
+ if (action === 'capability') return harnessTool.execute(capabilityArgs(args));
221
+ if (action === 'browser') return harnessTool.execute(browserArgs(args));
222
+ if (action === 'open_browser') return harnessTool.execute(openBrowserArgs(args));
223
+ if (action === 'control') return harnessTool.execute(controlArgs(args));
224
+ if (action === 'voice') return harnessTool.execute(voiceArgs(args));
225
+ if (action === 'provider') return harnessTool.execute(providerArgs(args));
226
+ if (action === 'open_tts_provider') return harnessTool.execute(openTtsProviderArgs(args));
227
+ if (action === 'open_tts_voice') return harnessTool.execute(openTtsVoiceArgs(args));
228
+
229
+ return error('Unknown device action. Use action:"status" for the device capability map.');
230
+ },
231
+ };
232
+ }
233
+
234
+ export function registerAgentDeviceTool(
235
+ registry: ToolRegistry,
236
+ commandRegistry: CommandRegistry,
237
+ commandContext: CommandContext,
238
+ ): void {
239
+ if (!registry.has('device')) registry.register(createAgentDeviceTool({ commandRegistry, commandContext, toolRegistry: registry }));
240
+ }