@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.
- package/README.md +30 -6
- package/package.json +2 -2
- package/src/app/agents/[id]/page.tsx +1 -18
- 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/connectors/route.ts +2 -2
- 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/settings/route.ts +0 -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/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 +21 -33
- package/src/cli/spec.js +19 -30
- 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/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 +0 -85
- package/src/lib/server/approvals.test.ts +6 -6
- package/src/lib/server/approvals.ts +0 -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 +119 -0
- package/src/lib/server/connectors/swarmdock.ts +255 -0
- package/src/lib/server/execution-brief.test.ts +2 -25
- package/src/lib/server/execution-brief.ts +12 -35
- package/src/lib/server/execution-engine/task-attempt.ts +0 -1
- 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 +8 -0
- package/src/lib/server/storage.ts +18 -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/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 +33 -2
- package/src/stores/slices/data-slice.ts +5 -1
- package/src/stores/slices/ui-slice.ts +0 -4
- package/src/types/agent.ts +0 -84
- package/src/types/app-settings.ts +0 -2
- package/src/types/approval.ts +0 -2
- package/src/types/connector.ts +1 -0
- package/src/types/index.ts +1 -1
- package/src/types/message.ts +0 -1
- package/src/types/misc.ts +0 -2
- 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 +7 -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
|
@@ -16,7 +16,6 @@ import { errorMessage } from '@/lib/shared-utils'
|
|
|
16
16
|
import { getAgents } from '@/lib/server/agents/agent-repository'
|
|
17
17
|
import { upsertTask } from '@/lib/server/tasks/task-repository'
|
|
18
18
|
import { notify } from '@/lib/server/ws-hub'
|
|
19
|
-
import { ensureMissionForTask } from '@/lib/server/missions/mission-service'
|
|
20
19
|
import { enqueueTask } from '@/lib/server/runtime/queue'
|
|
21
20
|
import { cleanText, isDiscussionStepKind, now, uniqueIds } from '@/lib/server/protocols/protocol-types'
|
|
22
21
|
import type { ProtocolRunDeps } from '@/lib/server/protocols/protocol-types'
|
|
@@ -227,7 +226,6 @@ export async function processEmitTasksPhase(run: ProtocolRun, phase: ProtocolPha
|
|
|
227
226
|
...extracted.map((item) => item.agentId || ''),
|
|
228
227
|
], 64))
|
|
229
228
|
const createdTaskIds: string[] = []
|
|
230
|
-
const linkedMissionId = typeof run.missionId === 'string' ? run.missionId : null
|
|
231
229
|
const taskProjectId = run.config?.taskProjectId || null
|
|
232
230
|
for (const item of extracted) {
|
|
233
231
|
const assignedAgentId = item.agentId && agents[item.agentId] ? item.agentId : fallbackAssignee
|
|
@@ -238,7 +236,6 @@ export async function processEmitTasksPhase(run: ProtocolRun, phase: ProtocolPha
|
|
|
238
236
|
description: cleanText(item.description, 1_000) || cleanText(artifact.content, 800),
|
|
239
237
|
status: 'backlog',
|
|
240
238
|
agentId: assignedAgentId,
|
|
241
|
-
missionId: linkedMissionId,
|
|
242
239
|
projectId: taskProjectId || undefined,
|
|
243
240
|
createdByAgentId: chooseFacilitator(run),
|
|
244
241
|
createdInSessionId: run.sessionId || null,
|
|
@@ -248,7 +245,6 @@ export async function processEmitTasksPhase(run: ProtocolRun, phase: ProtocolPha
|
|
|
248
245
|
tags: ['structured-session'],
|
|
249
246
|
}
|
|
250
247
|
upsertTask(task.id, task)
|
|
251
|
-
ensureMissionForTask(task, { source: 'manual' })
|
|
252
248
|
createdTaskIds.push(task.id)
|
|
253
249
|
appendProtocolEvent(run.id, {
|
|
254
250
|
type: 'task_emitted',
|
|
@@ -607,7 +603,6 @@ export function processDispatchTaskPhase(run: ProtocolRun, phase: ProtocolPhaseD
|
|
|
607
603
|
status: 'queued',
|
|
608
604
|
agentId,
|
|
609
605
|
protocolRunId: run.id,
|
|
610
|
-
missionId: run.missionId || null,
|
|
611
606
|
queuedAt: now(deps),
|
|
612
607
|
createdAt: now(deps),
|
|
613
608
|
updatedAt: now(deps),
|
|
@@ -656,7 +651,6 @@ export function processDispatchDelegationPhase(run: ProtocolRun, phase: Protocol
|
|
|
656
651
|
status: 'queued',
|
|
657
652
|
agentId: config.agentId,
|
|
658
653
|
protocolRunId: run.id,
|
|
659
|
-
missionId: run.missionId || null,
|
|
660
654
|
sourceType: 'delegation',
|
|
661
655
|
queuedAt: now(deps),
|
|
662
656
|
createdAt: now(deps),
|
|
@@ -90,7 +90,6 @@ export async function processSwarmStep(run: ProtocolRun, step: ProtocolStepDefin
|
|
|
90
90
|
status: 'queued',
|
|
91
91
|
agentId,
|
|
92
92
|
protocolRunId: started.id,
|
|
93
|
-
missionId: started.missionId || null,
|
|
94
93
|
sourceType: 'delegation',
|
|
95
94
|
queuedAt: now(deps),
|
|
96
95
|
createdAt: now(deps),
|
|
@@ -189,7 +188,6 @@ export function claimSwarmWorkItem(
|
|
|
189
188
|
status: 'queued',
|
|
190
189
|
agentId,
|
|
191
190
|
protocolRunId: runId,
|
|
192
|
-
missionId: run.missionId || null,
|
|
193
191
|
sourceType: 'delegation',
|
|
194
192
|
queuedAt: now(deps),
|
|
195
193
|
createdAt: now(deps),
|
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
BoardTask,
|
|
7
7
|
Chatroom,
|
|
8
8
|
MessageToolEvent,
|
|
9
|
-
Mission,
|
|
10
9
|
ProtocolBranchCase,
|
|
11
10
|
ProtocolPhaseDefinition,
|
|
12
11
|
ProtocolRepeatConfig,
|
|
@@ -31,7 +30,6 @@ export interface ProtocolRunDetail {
|
|
|
31
30
|
template: ProtocolTemplate | null
|
|
32
31
|
transcript: Chatroom | null
|
|
33
32
|
parentChatroom: Chatroom | null
|
|
34
|
-
linkedMission: Mission | null
|
|
35
33
|
linkedTask: BoardTask | null
|
|
36
34
|
events: ProtocolRunEvent[]
|
|
37
35
|
}
|
|
@@ -92,15 +92,6 @@ export function markProviderSuccess(providerId: string, credentialId?: string |
|
|
|
92
92
|
const { upsertStoredItem } = require('@/lib/server/storage')
|
|
93
93
|
upsertStoredItem('provider_health', key, states.get(key)!)
|
|
94
94
|
} catch {}
|
|
95
|
-
queueMicrotask(() => {
|
|
96
|
-
import('@/lib/server/missions/mission-service')
|
|
97
|
-
.then(({ requestMissionTicksForProviderRecovery }) => {
|
|
98
|
-
requestMissionTicksForProviderRecovery(providerId)
|
|
99
|
-
})
|
|
100
|
-
.catch(() => {
|
|
101
|
-
// Mission recovery is best-effort only.
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
95
|
}
|
|
105
96
|
|
|
106
97
|
export function isProviderCoolingDown(providerId: string, credentialId?: string | null): boolean {
|
|
@@ -66,7 +66,6 @@ import { loadEstopState } from '@/lib/server/runtime/estop'
|
|
|
66
66
|
import { classifyRuntimeFailure, recordSupervisorIncident } from '@/lib/server/autonomy/supervisor-reflection'
|
|
67
67
|
import { getMemoryDb } from '@/lib/server/memory/memory-db'
|
|
68
68
|
import { clearLogsByAge } from '@/lib/server/execution-log'
|
|
69
|
-
import { runMissionControllerStartupRecovery } from '@/lib/server/missions/mission-service'
|
|
70
69
|
|
|
71
70
|
const TAG = 'daemon-state'
|
|
72
71
|
|
|
@@ -293,14 +292,6 @@ export function startDaemon(options?: { source?: string; manualStart?: boolean }
|
|
|
293
292
|
if (lost > 0) log.info(TAG, `[daemon] Marked ${lost} in-flight swarm(s) as lost after restart`)
|
|
294
293
|
} catch { /* best-effort */ }
|
|
295
294
|
resumeQueue()
|
|
296
|
-
const missionRecovery = runMissionControllerStartupRecovery()
|
|
297
|
-
if (missionRecovery.recovered > 0 || missionRecovery.rerunVerification > 0) {
|
|
298
|
-
log.info(
|
|
299
|
-
TAG,
|
|
300
|
-
`[daemon] Recovered ${missionRecovery.recovered} mission(s) on startup`
|
|
301
|
-
+ ` (${missionRecovery.rerunVerification} queued for verification replay)`,
|
|
302
|
-
)
|
|
303
|
-
}
|
|
304
295
|
startScheduler()
|
|
305
296
|
startQueueProcessor()
|
|
306
297
|
startBrowserSweep()
|
|
@@ -245,41 +245,6 @@ describe('daemon start/stop lifecycle', () => {
|
|
|
245
245
|
}
|
|
246
246
|
})
|
|
247
247
|
|
|
248
|
-
it('startDaemon runs mission startup recovery once the daemon owns startup', async () => {
|
|
249
|
-
const storage = await import('@/lib/server/storage')
|
|
250
|
-
storage.saveMissions({
|
|
251
|
-
missionA: {
|
|
252
|
-
id: 'missionA',
|
|
253
|
-
source: 'chat',
|
|
254
|
-
sourceRef: { kind: 'chat', sessionId: 'sessionA' },
|
|
255
|
-
objective: 'Recover after daemon start',
|
|
256
|
-
status: 'active',
|
|
257
|
-
phase: 'executing',
|
|
258
|
-
sessionId: 'sessionA',
|
|
259
|
-
taskIds: [],
|
|
260
|
-
controllerState: {
|
|
261
|
-
activeRunId: 'run-stale',
|
|
262
|
-
currentTaskId: 'task-stale',
|
|
263
|
-
},
|
|
264
|
-
createdAt: 1,
|
|
265
|
-
updatedAt: 1,
|
|
266
|
-
},
|
|
267
|
-
})
|
|
268
|
-
|
|
269
|
-
await mod.stopDaemon({ source: 'test-prestart' })
|
|
270
|
-
mod.startDaemon({ source: 'test-mission-recovery', manualStart: true })
|
|
271
|
-
try {
|
|
272
|
-
const missions = await import('@/lib/server/missions/mission-service')
|
|
273
|
-
const mission = missions.loadMissionById('missionA')
|
|
274
|
-
assert.equal(mission?.status, 'active')
|
|
275
|
-
assert.equal(mission?.phase, 'planning')
|
|
276
|
-
const events = missions.listMissionEventsForMission('missionA')
|
|
277
|
-
assert.ok(events.some((event) => event.type === 'interrupted'))
|
|
278
|
-
} finally {
|
|
279
|
-
await mod.stopDaemon({ source: 'test-mission-recovery' })
|
|
280
|
-
}
|
|
281
|
-
})
|
|
282
|
-
|
|
283
248
|
it('stopDaemon sets running to false', async () => {
|
|
284
249
|
mod.startDaemon({ source: 'test', manualStart: true })
|
|
285
250
|
await mod.stopDaemon({ source: 'test' })
|
|
@@ -10,17 +10,15 @@ import { logActivity } from '@/lib/server/activity/activity-log'
|
|
|
10
10
|
import { loadApprovals } from '@/lib/server/approvals/approval-repository'
|
|
11
11
|
import { loadAgents, patchAgent } from '@/lib/server/agents/agent-repository'
|
|
12
12
|
import { loadChatrooms } from '@/lib/server/chatrooms/chatroom-repository'
|
|
13
|
-
import { loadMission } from '@/lib/server/missions/mission-repository'
|
|
14
13
|
import { loadSessions, patchSession } from '@/lib/server/sessions/session-repository'
|
|
15
14
|
import { loadSettings } from '@/lib/server/settings/settings-repository'
|
|
16
|
-
import {
|
|
15
|
+
import { buildPlatformStatusSummary } from '@/lib/server/chat-execution/situational-awareness'
|
|
17
16
|
import { drainDeferredWakes, hasDeferredWakes } from '@/lib/server/runtime/wake-dispatcher'
|
|
18
17
|
import { buildWakeTriggerContext } from '@/lib/server/runtime/heartbeat-wake'
|
|
19
18
|
import { enqueueSessionRun, getSessionRunState } from '@/lib/server/runtime/session-run-manager'
|
|
20
19
|
import { log } from '@/lib/server/logger'
|
|
21
20
|
import { WORKSPACE_DIR } from '@/lib/server/data-dir'
|
|
22
21
|
import { drainSystemEvents, drainOrchestratorEvents } from '@/lib/server/runtime/system-events'
|
|
23
|
-
import { buildMissionContextBlock } from '@/lib/server/missions/mission-service'
|
|
24
22
|
import { getMessages, getRecentMessages, clearMessages } from '@/lib/server/messages/message-repository'
|
|
25
23
|
import type { Agent, AppSettings, ApprovalRequest, Chatroom, Message, Session } from '@/types'
|
|
26
24
|
import { isOrchestratorEligible } from '@/lib/orchestrator-config'
|
|
@@ -357,12 +355,7 @@ export function buildAgentHeartbeatPrompt(
|
|
|
357
355
|
}
|
|
358
356
|
}
|
|
359
357
|
|
|
360
|
-
// ── Phase 3:
|
|
361
|
-
const missionId = (session.missionId || (agent as Record<string, unknown>).missionId || null) as string | null
|
|
362
|
-
const goalAncestry = buildGoalAncestrySection(missionId)
|
|
363
|
-
if (goalAncestry) sections.push(goalAncestry)
|
|
364
|
-
|
|
365
|
-
// ── Phase 4: Active task checkout & events ──
|
|
358
|
+
// ── Phase 3: Active task checkout & events ──
|
|
366
359
|
const events = drainSystemEvents(session.id!)
|
|
367
360
|
if (events.length > 0) {
|
|
368
361
|
const eventBlock = events.map((e) => `- [${new Date(e.timestamp).toISOString()}] ${e.text}`).join('\n')
|
|
@@ -983,20 +976,7 @@ export function buildOrchestratorWakePrompt(session: any, agent: Agent): string
|
|
|
983
976
|
addSection(`## System Events\n${eventBlock}`)
|
|
984
977
|
}
|
|
985
978
|
|
|
986
|
-
// 7.
|
|
987
|
-
const missionId = session.missionId || null
|
|
988
|
-
if (missionId) {
|
|
989
|
-
try {
|
|
990
|
-
const missionBlock = buildMissionContextBlock(loadMission(missionId))
|
|
991
|
-
if (missionBlock) addSection(missionBlock)
|
|
992
|
-
} catch { /* ignore */ }
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
// 8. Goal ancestry
|
|
996
|
-
const goalAncestry = buildGoalAncestrySection(missionId)
|
|
997
|
-
if (goalAncestry) addSection(goalAncestry)
|
|
998
|
-
|
|
999
|
-
// 9. Chatroom membership
|
|
979
|
+
// 7. Chatroom membership
|
|
1000
980
|
try {
|
|
1001
981
|
const chatrooms = Object.values(loadChatrooms()) as Chatroom[]
|
|
1002
982
|
const myChatrooms = chatrooms.filter((c) => !c.archivedAt && c.agentIds?.includes(agent.id))
|
|
@@ -23,6 +23,7 @@ import type { ExecuteChatTurnResult } from '@/lib/server/chat-execution/chat-exe
|
|
|
23
23
|
import { checkAgentBudgetLimits } from '@/lib/server/cost'
|
|
24
24
|
import { enqueueExecution } from '@/lib/server/execution-engine'
|
|
25
25
|
import { extractTaskResult, formatResultBody } from '@/lib/server/tasks/task-result'
|
|
26
|
+
import { checkoutTask } from '@/lib/server/tasks/task-checkout'
|
|
26
27
|
import {
|
|
27
28
|
classifyRuntimeFailure,
|
|
28
29
|
observeAutonomyRunOutcome,
|
|
@@ -51,7 +52,6 @@ import {
|
|
|
51
52
|
markValidatedTaskCompleted,
|
|
52
53
|
refreshTaskCompletionValidation,
|
|
53
54
|
} from '@/lib/server/tasks/task-lifecycle'
|
|
54
|
-
import { noteMissionTaskFinished, noteMissionTaskStarted } from '@/lib/server/missions/mission-service'
|
|
55
55
|
|
|
56
56
|
const TAG = 'queue'
|
|
57
57
|
|
|
@@ -1210,25 +1210,16 @@ export async function processNext() {
|
|
|
1210
1210
|
} catch {}
|
|
1211
1211
|
}
|
|
1212
1212
|
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
// Mark as running
|
|
1213
|
+
// Atomic checkout — prevents two runners from starting the same task
|
|
1214
|
+
const runId = genId()
|
|
1215
|
+
task = checkoutTask(taskId, runId) as BoardTask | undefined
|
|
1216
|
+
if (!task) return
|
|
1220
1217
|
applyTaskPolicyDefaults(task)
|
|
1221
|
-
task.status = 'running'
|
|
1222
|
-
task.startedAt = Date.now()
|
|
1223
|
-
task.lastActivityAt = Date.now()
|
|
1224
|
-
task.retryScheduledAt = null
|
|
1225
|
-
task.deadLetteredAt = null
|
|
1226
|
-
// Clear transient failure fields so validation/error state reflects only this attempt.
|
|
1227
|
-
task.error = null
|
|
1228
|
-
task.validation = null
|
|
1229
|
-
task.updatedAt = Date.now()
|
|
1230
1218
|
logActivity({ entityType: 'task', entityId: taskId, action: 'running', actor: 'system', actorId: task.agentId, summary: `Task started: "${task.title}"` })
|
|
1231
1219
|
|
|
1220
|
+
// Reload tasks map for resolution functions and final save (checkoutTask already saved the running status)
|
|
1221
|
+
const allTasks = loadTasks() as Record<string, BoardTask>
|
|
1222
|
+
allTasks[taskId] = task
|
|
1232
1223
|
const sessionsForCwd = loadSessions() as Record<string, SessionLike>
|
|
1233
1224
|
const taskCwd = resolveTaskExecutionCwd(task as ScheduleTaskMeta, sessionsForCwd)
|
|
1234
1225
|
task.cwd = taskCwd
|
|
@@ -1238,8 +1229,8 @@ export async function processNext() {
|
|
|
1238
1229
|
const sourceScheduleId = typeof scheduleTask.sourceScheduleId === 'string'
|
|
1239
1230
|
? scheduleTask.sourceScheduleId
|
|
1240
1231
|
: ''
|
|
1241
|
-
const reusableTaskSessionId = resolveReusableTaskSessionId(task,
|
|
1242
|
-
const resumeContext = resolveTaskResumeContext(task,
|
|
1232
|
+
const reusableTaskSessionId = resolveReusableTaskSessionId(task, allTasks, sessionsForCwd)
|
|
1233
|
+
const resumeContext = resolveTaskResumeContext(task, allTasks, sessionsForCwd as Record<string, SessionLike | Session>)
|
|
1243
1234
|
|
|
1244
1235
|
// Resolve the agent's persistent thread session to use as parentSessionId
|
|
1245
1236
|
const agentThreadSessionId = agent.threadSessionId || null
|
|
@@ -1307,8 +1298,7 @@ export async function processNext() {
|
|
|
1307
1298
|
note: `Attempt ${(task.attempts || 0) + 1}/${task.maxAttempts || '?'} started${continuationBits.length ? ` (${continuationBits.join('; ')})` : ''}`,
|
|
1308
1299
|
updatedAt: Date.now(),
|
|
1309
1300
|
}
|
|
1310
|
-
saveTasks(
|
|
1311
|
-
noteMissionTaskStarted(task, task.id)
|
|
1301
|
+
saveTasks(allTasks)
|
|
1312
1302
|
pushMainLoopEventToMainSessions({
|
|
1313
1303
|
type: 'task_running',
|
|
1314
1304
|
text: `Task running: "${task.title}" (${task.id}) with ${agent.name}`,
|
|
@@ -1485,13 +1475,6 @@ export async function processNext() {
|
|
|
1485
1475
|
disableSessionHeartbeat(t2[taskId].sessionId)
|
|
1486
1476
|
}
|
|
1487
1477
|
const doneTask = t2[taskId]
|
|
1488
|
-
if (doneTask?.status === 'completed') {
|
|
1489
|
-
noteMissionTaskFinished(doneTask, 'completed', taskRunId)
|
|
1490
|
-
} else if (doneTask?.status === 'failed') {
|
|
1491
|
-
noteMissionTaskFinished(doneTask, 'failed', taskRunId)
|
|
1492
|
-
} else if (doneTask?.status === 'cancelled') {
|
|
1493
|
-
noteMissionTaskFinished(doneTask, 'cancelled', taskRunId)
|
|
1494
|
-
}
|
|
1495
1478
|
queueTaskAutonomyObservation({
|
|
1496
1479
|
runId: taskRunId,
|
|
1497
1480
|
sessionId,
|
|
@@ -1636,11 +1619,6 @@ export async function processNext() {
|
|
|
1636
1619
|
})
|
|
1637
1620
|
}
|
|
1638
1621
|
saveTasks(t3)
|
|
1639
|
-
if (t3[taskId].status === 'failed') {
|
|
1640
|
-
noteMissionTaskFinished(t3[taskId], 'failed', taskRunId)
|
|
1641
|
-
} else if (t3[taskId].status === 'cancelled') {
|
|
1642
|
-
noteMissionTaskFinished(t3[taskId], 'cancelled', taskRunId)
|
|
1643
|
-
}
|
|
1644
1622
|
notify('tasks')
|
|
1645
1623
|
notify('runs')
|
|
1646
1624
|
disableSessionHeartbeat(t3[taskId].sessionId)
|
|
@@ -9,7 +9,7 @@ function readRepoSource(relativePath: string): string {
|
|
|
9
9
|
return fs.readFileSync(path.join(repoRoot, relativePath), 'utf-8')
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
test('runtime hot paths use row-level task, schedule, and
|
|
12
|
+
test('runtime hot paths use row-level task, schedule, and wallet writes', () => {
|
|
13
13
|
const expectations = [
|
|
14
14
|
{
|
|
15
15
|
file: 'src/lib/server/runtime/scheduler.ts',
|
|
@@ -17,14 +17,14 @@ test('runtime hot paths use row-level task, schedule, and agent writes', () => {
|
|
|
17
17
|
forbidden: ['saveTasks(', 'saveSchedules('],
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
file: 'src/
|
|
21
|
-
required: ['
|
|
20
|
+
file: 'src/lib/server/schedules/schedule-route-service.ts',
|
|
21
|
+
required: ['saveTask(', 'upsertSchedule('],
|
|
22
22
|
forbidden: ['saveTasks(', 'saveSchedules('],
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
|
-
file: 'src/lib/server/
|
|
26
|
-
required: ['
|
|
27
|
-
forbidden: ['
|
|
25
|
+
file: 'src/lib/server/wallets/wallet-service.ts',
|
|
26
|
+
required: ['saveWallet(', 'deleteWallet('],
|
|
27
|
+
forbidden: ['saveWallets('],
|
|
28
28
|
},
|
|
29
29
|
] as const
|
|
30
30
|
|
|
@@ -10,7 +10,6 @@ import { processDueWatchJobs } from '@/lib/server/runtime/watch-jobs'
|
|
|
10
10
|
import { isAgentDisabled } from '@/lib/server/agents/agent-availability'
|
|
11
11
|
import { prepareScheduledTaskRun } from '@/lib/server/tasks/task-lifecycle'
|
|
12
12
|
import { ensureAgentThreadSession } from '@/lib/server/agents/agent-thread-session'
|
|
13
|
-
import { ensureMissionForTask, noteScheduleMissionTriggered } from '@/lib/server/missions/mission-service'
|
|
14
13
|
import { hasActiveProtocolRunForSchedule, launchProtocolRunForSchedule } from '@/lib/server/protocols/protocol-service'
|
|
15
14
|
import { hmrSingleton } from '@/lib/shared-utils'
|
|
16
15
|
import { log } from '@/lib/server/logger'
|
|
@@ -168,10 +167,6 @@ async function tick(now = Date.now()) {
|
|
|
168
167
|
// Wake-only: no board task, just heartbeat the agent
|
|
169
168
|
upsertSchedule(schedule.id, schedule)
|
|
170
169
|
const wakeSessionId = resolveScheduleWakeSessionId(schedule, agents as Record<string, unknown>)
|
|
171
|
-
noteScheduleMissionTriggered(schedule, {
|
|
172
|
-
wakeOnly: true,
|
|
173
|
-
sessionId: wakeSessionId || schedule.createdInSessionId || null,
|
|
174
|
-
})
|
|
175
170
|
|
|
176
171
|
const wakeMessage = schedule.message || `Schedule triggered: ${schedule.name}`
|
|
177
172
|
pushMainLoopEventToMainSessions({
|
|
@@ -205,16 +200,8 @@ async function tick(now = Date.now()) {
|
|
|
205
200
|
now,
|
|
206
201
|
scheduleSignature,
|
|
207
202
|
})
|
|
208
|
-
const mission = noteScheduleMissionTriggered(schedule, {
|
|
209
|
-
taskId,
|
|
210
|
-
sessionId: schedule.createdInSessionId || null,
|
|
211
|
-
})
|
|
212
|
-
if (mission) {
|
|
213
|
-
tasks[taskId].missionId = mission.id
|
|
214
|
-
}
|
|
215
203
|
|
|
216
204
|
upsertTask(taskId, tasks[taskId])
|
|
217
|
-
ensureMissionForTask(tasks[taskId], { source: 'schedule' })
|
|
218
205
|
upsertSchedule(schedule.id, schedule)
|
|
219
206
|
|
|
220
207
|
enqueueTask(taskId)
|
|
@@ -90,7 +90,6 @@ export async function drainExecution(
|
|
|
90
90
|
})
|
|
91
91
|
|
|
92
92
|
let runtimeTimer: ReturnType<typeof setTimeout> | null = null
|
|
93
|
-
let finishedMissionId: string | null = null
|
|
94
93
|
if (next.maxRuntimeMs && next.maxRuntimeMs > 0) {
|
|
95
94
|
runtimeTimer = setTimeout(() => {
|
|
96
95
|
next.signalController.abort()
|
|
@@ -119,8 +118,6 @@ export async function drainExecution(
|
|
|
119
118
|
next.run.status = aborted ? 'cancelled' : (failed ? 'failed' : 'completed')
|
|
120
119
|
next.run.endedAt = next.run.endedAt || now()
|
|
121
120
|
next.run.error = aborted ? (next.run.error || 'Cancelled') : result.error
|
|
122
|
-
next.run.missionId = result.missionId || next.run.missionId || null
|
|
123
|
-
finishedMissionId = next.run.missionId || null
|
|
124
121
|
next.run.resultPreview = result.text?.slice(0, 280)
|
|
125
122
|
if (typeof result.inputTokens === 'number') next.run.totalInputTokens = result.inputTokens
|
|
126
123
|
if (typeof result.outputTokens === 'number') next.run.totalOutputTokens = result.outputTokens
|
|
@@ -186,7 +183,6 @@ export async function drainExecution(
|
|
|
186
183
|
next.run.status = aborted ? 'cancelled' : 'failed'
|
|
187
184
|
next.run.endedAt = now()
|
|
188
185
|
next.run.error = errorMessage(err)
|
|
189
|
-
finishedMissionId = next.run.missionId || null
|
|
190
186
|
syncRunRecord(next.run)
|
|
191
187
|
emitRunMeta(next, next.run.status, { error: next.run.error })
|
|
192
188
|
log.error('session-run', `Run failed ${next.run.id}`, {
|
|
@@ -216,26 +212,6 @@ export async function drainExecution(
|
|
|
216
212
|
decrementNonHeartbeatWork(next)
|
|
217
213
|
reconcileSessionActivityLease(next.run.sessionId)
|
|
218
214
|
notify(`stream-end:${next.run.sessionId}`)
|
|
219
|
-
if (finishedMissionId && next.run.source !== 'chat') {
|
|
220
|
-
const missionId = finishedMissionId
|
|
221
|
-
queueMicrotask(() => {
|
|
222
|
-
import('@/lib/server/missions/mission-service')
|
|
223
|
-
.then(({ loadMissionById, requestMissionTick }) => {
|
|
224
|
-
const mission = loadMissionById(missionId)
|
|
225
|
-
if (!mission) return
|
|
226
|
-
if (mission.status !== 'active') return
|
|
227
|
-
if (mission.phase === 'dispatching' || mission.phase === 'executing') return
|
|
228
|
-
requestMissionTick(missionId, 'run_drained', {
|
|
229
|
-
runId: next.run.id,
|
|
230
|
-
source: next.run.source,
|
|
231
|
-
status: next.run.status,
|
|
232
|
-
})
|
|
233
|
-
})
|
|
234
|
-
.catch((err: unknown) => {
|
|
235
|
-
log.warn('session-run', 'Mission tick failed', { missionId, runId: next.run.id, error: errorMessage(err) })
|
|
236
|
-
})
|
|
237
|
-
})
|
|
238
|
-
}
|
|
239
215
|
void drainExecution(executionKey, deps)
|
|
240
216
|
}
|
|
241
217
|
} finally {
|
|
@@ -215,7 +215,6 @@ export function enqueueSessionRun(
|
|
|
215
215
|
const run: SessionRunRecord = {
|
|
216
216
|
id: runId,
|
|
217
217
|
sessionId: input.sessionId,
|
|
218
|
-
missionId: input.missionId ?? getSession(input.sessionId)?.missionId ?? null,
|
|
219
218
|
kind: 'session_turn',
|
|
220
219
|
ownerType: 'session',
|
|
221
220
|
ownerId: input.sessionId,
|
|
@@ -37,7 +37,6 @@ function toQueuedTurn(entry: SessionRunQueueEntry, index: number): SessionQueued
|
|
|
37
37
|
return {
|
|
38
38
|
runId: entry.run.id,
|
|
39
39
|
sessionId: entry.run.sessionId,
|
|
40
|
-
missionId: entry.run.missionId || null,
|
|
41
40
|
text: entry.message,
|
|
42
41
|
queuedAt: entry.run.queuedAt,
|
|
43
42
|
position: index + 1,
|
|
@@ -48,7 +48,6 @@ function resolveRecoveredQueuedEntry(entry: SessionRunQueueEntry, reason: string
|
|
|
48
48
|
entry.resolve({
|
|
49
49
|
runId: entry.run.id,
|
|
50
50
|
sessionId: entry.run.sessionId,
|
|
51
|
-
...(entry.run.missionId ? { missionId: entry.run.missionId } : {}),
|
|
52
51
|
text: '',
|
|
53
52
|
persisted: false,
|
|
54
53
|
toolEvents: [],
|
|
@@ -249,34 +249,6 @@ describe('session-run-manager', () => {
|
|
|
249
249
|
assert.ok(run.queuedAt > 0)
|
|
250
250
|
})
|
|
251
251
|
|
|
252
|
-
it('copies the session mission id into queued run snapshots', () => {
|
|
253
|
-
storage.upsertSession('sess-mission', {
|
|
254
|
-
id: 'sess-mission',
|
|
255
|
-
cwd: process.cwd(),
|
|
256
|
-
user: 'tester',
|
|
257
|
-
provider: 'ollama',
|
|
258
|
-
model: 'test-model',
|
|
259
|
-
claudeSessionId: null,
|
|
260
|
-
messages: [],
|
|
261
|
-
createdAt: Date.now(),
|
|
262
|
-
lastActiveAt: Date.now(),
|
|
263
|
-
agentId: 'test-agent',
|
|
264
|
-
missionId: 'mission-123',
|
|
265
|
-
})
|
|
266
|
-
const release = mgr.acquireExternalSessionExecutionHold('sess-mission')
|
|
267
|
-
|
|
268
|
-
const result = enqueue({
|
|
269
|
-
sessionId: 'sess-mission',
|
|
270
|
-
message: 'Continue the release mission',
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
const run = mgr.getRunById(result.runId)
|
|
274
|
-
const snapshot = mgr.getSessionQueueSnapshot('sess-mission')
|
|
275
|
-
assert.equal(run?.missionId, 'mission-123')
|
|
276
|
-
assert.equal(snapshot.items[0]?.missionId, 'mission-123')
|
|
277
|
-
release()
|
|
278
|
-
})
|
|
279
|
-
|
|
280
252
|
it('persists run records and replay events in storage', () => {
|
|
281
253
|
const result = enqueue({
|
|
282
254
|
sessionId: 'sess-persisted',
|
|
@@ -38,7 +38,6 @@ import {
|
|
|
38
38
|
deriveTaskTitle,
|
|
39
39
|
prepareTaskCreation,
|
|
40
40
|
} from '@/lib/server/tasks/task-service'
|
|
41
|
-
import { ensureMissionForTask, enrichTaskWithMissionSummary } from '@/lib/server/missions/mission-service'
|
|
42
41
|
import { classifyMessage } from '@/lib/server/chat-execution/message-classifier'
|
|
43
42
|
import {
|
|
44
43
|
buildDelegationTaskProfile,
|
|
@@ -742,19 +741,6 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
742
741
|
|
|
743
742
|
res.save(all)
|
|
744
743
|
if (toolKey === 'manage_tasks') {
|
|
745
|
-
const mission = ensureMissionForTask(entry as BoardTask, {
|
|
746
|
-
source: entry.sourceType === 'schedule'
|
|
747
|
-
? 'schedule'
|
|
748
|
-
: entry.sourceType === 'delegation'
|
|
749
|
-
? 'delegation'
|
|
750
|
-
: 'manual',
|
|
751
|
-
})
|
|
752
|
-
if (mission) {
|
|
753
|
-
responseEntry = enrichTaskWithMissionSummary({
|
|
754
|
-
...(responseEntry as BoardTask),
|
|
755
|
-
missionId: mission.id,
|
|
756
|
-
})
|
|
757
|
-
}
|
|
758
744
|
if (taskDelegationAdvisory && responseEntry && typeof responseEntry === 'object') {
|
|
759
745
|
responseEntry = {
|
|
760
746
|
...(responseEntry as Record<string, unknown>),
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
registerDelegationRuntime,
|
|
22
22
|
startDelegationJob,
|
|
23
23
|
} from '@/lib/server/agents/delegation-jobs'
|
|
24
|
-
import { loadSession } from '@/lib/server/sessions/session-repository'
|
|
25
24
|
import { markProviderFailure, markProviderSuccess } from '../provider-health'
|
|
26
25
|
import { loadRuntimeSettings } from '../runtime/runtime-settings'
|
|
27
26
|
import { getSessionDepth } from '../agents/subagent-runtime'
|
|
@@ -463,8 +462,6 @@ async function executeDelegateAction(args: Record<string, unknown>, bctx: Delega
|
|
|
463
462
|
const jobId = typeof normalized.jobId === 'string' ? normalized.jobId.trim() : ''
|
|
464
463
|
const waitForCompletion = normalized.waitForCompletion !== false && normalized.background !== true
|
|
465
464
|
const parentSessionId = resolveDelegateSessionId(bctx)
|
|
466
|
-
const parentMissionId = parentSessionId ? loadSession(parentSessionId)?.missionId || null : null
|
|
467
|
-
|
|
468
465
|
recoverStaleDelegationJobs()
|
|
469
466
|
|
|
470
467
|
if (action === 'status') {
|
|
@@ -505,7 +502,6 @@ async function executeDelegateAction(args: Record<string, unknown>, bctx: Delega
|
|
|
505
502
|
const job = createDelegationJob({
|
|
506
503
|
kind: 'delegate',
|
|
507
504
|
parentSessionId,
|
|
508
|
-
parentMissionId,
|
|
509
505
|
backend: requestedBackend,
|
|
510
506
|
task,
|
|
511
507
|
cwd: bctx.cwd || null,
|
|
@@ -19,8 +19,6 @@ import { buildMemoryTools } from './memory'
|
|
|
19
19
|
import { buildChatroomTools } from './chatroom'
|
|
20
20
|
import { buildProtocolTools } from './protocol'
|
|
21
21
|
import { buildSubagentTools } from './subagent'
|
|
22
|
-
import { buildCanvasTools } from './canvas'
|
|
23
|
-
import { buildWalletTools } from './wallet'
|
|
24
22
|
import { buildOpenClawWorkspaceTools } from './openclaw-workspace'
|
|
25
23
|
import { buildScheduleTools } from './schedule'
|
|
26
24
|
import { buildPlatformTools } from './platform'
|
|
@@ -187,8 +185,6 @@ export async function buildSessionTools(cwd: string, enabledExtensions: string[]
|
|
|
187
185
|
['manage_chatrooms', buildChatroomTools],
|
|
188
186
|
['manage_protocols', buildProtocolTools],
|
|
189
187
|
['spawn_subagent', buildSubagentTools],
|
|
190
|
-
['canvas', buildCanvasTools],
|
|
191
|
-
['wallet', buildWalletTools],
|
|
192
188
|
['openclaw_workspace', buildOpenClawWorkspaceTools],
|
|
193
189
|
['schedule', buildScheduleTools],
|
|
194
190
|
['manage_sessions', buildSessionInfoTools],
|
|
@@ -168,9 +168,6 @@ async function formatPeerContext(agentId: string, peerId: string): Promise<strin
|
|
|
168
168
|
const activeSession = Object.values(sessions).find(
|
|
169
169
|
(s) => s.agentId === peerId && s.active,
|
|
170
170
|
)
|
|
171
|
-
if (activeSession?.missionId) {
|
|
172
|
-
result.activeMission = { missionId: activeSession.missionId }
|
|
173
|
-
}
|
|
174
171
|
} catch { /* non-critical */ }
|
|
175
172
|
|
|
176
173
|
// Enforce output cap — drop large fields instead of slicing mid-JSON
|
|
@@ -435,6 +435,7 @@ export function normalizeStoredRecord(
|
|
|
435
435
|
&& table !== 'schedules' && table !== 'sessions'
|
|
436
436
|
&& table !== 'provider_configs'
|
|
437
437
|
&& table !== 'runtime_runs' && table !== 'runtime_run_events'
|
|
438
|
+
&& table !== 'wallets'
|
|
438
439
|
) {
|
|
439
440
|
return { value, changed: false }
|
|
440
441
|
}
|
|
@@ -573,6 +574,13 @@ function normalizeStoredRecordInner(
|
|
|
573
574
|
return normalizeStoredScheduleRecord(value, loadItem)
|
|
574
575
|
}
|
|
575
576
|
|
|
577
|
+
if (table === 'wallets') {
|
|
578
|
+
const wallet = value as StoredObject
|
|
579
|
+
if (wallet.chain !== 'base') wallet.chain = 'base'
|
|
580
|
+
if (typeof wallet.createdAt !== 'number') wallet.createdAt = Date.now()
|
|
581
|
+
return wallet
|
|
582
|
+
}
|
|
583
|
+
|
|
576
584
|
// sessions
|
|
577
585
|
const session = value as StoredObject
|
|
578
586
|
// Migrate legacy 'orchestrated' → 'delegated'
|