@swarmclawai/swarmclaw 1.2.8 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +39 -6
  2. package/package.json +2 -2
  3. package/src/app/agents/[id]/page.tsx +1 -18
  4. package/src/app/api/activity/route.ts +9 -23
  5. package/src/app/api/agents/route.ts +17 -1
  6. package/src/app/api/agents/thread-route.test.ts +0 -1
  7. package/src/app/api/approvals/route.test.ts +6 -22
  8. package/src/app/api/approvals/route.ts +13 -5
  9. package/src/app/api/connectors/route.ts +2 -2
  10. package/src/app/api/credentials/[id]/route.ts +2 -0
  11. package/src/app/api/credentials/route.ts +4 -1
  12. package/src/app/api/goals/[id]/route.ts +28 -0
  13. package/src/app/api/goals/route.ts +33 -0
  14. package/src/app/api/portability/export/route.ts +8 -0
  15. package/src/app/api/portability/import/route.test.ts +80 -0
  16. package/src/app/api/portability/import/route.ts +28 -0
  17. package/src/app/api/protocols/templates/[id]/route.ts +2 -1
  18. package/src/app/api/protocols/templates/route.ts +2 -1
  19. package/src/app/api/settings/route.ts +13 -2
  20. package/src/app/api/wallets/[id]/route.ts +15 -157
  21. package/src/app/api/wallets/generate/route.ts +22 -0
  22. package/src/app/api/wallets/route.test.ts +147 -0
  23. package/src/app/api/wallets/route.ts +13 -95
  24. package/src/app/autonomy/page.tsx +2 -57
  25. package/src/app/home/page.tsx +3 -0
  26. package/src/app/protocols/page.tsx +2 -21
  27. package/src/app/settings/page.tsx +0 -9
  28. package/src/app/wallets/page.tsx +105 -5
  29. package/src/cli/index.js +32 -33
  30. package/src/cli/spec.js +26 -27
  31. package/src/components/agents/agent-sheet.tsx +2 -40
  32. package/src/components/agents/inspector-panel.tsx +0 -83
  33. package/src/components/chat/chat-card.tsx +0 -31
  34. package/src/components/chat/message-bubble.tsx +1 -108
  35. package/src/components/connectors/connector-sheet.tsx +25 -1
  36. package/src/components/layout/sidebar-rail.tsx +6 -10
  37. package/src/components/projects/project-detail.tsx +3 -35
  38. package/src/components/projects/tabs/overview-tab.tsx +3 -59
  39. package/src/components/projects/tabs/work-tab.tsx +7 -77
  40. package/src/components/protocols/structured-session-launcher.tsx +1 -22
  41. package/src/components/shared/connector-platform-icon.tsx +1 -0
  42. package/src/components/tasks/task-card.tsx +4 -34
  43. package/src/components/tasks/task-sheet.tsx +6 -36
  44. package/src/components/wallets/wallet-list.tsx +150 -0
  45. package/src/lib/app/navigation.test.ts +0 -13
  46. package/src/lib/app/navigation.ts +2 -7
  47. package/src/lib/app/view-constants.ts +14 -19
  48. package/src/lib/server/activity/activity-log.ts +16 -1
  49. package/src/lib/server/agents/agent-service.ts +24 -11
  50. package/src/lib/server/agents/agent-thread-session.ts +0 -1
  51. package/src/lib/server/agents/delegation-advisory.test.ts +0 -1
  52. package/src/lib/server/agents/delegation-jobs.test.ts +0 -69
  53. package/src/lib/server/agents/delegation-jobs.ts +0 -25
  54. package/src/lib/server/agents/main-agent-loop.ts +1 -49
  55. package/src/lib/server/agents/subagent-runtime.ts +0 -1
  56. package/src/lib/server/approval-match.ts +14 -85
  57. package/src/lib/server/approvals/approval-hooks.ts +81 -0
  58. package/src/lib/server/approvals.test.ts +6 -6
  59. package/src/lib/server/approvals.ts +11 -6
  60. package/src/lib/server/autonomy/supervisor-reflection.test.ts +0 -1
  61. package/src/lib/server/builtin-extensions.ts +0 -2
  62. package/src/lib/server/capability-router.test.ts +0 -2
  63. package/src/lib/server/chat-execution/chat-execution-tool-events.test.ts +14 -14
  64. package/src/lib/server/chat-execution/chat-execution-types.ts +0 -2
  65. package/src/lib/server/chat-execution/chat-execution-utils.ts +0 -2
  66. package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -30
  67. package/src/lib/server/chat-execution/chat-turn-finalization.ts +1 -36
  68. package/src/lib/server/chat-execution/chat-turn-preparation.ts +2 -22
  69. package/src/lib/server/chat-execution/iteration-event-handler.ts +0 -24
  70. package/src/lib/server/chat-execution/message-classifier.test.ts +0 -45
  71. package/src/lib/server/chat-execution/message-classifier.ts +1 -16
  72. package/src/lib/server/chat-execution/prompt-builder.test.ts +0 -1
  73. package/src/lib/server/chat-execution/prompt-builder.ts +0 -30
  74. package/src/lib/server/chat-execution/prompt-sections.ts +0 -1
  75. package/src/lib/server/chat-execution/situational-awareness.test.ts +2 -73
  76. package/src/lib/server/chat-execution/situational-awareness.ts +4 -38
  77. package/src/lib/server/chat-execution/stream-agent-chat.test.ts +8 -123
  78. package/src/lib/server/chat-execution/stream-agent-chat.ts +1 -5
  79. package/src/lib/server/chat-execution/stream-continuation.test.ts +4 -52
  80. package/src/lib/server/chat-execution/stream-continuation.ts +6 -48
  81. package/src/lib/server/chatrooms/session-mailbox.ts +0 -10
  82. package/src/lib/server/chats/chat-session-service.ts +3 -5
  83. package/src/lib/server/connectors/connector-inbound.ts +0 -1
  84. package/src/lib/server/connectors/connector-lifecycle.ts +19 -3
  85. package/src/lib/server/connectors/connector-service.ts +39 -9
  86. package/src/lib/server/connectors/swarmdock-bidding.ts +74 -0
  87. package/src/lib/server/connectors/swarmdock-payloads.test.ts +85 -0
  88. package/src/lib/server/connectors/swarmdock-secret.test.ts +128 -0
  89. package/src/lib/server/connectors/swarmdock-secret.ts +152 -0
  90. package/src/lib/server/connectors/swarmdock-tasks.ts +127 -0
  91. package/src/lib/server/connectors/swarmdock.ts +285 -0
  92. package/src/lib/server/execution-brief.test.ts +2 -25
  93. package/src/lib/server/execution-brief.ts +30 -35
  94. package/src/lib/server/execution-engine/task-attempt.ts +0 -1
  95. package/src/lib/server/goals/goal-repository.ts +19 -0
  96. package/src/lib/server/goals/goal-service.ts +143 -0
  97. package/src/lib/server/persistence/storage-context.ts +0 -5
  98. package/src/lib/server/portability/export.ts +109 -0
  99. package/src/lib/server/portability/import.ts +159 -0
  100. package/src/lib/server/protocols/protocol-normalization.ts +0 -4
  101. package/src/lib/server/protocols/protocol-queries.ts +0 -6
  102. package/src/lib/server/protocols/protocol-run-lifecycle.ts +4 -32
  103. package/src/lib/server/protocols/protocol-service.ts +0 -1
  104. package/src/lib/server/protocols/protocol-step-helpers.ts +0 -4
  105. package/src/lib/server/protocols/protocol-step-processors.ts +0 -6
  106. package/src/lib/server/protocols/protocol-swarm.ts +0 -2
  107. package/src/lib/server/protocols/protocol-types.ts +0 -2
  108. package/src/lib/server/provider-health.ts +0 -9
  109. package/src/lib/server/runtime/daemon-state/core.ts +0 -9
  110. package/src/lib/server/runtime/daemon-state.test.ts +0 -35
  111. package/src/lib/server/runtime/heartbeat-service.ts +3 -23
  112. package/src/lib/server/runtime/queue/core.ts +11 -33
  113. package/src/lib/server/runtime/runtime-storage-write-paths.test.ts +6 -6
  114. package/src/lib/server/runtime/scheduler.ts +0 -13
  115. package/src/lib/server/runtime/session-run-manager/drain.ts +0 -24
  116. package/src/lib/server/runtime/session-run-manager/enqueue.ts +0 -1
  117. package/src/lib/server/runtime/session-run-manager/queries.ts +0 -1
  118. package/src/lib/server/runtime/session-run-manager/recovery.ts +0 -1
  119. package/src/lib/server/runtime/session-run-manager.test.ts +0 -28
  120. package/src/lib/server/session-tools/crud.ts +0 -14
  121. package/src/lib/server/session-tools/delegate.ts +0 -4
  122. package/src/lib/server/session-tools/index.ts +0 -4
  123. package/src/lib/server/session-tools/team-context.ts +0 -3
  124. package/src/lib/server/storage-normalization.ts +13 -0
  125. package/src/lib/server/storage.ts +75 -45
  126. package/src/lib/server/tasks/task-checkout.ts +59 -0
  127. package/src/lib/server/tasks/task-lifecycle.ts +2 -0
  128. package/src/lib/server/tasks/task-route-service.ts +4 -26
  129. package/src/lib/server/tasks/task-service.ts +0 -7
  130. package/src/lib/server/tool-aliases.ts +0 -1
  131. package/src/lib/server/tool-capability-policy-advanced.test.ts +4 -4
  132. package/src/lib/server/tool-capability-policy.ts +0 -2
  133. package/src/lib/server/tool-planning.ts +0 -12
  134. package/src/lib/server/universal-tool-access.ts +0 -1
  135. package/src/lib/server/usage/cost-rollup.ts +124 -0
  136. package/src/lib/server/usage/usage-repository.ts +6 -0
  137. package/src/lib/server/wallets/wallet-crypto.ts +33 -0
  138. package/src/lib/server/wallets/wallet-repository.ts +24 -0
  139. package/src/lib/server/wallets/wallet-service.ts +119 -0
  140. package/src/lib/server/working-state/extraction.ts +8 -42
  141. package/src/lib/server/working-state/normalization.ts +10 -103
  142. package/src/lib/server/working-state/service.ts +12 -21
  143. package/src/lib/strip-internal-metadata.test.ts +1 -1
  144. package/src/lib/strip-internal-metadata.ts +1 -1
  145. package/src/lib/tool-definitions.ts +0 -1
  146. package/src/lib/validation/schemas.ts +36 -32
  147. package/src/lib/validation/server-schemas.ts +35 -0
  148. package/src/stores/slices/data-slice.ts +5 -1
  149. package/src/stores/slices/ui-slice.ts +0 -4
  150. package/src/types/agent.ts +10 -84
  151. package/src/types/app-settings.ts +6 -2
  152. package/src/types/approval.ts +3 -2
  153. package/src/types/connector.ts +1 -0
  154. package/src/types/goal.ts +30 -0
  155. package/src/types/index.ts +2 -1
  156. package/src/types/message.ts +0 -1
  157. package/src/types/misc.ts +2 -4
  158. package/src/types/protocol.ts +0 -2
  159. package/src/types/run.ts +0 -3
  160. package/src/types/session.ts +1 -51
  161. package/src/types/swarmdock.ts +29 -0
  162. package/src/types/task.ts +9 -3
  163. package/src/types/working-state.ts +2 -9
  164. package/src/views/settings/section-runtime-loop.tsx +0 -14
  165. package/src/app/api/canvas/[sessionId]/route.ts +0 -35
  166. package/src/app/api/missions/[id]/actions/route.ts +0 -31
  167. package/src/app/api/missions/[id]/events/route.ts +0 -14
  168. package/src/app/api/missions/[id]/route.ts +0 -10
  169. package/src/app/api/missions/route.test.ts +0 -244
  170. package/src/app/api/missions/route.ts +0 -57
  171. package/src/app/api/wallets/[id]/approve/route.ts +0 -79
  172. package/src/app/api/wallets/[id]/balance-history/route.ts +0 -18
  173. package/src/app/api/wallets/[id]/send/route.ts +0 -113
  174. package/src/app/api/wallets/[id]/transactions/route.ts +0 -18
  175. package/src/app/missions/[id]/page.tsx +0 -3
  176. package/src/app/missions/page.tsx +0 -685
  177. package/src/components/canvas/canvas-panel.tsx +0 -267
  178. package/src/components/wallets/wallet-approval-dialog.tsx +0 -107
  179. package/src/components/wallets/wallet-panel.tsx +0 -1010
  180. package/src/components/wallets/wallet-section.tsx +0 -260
  181. package/src/features/missions/queries.ts +0 -23
  182. package/src/lib/canvas-content.test.ts +0 -360
  183. package/src/lib/canvas-content.ts +0 -198
  184. package/src/lib/server/canvas-content.test.ts +0 -32
  185. package/src/lib/server/canvas-content.ts +0 -6
  186. package/src/lib/server/ethereum.ts +0 -591
  187. package/src/lib/server/evm-swap.ts +0 -476
  188. package/src/lib/server/missions/mission-intent.test.ts +0 -63
  189. package/src/lib/server/missions/mission-intent.ts +0 -569
  190. package/src/lib/server/missions/mission-repository.ts +0 -74
  191. package/src/lib/server/missions/mission-service/actions.ts +0 -6
  192. package/src/lib/server/missions/mission-service/bindings.ts +0 -9
  193. package/src/lib/server/missions/mission-service/context.ts +0 -4
  194. package/src/lib/server/missions/mission-service/core.ts +0 -2271
  195. package/src/lib/server/missions/mission-service/queries.ts +0 -12
  196. package/src/lib/server/missions/mission-service/recovery.ts +0 -5
  197. package/src/lib/server/missions/mission-service/ticks.ts +0 -9
  198. package/src/lib/server/missions/mission-service.test.ts +0 -888
  199. package/src/lib/server/missions/mission-service.ts +0 -6
  200. package/src/lib/server/session-tools/canvas.ts +0 -105
  201. package/src/lib/server/session-tools/wallet-tool.test.ts +0 -150
  202. package/src/lib/server/session-tools/wallet.ts +0 -1287
  203. package/src/lib/server/solana.ts +0 -327
  204. package/src/lib/server/wallet/wallet-execution.test.ts +0 -198
  205. package/src/lib/server/wallet/wallet-portfolio.test.ts +0 -98
  206. package/src/lib/server/wallet/wallet-portfolio.ts +0 -772
  207. package/src/lib/server/wallet/wallet-service.test.ts +0 -81
  208. package/src/lib/server/wallet/wallet-service.ts +0 -225
  209. package/src/lib/wallet/wallet-transactions.test.ts +0 -75
  210. package/src/lib/wallet/wallet-transactions.ts +0 -43
  211. package/src/lib/wallet/wallet.test.ts +0 -333
  212. package/src/lib/wallet/wallet.ts +0 -183
  213. package/src/types/mission.ts +0 -185
  214. package/src/views/settings/section-wallets.tsx +0 -35
