@swarmclawai/swarmclaw 1.2.8 → 1.2.9

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 (195) hide show
  1. package/README.md +30 -6
  2. package/package.json +2 -2
  3. package/src/app/agents/[id]/page.tsx +1 -18
  4. package/src/app/api/agents/thread-route.test.ts +0 -1
  5. package/src/app/api/approvals/route.test.ts +6 -22
  6. package/src/app/api/connectors/route.ts +2 -2
  7. package/src/app/api/portability/export/route.ts +8 -0
  8. package/src/app/api/portability/import/route.test.ts +80 -0
  9. package/src/app/api/portability/import/route.ts +28 -0
  10. package/src/app/api/settings/route.ts +0 -2
  11. package/src/app/api/wallets/[id]/route.ts +15 -157
  12. package/src/app/api/wallets/generate/route.ts +22 -0
  13. package/src/app/api/wallets/route.test.ts +147 -0
  14. package/src/app/api/wallets/route.ts +13 -95
  15. package/src/app/autonomy/page.tsx +2 -57
  16. package/src/app/protocols/page.tsx +2 -21
  17. package/src/app/settings/page.tsx +0 -9
  18. package/src/app/wallets/page.tsx +105 -5
  19. package/src/cli/index.js +21 -33
  20. package/src/cli/spec.js +19 -30
  21. package/src/components/agents/agent-sheet.tsx +2 -40
  22. package/src/components/agents/inspector-panel.tsx +0 -83
  23. package/src/components/chat/chat-card.tsx +0 -31
  24. package/src/components/chat/message-bubble.tsx +1 -108
  25. package/src/components/connectors/connector-sheet.tsx +25 -1
  26. package/src/components/layout/sidebar-rail.tsx +6 -10
  27. package/src/components/projects/project-detail.tsx +3 -35
  28. package/src/components/projects/tabs/overview-tab.tsx +3 -59
  29. package/src/components/projects/tabs/work-tab.tsx +7 -77
  30. package/src/components/protocols/structured-session-launcher.tsx +1 -22
  31. package/src/components/shared/connector-platform-icon.tsx +1 -0
  32. package/src/components/tasks/task-card.tsx +4 -34
  33. package/src/components/tasks/task-sheet.tsx +6 -36
  34. package/src/components/wallets/wallet-list.tsx +150 -0
  35. package/src/lib/app/navigation.test.ts +0 -13
  36. package/src/lib/app/navigation.ts +2 -7
  37. package/src/lib/app/view-constants.ts +14 -19
  38. package/src/lib/server/agents/agent-thread-session.ts +0 -1
  39. package/src/lib/server/agents/delegation-advisory.test.ts +0 -1
  40. package/src/lib/server/agents/delegation-jobs.test.ts +0 -69
  41. package/src/lib/server/agents/delegation-jobs.ts +0 -25
  42. package/src/lib/server/agents/main-agent-loop.ts +1 -49
  43. package/src/lib/server/agents/subagent-runtime.ts +0 -1
  44. package/src/lib/server/approval-match.ts +0 -85
  45. package/src/lib/server/approvals.test.ts +6 -6
  46. package/src/lib/server/approvals.ts +0 -6
  47. package/src/lib/server/autonomy/supervisor-reflection.test.ts +0 -1
  48. package/src/lib/server/builtin-extensions.ts +0 -2
  49. package/src/lib/server/capability-router.test.ts +0 -2
  50. package/src/lib/server/chat-execution/chat-execution-tool-events.test.ts +14 -14
  51. package/src/lib/server/chat-execution/chat-execution-types.ts +0 -2
  52. package/src/lib/server/chat-execution/chat-execution-utils.ts +0 -2
  53. package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -30
  54. package/src/lib/server/chat-execution/chat-turn-finalization.ts +1 -36
  55. package/src/lib/server/chat-execution/chat-turn-preparation.ts +2 -22
  56. package/src/lib/server/chat-execution/iteration-event-handler.ts +0 -24
  57. package/src/lib/server/chat-execution/message-classifier.test.ts +0 -45
  58. package/src/lib/server/chat-execution/message-classifier.ts +1 -16
  59. package/src/lib/server/chat-execution/prompt-builder.test.ts +0 -1
  60. package/src/lib/server/chat-execution/prompt-builder.ts +0 -30
  61. package/src/lib/server/chat-execution/prompt-sections.ts +0 -1
  62. package/src/lib/server/chat-execution/situational-awareness.test.ts +2 -73
  63. package/src/lib/server/chat-execution/situational-awareness.ts +4 -38
  64. package/src/lib/server/chat-execution/stream-agent-chat.test.ts +8 -123
  65. package/src/lib/server/chat-execution/stream-agent-chat.ts +1 -5
  66. package/src/lib/server/chat-execution/stream-continuation.test.ts +4 -52
  67. package/src/lib/server/chat-execution/stream-continuation.ts +6 -48
  68. package/src/lib/server/chatrooms/session-mailbox.ts +0 -10
  69. package/src/lib/server/chats/chat-session-service.ts +3 -5
  70. package/src/lib/server/connectors/connector-inbound.ts +0 -1
  71. package/src/lib/server/connectors/connector-lifecycle.ts +19 -3
  72. package/src/lib/server/connectors/connector-service.ts +39 -9
  73. package/src/lib/server/connectors/swarmdock-bidding.ts +74 -0
  74. package/src/lib/server/connectors/swarmdock-payloads.test.ts +85 -0
  75. package/src/lib/server/connectors/swarmdock-secret.test.ts +128 -0
  76. package/src/lib/server/connectors/swarmdock-secret.ts +152 -0
  77. package/src/lib/server/connectors/swarmdock-tasks.ts +119 -0
  78. package/src/lib/server/connectors/swarmdock.ts +255 -0
  79. package/src/lib/server/execution-brief.test.ts +2 -25
  80. package/src/lib/server/execution-brief.ts +12 -35
  81. package/src/lib/server/execution-engine/task-attempt.ts +0 -1
  82. package/src/lib/server/persistence/storage-context.ts +0 -5
  83. package/src/lib/server/portability/export.ts +109 -0
  84. package/src/lib/server/portability/import.ts +159 -0
  85. package/src/lib/server/protocols/protocol-normalization.ts +0 -4
  86. package/src/lib/server/protocols/protocol-queries.ts +0 -6
  87. package/src/lib/server/protocols/protocol-run-lifecycle.ts +4 -32
  88. package/src/lib/server/protocols/protocol-service.ts +0 -1
  89. package/src/lib/server/protocols/protocol-step-helpers.ts +0 -4
  90. package/src/lib/server/protocols/protocol-step-processors.ts +0 -6
  91. package/src/lib/server/protocols/protocol-swarm.ts +0 -2
  92. package/src/lib/server/protocols/protocol-types.ts +0 -2
  93. package/src/lib/server/provider-health.ts +0 -9
  94. package/src/lib/server/runtime/daemon-state/core.ts +0 -9
  95. package/src/lib/server/runtime/daemon-state.test.ts +0 -35
  96. package/src/lib/server/runtime/heartbeat-service.ts +3 -23
  97. package/src/lib/server/runtime/queue/core.ts +11 -33
  98. package/src/lib/server/runtime/runtime-storage-write-paths.test.ts +6 -6
  99. package/src/lib/server/runtime/scheduler.ts +0 -13
  100. package/src/lib/server/runtime/session-run-manager/drain.ts +0 -24
  101. package/src/lib/server/runtime/session-run-manager/enqueue.ts +0 -1
  102. package/src/lib/server/runtime/session-run-manager/queries.ts +0 -1
  103. package/src/lib/server/runtime/session-run-manager/recovery.ts +0 -1
  104. package/src/lib/server/runtime/session-run-manager.test.ts +0 -28
  105. package/src/lib/server/session-tools/crud.ts +0 -14
  106. package/src/lib/server/session-tools/delegate.ts +0 -4
  107. package/src/lib/server/session-tools/index.ts +0 -4
  108. package/src/lib/server/session-tools/team-context.ts +0 -3
  109. package/src/lib/server/storage-normalization.ts +8 -0
  110. package/src/lib/server/storage.ts +18 -45
  111. package/src/lib/server/tasks/task-checkout.ts +59 -0
  112. package/src/lib/server/tasks/task-lifecycle.ts +2 -0
  113. package/src/lib/server/tasks/task-route-service.ts +4 -26
  114. package/src/lib/server/tasks/task-service.ts +0 -7
  115. package/src/lib/server/tool-aliases.ts +0 -1
  116. package/src/lib/server/tool-capability-policy-advanced.test.ts +4 -4
  117. package/src/lib/server/tool-capability-policy.ts +0 -2
  118. package/src/lib/server/tool-planning.ts +0 -12
  119. package/src/lib/server/universal-tool-access.ts +0 -1
  120. package/src/lib/server/wallets/wallet-crypto.ts +33 -0
  121. package/src/lib/server/wallets/wallet-repository.ts +24 -0
  122. package/src/lib/server/wallets/wallet-service.ts +119 -0
  123. package/src/lib/server/working-state/extraction.ts +8 -42
  124. package/src/lib/server/working-state/normalization.ts +10 -103
  125. package/src/lib/server/working-state/service.ts +12 -21
  126. package/src/lib/strip-internal-metadata.test.ts +1 -1
  127. package/src/lib/strip-internal-metadata.ts +1 -1
  128. package/src/lib/tool-definitions.ts +0 -1
  129. package/src/lib/validation/schemas.ts +33 -2
  130. package/src/stores/slices/data-slice.ts +5 -1
  131. package/src/stores/slices/ui-slice.ts +0 -4
  132. package/src/types/agent.ts +0 -84
  133. package/src/types/app-settings.ts +0 -2
  134. package/src/types/approval.ts +0 -2
  135. package/src/types/connector.ts +1 -0
  136. package/src/types/index.ts +1 -1
  137. package/src/types/message.ts +0 -1
  138. package/src/types/misc.ts +0 -2
  139. package/src/types/protocol.ts +0 -2
  140. package/src/types/run.ts +0 -3
  141. package/src/types/session.ts +1 -51
  142. package/src/types/swarmdock.ts +29 -0
  143. package/src/types/task.ts +7 -3
  144. package/src/types/working-state.ts +2 -9
  145. package/src/views/settings/section-runtime-loop.tsx +0 -14
  146. package/src/app/api/canvas/[sessionId]/route.ts +0 -35
  147. package/src/app/api/missions/[id]/actions/route.ts +0 -31
  148. package/src/app/api/missions/[id]/events/route.ts +0 -14
  149. package/src/app/api/missions/[id]/route.ts +0 -10
  150. package/src/app/api/missions/route.test.ts +0 -244
  151. package/src/app/api/missions/route.ts +0 -57
  152. package/src/app/api/wallets/[id]/approve/route.ts +0 -79
  153. package/src/app/api/wallets/[id]/balance-history/route.ts +0 -18
  154. package/src/app/api/wallets/[id]/send/route.ts +0 -113
  155. package/src/app/api/wallets/[id]/transactions/route.ts +0 -18
  156. package/src/app/missions/[id]/page.tsx +0 -3
  157. package/src/app/missions/page.tsx +0 -685
  158. package/src/components/canvas/canvas-panel.tsx +0 -267
  159. package/src/components/wallets/wallet-approval-dialog.tsx +0 -107
  160. package/src/components/wallets/wallet-panel.tsx +0 -1010
  161. package/src/components/wallets/wallet-section.tsx +0 -260
  162. package/src/features/missions/queries.ts +0 -23
  163. package/src/lib/canvas-content.test.ts +0 -360
  164. package/src/lib/canvas-content.ts +0 -198
  165. package/src/lib/server/canvas-content.test.ts +0 -32
  166. package/src/lib/server/canvas-content.ts +0 -6
  167. package/src/lib/server/ethereum.ts +0 -591
  168. package/src/lib/server/evm-swap.ts +0 -476
  169. package/src/lib/server/missions/mission-intent.test.ts +0 -63
  170. package/src/lib/server/missions/mission-intent.ts +0 -569
  171. package/src/lib/server/missions/mission-repository.ts +0 -74
  172. package/src/lib/server/missions/mission-service/actions.ts +0 -6
  173. package/src/lib/server/missions/mission-service/bindings.ts +0 -9
  174. package/src/lib/server/missions/mission-service/context.ts +0 -4
  175. package/src/lib/server/missions/mission-service/core.ts +0 -2271
  176. package/src/lib/server/missions/mission-service/queries.ts +0 -12
  177. package/src/lib/server/missions/mission-service/recovery.ts +0 -5
  178. package/src/lib/server/missions/mission-service/ticks.ts +0 -9
  179. package/src/lib/server/missions/mission-service.test.ts +0 -888
  180. package/src/lib/server/missions/mission-service.ts +0 -6
  181. package/src/lib/server/session-tools/canvas.ts +0 -105
  182. package/src/lib/server/session-tools/wallet-tool.test.ts +0 -150
  183. package/src/lib/server/session-tools/wallet.ts +0 -1287
  184. package/src/lib/server/solana.ts +0 -327
  185. package/src/lib/server/wallet/wallet-execution.test.ts +0 -198
  186. package/src/lib/server/wallet/wallet-portfolio.test.ts +0 -98
  187. package/src/lib/server/wallet/wallet-portfolio.ts +0 -772
  188. package/src/lib/server/wallet/wallet-service.test.ts +0 -81
  189. package/src/lib/server/wallet/wallet-service.ts +0 -225
  190. package/src/lib/wallet/wallet-transactions.test.ts +0 -75
  191. package/src/lib/wallet/wallet-transactions.ts +0 -43
  192. package/src/lib/wallet/wallet.test.ts +0 -333
  193. package/src/lib/wallet/wallet.ts +0 -183
  194. package/src/types/mission.ts +0 -185
  195. package/src/views/settings/section-wallets.tsx +0 -35
