@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.
- package/README.md +39 -6
- package/package.json +2 -2
- package/src/app/agents/[id]/page.tsx +1 -18
- package/src/app/api/activity/route.ts +9 -23
- package/src/app/api/agents/route.ts +17 -1
- package/src/app/api/agents/thread-route.test.ts +0 -1
- package/src/app/api/approvals/route.test.ts +6 -22
- package/src/app/api/approvals/route.ts +13 -5
- package/src/app/api/connectors/route.ts +2 -2
- package/src/app/api/credentials/[id]/route.ts +2 -0
- package/src/app/api/credentials/route.ts +4 -1
- package/src/app/api/goals/[id]/route.ts +28 -0
- package/src/app/api/goals/route.ts +33 -0
- package/src/app/api/portability/export/route.ts +8 -0
- package/src/app/api/portability/import/route.test.ts +80 -0
- package/src/app/api/portability/import/route.ts +28 -0
- package/src/app/api/protocols/templates/[id]/route.ts +2 -1
- package/src/app/api/protocols/templates/route.ts +2 -1
- package/src/app/api/settings/route.ts +13 -2
- package/src/app/api/wallets/[id]/route.ts +15 -157
- package/src/app/api/wallets/generate/route.ts +22 -0
- package/src/app/api/wallets/route.test.ts +147 -0
- package/src/app/api/wallets/route.ts +13 -95
- package/src/app/autonomy/page.tsx +2 -57
- package/src/app/home/page.tsx +3 -0
- package/src/app/protocols/page.tsx +2 -21
- package/src/app/settings/page.tsx +0 -9
- package/src/app/wallets/page.tsx +105 -5
- package/src/cli/index.js +32 -33
- package/src/cli/spec.js +26 -27
- package/src/components/agents/agent-sheet.tsx +2 -40
- package/src/components/agents/inspector-panel.tsx +0 -83
- package/src/components/chat/chat-card.tsx +0 -31
- package/src/components/chat/message-bubble.tsx +1 -108
- package/src/components/connectors/connector-sheet.tsx +25 -1
- package/src/components/layout/sidebar-rail.tsx +6 -10
- package/src/components/projects/project-detail.tsx +3 -35
- package/src/components/projects/tabs/overview-tab.tsx +3 -59
- package/src/components/projects/tabs/work-tab.tsx +7 -77
- package/src/components/protocols/structured-session-launcher.tsx +1 -22
- package/src/components/shared/connector-platform-icon.tsx +1 -0
- package/src/components/tasks/task-card.tsx +4 -34
- package/src/components/tasks/task-sheet.tsx +6 -36
- package/src/components/wallets/wallet-list.tsx +150 -0
- package/src/lib/app/navigation.test.ts +0 -13
- package/src/lib/app/navigation.ts +2 -7
- package/src/lib/app/view-constants.ts +14 -19
- package/src/lib/server/activity/activity-log.ts +16 -1
- package/src/lib/server/agents/agent-service.ts +24 -11
- package/src/lib/server/agents/agent-thread-session.ts +0 -1
- package/src/lib/server/agents/delegation-advisory.test.ts +0 -1
- package/src/lib/server/agents/delegation-jobs.test.ts +0 -69
- package/src/lib/server/agents/delegation-jobs.ts +0 -25
- package/src/lib/server/agents/main-agent-loop.ts +1 -49
- package/src/lib/server/agents/subagent-runtime.ts +0 -1
- package/src/lib/server/approval-match.ts +14 -85
- package/src/lib/server/approvals/approval-hooks.ts +81 -0
- package/src/lib/server/approvals.test.ts +6 -6
- package/src/lib/server/approvals.ts +11 -6
- package/src/lib/server/autonomy/supervisor-reflection.test.ts +0 -1
- package/src/lib/server/builtin-extensions.ts +0 -2
- package/src/lib/server/capability-router.test.ts +0 -2
- package/src/lib/server/chat-execution/chat-execution-tool-events.test.ts +14 -14
- package/src/lib/server/chat-execution/chat-execution-types.ts +0 -2
- package/src/lib/server/chat-execution/chat-execution-utils.ts +0 -2
- package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -30
- package/src/lib/server/chat-execution/chat-turn-finalization.ts +1 -36
- package/src/lib/server/chat-execution/chat-turn-preparation.ts +2 -22
- package/src/lib/server/chat-execution/iteration-event-handler.ts +0 -24
- package/src/lib/server/chat-execution/message-classifier.test.ts +0 -45
- package/src/lib/server/chat-execution/message-classifier.ts +1 -16
- package/src/lib/server/chat-execution/prompt-builder.test.ts +0 -1
- package/src/lib/server/chat-execution/prompt-builder.ts +0 -30
- package/src/lib/server/chat-execution/prompt-sections.ts +0 -1
- package/src/lib/server/chat-execution/situational-awareness.test.ts +2 -73
- package/src/lib/server/chat-execution/situational-awareness.ts +4 -38
- package/src/lib/server/chat-execution/stream-agent-chat.test.ts +8 -123
- package/src/lib/server/chat-execution/stream-agent-chat.ts +1 -5
- package/src/lib/server/chat-execution/stream-continuation.test.ts +4 -52
- package/src/lib/server/chat-execution/stream-continuation.ts +6 -48
- package/src/lib/server/chatrooms/session-mailbox.ts +0 -10
- package/src/lib/server/chats/chat-session-service.ts +3 -5
- package/src/lib/server/connectors/connector-inbound.ts +0 -1
- package/src/lib/server/connectors/connector-lifecycle.ts +19 -3
- package/src/lib/server/connectors/connector-service.ts +39 -9
- package/src/lib/server/connectors/swarmdock-bidding.ts +74 -0
- package/src/lib/server/connectors/swarmdock-payloads.test.ts +85 -0
- package/src/lib/server/connectors/swarmdock-secret.test.ts +128 -0
- package/src/lib/server/connectors/swarmdock-secret.ts +152 -0
- package/src/lib/server/connectors/swarmdock-tasks.ts +127 -0
- package/src/lib/server/connectors/swarmdock.ts +285 -0
- package/src/lib/server/execution-brief.test.ts +2 -25
- package/src/lib/server/execution-brief.ts +30 -35
- package/src/lib/server/execution-engine/task-attempt.ts +0 -1
- package/src/lib/server/goals/goal-repository.ts +19 -0
- package/src/lib/server/goals/goal-service.ts +143 -0
- package/src/lib/server/persistence/storage-context.ts +0 -5
- package/src/lib/server/portability/export.ts +109 -0
- package/src/lib/server/portability/import.ts +159 -0
- package/src/lib/server/protocols/protocol-normalization.ts +0 -4
- package/src/lib/server/protocols/protocol-queries.ts +0 -6
- package/src/lib/server/protocols/protocol-run-lifecycle.ts +4 -32
- package/src/lib/server/protocols/protocol-service.ts +0 -1
- package/src/lib/server/protocols/protocol-step-helpers.ts +0 -4
- package/src/lib/server/protocols/protocol-step-processors.ts +0 -6
- package/src/lib/server/protocols/protocol-swarm.ts +0 -2
- package/src/lib/server/protocols/protocol-types.ts +0 -2
- package/src/lib/server/provider-health.ts +0 -9
- package/src/lib/server/runtime/daemon-state/core.ts +0 -9
- package/src/lib/server/runtime/daemon-state.test.ts +0 -35
- package/src/lib/server/runtime/heartbeat-service.ts +3 -23
- package/src/lib/server/runtime/queue/core.ts +11 -33
- package/src/lib/server/runtime/runtime-storage-write-paths.test.ts +6 -6
- package/src/lib/server/runtime/scheduler.ts +0 -13
- package/src/lib/server/runtime/session-run-manager/drain.ts +0 -24
- package/src/lib/server/runtime/session-run-manager/enqueue.ts +0 -1
- package/src/lib/server/runtime/session-run-manager/queries.ts +0 -1
- package/src/lib/server/runtime/session-run-manager/recovery.ts +0 -1
- package/src/lib/server/runtime/session-run-manager.test.ts +0 -28
- package/src/lib/server/session-tools/crud.ts +0 -14
- package/src/lib/server/session-tools/delegate.ts +0 -4
- package/src/lib/server/session-tools/index.ts +0 -4
- package/src/lib/server/session-tools/team-context.ts +0 -3
- package/src/lib/server/storage-normalization.ts +13 -0
- package/src/lib/server/storage.ts +75 -45
- package/src/lib/server/tasks/task-checkout.ts +59 -0
- package/src/lib/server/tasks/task-lifecycle.ts +2 -0
- package/src/lib/server/tasks/task-route-service.ts +4 -26
- package/src/lib/server/tasks/task-service.ts +0 -7
- package/src/lib/server/tool-aliases.ts +0 -1
- package/src/lib/server/tool-capability-policy-advanced.test.ts +4 -4
- package/src/lib/server/tool-capability-policy.ts +0 -2
- package/src/lib/server/tool-planning.ts +0 -12
- package/src/lib/server/universal-tool-access.ts +0 -1
- package/src/lib/server/usage/cost-rollup.ts +124 -0
- package/src/lib/server/usage/usage-repository.ts +6 -0
- package/src/lib/server/wallets/wallet-crypto.ts +33 -0
- package/src/lib/server/wallets/wallet-repository.ts +24 -0
- package/src/lib/server/wallets/wallet-service.ts +119 -0
- package/src/lib/server/working-state/extraction.ts +8 -42
- package/src/lib/server/working-state/normalization.ts +10 -103
- package/src/lib/server/working-state/service.ts +12 -21
- package/src/lib/strip-internal-metadata.test.ts +1 -1
- package/src/lib/strip-internal-metadata.ts +1 -1
- package/src/lib/tool-definitions.ts +0 -1
- package/src/lib/validation/schemas.ts +36 -32
- package/src/lib/validation/server-schemas.ts +35 -0
- package/src/stores/slices/data-slice.ts +5 -1
- package/src/stores/slices/ui-slice.ts +0 -4
- package/src/types/agent.ts +10 -84
- package/src/types/app-settings.ts +6 -2
- package/src/types/approval.ts +3 -2
- package/src/types/connector.ts +1 -0
- package/src/types/goal.ts +30 -0
- package/src/types/index.ts +2 -1
- package/src/types/message.ts +0 -1
- package/src/types/misc.ts +2 -4
- package/src/types/protocol.ts +0 -2
- package/src/types/run.ts +0 -3
- package/src/types/session.ts +1 -51
- package/src/types/swarmdock.ts +29 -0
- package/src/types/task.ts +9 -3
- package/src/types/working-state.ts +2 -9
- package/src/views/settings/section-runtime-loop.tsx +0 -14
- package/src/app/api/canvas/[sessionId]/route.ts +0 -35
- package/src/app/api/missions/[id]/actions/route.ts +0 -31
- package/src/app/api/missions/[id]/events/route.ts +0 -14
- package/src/app/api/missions/[id]/route.ts +0 -10
- package/src/app/api/missions/route.test.ts +0 -244
- package/src/app/api/missions/route.ts +0 -57
- package/src/app/api/wallets/[id]/approve/route.ts +0 -79
- package/src/app/api/wallets/[id]/balance-history/route.ts +0 -18
- package/src/app/api/wallets/[id]/send/route.ts +0 -113
- package/src/app/api/wallets/[id]/transactions/route.ts +0 -18
- package/src/app/missions/[id]/page.tsx +0 -3
- package/src/app/missions/page.tsx +0 -685
- package/src/components/canvas/canvas-panel.tsx +0 -267
- package/src/components/wallets/wallet-approval-dialog.tsx +0 -107
- package/src/components/wallets/wallet-panel.tsx +0 -1010
- package/src/components/wallets/wallet-section.tsx +0 -260
- package/src/features/missions/queries.ts +0 -23
- package/src/lib/canvas-content.test.ts +0 -360
- package/src/lib/canvas-content.ts +0 -198
- package/src/lib/server/canvas-content.test.ts +0 -32
- package/src/lib/server/canvas-content.ts +0 -6
- package/src/lib/server/ethereum.ts +0 -591
- package/src/lib/server/evm-swap.ts +0 -476
- package/src/lib/server/missions/mission-intent.test.ts +0 -63
- package/src/lib/server/missions/mission-intent.ts +0 -569
- package/src/lib/server/missions/mission-repository.ts +0 -74
- package/src/lib/server/missions/mission-service/actions.ts +0 -6
- package/src/lib/server/missions/mission-service/bindings.ts +0 -9
- package/src/lib/server/missions/mission-service/context.ts +0 -4
- package/src/lib/server/missions/mission-service/core.ts +0 -2271
- package/src/lib/server/missions/mission-service/queries.ts +0 -12
- package/src/lib/server/missions/mission-service/recovery.ts +0 -5
- package/src/lib/server/missions/mission-service/ticks.ts +0 -9
- package/src/lib/server/missions/mission-service.test.ts +0 -888
- package/src/lib/server/missions/mission-service.ts +0 -6
- package/src/lib/server/session-tools/canvas.ts +0 -105
- package/src/lib/server/session-tools/wallet-tool.test.ts +0 -150
- package/src/lib/server/session-tools/wallet.ts +0 -1287
- package/src/lib/server/solana.ts +0 -327
- package/src/lib/server/wallet/wallet-execution.test.ts +0 -198
- package/src/lib/server/wallet/wallet-portfolio.test.ts +0 -98
- package/src/lib/server/wallet/wallet-portfolio.ts +0 -772
- package/src/lib/server/wallet/wallet-service.test.ts +0 -81
- package/src/lib/server/wallet/wallet-service.ts +0 -225
- package/src/lib/wallet/wallet-transactions.test.ts +0 -75
- package/src/lib/wallet/wallet-transactions.ts +0 -43
- package/src/lib/wallet/wallet.test.ts +0 -333
- package/src/lib/wallet/wallet.ts +0 -183
- package/src/types/mission.ts +0 -185
- 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(
|
|
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
|
-
|
|
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)
|
|
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:
|
|
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 =
|
|
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,"
|
|
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
|
|
@@ -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
|
}
|
|
@@ -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,
|
|
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: [],
|
|
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
|
|