@@ -321,7 +321,6 @@ export function requestedToolNamesFromMessage(message: string): string[] {
321
321
  'memory_get',
322
322
  'memory_store',
323
323
  'memory_update',
324
- 'wallet_tool',
325
324
  'http_request',
326
325
  'send_file',
327
326
  'schedule_wake',
@@ -339,7 +338,6 @@ export function requestedToolNamesFromMessage(message: string): string[] {
339
338
  'execute',
340
339
  'files',
341
340
  'edit_file',
342
- 'canvas',
343
341
  'mailbox',
344
342
  'email',
345
343
  ]
@@ -72,22 +72,14 @@ export function getExplicitRequiredToolNames(userMessage: string, enabledExtensi
72
72
  return required
73
73
  }
74
74
 
75
- export function shouldForceExternalServiceSummary(params: {
75
+ export function shouldForceExternalServiceSummary(_params: {
76
76
  userMessage: string
77
77
  finalResponse: string
78
78
  hasToolCalls: boolean
79
79
  toolEventCount: number
80
80
  classification?: MessageClassification | null
81
81
  }): boolean {
82
- const walletDetected = params.classification?.walletIntent !== undefined
83
- && params.classification.walletIntent !== 'none'
84
- if (!walletDetected) return false
85
- if (!params.hasToolCalls || params.toolEventCount === 0) return false
86
- const trimmed = params.finalResponse.trim()
87
- if (!trimmed) return true
88
- if (/\b(blocker|blocked|cannot|can't|requires|need|missing|last reversible step|next step)\b/i.test(trimmed)) return false
89
- if (trimmed.length >= 240 && !/(let me|i'll|i will|checking|verify|promising|look into|explore|access their interface)/i.test(trimmed)) return false
90
- return /:$/.test(trimmed) || /(let me|i'll|i will|checking|verify|promising|look into|explore|access their interface)/i.test(trimmed) || trimmed.length < 240
82
+ return false
91
83
  }
92
84
 
93
85
  export type TerminalToolBoundary =
@@ -146,26 +138,6 @@ export function resolveSuccessfulTerminalToolBoundary(params: {
146
138
  return null
147
139
  }
148
140
 
149
- export function getWalletApprovalBoundaryAction(output: string): string | null {
150
- if (!output.includes('extension_wallet_')) return null
151
- if (/"type":"extension_wallet_transfer_request"/.test(output)) return 'send'
152
- const actionMatch = output.match(/"action":"([^"]+)"/)
153
- const action = actionMatch?.[1] || ''
154
- if (!action) return null
155
- const readOnlyActions = new Set([
156
- 'balance',
157
- 'address',
158
- 'transactions',
159
- 'encode_contract_call',
160
- 'simulate_transaction',
161
- ])
162
- return readOnlyActions.has(action) ? null : action
163
- }
164
-
165
- export function isWalletSimulationResult(toolName: string, output: string): boolean {
166
- return toolName === 'wallet_tool' && /"status":"simulated"/.test(output)
167
- }
168
-
169
141
  export function updateStreamedToolEvents(
170
142
  events: MessageToolEvent[],
171
143
  event: { type: 'call' | 'result'; name: string; input?: string; output?: string; toolCallId?: string },
@@ -26,9 +26,6 @@ import { estimateCost } from '@/lib/server/cost'
26
26
  import { refreshSessionIdentityState } from '@/lib/server/identity-continuity'
27
27
  import { log } from '@/lib/server/logger'
28
28
  import { syncSessionArchiveMemory } from '@/lib/server/memory/session-archive-memory'
29
- import {
30
- applyMissionOutcomeForTurn,
31
- } from '@/lib/server/missions/mission-service'
32
29
  import { runCapabilityHook, transformCapabilityText } from '@/lib/server/native-capabilities'
33
30
  import { isHeartbeatSource } from '@/lib/server/runtime/heartbeat-source'
34
31
  import { perf } from '@/lib/server/runtime/perf'
@@ -181,7 +178,6 @@ export async function finalizeChatTurn(params: {
181
178
  sessionForRun,
182
179
  appSettings,
183
180
  lifecycleRunId,
184
- mission,
185
181
  extensionsForRun,
186
182
  effectiveMessage,
187
183
  providerType,
@@ -589,45 +585,15 @@ export async function finalizeChatTurn(params: {
589
585
  }
590
586
 
591
587
  refreshSessionIdentityState(current, currentAgent)
592
- let resolvedMissionId = mission?.id || current.missionId || null
593
- let updatedMission = mission || null
594
- if (resolvedMissionId) {
595
- updatedMission = await applyMissionOutcomeForTurn({
596
- session: current,
597
- missionId: resolvedMissionId,
598
- source,
599
- runId: lifecycleRunId,
600
- message,
601
- assistantText: hiddenControlOnly ? '' : textForPersistence,
602
- error: errorMessage || null,
603
- toolEvents: persistedToolEvents,
604
- })
605
- if (updatedMission?.id) {
606
- resolvedMissionId = updatedMission.id
607
- current.missionId = updatedMission.id
608
- }
609
- }
610
- const missionStateChanged = Boolean(
611
- updatedMission
612
- && (
613
- updatedMission.id !== mission?.id
614
- || updatedMission.updatedAt !== mission?.updatedAt
615
- || updatedMission.status !== mission?.status
616
- || updatedMission.phase !== mission?.phase
617
- || updatedMission.currentStep !== mission?.currentStep
618
- || updatedMission.waitState?.reason !== mission?.waitState?.reason
619
- )
620
- )
621
588
  const shouldSyncWorkingState = (
622
589
  (!isHeartbeatRun && (assistantPersisted || persistedToolEvents.length > 0 || Boolean(errorMessage)))
623
- || (isHeartbeatRun && (persistedToolEvents.length > 0 || Boolean(errorMessage) || missionStateChanged))
590
+ || (isHeartbeatRun && (persistedToolEvents.length > 0 || Boolean(errorMessage)))
624
591
  )
625
592
  if (shouldSyncWorkingState) {
626
593
  try {
627
594
  await synchronizeWorkingStateForTurn({
628
595
  sessionId,
629
596
  agentId: current.agentId || null,
630
- mission: updatedMission,
631
597
  message,
632
598
  assistantText: hiddenControlOnly ? '' : textForPersistence,
633
599
  error: errorMessage || null,
@@ -673,7 +639,6 @@ export async function finalizeChatTurn(params: {
673
639
  return {
674
640
  runId,
675
641
  sessionId,
676
- missionId: mission?.id || null,
677
642
  text: hiddenControlOnly ? '' : textForPersistence,
678
643
  persisted: assistantPersisted,
679
644
  toolEvents: persistedToolEvents,
@@ -45,9 +45,6 @@ import {
45
45
  } from '@/lib/capability-selection'
46
46
  import { normalizeProviderEndpoint, isLocalOpenClawEndpoint } from '@/lib/openclaw/openclaw-endpoint'
47
47
  import { NON_LANGGRAPH_PROVIDER_IDS } from '@/lib/provider-sets'
48
- import {
49
- resolveMissionForTurn,
50
- } from '@/lib/server/missions/mission-service'
51
48
  import {
52
49
  bridgeHumanReplyFromChat,
53
50
  } from '@/lib/server/chatrooms/session-mailbox'
@@ -465,7 +462,7 @@ export interface PreparedExecutableChatTurn {
465
462
  appSettings: ReturnType<typeof loadSettings>
466
463
  lifecycleRunId: string
467
464
  agentForSession: ReturnType<typeof getAgent>
468
- mission: Awaited<ReturnType<typeof resolveMissionForTurn>>
465
+ mission: null
469
466
  executionBrief: ExecutionBrief
470
467
  executionBriefContextBlock?: string
471
468
  extensionsForRun: string[]
@@ -503,7 +500,6 @@ export async function prepareChatTurn(input: ExecuteChatTurnInput): Promise<Prep
503
500
  imagePath,
504
501
  imageUrl,
505
502
  attachedFiles,
506
- missionId: explicitMissionId,
507
503
  internal = false,
508
504
  runId,
509
505
  source = 'chat',
@@ -580,17 +576,7 @@ export async function prepareChatTurn(input: ExecuteChatTurnInput): Promise<Prep
580
576
  try { syncSessionArchiveMemory(session, { agent: agentForSession }) } catch { /* best-effort */ }
581
577
  }
582
578
 
583
- const mission = await resolveMissionForTurn({
584
- session,
585
- message,
586
- source,
587
- internal,
588
- runId: lifecycleRunId,
589
- explicitMissionId: explicitMissionId || null,
590
- })
591
- if (mission?.id) {
592
- session.missionId = mission.id
593
- }
579
+ const mission = null
594
580
  const extensionsForRun = toolPolicy.enabledExtensions
595
581
  if (runMessageStartIndex === 0) {
596
582
  await runCapabilityHook(
@@ -606,12 +592,6 @@ export async function prepareChatTurn(input: ExecuteChatTurnInput): Promise<Prep
606
592
  let sessionForRun = JSON.stringify(runtimeCapabilityIds) === JSON.stringify(extensionsForRun)
607
593
  ? session
608
594
  : { ...session, tools: sessionForRunSelection.tools, extensions: sessionForRunSelection.extensions }
609
- if (mission?.id) {
610
- sessionForRun = {
611
- ...sessionForRun,
612
- missionId: mission.id,
613
- }
614
- }
615
595
  if (agentForSession) {
616
596
  const preferredRoute = resolvePrimaryAgentRoute(agentForSession, undefined, {
617
597
  preferredGatewayTags: session.routePreferredGatewayTags || [],
@@ -12,8 +12,6 @@ import { canonicalizeExtensionId } from '@/lib/server/tool-aliases'
12
12
  import { logExecution } from '@/lib/server/execution-log'
13
13
  import { perf } from '@/lib/server/runtime/perf'
14
14
  import {
15
- getWalletApprovalBoundaryAction,
16
- isWalletSimulationResult,
17
15
  resolveSuccessfulTerminalToolBoundary,
18
16
  updateStreamedToolEvents,
19
17
  } from '@/lib/server/chat-execution/chat-streaming-utils'
@@ -21,7 +19,6 @@ import {
21
19
  resolveToolAction,
22
20
  } from '@/lib/server/chat-execution/memory-mutation-tools'
23
21
  import {
24
- hasStateChangingWalletEvidence,
25
22
  countExternalExecutionResearchSteps,
26
23
  countDistinctExternalResearchHosts,
27
24
  } from '@/lib/server/chat-execution/stream-continuation'
@@ -328,18 +325,9 @@ export async function processIterationEvents(opts: ProcessIterationEventsOpts):
328
325
  break
329
326
  }
330
327
  }
331
- if (boundedExternalExecutionTask && getWalletApprovalBoundaryAction(outputStr || '')) {
332
- reachedExecutionBoundary = true
333
- write(`data: ${JSON.stringify({
334
- t: 'status',
335
- text: JSON.stringify({ executionBoundary: 'wallet_approval' }),
336
- })}\n\n`)
337
- break
338
- }
339
328
  if (
340
329
  boundedExternalExecutionTask
341
330
  && ['http_request', 'web', 'web_search', 'web_fetch', 'browser'].includes(toolName)
342
- && !hasStateChangingWalletEvidence(state.streamedToolEvents)
343
331
  && countExternalExecutionResearchSteps(state.streamedToolEvents) >= 5
344
332
  && countDistinctExternalResearchHosts(state.streamedToolEvents) >= 3
345
333
  ) {
@@ -350,18 +338,6 @@ export async function processIterationEvents(opts: ProcessIterationEventsOpts):
350
338
  })}\n\n`)
351
339
  break
352
340
  }
353
- if (
354
- boundedExternalExecutionTask
355
- && !hasStateChangingWalletEvidence(state.streamedToolEvents)
356
- && isWalletSimulationResult(toolName, outputStr || '')
357
- ) {
358
- executionFollowthroughReason = 'post_simulation'
359
- write(`data: ${JSON.stringify({
360
- t: 'status',
361
- text: JSON.stringify({ executionBoundary: 'post_simulation' }),
362
- })}\n\n`)
363
- break
364
- }
365
341
  }
366
342
  }
367
343
 
@@ -26,7 +26,6 @@ describe('parseClassificationResponse', () => {
26
26
  taskIntent: 'general',
27
27
  isDeliverableTask: true,
28
28
  isBroadGoal: false,
29
- walletIntent: 'none',
30
29
  hasHumanSignals: false,
31
30
  hasSignificantEvent: false,
32
31
  isResearchSynthesis: false,
@@ -40,7 +39,6 @@ describe('parseClassificationResponse', () => {
40
39
  assert.ok(result)
41
40
  assert.equal(result!.isDeliverableTask, true)
42
41
  assert.equal(result!.isBroadGoal, false)
43
- assert.equal(result!.walletIntent, 'none')
44
42
  assert.equal(result!.taskIntent, 'general')
45
43
  assert.equal(result!.workType, 'general')
46
44
  assert.equal(result!.confidence, 0.9)
@@ -62,7 +60,6 @@ describe('parseClassificationResponse', () => {
62
60
  taskIntent: 'general',
63
61
  isDeliverableTask: true,
64
62
  isBroadGoal: false,
65
- walletIntent: 'none',
66
63
  hasHumanSignals: false,
67
64
  hasSignificantEvent: false,
68
65
  isResearchSynthesis: false,
@@ -128,44 +125,6 @@ describe('isBroadGoal', () => {
128
125
  })
129
126
  })
130
127
 
131
- // ---------------------------------------------------------------------------
132
- // hasWalletIntent
133
- // ---------------------------------------------------------------------------
134
-
135
- describe('hasWalletIntent', () => {
136
- it('walletIntent none returns false', () => {
137
- assert.equal(mod.hasWalletIntent(makeClassification({ walletIntent: 'none' }), ''), false)
138
- })
139
-
140
- it('walletIntent read_only returns true', () => {
141
- assert.equal(mod.hasWalletIntent(makeClassification({ walletIntent: 'read_only' }), ''), true)
142
- })
143
-
144
- it('walletIntent transactional returns true', () => {
145
- assert.equal(mod.hasWalletIntent(makeClassification({ walletIntent: 'transactional' }), ''), true)
146
- })
147
-
148
- it('falls back to regex when classification is null', () => {
149
- assert.equal(mod.hasWalletIntent(null, 'check my wallet balance'), false)
150
- })
151
- })
152
-
153
- // ---------------------------------------------------------------------------
154
- // hasTransactionalWalletIntent
155
- // ---------------------------------------------------------------------------
156
-
157
- describe('hasTransactionalWalletIntent', () => {
158
- it('only transactional returns true', () => {
159
- assert.equal(mod.hasTransactionalWalletIntent(makeClassification({ walletIntent: 'transactional' }), ''), true)
160
- assert.equal(mod.hasTransactionalWalletIntent(makeClassification({ walletIntent: 'read_only' }), ''), false)
161
- assert.equal(mod.hasTransactionalWalletIntent(makeClassification({ walletIntent: 'none' }), ''), false)
162
- })
163
-
164
- it('falls back to regex when classification is null', () => {
165
- assert.equal(mod.hasTransactionalWalletIntent(null, 'swap 1 ETH for USDC'), false)
166
- })
167
- })
168
-
169
128
  // ---------------------------------------------------------------------------
170
129
  // hasHumanSignals
171
130
  // ---------------------------------------------------------------------------
@@ -227,7 +186,6 @@ describe('classifyMessage', () => {
227
186
  taskIntent: 'coding',
228
187
  isDeliverableTask: true,
229
188
  isBroadGoal: false,
230
- walletIntent: 'none',
231
189
  hasHumanSignals: false,
232
190
  hasSignificantEvent: false,
233
191
  isResearchSynthesis: false,
@@ -244,7 +202,6 @@ describe('classifyMessage', () => {
244
202
  assert.ok(result)
245
203
  assert.equal(result!.isDeliverableTask, true)
246
204
  assert.equal(result!.taskIntent, 'coding')
247
- assert.equal(result!.walletIntent, 'none')
248
205
  assert.equal(result!.workType, 'coding')
249
206
  assert.deepEqual(result!.explicitToolRequests, ['shell'])
250
207
  })
@@ -284,7 +241,6 @@ describe('classifyMessage', () => {
284
241
  taskIntent: 'general',
285
242
  isDeliverableTask: false,
286
243
  isBroadGoal: false,
287
- walletIntent: 'none',
288
244
  hasHumanSignals: false,
289
245
  hasSignificantEvent: false,
290
246
  isResearchSynthesis: false,
@@ -326,7 +282,6 @@ function makeClassification(overrides: Partial<import('@/lib/server/chat-executi
326
282
  taskIntent: 'general',
327
283
  isDeliverableTask: false,
328
284
  isBroadGoal: false,
329
- walletIntent: 'none',
330
285
  hasHumanSignals: false,
331
286
  hasSignificantEvent: false,
332
287
  isResearchSynthesis: false,
@@ -32,7 +32,6 @@ export const MessageClassificationSchema = z.object({
32
32
  isDeliverableTask: z.boolean(),
33
33
  isBroadGoal: z.boolean(),
34
34
  isLightweightDirectChat: z.boolean().optional().default(false),
35
- walletIntent: z.enum(['none', 'read_only', 'transactional']),
36
35
  hasHumanSignals: z.boolean(),
37
36
  hasSignificantEvent: z.boolean(),
38
37
  isResearchSynthesis: z.boolean(),
@@ -49,7 +48,6 @@ export interface MessageClassification {
49
48
  isDeliverableTask: boolean
50
49
  isBroadGoal: boolean
51
50
  isLightweightDirectChat?: boolean
52
- walletIntent: 'none' | 'read_only' | 'transactional'
53
51
  hasHumanSignals: boolean
54
52
  hasSignificantEvent: boolean
55
53
  isResearchSynthesis: boolean
@@ -105,7 +103,6 @@ function buildClassificationPrompt(message: string, recentHistory: string): stri
105
103
  '- isDeliverableTask (bool): The user wants a concrete artifact produced — a document, report, plan, proposal, landing page, dashboard, HTML file, markdown file, brief, copy, screenshots, or similar deliverable. NOT simple Q&A, code fixes, or single-command tasks.',
106
104
  '- isBroadGoal (bool): The message describes a broad, multi-step goal (50+ chars, no code blocks, no file paths, no numbered lists). Short questions ending with "?" are NOT broad goals.',
107
105
  '- isLightweightDirectChat (bool): This is a low-signal direct chat turn that should get a natural lightweight reply, such as a greeting, acknowledgment, check-in, or simple social/direct question that does NOT require research, file work, planning, delegation, or tool execution.',
108
- '- walletIntent: "none" if no crypto/wallet/trading context. "read_only" if mentioning wallet/crypto but only for checking balances, viewing transactions, or research. "transactional" if the user wants to swap, trade, buy, sell, mint, claim, deposit, withdraw, bridge, or execute a transaction.',
109
106
  '- hasHumanSignals (bool): The message contains personal signals — preferences ("I prefer", "call me"), relationships ("my wife", "my partner", "my kid"), life events ("birthday", "wedding", "promotion", "moving", "graduation", "hospital"), or personal disclosures.',
110
107
  '- hasSignificantEvent (bool): The message mentions a notable life/work event or milestone (birthday, anniversary, wedding, graduation, promotion, new job, relocation, illness, funeral, travel, house, deadline, launch).',
111
108
  '- isResearchSynthesis (bool): The task requires gathering information from multiple sources and synthesizing it — research reports, competitive analysis, market overviews, literature reviews, multi-source comparisons. NOT simple factual lookups.',
@@ -120,12 +117,11 @@ function buildClassificationPrompt(message: string, recentHistory: string): stri
120
117
  '- Be conservative. When unsure, default to false/none/empty.',
121
118
  '- Mark isLightweightDirectChat true only when a short natural reply is enough and escalating into planning, delegation, or tool execution would be unnecessary.',
122
119
  '- A message can be both a deliverable task AND a broad goal.',
123
- '- "walletIntent" should be "transactional" only if the user wants to execute a state-changing action, not just discuss crypto.',
124
120
  '- For "explicitToolRequests", only include tools the user explicitly mentions by name or clear synonym. Do not infer tool needs from the task type.',
125
121
  '- Prefer the most execution-relevant taskIntent. Example: "research this and send me a voice note" is "research", not "outreach".',
126
122
  '',
127
123
  'Output shape:',
128
- '{"taskIntent":"coding|research|browsing|outreach|scheduling|general","isDeliverableTask":bool,"isBroadGoal":bool,"isLightweightDirectChat":bool,"walletIntent":"none|read_only|transactional","hasHumanSignals":bool,"hasSignificantEvent":bool,"isResearchSynthesis":bool,"workType":"coding|research|writing|review|operations|general","wantsScreenshots":bool,"wantsOutboundDelivery":bool,"wantsVoiceDelivery":bool,"explicitToolRequests":[],"confidence":0.0-1.0}',
124
+ '{"taskIntent":"coding|research|browsing|outreach|scheduling|general","isDeliverableTask":bool,"isBroadGoal":bool,"isLightweightDirectChat":bool,"hasHumanSignals":bool,"hasSignificantEvent":bool,"isResearchSynthesis":bool,"workType":"coding|research|writing|review|operations|general","wantsScreenshots":bool,"wantsOutboundDelivery":bool,"wantsVoiceDelivery":bool,"explicitToolRequests":[],"confidence":0.0-1.0}',
129
125
  '',
130
126
  recentHistory ? `Recent context:\n${recentHistory}\n` : '',
131
127
  `User message: ${JSON.stringify(message)}`,
@@ -276,7 +272,6 @@ export function toMessageSemanticsSummary(classification: MessageClassification
276
272
  return {
277
273
  taskIntent: classification.taskIntent,
278
274
  workType: classification.workType || 'general',
279
- walletIntent: classification.walletIntent,
280
275
  isDeliverableTask: classification.isDeliverableTask,
281
276
  isBroadGoal: classification.isBroadGoal,
282
277
  isResearchSynthesis: classification.isResearchSynthesis,
@@ -305,16 +300,6 @@ export function isBroadGoal(classification: MessageClassification | null, messag
305
300
  return classification?.isBroadGoal === true
306
301
  }
307
302
 
308
- export function hasWalletIntent(classification: MessageClassification | null, message?: string): boolean {
309
- void message
310
- return classification?.walletIntent !== undefined && classification.walletIntent !== 'none'
311
- }
312
-
313
- export function hasTransactionalWalletIntent(classification: MessageClassification | null, message?: string): boolean {
314
- void message
315
- return classification?.walletIntent === 'transactional'
316
- }
317
-
318
303
  export function hasHumanSignals(classification: MessageClassification | null, transcript?: string): boolean {
319
304
  void transcript
320
305
  return classification?.hasHumanSignals === true
@@ -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