@@ -40,7 +40,6 @@ describe('buildAgenticExecutionPolicy', () => {
40
40
  isDeliverableTask: false,
41
41
  isBroadGoal: false,
42
42
  isLightweightDirectChat: true,
43
- walletIntent: 'none',
44
43
  hasHumanSignals: false,
45
44
  hasSignificantEvent: false,
46
45
  isResearchSynthesis: false,
@@ -13,7 +13,6 @@ import {
13
13
  import { getExtensionManager } from '@/lib/server/extensions'
14
14
  import {
15
15
  getEnabledToolPlanningView,
16
- getFirstToolForCapability,
17
16
  getToolsForCapability,
18
17
  TOOL_CAPABILITY,
19
18
  } from '@/lib/server/tool-planning'
@@ -23,7 +22,6 @@ import { routeTaskIntent } from '@/lib/server/capability-router'
23
22
  import type { MessageClassification } from '@/lib/server/chat-execution/message-classifier'
24
23
  import {
25
24
  isBroadGoal as classifiedIsBroadGoal,
26
- hasWalletIntent as classifiedHasWalletIntent,
27
25
  isDeliverableTask as classifiedIsDeliverableTask,
28
26
  } from '@/lib/server/chat-execution/message-classifier'
29
27
  import { isCurrentThreadRecallRequest } from '@/lib/server/memory/memory-policy'
@@ -112,7 +110,6 @@ export function buildToolDisciplineLines(enabledExtensions: string[]): string[]
112
110
  const planning = getEnabledToolPlanningView(enabledExtensions)
113
111
  const uniqueTools = buildExactToolNameList(enabledExtensions)
114
112
  if (uniqueTools.length === 0) return []
115
- const walletTools = getToolsForCapability(enabledExtensions, TOOL_CAPABILITY.walletInspect)
116
113
  const httpTools = getToolsForCapability(enabledExtensions, 'network.http')
117
114
 
118
115
  const lines = [
@@ -164,10 +161,6 @@ export function buildToolDisciplineLines(enabledExtensions: string[]): string[]
164
161
  lines.push(`If one research path is blocked, try another (${alternateResearchTools.map((toolName) => `\`${toolName}\``).join(', ')}) before giving up.`)
165
162
  }
166
163
 
167
- if (walletTools.length && (uniqueTools.includes('browser') || httpTools.length > 0)) {
168
- lines.push(`For wallet/trading tasks, inspect the wallet first with \`${walletTools[0]}\`. Use a bounded loop: verify, attempt one reversible step, then execute or state the blocker.`)
169
- }
170
-
171
164
  if (uniqueTools.includes('manage_secrets')) {
172
165
  lines.push('Store secrets (passwords, API keys, tokens) with `manage_secrets` — never echo raw values in assistant text.')
173
166
  }
@@ -211,25 +204,6 @@ export function shouldForceAttachmentFollowthrough(params: {
211
204
  return decision.preferredTools.some((toolName) => extensionIdMatches(params.enabledExtensions, toolName))
212
205
  }
213
206
 
214
- export function buildExternalWalletExecutionBlock(enabledExtensions: string[]): string {
215
- const hasExecutionContext = Boolean(
216
- getFirstToolForCapability(enabledExtensions, TOOL_CAPABILITY.walletInspect)
217
- || getFirstToolForCapability(enabledExtensions, 'network.http')
218
- || getEnabledDisplayTool(enabledExtensions, 'browser')
219
- || getEnabledDisplayTool(enabledExtensions, 'manage_capabilities'),
220
- )
221
- if (!hasExecutionContext) return ''
222
- const lines = [
223
- '## External Service Execution',
224
- 'Define a stop condition before exploring: either complete one concrete reversible action, or identify the exact blocker with evidence.',
225
- 'A prose sentence saying approval is needed is not enough. When the next step is a wallet signature or transaction, trigger the actual wallet approval request through the tool.',
226
- 'After one or two discovery bursts, stop exploring and summarize the blocker if execution still depends on a missing capability such as injected wallet signing, external credentials, or unavailable approvals.',
227
- 'Do not mutate already confirmed identifiers unless newer tool evidence proves the earlier value was wrong.',
228
- 'Never claim success on a trading or dApp task unless you either completed the reversible step with tool evidence or clearly stated the final missing step.',
229
- ]
230
- return lines.join('\n')
231
- }
232
-
233
207
  export async function buildForcedExternalServiceSummary(params: {
234
208
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
235
209
  llm: { invoke: (messages: any[]) => Promise<{ content: unknown }> }
@@ -471,10 +445,6 @@ export function buildAgenticExecutionPolicy(opts: {
471
445
  // Situational blocks — skipped in minimal mode
472
446
  if (!isMinimal) {
473
447
  if (opts.userMessage && classifiedIsBroadGoal(opts.classification ?? null, opts.userMessage)) parts.push(GOAL_DECOMPOSITION_BLOCK)
474
- if (opts.userMessage && classifiedHasWalletIntent(opts.classification ?? null, opts.userMessage)) {
475
- const externalExecutionBlock = buildExternalWalletExecutionBlock(opts.enabledExtensions)
476
- if (externalExecutionBlock) parts.push(externalExecutionBlock)
477
- }
478
448
  if (opts.userMessage && classifiedIsDeliverableTask(opts.classification ?? null, opts.userMessage) && opts.enabledExtensions.some((toolId) => toolId === 'files' || toolId === 'edit_file')) {
479
449
  parts.push(OPEN_ENDED_REVISION_BLOCK)
480
450
  }
@@ -310,7 +310,6 @@ export async function buildSituationalSection(
310
310
  return buildSituationalAwarenessBlock({
311
311
  agentId: session.agentId,
312
312
  sessionId: session.id,
313
- missionId: session.missionId || null,
314
313
  }) || null
315
314
  } catch { return null }
316
315
  }
@@ -5,12 +5,12 @@ import {
5
5
  timeAgo,
6
6
  type SituationalAwarenessData,
7
7
  } from '@/lib/server/chat-execution/situational-awareness'
8
- import type { BoardTask, Mission, Schedule, SupervisorIncident, SessionRunRecord } from '@/types'
8
+ import type { BoardTask, Schedule, SupervisorIncident, SessionRunRecord } from '@/types'
9
9
 
10
10
  const NOW = 1_710_500_000_000 // fixed timestamp for deterministic tests
11
11
 
12
12
  function emptyData(): SituationalAwarenessData {
13
- return { tasks: [], schedules: [], failedRuns: [], incidents: [], mission: null, now: NOW }
13
+ return { tasks: [], schedules: [], failedRuns: [], incidents: [], now: NOW }
14
14
  }
15
15
 
16
16
  function makeTask(overrides: Partial<BoardTask> & { id: string; title: string; status: string; agentId: string }): BoardTask {
@@ -192,58 +192,6 @@ describe('formatSituationalAwareness', () => {
192
192
  assert.equal(failureLines.length, 2)
193
193
  })
194
194
 
195
- it('builds mission section for active mission', () => {
196
- const data = emptyData()
197
- data.mission = {
198
- id: 'm1',
199
- source: 'user' as const,
200
- objective: 'Implement user auth flow',
201
- status: 'active',
202
- phase: 'dispatching',
203
- createdAt: NOW,
204
- updatedAt: NOW,
205
- } as unknown as Mission
206
-
207
- const result = formatSituationalAwareness(data)
208
-
209
- assert.ok(result.includes('### Current Mission'))
210
- assert.ok(result.includes('Implement user auth flow'))
211
- assert.ok(result.includes('Status: active'))
212
- assert.ok(result.includes('Phase: dispatching'))
213
- })
214
-
215
- it('omits mission section for completed missions', () => {
216
- const data = emptyData()
217
- data.mission = {
218
- id: 'm1',
219
- source: 'user' as const,
220
- objective: 'Done task',
221
- status: 'completed',
222
- phase: 'completed',
223
- createdAt: NOW,
224
- updatedAt: NOW,
225
- } as unknown as Mission
226
-
227
- const result = formatSituationalAwareness(data)
228
- assert.ok(!result.includes('### Current Mission'))
229
- })
230
-
231
- it('omits mission section for failed missions', () => {
232
- const data = emptyData()
233
- data.mission = {
234
- id: 'm1',
235
- source: 'user' as const,
236
- objective: 'Failed task',
237
- status: 'failed',
238
- phase: 'failed',
239
- createdAt: NOW,
240
- updatedAt: NOW,
241
- } as unknown as Mission
242
-
243
- const result = formatSituationalAwareness(data)
244
- assert.ok(!result.includes('### Current Mission'))
245
- })
246
-
247
195
  it('produces all sections within token budget', () => {
248
196
  const data = emptyData()
249
197
  for (let i = 0; i < 5; i++) {
@@ -265,15 +213,6 @@ describe('formatSituationalAwareness', () => {
265
213
  }))
266
214
  }
267
215
  data.failedRuns.push(makeRun({ id: 'r1', sessionId: 'sess-1', endedAt: NOW - 3_600_000, error: 'Test failure' }))
268
- data.mission = {
269
- id: 'm1',
270
- source: 'user' as const,
271
- objective: 'Test mission objective',
272
- status: 'active',
273
- phase: 'executing',
274
- createdAt: NOW,
275
- updatedAt: NOW,
276
- } as unknown as Mission
277
216
 
278
217
  const result = formatSituationalAwareness(data)
279
218
 
@@ -281,7 +220,6 @@ describe('formatSituationalAwareness', () => {
281
220
  assert.ok(result.includes('### Active Tasks'))
282
221
  assert.ok(result.includes('### Recent Failures'))
283
222
  assert.ok(result.includes('### My Schedule'))
284
- assert.ok(result.includes('### Current Mission'))
285
223
  assert.ok(result.length <= 3200, `Block is ${result.length} chars, should be <= 3200`)
286
224
  })
287
225
 
@@ -299,15 +237,6 @@ describe('formatSituationalAwareness', () => {
299
237
  for (let i = 0; i < 3; i++) {
300
238
  data.schedules.push(makeSchedule({ id: `s${i}`, name: 'S'.repeat(60), agentId: 'a1', nextRunAt: NOW + 3_600_000, frequency: 'daily' }))
301
239
  }
302
- data.mission = {
303
- id: 'm1',
304
- source: 'user' as const,
305
- objective: 'O'.repeat(100),
306
- status: 'active',
307
- phase: 'executing',
308
- createdAt: NOW,
309
- updatedAt: NOW,
310
- } as unknown as Mission
311
240
 
312
241
  const result = formatSituationalAwareness(data)
313
242
 
@@ -2,17 +2,15 @@ import { listAgentIncidents } from '@/lib/server/autonomy/supervisor-incident-re
2
2
  import { listAgents } from '@/lib/server/agents/agent-repository'
3
3
  import { loadChatrooms } from '@/lib/server/chatrooms/chatroom-repository'
4
4
  import { loadConnectors } from '@/lib/server/connectors/connector-repository'
5
- import { loadMission } from '@/lib/server/missions/mission-repository'
6
5
  import { loadSchedules } from '@/lib/server/schedules/schedule-repository'
7
6
  import { loadTasks } from '@/lib/server/tasks/task-repository'
8
7
  import { loadUsage } from '@/lib/server/usage/usage-repository'
9
8
  import { listPersistedRuns } from '@/lib/server/runtime/run-ledger'
10
- import type { BoardTask, Mission, Schedule, SupervisorIncident, SessionRunRecord } from '@/types'
9
+ import type { BoardTask, Schedule, SupervisorIncident, SessionRunRecord } from '@/types'
11
10
 
12
11
  export interface SituationalAwarenessInput {
13
12
  agentId: string
14
13
  sessionId: string
15
- missionId?: string | null
16
14
  }
17
15
 
18
16
  /** Pre-loaded data passed to the pure formatter. Exported for testing. */
@@ -21,7 +19,6 @@ export interface SituationalAwarenessData {
21
19
  schedules: Schedule[]
22
20
  failedRuns: SessionRunRecord[]
23
21
  incidents: SupervisorIncident[]
24
- mission: Mission | null
25
22
  now: number
26
23
  }
27
24
 
@@ -170,33 +167,11 @@ function buildFailuresSection(failures: FailureEntry[], now: number): string | n
170
167
  return lines.join('\n')
171
168
  }
172
169
 
173
- export function buildGoalAncestrySection(missionId: string | null | undefined): string | null {
174
- if (!missionId) return null
175
- const chain: string[] = []
176
- let currentId: string | null = missionId
177
- const visited = new Set<string>()
178
- while (currentId && chain.length < 10) {
179
- if (visited.has(currentId)) break
180
- visited.add(currentId)
181
- const mission = loadMission(currentId)
182
- if (!mission) break
183
- chain.unshift(mission.objective.slice(0, 80))
184
- currentId = mission.parentMissionId || null
185
- }
186
- if (chain.length <= 1) return null
187
- return `### Goal Ancestry\n${chain.map((obj, i) => `${' '.repeat(i)}${i === chain.length - 1 ? '→' : '↓'} ${obj}`).join('\n')}`
188
- }
189
-
190
- function buildMissionSection(mission: Mission | null): string | null {
191
- if (!mission) return null
192
- if (mission.status === 'completed' || mission.status === 'failed' || mission.status === 'cancelled') return null
193
- return `### Current Mission\nObjective: ${mission.objective.slice(0, 100)} | Status: ${mission.status} | Phase: ${mission.phase}`
194
- }
195
170
 
196
171
  // --- pure formatter (testable) ---
197
172
 
198
173
  export function formatSituationalAwareness(data: SituationalAwarenessData): string {
199
- const { tasks, schedules, failedRuns, incidents, mission, now } = data
174
+ const { tasks, schedules, failedRuns, incidents, now } = data
200
175
 
201
176
  const filteredTasks = tasks
202
177
  .filter((t) => ACTIVE_TASK_STATUSES.has(t.status))
@@ -245,13 +220,6 @@ export function formatSituationalAwareness(data: SituationalAwarenessData): stri
245
220
  charCount += schedulesSection.length
246
221
  }
247
222
 
248
- // Priority 4: Mission
249
- const missionSection = buildMissionSection(mission)
250
- if (missionSection && charCount + missionSection.length + header.length < MAX_CHARS) {
251
- sections.push(missionSection)
252
- charCount += missionSection.length
253
- }
254
-
255
223
  if (sections.length === 0) return ''
256
224
 
257
225
  return [header, ...sections].join('\n\n')
@@ -343,7 +311,7 @@ function computeTodaySpend(sinceTs: number): number {
343
311
  // --- main builder (loads data, calls formatter) ---
344
312
 
345
313
  export function buildSituationalAwarenessBlock(input: SituationalAwarenessInput): string {
346
- const { agentId, sessionId, missionId } = input
314
+ const { agentId, sessionId } = input
347
315
  const now = Date.now()
348
316
 
349
317
  const allTasks = loadTasks() as Record<string, BoardTask>
@@ -356,7 +324,5 @@ export function buildSituationalAwarenessBlock(input: SituationalAwarenessInput)
356
324
 
357
325
  const incidents = listAgentIncidents(agentId)
358
326
 
359
- const mission = missionId ? loadMission(missionId) : null
360
-
361
- return formatSituationalAwareness({ tasks, schedules, failedRuns, incidents, mission, now })
327
+ return formatSituationalAwareness({ tasks, schedules, failedRuns, incidents, now })
362
328
  }
@@ -6,10 +6,8 @@ import type { MessageToolEvent } from '@/types'
6
6
  import { buildSuccessfulMemoryMutationResponse } from '@/lib/server/chat-execution/memory-mutation-tools'
7
7
  import {
8
8
  buildToolAvailabilityLines,
9
- buildExternalWalletExecutionBlock,
10
9
  buildToolDisciplineLines,
11
10
  getExplicitRequiredToolNames,
12
- isWalletSimulationResult,
13
11
  looksLikeOpenEndedDeliverableTask,
14
12
  pruneIncompleteToolEvents,
15
13
  resolveExclusiveMemoryWriteTerminalAllowance,
@@ -35,8 +33,6 @@ import {
35
33
  parseClassificationResponse,
36
34
  isDeliverableTask,
37
35
  isBroadGoal,
38
- hasWalletIntent,
39
- hasTransactionalWalletIntent,
40
36
  hasHumanSignals,
41
37
  hasSignificantEvent,
42
38
  isResearchSynthesis,
@@ -122,14 +118,6 @@ describe('buildToolDisciplineLines', () => {
122
118
  assert.ok(lines.some((line) => line.includes('Store secrets (passwords, API keys, tokens) with `manage_secrets`')))
123
119
  })
124
120
 
125
- it('adds bounded execution guidance for wallet-connected external-service tasks', () => {
126
- const lines = buildToolDisciplineLines(['wallet', 'browser', 'http_request', 'manage_capabilities'])
127
-
128
- assert.ok(lines.some((line) => line.includes('inspect the wallet first with `wallet_tool`')))
129
- assert.ok(lines.some((line) => line.includes('Use a bounded loop: verify, attempt one reversible step, then execute or state the blocker.')))
130
- assert.ok(lines.some((line) => line.includes('stop venue-shopping') && line.includes('call_contract')))
131
- })
132
-
133
121
  it('includes concrete local coding tool guidance when coding tools are already available', () => {
134
122
  const lines = buildToolDisciplineLines(['files', 'shell', 'delegate'])
135
123
 
@@ -173,14 +161,6 @@ describe('buildToolDisciplineLines', () => {
173
161
  assert.deepEqual(required, [])
174
162
  })
175
163
 
176
- it('does not force wallet tools based on keyword matching', () => {
177
- const required = getExplicitRequiredToolNames(
178
- 'Use the available wallets and figure out how to trade on Hyperliquid.',
179
- ['wallet', 'browser', 'http_request'],
180
- )
181
- assert.deepEqual(required, [])
182
- })
183
-
184
164
  it('treats explicit curl or terminal execution requests as shell requirements when shell is enabled', () => {
185
165
  const required = getExplicitRequiredToolNames(
186
166
  'Yeah, do the curl. Curl request.',
@@ -291,41 +271,6 @@ describe('buildToolDisciplineLines', () => {
291
271
  })
292
272
  })
293
273
 
294
- describe('buildExternalWalletExecutionBlock', () => {
295
- it('omits extension-specific tool names when wallet/network capabilities are unavailable', () => {
296
- const block = buildExternalWalletExecutionBlock(['files'])
297
-
298
- assert.equal(block, '')
299
- })
300
-
301
- it('uses only enabled wallet-related tools in the external execution block', () => {
302
- const block = buildExternalWalletExecutionBlock(['wallet', 'http_request', 'manage_capabilities'])
303
-
304
- assert.ok(block.includes('## External Service Execution'))
305
- assert.ok(!block.includes('`browser`'))
306
- assert.ok(!block.includes('`wallet_tool`'))
307
- assert.ok(!block.includes('`manage_capabilities`'))
308
- assert.ok(block.includes('Define a stop condition before exploring'))
309
- })
310
- })
311
-
312
- describe('isWalletSimulationResult', () => {
313
- it('detects simulated wallet transaction outputs and ignores other tool outputs', () => {
314
- assert.equal(
315
- isWalletSimulationResult('wallet_tool', '{"status":"simulated","action":"simulate_transaction"}'),
316
- true,
317
- )
318
- assert.equal(
319
- isWalletSimulationResult('wallet_tool', '{"status":"broadcast","action":"send_transaction"}'),
320
- false,
321
- )
322
- assert.equal(
323
- isWalletSimulationResult('http_request', '{"status":"simulated"}'),
324
- false,
325
- )
326
- })
327
- })
328
-
329
274
  describe('shouldSkipToolSummaryForShortResponse', () => {
330
275
  it('skips forced tool-summary continuation for short responses after pure use_skill calls', () => {
331
276
  assert.equal(
@@ -765,7 +710,7 @@ describe('shouldForceExternalServiceSummary', () => {
765
710
  it('forces a summary when an external-service run ends with an unfinished exploration sentence', () => {
766
711
  assert.equal(
767
712
  shouldForceExternalServiceSummary({
768
- userMessage: 'Try to trade on Hyperliquid with the available wallet and stop at the blocker.',
713
+ userMessage: 'Try to interact with the Hyperliquid API and stop at the blocker.',
769
714
  finalResponse: 'This is promising - Hyperliquid runs on Arbitrum! Let me verify this and check if I can access their interface:',
770
715
  hasToolCalls: true,
771
716
  toolEventCount: 6,
@@ -777,8 +722,8 @@ describe('shouldForceExternalServiceSummary', () => {
777
722
  it('does not force a summary when the final response already states the blocker', () => {
778
723
  assert.equal(
779
724
  shouldForceExternalServiceSummary({
780
- userMessage: 'Try to trade on Hyperliquid with the available wallet and stop at the blocker.',
781
- finalResponse: 'Last reversible step: I verified the funded Arbitrum wallet and opened the site. Exact blocker: this runtime cannot complete a WalletConnect signature prompt.',
725
+ userMessage: 'Try to interact with the Hyperliquid API and stop at the blocker.',
726
+ finalResponse: 'Last reversible step: I verified the funded Arbitrum account and opened the site. Exact blocker: this runtime cannot complete a signature prompt.',
782
727
  hasToolCalls: true,
783
728
  toolEventCount: 6,
784
729
  }),
@@ -789,7 +734,6 @@ describe('shouldForceExternalServiceSummary', () => {
789
734
 
790
735
  describe('shouldForceExternalExecutionFollowthrough', () => {
791
736
  const researchToolEvents = [
792
- { name: 'wallet_tool', input: '{"action":"balance","chain":"ethereum"}', output: '{"status":"ok"}' },
793
737
  { name: 'http_request', input: '{"method":"GET","url":"https://example.com/quote"}', output: '{"status":200}' },
794
738
  { name: 'web', input: '{"action":"open","url":"https://example.com/swap"}', output: '{"status":"ok"}' },
795
739
  { name: 'browser', input: '{"action":"read_page"}', output: '{"title":"Swap"}' },
@@ -826,7 +770,6 @@ describe('shouldForceExternalExecutionFollowthrough', () => {
826
770
  finalResponse: 'Let me try another aggregator before proceeding.',
827
771
  hasToolCalls: true,
828
772
  toolEvents: [
829
- { name: 'wallet_tool', input: '{"action":"balance","chain":"ethereum"}', output: '{"status":"ok"}' },
830
773
  { name: 'http_request', input: '{"method":"GET","url":"https://api.0x.org/swap/v1/quote"}', output: '{"status":404}' },
831
774
  { name: 'http_request', input: '{"method":"GET","url":"https://apiv5.paraswap.io/prices"}', output: '{"status":400}' },
832
775
  { name: 'http_request', input: '{"method":"POST","url":"https://api.odos.xyz/sor/quote/v2"}', output: '{"status":200}' },
@@ -836,31 +779,13 @@ describe('shouldForceExternalExecutionFollowthrough', () => {
836
779
  )
837
780
  })
838
781
 
839
- it('does not force a followthrough after a wallet approval boundary is reached', () => {
840
- assert.equal(
841
- shouldForceExternalExecutionFollowthrough({
842
- userMessage: 'Do one tiny live swap on Arbitrum and stop at the first approval boundary.',
843
- finalResponse: 'Current status: approval required for the exact-input token approval.',
844
- hasToolCalls: true,
845
- toolEvents: [
846
- ...researchToolEvents,
847
- {
848
- name: 'wallet_tool',
849
- input: '{"action":"send_transaction","chain":"ethereum"}',
850
- output: '{"type":"extension_wallet_action_request","status":"pending"}',
851
- },
852
- ],
853
- }),
854
- false,
855
- )
856
- })
857
782
  })
858
783
 
859
784
  describe('shouldForceExternalExecutionKickoffFollowthrough', () => {
860
785
  it('forces a bounded continuation when an execution task stops at an intent-only kickoff', () => {
861
786
  assert.equal(
862
787
  shouldForceExternalExecutionKickoffFollowthrough({
863
- userMessage: 'Try buy one NFT on Arbitrum and show me what happened.',
788
+ userMessage: 'Try to interact with the NFT marketplace API and show me what happened.',
864
789
  finalResponse: 'Let me try to interact directly with the NFT contract and see if I can mint one:',
865
790
  hasToolCalls: false,
866
791
  toolEvents: [],
@@ -872,8 +797,8 @@ describe('shouldForceExternalExecutionKickoffFollowthrough', () => {
872
797
  it('does not force kickoff when the model already surfaced a real blocker or asked a blocking question', () => {
873
798
  assert.equal(
874
799
  shouldForceExternalExecutionKickoffFollowthrough({
875
- userMessage: 'Try buy one NFT on Arbitrum and show me what happened.',
876
- finalResponse: 'Exact blocker: this wallet cannot complete the required signature in the current runtime.',
800
+ userMessage: 'Try to interact with the NFT marketplace API and show me what happened.',
801
+ finalResponse: 'Exact blocker: this runtime cannot complete the required signature step.',
877
802
  hasToolCalls: false,
878
803
  toolEvents: [],
879
804
  }),
@@ -881,7 +806,7 @@ describe('shouldForceExternalExecutionKickoffFollowthrough', () => {
881
806
  )
882
807
  assert.equal(
883
808
  shouldForceExternalExecutionKickoffFollowthrough({
884
- userMessage: 'Try buy one NFT on Arbitrum and show me what happened.',
809
+ userMessage: 'Try to interact with the NFT marketplace API and show me what happened.',
885
810
  finalResponse: 'Which collection do you want me to target?',
886
811
  hasToolCalls: false,
887
812
  toolEvents: [],
@@ -1223,7 +1148,6 @@ describe('parseClassificationResponse', () => {
1223
1148
  const result = parseClassificationResponse(JSON.stringify({
1224
1149
  isDeliverableTask: true,
1225
1150
  isBroadGoal: false,
1226
- walletIntent: 'none',
1227
1151
  hasHumanSignals: false,
1228
1152
  hasSignificantEvent: false,
1229
1153
  isResearchSynthesis: true,
@@ -1233,14 +1157,13 @@ describe('parseClassificationResponse', () => {
1233
1157
  assert.ok(result)
1234
1158
  assert.equal(result.isDeliverableTask, true)
1235
1159
  assert.equal(result.isBroadGoal, false)
1236
- assert.equal(result.walletIntent, 'none')
1237
1160
  assert.equal(result.isResearchSynthesis, true)
1238
1161
  assert.deepEqual(result.explicitToolRequests, ['web'])
1239
1162
  assert.equal(result.confidence, 0.9)
1240
1163
  })
1241
1164
 
1242
1165
  it('extracts JSON from markdown code block', () => {
1243
- const text = '```json\n{"isDeliverableTask":false,"isBroadGoal":false,"walletIntent":"none","hasHumanSignals":false,"hasSignificantEvent":false,"isResearchSynthesis":false,"explicitToolRequests":[],"confidence":0.8}\n```'
1166
+ const text = '```json\n{"isDeliverableTask":false,"isBroadGoal":false,"hasHumanSignals":false,"hasSignificantEvent":false,"isResearchSynthesis":false,"explicitToolRequests":[],"confidence":0.8}\n```'
1244
1167
  const result = parseClassificationResponse(text)
1245
1168
  assert.ok(result)
1246
1169
  assert.equal(result.isDeliverableTask, false)
@@ -1257,19 +1180,6 @@ describe('parseClassificationResponse', () => {
1257
1180
  assert.equal(result, null)
1258
1181
  })
1259
1182
 
1260
- it('rejects invalid walletIntent values', () => {
1261
- const result = parseClassificationResponse(JSON.stringify({
1262
- isDeliverableTask: false,
1263
- isBroadGoal: false,
1264
- walletIntent: 'invalid',
1265
- hasHumanSignals: false,
1266
- hasSignificantEvent: false,
1267
- isResearchSynthesis: false,
1268
- explicitToolRequests: [],
1269
- confidence: 0.5,
1270
- }))
1271
- assert.equal(result, null)
1272
- })
1273
1183
  })
1274
1184
 
1275
1185
  describe('message classifier adapter functions', () => {
@@ -1277,7 +1187,6 @@ describe('message classifier adapter functions', () => {
1277
1187
  taskIntent: 'general',
1278
1188
  isDeliverableTask: true,
1279
1189
  isBroadGoal: true,
1280
- walletIntent: 'none',
1281
1190
  hasHumanSignals: false,
1282
1191
  hasSignificantEvent: false,
1283
1192
  isResearchSynthesis: false,
@@ -1285,23 +1194,10 @@ describe('message classifier adapter functions', () => {
1285
1194
  confidence: 0.95,
1286
1195
  }
1287
1196
 
1288
- const walletClassification: MessageClassification = {
1289
- taskIntent: 'general',
1290
- isDeliverableTask: false,
1291
- isBroadGoal: false,
1292
- walletIntent: 'transactional',
1293
- hasHumanSignals: false,
1294
- hasSignificantEvent: false,
1295
- isResearchSynthesis: false,
1296
- explicitToolRequests: [],
1297
- confidence: 0.9,
1298
- }
1299
-
1300
1197
  const humanSignalClassification: MessageClassification = {
1301
1198
  taskIntent: 'general',
1302
1199
  isDeliverableTask: false,
1303
1200
  isBroadGoal: false,
1304
- walletIntent: 'none',
1305
1201
  hasHumanSignals: true,
1306
1202
  hasSignificantEvent: true,
1307
1203
  isResearchSynthesis: false,
@@ -1326,17 +1222,6 @@ describe('message classifier adapter functions', () => {
1326
1222
  assert.equal(isBroadGoal({ ...deliverableClassification, isBroadGoal: false }, 'short'), false)
1327
1223
  })
1328
1224
 
1329
- it('hasWalletIntent uses classification', () => {
1330
- assert.equal(hasWalletIntent(walletClassification, 'swap ETH for USDC'), true)
1331
- assert.equal(hasWalletIntent({ ...walletClassification, walletIntent: 'none' }, 'swap ETH for USDC'), false)
1332
- })
1333
-
1334
- it('hasTransactionalWalletIntent distinguishes read_only from transactional', () => {
1335
- assert.equal(hasTransactionalWalletIntent(walletClassification, 'anything'), true)
1336
- assert.equal(hasTransactionalWalletIntent({ ...walletClassification, walletIntent: 'read_only' }, 'anything'), false)
1337
- assert.equal(hasTransactionalWalletIntent({ ...walletClassification, walletIntent: 'none' }, 'anything'), false)
1338
- })
1339
-
1340
1225
  it('hasHumanSignals uses classification', () => {
1341
1226
  assert.equal(hasHumanSignals(humanSignalClassification, 'anything'), true)
1342
1227
  assert.equal(hasHumanSignals({ ...humanSignalClassification, hasHumanSignals: false }, 'anything'), false)
@@ -78,7 +78,6 @@ import {
78
78
  buildToolAvailabilityLines,
79
79
  buildToolDisciplineLines,
80
80
  buildToolSection,
81
- buildExternalWalletExecutionBlock,
82
81
  buildForcedExternalServiceSummary,
83
82
  shouldForceAttachmentFollowthrough,
84
83
  joinPromptSegments,
@@ -101,7 +100,6 @@ import { finalizeStreamResult } from '@/lib/server/chat-execution/post-stream-fi
101
100
  import {
102
101
  classifyMessage,
103
102
  isDeliverableTask as classifiedIsDeliverableTask,
104
- hasTransactionalWalletIntent as classifiedHasTransactionalWalletIntent,
105
103
  isResearchSynthesis as classifiedIsResearchSynthesis,
106
104
  type MessageClassification,
107
105
  } from '@/lib/server/chat-execution/message-classifier'
@@ -125,7 +123,6 @@ export {
125
123
  buildToolAvailabilityLines,
126
124
  buildToolDisciplineLines,
127
125
  buildToolSection,
128
- buildExternalWalletExecutionBlock,
129
126
  shouldForceAttachmentFollowthrough,
130
127
  buildForcedExternalServiceSummary,
131
128
  }
@@ -142,7 +139,6 @@ export {
142
139
  } from '@/lib/server/chat-execution/stream-continuation'
143
140
 
144
141
  export {
145
- isWalletSimulationResult,
146
142
  resolveSuccessfulTerminalToolBoundary,
147
143
  shouldForceExternalServiceSummary,
148
144
  } from '@/lib/server/chat-execution/chat-streaming-utils'
@@ -889,7 +885,7 @@ async function streamAgentChatCore(opts: StreamAgentChatOpts): Promise<StreamAge
889
885
  const routingDecision = routeTaskIntent(message, sessionExtensions, null, classification)
890
886
  const explicitRequiredToolNames = getExplicitRequiredToolNames(message, sessionExtensions)
891
887
 
892
- const boundedExternalExecutionTask = classifiedHasTransactionalWalletIntent(classification, message)
888
+ const boundedExternalExecutionTask = false
893
889
  const likelyResearchSynthesisTask = classifiedIsResearchSynthesis(classification, routingDecision.intent)
894
890
  const shouldEnforceEarlyRequiredToolKickoff = explicitRequiredToolNames.length > 0
895
891
  && classifiedIsDeliverableTask(classification, message)