@swarmclawai/swarmclaw 0.8.4 → 0.8.7
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 +9 -9
- package/bin/swarmclaw.js +5 -1
- package/bin/worker-cmd.js +73 -0
- package/package.json +2 -1
- package/src/app/api/agents/[id]/route.ts +17 -7
- package/src/app/api/agents/route.ts +21 -8
- package/src/app/api/approvals/route.test.ts +6 -6
- package/src/app/api/approvals/route.ts +2 -1
- package/src/app/api/auth/route.ts +2 -3
- package/src/app/api/chatrooms/[id]/chat/route.test.ts +299 -0
- package/src/app/api/chatrooms/[id]/chat/route.ts +3 -2
- package/src/app/api/chatrooms/[id]/route.ts +7 -6
- package/src/app/api/chats/[id]/chat/route.test.ts +496 -0
- package/src/app/api/chats/[id]/chat/route.ts +7 -3
- package/src/app/api/chats/[id]/clear/route.ts +9 -9
- package/src/app/api/chats/[id]/devserver/route.ts +2 -1
- package/src/app/api/chats/[id]/edit-resend/route.ts +3 -4
- package/src/app/api/chats/[id]/fork/route.ts +3 -5
- package/src/app/api/chats/[id]/restore/route.ts +6 -7
- package/src/app/api/chats/[id]/retry/route.ts +3 -4
- package/src/app/api/chats/[id]/route.ts +61 -62
- package/src/app/api/chats/route.ts +7 -1
- package/src/app/api/connectors/[id]/route.ts +7 -8
- package/src/app/api/connectors/route.ts +5 -4
- package/src/app/api/eval/run/route.ts +2 -1
- package/src/app/api/eval/suite/route.ts +2 -1
- package/src/app/api/external-agents/route.test.ts +1 -1
- package/src/app/api/external-agents/route.ts +2 -2
- package/src/app/api/files/serve/route.ts +1 -1
- package/src/app/api/gateways/[id]/route.ts +7 -5
- package/src/app/api/gateways/route.ts +1 -1
- package/src/app/api/knowledge/upload/route.ts +1 -1
- package/src/app/api/logs/route.ts +5 -7
- package/src/app/api/memory-images/[filename]/route.ts +2 -3
- package/src/app/api/openclaw/agent-files/route.ts +4 -3
- package/src/app/api/openclaw/approvals/route.ts +3 -4
- package/src/app/api/openclaw/config-sync/route.ts +3 -2
- package/src/app/api/openclaw/cron/route.ts +3 -2
- package/src/app/api/openclaw/dotenv-keys/route.ts +2 -1
- package/src/app/api/openclaw/exec-config/route.ts +3 -2
- package/src/app/api/openclaw/gateway/route.ts +5 -4
- package/src/app/api/openclaw/history/route.ts +3 -2
- package/src/app/api/openclaw/media/route.ts +2 -1
- package/src/app/api/openclaw/permissions/route.ts +3 -2
- package/src/app/api/openclaw/sandbox-env/route.ts +3 -2
- package/src/app/api/openclaw/skills/install/route.ts +2 -1
- package/src/app/api/openclaw/skills/remove/route.ts +2 -1
- package/src/app/api/openclaw/skills/route.ts +3 -2
- package/src/app/api/orchestrator/run/route.ts +5 -14
- package/src/app/api/perf/route.ts +43 -0
- package/src/app/api/plugins/dependencies/route.ts +2 -1
- package/src/app/api/plugins/install/route.ts +2 -1
- package/src/app/api/plugins/marketplace/route.ts +3 -2
- package/src/app/api/plugins/settings/route.ts +2 -1
- package/src/app/api/preview-server/route.ts +11 -10
- package/src/app/api/projects/[id]/route.ts +1 -1
- package/src/app/api/schedules/[id]/route.test.ts +128 -0
- package/src/app/api/schedules/[id]/route.ts +43 -43
- package/src/app/api/schedules/[id]/run/route.ts +11 -62
- package/src/app/api/schedules/route.ts +21 -87
- package/src/app/api/settings/route.ts +2 -0
- package/src/app/api/setup/doctor/route.ts +9 -8
- package/src/app/api/tasks/[id]/approve/route.ts +33 -30
- package/src/app/api/tasks/[id]/route.ts +12 -35
- package/src/app/api/tasks/import/github/route.ts +2 -1
- package/src/app/api/tasks/route.ts +79 -91
- package/src/app/api/wallets/[id]/approve/route.ts +2 -1
- package/src/app/api/wallets/[id]/route.ts +13 -19
- package/src/app/api/wallets/[id]/send/route.ts +2 -1
- package/src/app/api/wallets/route.ts +2 -1
- package/src/app/api/webhooks/[id]/route.ts +2 -1
- package/src/app/api/webhooks/route.test.ts +3 -1
- package/src/app/page.tsx +23 -331
- package/src/cli/index.js +19 -0
- package/src/cli/index.ts +38 -7
- package/src/cli/spec.js +9 -0
- package/src/components/activity/activity-feed.tsx +7 -4
- package/src/components/agents/agent-card.tsx +32 -6
- package/src/components/agents/agent-chat-list.tsx +55 -22
- package/src/components/agents/agent-files-editor.tsx +3 -2
- package/src/components/agents/agent-sheet.tsx +123 -22
- package/src/components/agents/inspector-panel.tsx +1 -1
- package/src/components/agents/openclaw-skills-panel.tsx +2 -1
- package/src/components/agents/trash-list.tsx +1 -1
- package/src/components/auth/access-key-gate.tsx +8 -2
- package/src/components/auth/setup-wizard.tsx +10 -9
- package/src/components/auth/user-picker.tsx +3 -2
- package/src/components/chat/chat-area.tsx +20 -1
- package/src/components/chat/chat-card.tsx +18 -3
- package/src/components/chat/chat-header.tsx +24 -4
- package/src/components/chat/chat-list.tsx +2 -11
- package/src/components/chat/heartbeat-history-panel.tsx +2 -1
- package/src/components/chat/message-bubble.tsx +45 -6
- package/src/components/chat/message-list.tsx +280 -145
- package/src/components/chat/streaming-bubble.tsx +217 -60
- package/src/components/chat/swarm-panel.test.ts +274 -0
- package/src/components/chat/swarm-panel.tsx +410 -0
- package/src/components/chat/swarm-status-card.tsx +346 -0
- package/src/components/chat/tool-call-bubble.tsx +48 -23
- package/src/components/chatrooms/chatroom-list.tsx +8 -5
- package/src/components/chatrooms/chatroom-message.tsx +10 -7
- package/src/components/chatrooms/chatroom-view.tsx +12 -9
- package/src/components/connectors/connector-health.tsx +6 -4
- package/src/components/connectors/connector-list.tsx +16 -11
- package/src/components/connectors/connector-sheet.tsx +12 -6
- package/src/components/home/home-view.tsx +38 -24
- package/src/components/input/chat-input.tsx +10 -1
- package/src/components/layout/app-layout.tsx +2 -38
- package/src/components/layout/sheet-layer.tsx +50 -0
- package/src/components/mcp-servers/mcp-server-list.tsx +37 -5
- package/src/components/mcp-servers/mcp-server-sheet.tsx +12 -2
- package/src/components/plugins/plugin-list.tsx +8 -4
- package/src/components/plugins/plugin-sheet.tsx +2 -1
- package/src/components/providers/provider-list.tsx +3 -2
- package/src/components/providers/provider-sheet.tsx +2 -1
- package/src/components/runs/run-list.tsx +11 -7
- package/src/components/schedules/schedule-card.tsx +5 -3
- package/src/components/shared/agent-switch-dialog.tsx +1 -1
- package/src/components/shared/attachment-chip.tsx +19 -3
- package/src/components/shared/notification-center.tsx +6 -3
- package/src/components/shared/settings/plugin-manager.tsx +3 -2
- package/src/components/shared/settings/section-embedding.tsx +2 -1
- package/src/components/shared/settings/section-orchestrator.tsx +2 -1
- package/src/components/shared/settings/section-user-preferences.tsx +107 -0
- package/src/components/shared/settings/settings-page.tsx +13 -9
- package/src/components/skills/clawhub-browser.tsx +15 -4
- package/src/components/skills/skill-list.tsx +15 -4
- package/src/components/tasks/approvals-panel.tsx +2 -1
- package/src/components/tasks/task-board.tsx +35 -37
- package/src/components/tasks/task-sheet.tsx +4 -3
- package/src/components/ui/full-screen-loader.tsx +164 -0
- package/src/components/wallets/wallet-approval-dialog.tsx +2 -1
- package/src/components/wallets/wallet-panel.tsx +6 -5
- package/src/components/wallets/wallet-section.tsx +3 -2
- package/src/components/webhooks/webhook-list.tsx +4 -5
- package/src/components/webhooks/webhook-sheet.tsx +6 -6
- package/src/hooks/use-app-bootstrap.ts +202 -0
- package/src/hooks/use-mounted-ref.ts +14 -0
- package/src/hooks/use-now.ts +31 -0
- package/src/hooks/use-openclaw-gateway.ts +2 -1
- package/src/instrumentation.ts +20 -8
- package/src/lib/agent-default-tools.test.ts +52 -0
- package/src/lib/agent-default-tools.ts +40 -0
- package/src/lib/api-client.test.ts +21 -0
- package/src/lib/api-client.ts +6 -11
- package/src/lib/canvas-content.test.ts +360 -0
- package/src/lib/chat-streaming-state.test.ts +49 -2
- package/src/lib/chat-streaming-state.ts +26 -10
- package/src/lib/fetch-timeout.test.ts +54 -0
- package/src/lib/fetch-timeout.ts +60 -3
- package/src/lib/live-tool-events.test.ts +77 -0
- package/src/lib/live-tool-events.ts +73 -0
- package/src/lib/local-observability.test.ts +2 -2
- package/src/lib/openclaw-endpoint.test.ts +1 -1
- package/src/lib/providers/anthropic.ts +12 -16
- package/src/lib/providers/index.ts +4 -2
- package/src/lib/providers/ollama.ts +9 -6
- package/src/lib/providers/openai.ts +11 -14
- package/src/lib/runtime-env.test.ts +8 -8
- package/src/lib/schedule-dedupe-advanced.test.ts +2 -2
- package/src/lib/schedule-dedupe.test.ts +1 -1
- package/src/lib/schedule-dedupe.ts +3 -2
- package/src/lib/server/agent-thread-session.test.ts +6 -6
- package/src/lib/server/agent-thread-session.ts +6 -9
- package/src/lib/server/alert-dispatch.ts +2 -1
- package/src/lib/server/api-routes.test.ts +6 -6
- package/src/lib/server/approval-connector-notify.test.ts +4 -4
- package/src/lib/server/approvals-auto-approve.test.ts +29 -29
- package/src/lib/server/approvals.test.ts +317 -0
- package/src/lib/server/approvals.ts +5 -4
- package/src/lib/server/autonomy-runtime.test.ts +11 -11
- package/src/lib/server/browser-state.ts +2 -2
- package/src/lib/server/capability-router.test.ts +1 -1
- package/src/lib/server/capability-router.ts +3 -2
- package/src/lib/server/chat-execution-advanced.test.ts +15 -2
- package/src/lib/server/chat-execution-connector-delivery.ts +67 -0
- package/src/lib/server/chat-execution-disabled.test.ts +3 -3
- package/src/lib/server/chat-execution-eval-history.test.ts +3 -3
- package/src/lib/server/chat-execution-heartbeat.test.ts +42 -1
- package/src/lib/server/chat-execution-session-sync.test.ts +119 -0
- package/src/lib/server/chat-execution-tool-events.ts +116 -0
- package/src/lib/server/chat-execution-utils.test.ts +479 -0
- package/src/lib/server/chat-execution-utils.ts +533 -0
- package/src/lib/server/chat-execution.ts +153 -748
- package/src/lib/server/chat-streaming-utils.ts +174 -0
- package/src/lib/server/chat-turn-tool-routing.ts +310 -0
- package/src/lib/server/chatroom-session-persistence.test.ts +2 -2
- package/src/lib/server/clawhub-client.ts +2 -1
- package/src/lib/server/collection-helpers.test.ts +92 -0
- package/src/lib/server/collection-helpers.ts +25 -3
- package/src/lib/server/connectors/access.ts +146 -0
- package/src/lib/server/connectors/bluebubbles.test.ts +1 -1
- package/src/lib/server/connectors/bluebubbles.ts +4 -4
- package/src/lib/server/connectors/commands.ts +367 -0
- package/src/lib/server/connectors/connector-routing.test.ts +4 -4
- package/src/lib/server/connectors/delivery.ts +142 -0
- package/src/lib/server/connectors/discord.ts +37 -40
- package/src/lib/server/connectors/email.ts +11 -10
- package/src/lib/server/connectors/googlechat.ts +4 -4
- package/src/lib/server/connectors/inbound-audio-transcription.ts +2 -1
- package/src/lib/server/connectors/ingress-delivery.ts +23 -0
- package/src/lib/server/connectors/manager-roundtrip.test.ts +300 -0
- package/src/lib/server/connectors/manager.test.ts +352 -77
- package/src/lib/server/connectors/manager.ts +134 -673
- package/src/lib/server/connectors/matrix.ts +4 -4
- package/src/lib/server/connectors/message-sentinel.ts +7 -0
- package/src/lib/server/connectors/openclaw.test.ts +1 -1
- package/src/lib/server/connectors/openclaw.ts +8 -10
- package/src/lib/server/connectors/outbox.test.ts +192 -0
- package/src/lib/server/connectors/outbox.ts +369 -0
- package/src/lib/server/connectors/pairing.test.ts +18 -1
- package/src/lib/server/connectors/pairing.ts +49 -4
- package/src/lib/server/connectors/policy.ts +9 -3
- package/src/lib/server/connectors/reconnect-state.ts +71 -0
- package/src/lib/server/connectors/response-media.ts +256 -0
- package/src/lib/server/connectors/runtime-state.ts +67 -0
- package/src/lib/server/connectors/session.test.ts +357 -0
- package/src/lib/server/connectors/session.ts +422 -0
- package/src/lib/server/connectors/signal.ts +7 -7
- package/src/lib/server/connectors/slack.ts +43 -43
- package/src/lib/server/connectors/teams.ts +4 -4
- package/src/lib/server/connectors/telegram.ts +37 -43
- package/src/lib/server/connectors/types.ts +31 -1
- package/src/lib/server/connectors/whatsapp.test.ts +108 -0
- package/src/lib/server/connectors/whatsapp.ts +106 -34
- package/src/lib/server/context-manager.test.ts +409 -0
- package/src/lib/server/cost.test.ts +1 -1
- package/src/lib/server/daemon-policy.ts +78 -0
- package/src/lib/server/daemon-state-connectors.test.ts +167 -0
- package/src/lib/server/daemon-state.test.ts +283 -55
- package/src/lib/server/daemon-state.ts +106 -109
- package/src/lib/server/data-dir.test.ts +5 -5
- package/src/lib/server/data-dir.ts +4 -0
- package/src/lib/server/delegation-jobs-advanced.test.ts +1 -1
- package/src/lib/server/delegation-jobs.test.ts +87 -0
- package/src/lib/server/delegation-jobs.ts +42 -48
- package/src/lib/server/devserver-launch.ts +1 -1
- package/src/lib/server/document-utils.ts +7 -9
- package/src/lib/server/elevenlabs.ts +2 -1
- package/src/lib/server/embeddings.test.ts +105 -0
- package/src/lib/server/ethereum.ts +3 -2
- package/src/lib/server/eval/agent-regression.ts +3 -2
- package/src/lib/server/eval/runner.ts +2 -1
- package/src/lib/server/eval/scorer.ts +2 -1
- package/src/lib/server/evm-swap.ts +2 -1
- package/src/lib/server/gateway/protocol.test.ts +1 -1
- package/src/lib/server/guardian.ts +2 -1
- package/src/lib/server/heartbeat-blocked-suppression.test.ts +151 -0
- package/src/lib/server/heartbeat-service-timer.test.ts +6 -6
- package/src/lib/server/heartbeat-service.test.ts +406 -0
- package/src/lib/server/heartbeat-service.ts +54 -7
- package/src/lib/server/heartbeat-wake.test.ts +19 -0
- package/src/lib/server/heartbeat-wake.ts +17 -16
- package/src/lib/server/integrity-monitor.test.ts +149 -0
- package/src/lib/server/json-utils.ts +22 -0
- package/src/lib/server/knowledge-db.test.ts +13 -13
- package/src/lib/server/link-understanding.ts +2 -1
- package/src/lib/server/llm-response-cache.test.ts +1 -1
- package/src/lib/server/main-agent-loop-advanced.test.ts +65 -3
- package/src/lib/server/main-agent-loop.test.ts +6 -6
- package/src/lib/server/main-agent-loop.ts +21 -7
- package/src/lib/server/mcp-client.test.ts +1 -1
- package/src/lib/server/mcp-conformance.test.ts +1 -1
- package/src/lib/server/mcp-conformance.ts +3 -2
- package/src/lib/server/memory-consolidation.ts +2 -1
- package/src/lib/server/memory-db.test.ts +485 -0
- package/src/lib/server/memory-db.ts +39 -26
- package/src/lib/server/memory-graph.test.ts +2 -2
- package/src/lib/server/memory-policy.test.ts +7 -7
- package/src/lib/server/memory-retrieval.test.ts +1 -1
- package/src/lib/server/openclaw-config-sync.ts +2 -1
- package/src/lib/server/openclaw-deploy.test.ts +1 -1
- package/src/lib/server/openclaw-deploy.ts +8 -12
- package/src/lib/server/openclaw-exec-config.ts +2 -1
- package/src/lib/server/openclaw-gateway.ts +6 -7
- package/src/lib/server/openclaw-skills-normalize.ts +2 -1
- package/src/lib/server/openclaw-sync.ts +7 -5
- package/src/lib/server/orchestrator-lg-structure.test.ts +17 -0
- package/src/lib/server/orchestrator-lg.ts +199 -327
- package/src/lib/server/path-utils.ts +31 -0
- package/src/lib/server/perf.ts +161 -0
- package/src/lib/server/plugins-approval-guidance.ts +115 -0
- package/src/lib/server/plugins.test.ts +1 -1
- package/src/lib/server/plugins.ts +22 -132
- package/src/lib/server/process-manager.ts +5 -8
- package/src/lib/server/provider-health.test.ts +137 -0
- package/src/lib/server/provider-health.ts +3 -3
- package/src/lib/server/provider-model-discovery.ts +3 -12
- package/src/lib/server/queue-followups.test.ts +9 -9
- package/src/lib/server/queue-reconcile.test.ts +2 -2
- package/src/lib/server/queue-recovery.test.ts +269 -0
- package/src/lib/server/queue.test.ts +570 -0
- package/src/lib/server/queue.ts +62 -455
- package/src/lib/server/resolve-image.ts +30 -0
- package/src/lib/server/runtime-settings.test.ts +4 -4
- package/src/lib/server/runtime-storage-write-paths.test.ts +60 -0
- package/src/lib/server/schedule-normalization.test.ts +279 -0
- package/src/lib/server/schedule-service.ts +263 -0
- package/src/lib/server/scheduler.ts +17 -74
- package/src/lib/server/session-mailbox.test.ts +191 -0
- package/src/lib/server/session-run-manager.test.ts +640 -0
- package/src/lib/server/session-run-manager.ts +59 -15
- package/src/lib/server/session-tools/autonomy-tools.test.ts +20 -20
- package/src/lib/server/session-tools/calendar.ts +2 -1
- package/src/lib/server/session-tools/canvas.ts +2 -1
- package/src/lib/server/session-tools/chatroom.ts +2 -1
- package/src/lib/server/session-tools/connector.ts +26 -28
- package/src/lib/server/session-tools/context-mgmt.ts +3 -2
- package/src/lib/server/session-tools/crawl.ts +4 -3
- package/src/lib/server/session-tools/crud.ts +105 -324
- package/src/lib/server/session-tools/delegate-fallback.test.ts +9 -9
- package/src/lib/server/session-tools/delegate.ts +6 -8
- package/src/lib/server/session-tools/discovery-approvals.test.ts +15 -15
- package/src/lib/server/session-tools/discovery.ts +4 -3
- package/src/lib/server/session-tools/document.ts +2 -1
- package/src/lib/server/session-tools/email.ts +2 -1
- package/src/lib/server/session-tools/extract.ts +2 -1
- package/src/lib/server/session-tools/file.ts +4 -3
- package/src/lib/server/session-tools/http.ts +2 -1
- package/src/lib/server/session-tools/human-loop.ts +2 -1
- package/src/lib/server/session-tools/image-gen.ts +4 -3
- package/src/lib/server/session-tools/index.ts +26 -30
- package/src/lib/server/session-tools/mailbox.ts +2 -1
- package/src/lib/server/session-tools/manage-connectors.test.ts +4 -4
- package/src/lib/server/session-tools/manage-schedules.test.ts +12 -12
- package/src/lib/server/session-tools/manage-tasks-advanced.test.ts +5 -5
- package/src/lib/server/session-tools/manage-tasks.test.ts +2 -2
- package/src/lib/server/session-tools/monitor.ts +2 -1
- package/src/lib/server/session-tools/platform.ts +2 -1
- package/src/lib/server/session-tools/plugin-creator.ts +2 -1
- package/src/lib/server/session-tools/replicate.ts +3 -2
- package/src/lib/server/session-tools/session-tools-wiring.test.ts +6 -6
- package/src/lib/server/session-tools/shell.ts +4 -9
- package/src/lib/server/session-tools/subagent.ts +322 -170
- package/src/lib/server/session-tools/table.ts +6 -5
- package/src/lib/server/session-tools/wallet-tool.test.ts +3 -3
- package/src/lib/server/session-tools/wallet.ts +7 -6
- package/src/lib/server/session-tools/web-browser-config.test.ts +1 -0
- package/src/lib/server/session-tools/web-utils.ts +317 -0
- package/src/lib/server/session-tools/web.ts +62 -328
- package/src/lib/server/skill-prompt-budget.test.ts +1 -1
- package/src/lib/server/skills-normalize.ts +2 -1
- package/src/lib/server/storage-item-access.test.ts +302 -0
- package/src/lib/server/storage.ts +366 -314
- package/src/lib/server/stream-agent-chat.test.ts +82 -3
- package/src/lib/server/stream-agent-chat.ts +146 -510
- package/src/lib/server/stream-continuation.ts +412 -0
- package/src/lib/server/subagent-lineage.test.ts +647 -0
- package/src/lib/server/subagent-lineage.ts +435 -0
- package/src/lib/server/subagent-runtime.test.ts +484 -0
- package/src/lib/server/subagent-runtime.ts +419 -0
- package/src/lib/server/subagent-swarm.test.ts +391 -0
- package/src/lib/server/subagent-swarm.ts +564 -0
- package/src/lib/server/system-events.ts +3 -3
- package/src/lib/server/task-followups.test.ts +491 -0
- package/src/lib/server/task-followups.ts +391 -0
- package/src/lib/server/task-lifecycle.test.ts +205 -0
- package/src/lib/server/task-lifecycle.ts +200 -0
- package/src/lib/server/task-quality-gate.test.ts +1 -1
- package/src/lib/server/task-resume.ts +208 -0
- package/src/lib/server/task-service.test.ts +108 -0
- package/src/lib/server/task-service.ts +264 -0
- package/src/lib/server/task-validation.test.ts +1 -1
- package/src/lib/server/test-utils/run-with-temp-data-dir.ts +42 -0
- package/src/lib/server/tool-capability-policy.test.ts +2 -2
- package/src/lib/server/tool-capability-policy.ts +3 -2
- package/src/lib/server/tool-planning.ts +2 -1
- package/src/lib/server/tool-retry.ts +2 -3
- package/src/lib/server/wake-dispatcher.test.ts +303 -0
- package/src/lib/server/wake-dispatcher.ts +318 -0
- package/src/lib/server/wake-mode.test.ts +161 -0
- package/src/lib/server/wake-mode.ts +174 -0
- package/src/lib/server/wallet-service.ts +8 -9
- package/src/lib/server/watch-jobs.ts +2 -1
- package/src/lib/server/workspace-context.ts +2 -2
- package/src/lib/shared-utils.test.ts +142 -0
- package/src/lib/shared-utils.ts +62 -0
- package/src/lib/tool-event-summary.ts +2 -1
- package/src/lib/view-routes.test.ts +100 -0
- package/src/lib/wallet.test.ts +322 -6
- package/src/proxy.test.ts +4 -4
- package/src/proxy.ts +2 -3
- package/src/stores/set-if-changed.ts +40 -0
- package/src/stores/slices/agent-slice.ts +111 -0
- package/src/stores/slices/auth-slice.ts +25 -0
- package/src/stores/slices/data-slice.ts +301 -0
- package/src/stores/slices/index.ts +7 -0
- package/src/stores/slices/session-slice.ts +112 -0
- package/src/stores/slices/task-slice.ts +63 -0
- package/src/stores/slices/ui-slice.ts +192 -0
- package/src/stores/use-app-store.ts +17 -822
- package/src/stores/use-approval-store.ts +2 -1
- package/src/stores/use-chat-store.ts +8 -1
- package/src/types/index.ts +10 -0
|
@@ -7,6 +7,7 @@ import type { Plugin, PluginHooks } from '@/types'
|
|
|
7
7
|
import { getPluginManager } from '../plugins'
|
|
8
8
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
9
9
|
import { canonicalizePluginId } from '../tool-aliases'
|
|
10
|
+
import { errorMessage, sleep } from '@/lib/shared-utils'
|
|
10
11
|
import {
|
|
11
12
|
appendDelegationCheckpoint,
|
|
12
13
|
cancelDelegationJob,
|
|
@@ -87,9 +88,6 @@ function _computeDelegationDepth(
|
|
|
87
88
|
return depth
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
function sleep(ms: number) {
|
|
91
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
92
|
-
}
|
|
93
91
|
|
|
94
92
|
function buildDelegateContextFromSessionish(session: unknown): DelegateContext {
|
|
95
93
|
const record = session && typeof session === 'object' ? session as Record<string, unknown> : {}
|
|
@@ -560,7 +558,7 @@ async function executeDelegateAction(args: Record<string, unknown>, bctx: Delega
|
|
|
560
558
|
return { backend, result }
|
|
561
559
|
})
|
|
562
560
|
.catch((err: unknown) => {
|
|
563
|
-
const message =
|
|
561
|
+
const message = errorMessage(err)
|
|
564
562
|
const latest = getDelegationJob(job.id)
|
|
565
563
|
if (latest?.status === 'cancelled') return { backend: requestedBackend, result: `Error: ${message}` }
|
|
566
564
|
appendDelegationCheckpoint(job.id, `Delegate crashed on ${requestedBackend}: ${message}`, 'failed')
|
|
@@ -697,7 +695,7 @@ async function runCodexDelegate(binary: string, task: string, resume: boolean, r
|
|
|
697
695
|
child.stdin?.end()
|
|
698
696
|
})
|
|
699
697
|
} catch (err: unknown) {
|
|
700
|
-
return `Error: ${
|
|
698
|
+
return `Error: ${errorMessage(err)}`
|
|
701
699
|
}
|
|
702
700
|
}
|
|
703
701
|
|
|
@@ -774,7 +772,7 @@ async function runOpenCodeDelegate(binary: string, task: string, resume: boolean
|
|
|
774
772
|
})
|
|
775
773
|
})
|
|
776
774
|
} catch (err: unknown) {
|
|
777
|
-
return `Error: ${
|
|
775
|
+
return `Error: ${errorMessage(err)}`
|
|
778
776
|
}
|
|
779
777
|
}
|
|
780
778
|
|
|
@@ -855,7 +853,7 @@ async function runGeminiDelegate(binary: string, task: string, resume: boolean,
|
|
|
855
853
|
})
|
|
856
854
|
})
|
|
857
855
|
} catch (err: unknown) {
|
|
858
|
-
return `Error: ${
|
|
856
|
+
return `Error: ${errorMessage(err)}`
|
|
859
857
|
}
|
|
860
858
|
}
|
|
861
859
|
|
|
@@ -913,7 +911,7 @@ async function runClaudeDelegate(binary: string, task: string, resume: boolean,
|
|
|
913
911
|
child.stdin?.write(task)
|
|
914
912
|
child.stdin?.end()
|
|
915
913
|
})
|
|
916
|
-
} catch (err: unknown) { return `Error: ${
|
|
914
|
+
} catch (err: unknown) { return `Error: ${errorMessage(err)}` }
|
|
917
915
|
}
|
|
918
916
|
|
|
919
917
|
/**
|
|
@@ -35,8 +35,8 @@ function runWithTempDataDir(script: string) {
|
|
|
35
35
|
describe('discovery approval flows', () => {
|
|
36
36
|
it('request_tool_access creates a real approval and grants the tool when auto-approved', () => {
|
|
37
37
|
const output = runWithTempDataDir(`
|
|
38
|
-
const storageMod = await import('./src/lib/server/storage
|
|
39
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
38
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
39
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
40
40
|
const storage = storageMod.default || storageMod
|
|
41
41
|
const toolsApi = toolsMod.default || toolsMod
|
|
42
42
|
|
|
@@ -84,8 +84,8 @@ describe('discovery approval flows', () => {
|
|
|
84
84
|
|
|
85
85
|
it('manage_capabilities request_access accepts query aliases for pluginId', () => {
|
|
86
86
|
const output = runWithTempDataDir(`
|
|
87
|
-
const storageMod = await import('./src/lib/server/storage
|
|
88
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
87
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
88
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
89
89
|
const storage = storageMod.default || storageMod
|
|
90
90
|
const toolsApi = toolsMod.default || toolsMod
|
|
91
91
|
|
|
@@ -130,8 +130,8 @@ describe('discovery approval flows', () => {
|
|
|
130
130
|
|
|
131
131
|
it('manage_capabilities request_access tells the agent to call already-available alias tools directly', () => {
|
|
132
132
|
const output = runWithTempDataDir(`
|
|
133
|
-
const storageMod = await import('./src/lib/server/storage
|
|
134
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
133
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
134
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
135
135
|
const storage = storageMod.default || storageMod
|
|
136
136
|
const toolsApi = toolsMod.default || toolsMod
|
|
137
137
|
|
|
@@ -170,8 +170,8 @@ describe('discovery approval flows', () => {
|
|
|
170
170
|
|
|
171
171
|
it('granting manage_schedules does not surface the manage_platform umbrella tool', () => {
|
|
172
172
|
const output = runWithTempDataDir(`
|
|
173
|
-
const storageMod = await import('./src/lib/server/storage
|
|
174
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
173
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
174
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
175
175
|
const storage = storageMod.default || storageMod
|
|
176
176
|
const toolsApi = toolsMod.default || toolsMod
|
|
177
177
|
|
|
@@ -210,8 +210,8 @@ describe('discovery approval flows', () => {
|
|
|
210
210
|
|
|
211
211
|
it('session-granted builtins disabled by default still appear in the next turn tool list', () => {
|
|
212
212
|
const output = runWithTempDataDir(`
|
|
213
|
-
const storageMod = await import('./src/lib/server/storage
|
|
214
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
213
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
214
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
215
215
|
const storage = storageMod.default || storageMod
|
|
216
216
|
const toolsApi = toolsMod.default || toolsMod
|
|
217
217
|
|
|
@@ -249,8 +249,8 @@ describe('discovery approval flows', () => {
|
|
|
249
249
|
|
|
250
250
|
it('discover reports session-granted builtin tools as available now', () => {
|
|
251
251
|
const output = runWithTempDataDir(`
|
|
252
|
-
const storageMod = await import('./src/lib/server/storage
|
|
253
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
252
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
253
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
254
254
|
const storage = storageMod.default || storageMod
|
|
255
255
|
const toolsApi = toolsMod.default || toolsMod
|
|
256
256
|
|
|
@@ -293,9 +293,9 @@ describe('discovery approval flows', () => {
|
|
|
293
293
|
|
|
294
294
|
it('hydrates agent-approved tools into stale connector sessions on the next turn', () => {
|
|
295
295
|
const output = runWithTempDataDir(`
|
|
296
|
-
const storageMod = await import('./src/lib/server/storage
|
|
297
|
-
const toolsMod = await import('./src/lib/server/session-tools/index
|
|
298
|
-
const approvalsMod = await import('./src/lib/server/approvals
|
|
296
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
297
|
+
const toolsMod = await import('./src/lib/server/session-tools/index')
|
|
298
|
+
const approvalsMod = await import('./src/lib/server/approvals')
|
|
299
299
|
const storage = storageMod.default || storageMod
|
|
300
300
|
const toolsApi = toolsMod.default || toolsMod
|
|
301
301
|
const approvals = approvalsMod.default || approvalsMod
|
|
@@ -8,6 +8,7 @@ import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
|
8
8
|
import { pluginIdMatches } from '../tool-aliases'
|
|
9
9
|
import { loadSessions } from '../storage'
|
|
10
10
|
import { inferPluginPublisherSourceFromUrl } from '@/lib/plugin-sources'
|
|
11
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
11
12
|
|
|
12
13
|
function trimString(value: unknown): string {
|
|
13
14
|
return typeof value === 'string' ? value.trim() : ''
|
|
@@ -91,7 +92,7 @@ async function executeDiscoveryAction(args: Record<string, unknown>, bctx?: Tool
|
|
|
91
92
|
})))
|
|
92
93
|
}
|
|
93
94
|
} catch (err: unknown) {
|
|
94
|
-
console.error('[discovery] ClawHub search failed:',
|
|
95
|
+
console.error('[discovery] ClawHub search failed:', errorMessage(err))
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
try {
|
|
@@ -123,7 +124,7 @@ async function executeDiscoveryAction(args: Record<string, unknown>, bctx?: Tool
|
|
|
123
124
|
}
|
|
124
125
|
results.push(...registryResults.values())
|
|
125
126
|
} catch (err: unknown) {
|
|
126
|
-
console.error('[discovery] SC Registry search failed:',
|
|
127
|
+
console.error('[discovery] SC Registry search failed:', errorMessage(err))
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
if (results.length === 0) {
|
|
@@ -214,7 +215,7 @@ async function executeDiscoveryAction(args: Record<string, unknown>, bctx?: Tool
|
|
|
214
215
|
return `Error: Unknown action "${action}"`
|
|
215
216
|
}
|
|
216
217
|
} catch (err: unknown) {
|
|
217
|
-
const msg =
|
|
218
|
+
const msg = errorMessage(err)
|
|
218
219
|
console.error('[discovery] executeDiscoveryAction failed:', msg)
|
|
219
220
|
return `Error: ${msg}`
|
|
220
221
|
}
|
|
@@ -9,6 +9,7 @@ import { extractDocumentArtifact } from '../document-utils'
|
|
|
9
9
|
import type { ToolBuildContext } from './context'
|
|
10
10
|
import { findBinaryOnPath, safePath } from './context'
|
|
11
11
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
12
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
12
13
|
|
|
13
14
|
function parseMetadataInput(value: unknown): Record<string, unknown> {
|
|
14
15
|
if (!value) return {}
|
|
@@ -219,7 +220,7 @@ async function executeDocumentAction(
|
|
|
219
220
|
|
|
220
221
|
return `Error: Unknown action "${action}".`
|
|
221
222
|
} catch (err: unknown) {
|
|
222
|
-
return `Error: ${
|
|
223
|
+
return `Error: ${errorMessage(err)}`
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
|
|
@@ -4,6 +4,7 @@ import type { Plugin, PluginHooks } from '@/types'
|
|
|
4
4
|
import { getPluginManager } from '../plugins'
|
|
5
5
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
6
6
|
import type { ToolBuildContext } from './context'
|
|
7
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
7
8
|
|
|
8
9
|
interface SmtpConfig {
|
|
9
10
|
host: string
|
|
@@ -186,7 +187,7 @@ async function executeEmail(args: Record<string, unknown>): Promise<string> {
|
|
|
186
187
|
const result = await sendSmtpEmail(cfg, recipients, subject, body, html)
|
|
187
188
|
return `${result}\nTo: ${recipients.join(', ')}\nSubject: ${subject}`
|
|
188
189
|
} catch (err: unknown) {
|
|
189
|
-
return `Error sending email: ${
|
|
190
|
+
return `Error sending email: ${errorMessage(err)}`
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
193
|
|
|
@@ -7,6 +7,7 @@ import { runStructuredExtraction } from '../structured-extract'
|
|
|
7
7
|
import type { ToolBuildContext } from './context'
|
|
8
8
|
import { safePath } from './context'
|
|
9
9
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
10
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
10
11
|
|
|
11
12
|
function resolveSessionForExtraction(bctx: ToolBuildContext) {
|
|
12
13
|
const session = bctx.resolveCurrentSession?.()
|
|
@@ -67,7 +68,7 @@ async function executeExtractAction(args: Record<string, unknown>, bctx: ToolBui
|
|
|
67
68
|
raw: normalized.includeRaw === true ? result.raw : undefined,
|
|
68
69
|
})
|
|
69
70
|
} catch (err: unknown) {
|
|
70
|
-
return `Error: ${
|
|
71
|
+
return `Error: ${errorMessage(err)}`
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -10,6 +10,7 @@ import { safePath, truncate, listDirRecursive, MAX_FILE } from './context'
|
|
|
10
10
|
import type { Plugin, PluginHooks } from '@/types'
|
|
11
11
|
import { getPluginManager } from '../plugins'
|
|
12
12
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
13
|
+
import { dedup, errorMessage } from '@/lib/shared-utils'
|
|
13
14
|
|
|
14
15
|
function pickNonEmptyString(...values: unknown[]): string | undefined {
|
|
15
16
|
for (const value of values) {
|
|
@@ -269,7 +270,7 @@ export async function executeFileAction(args: Record<string, unknown>, bctx: { c
|
|
|
269
270
|
return `Error: Unknown action "${action}"`
|
|
270
271
|
}
|
|
271
272
|
} catch (err: unknown) {
|
|
272
|
-
return `Error: ${
|
|
273
|
+
return `Error: ${errorMessage(err)}`
|
|
273
274
|
}
|
|
274
275
|
}
|
|
275
276
|
|
|
@@ -382,7 +383,7 @@ export function findRecentSendFileFallbackPaths(cwd: string, maxAgeMs = 10 * 60
|
|
|
382
383
|
const resolvedRoot = path.resolve(cwd)
|
|
383
384
|
const candidates: string[] = []
|
|
384
385
|
collectRecentFiles(resolvedRoot, resolvedRoot, maxAgeMs, candidates, 0)
|
|
385
|
-
return
|
|
386
|
+
return dedup(candidates)
|
|
386
387
|
}
|
|
387
388
|
|
|
388
389
|
export function resolveSendFileSourcePath(cwd: string, rawPath: string): string {
|
|
@@ -445,7 +446,7 @@ async function executeSendFile(args: Record<string, unknown>, bctx: { cwd: strin
|
|
|
445
446
|
if (errors.length === 0) return links.join('\n')
|
|
446
447
|
return `${links.join('\n')}\n\nSkipped: ${errors.join('; ')}`
|
|
447
448
|
} catch (err: unknown) {
|
|
448
|
-
return `Error: ${
|
|
449
|
+
return `Error: ${errorMessage(err)}`
|
|
449
450
|
}
|
|
450
451
|
}
|
|
451
452
|
|
|
@@ -6,6 +6,7 @@ import { withRetry } from '../tool-retry'
|
|
|
6
6
|
import type { Plugin, PluginHooks } from '@/types'
|
|
7
7
|
import { getPluginManager } from '../plugins'
|
|
8
8
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
9
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
9
10
|
|
|
10
11
|
interface HttpRequestArgs {
|
|
11
12
|
method: string
|
|
@@ -58,7 +59,7 @@ async function executeHttpAction(args: HttpRequestArgs) {
|
|
|
58
59
|
}
|
|
59
60
|
return JSON.stringify({ status: res.status, statusText: res.statusText, headers: resHeaders, body: resBody })
|
|
60
61
|
} catch (err: unknown) {
|
|
61
|
-
return JSON.stringify({ error:
|
|
62
|
+
return JSON.stringify({ error: errorMessage(err) })
|
|
62
63
|
}
|
|
63
64
|
}, requestArgs)
|
|
64
65
|
}
|
|
@@ -8,6 +8,7 @@ import { ackMailboxEnvelope, listMailbox, sendMailboxEnvelope } from '../session
|
|
|
8
8
|
import { loadApprovals } from '../storage'
|
|
9
9
|
import { requestApprovalMaybeAutoApprove } from '../approvals'
|
|
10
10
|
import { createWatchJob, getWatchJob } from '../watch-jobs'
|
|
11
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
11
12
|
|
|
12
13
|
async function executeHumanLoopAction(args: Record<string, unknown>, bctx: { sessionId?: string | null; agentId?: string | null }) {
|
|
13
14
|
const normalized = normalizeToolInputArgs(args)
|
|
@@ -166,7 +167,7 @@ async function executeHumanLoopAction(args: Record<string, unknown>, bctx: { ses
|
|
|
166
167
|
|
|
167
168
|
return `Error: Unknown action "${action}".`
|
|
168
169
|
} catch (err: unknown) {
|
|
169
|
-
return `Error: ${
|
|
170
|
+
return `Error: ${errorMessage(err)}`
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
173
|
|
|
@@ -7,6 +7,7 @@ import { getPluginManager } from '../plugins'
|
|
|
7
7
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
8
8
|
import { UPLOAD_DIR } from '../storage'
|
|
9
9
|
import type { ToolBuildContext } from './context'
|
|
10
|
+
import { errorMessage, sleep } from '@/lib/shared-utils'
|
|
10
11
|
|
|
11
12
|
type ImageProvider = 'openai' | 'stability' | 'replicate' | 'fal' | 'together' | 'fireworks' | 'bfl' | 'custom'
|
|
12
13
|
|
|
@@ -87,7 +88,7 @@ async function generateReplicate(prompt: string, size: string, cfg: PluginConfig
|
|
|
87
88
|
if (prediction.status !== 'succeeded' && prediction.status !== 'failed' && prediction.urls?.get) {
|
|
88
89
|
const deadline = Date.now() + 120_000
|
|
89
90
|
while (prediction.status !== 'succeeded' && prediction.status !== 'failed' && Date.now() < deadline) {
|
|
90
|
-
await
|
|
91
|
+
await sleep(2000)
|
|
91
92
|
const pollRes = await fetch(prediction.urls.get, {
|
|
92
93
|
headers: { Authorization: `Bearer ${cfg.apiKey}` },
|
|
93
94
|
signal: AbortSignal.timeout(10_000),
|
|
@@ -174,7 +175,7 @@ async function generateBFL(prompt: string, size: string, cfg: PluginConfig): Pro
|
|
|
174
175
|
// Poll for result
|
|
175
176
|
const deadline = Date.now() + 120_000
|
|
176
177
|
while (Date.now() < deadline) {
|
|
177
|
-
await
|
|
178
|
+
await sleep(2000)
|
|
178
179
|
const pollRes = await fetch(pollingUrl, {
|
|
179
180
|
headers: { 'x-key': cfg.apiKey },
|
|
180
181
|
signal: AbortSignal.timeout(10_000),
|
|
@@ -270,7 +271,7 @@ async function executeImageGen(args: Record<string, unknown>): Promise<string> {
|
|
|
270
271
|
const result = await generate(prompt, size, quality, cfg)
|
|
271
272
|
return saveImageResult(result, prompt, filename)
|
|
272
273
|
} catch (err: unknown) {
|
|
273
|
-
return `Error: ${
|
|
274
|
+
return `Error: ${errorMessage(err)}`
|
|
274
275
|
}
|
|
275
276
|
}
|
|
276
277
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { tool, type StructuredToolInterface } from '@langchain/core/tools'
|
|
3
3
|
import type { Session } from '@/types'
|
|
4
|
-
import {
|
|
4
|
+
import { dedup, errorMessage } from '@/lib/shared-utils'
|
|
5
|
+
import { loadApprovals, loadSettings, loadSession, loadMcpServers, patchSession } from '../storage'
|
|
5
6
|
import { loadRuntimeSettings } from '../runtime-settings'
|
|
6
7
|
import { log } from '../logger'
|
|
7
8
|
import { resolveSessionToolPolicy } from '../tool-capability-policy'
|
|
@@ -80,23 +81,20 @@ export async function buildSessionTools(cwd: string, enabledPlugins: string[], c
|
|
|
80
81
|
const cliProcessTimeoutMs = runtime.cliProcessTimeoutMs
|
|
81
82
|
const appSettings = loadSettings()
|
|
82
83
|
const grantedToolIds = approvedToolAccessIds(ctx)
|
|
83
|
-
const effectiveEnabledPlugins =
|
|
84
|
+
const effectiveEnabledPlugins = dedup([
|
|
84
85
|
...(Array.isArray(enabledPlugins) ? enabledPlugins : []),
|
|
85
86
|
...grantedToolIds,
|
|
86
|
-
])
|
|
87
|
+
])
|
|
87
88
|
if (ctx?.sessionId && grantedToolIds.length > 0) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (currentSession) {
|
|
89
|
+
patchSession(ctx.sessionId, (currentSession) => {
|
|
90
|
+
if (!currentSession) return currentSession
|
|
91
91
|
const currentPlugins = Array.isArray(currentSession.plugins) ? currentSession.plugins : []
|
|
92
|
-
const mergedPlugins =
|
|
93
|
-
if (mergedPlugins.length
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
}
|
|
92
|
+
const mergedPlugins = dedup([...currentPlugins, ...grantedToolIds])
|
|
93
|
+
if (mergedPlugins.length === currentPlugins.length) return currentSession
|
|
94
|
+
currentSession.plugins = mergedPlugins
|
|
95
|
+
currentSession.updatedAt = Date.now()
|
|
96
|
+
return currentSession
|
|
97
|
+
})
|
|
100
98
|
}
|
|
101
99
|
const toolPolicy = resolveSessionToolPolicy(effectiveEnabledPlugins, appSettings)
|
|
102
100
|
const expandedEnabled = expandPluginIds(toolPolicy.enabledPlugins)
|
|
@@ -124,8 +122,7 @@ export async function buildSessionTools(cwd: string, enabledPlugins: string[], c
|
|
|
124
122
|
|
|
125
123
|
const resolveCurrentSession = (): Session | null => {
|
|
126
124
|
if (!ctx?.sessionId) return null
|
|
127
|
-
|
|
128
|
-
return sessions[ctx.sessionId] || null
|
|
125
|
+
return loadSession(ctx.sessionId)
|
|
129
126
|
}
|
|
130
127
|
|
|
131
128
|
const readStoredDelegateResumeId = (key: 'claudeCode' | 'codex' | 'opencode' | 'gemini'): string | null => {
|
|
@@ -138,19 +135,18 @@ export async function buildSessionTools(cwd: string, enabledPlugins: string[], c
|
|
|
138
135
|
const persistDelegateResumeId = (key: 'claudeCode' | 'codex' | 'opencode' | 'gemini', resumeId: string | null | undefined): void => {
|
|
139
136
|
const normalized = typeof resumeId === 'string' ? resumeId.trim() : ''
|
|
140
137
|
if (!normalized || !ctx?.sessionId) return
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
saveSessions(sessions)
|
|
138
|
+
patchSession(ctx.sessionId, (target) => {
|
|
139
|
+
if (!target) return target
|
|
140
|
+
const current = (target.delegateResumeIds && typeof target.delegateResumeIds === 'object')
|
|
141
|
+
? target.delegateResumeIds
|
|
142
|
+
: {}
|
|
143
|
+
target.delegateResumeIds = {
|
|
144
|
+
...current,
|
|
145
|
+
[key]: normalized,
|
|
146
|
+
}
|
|
147
|
+
target.updatedAt = Date.now()
|
|
148
|
+
return target
|
|
149
|
+
})
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
const bctx: ToolBuildContext = {
|
|
@@ -266,7 +262,7 @@ export async function buildSessionTools(cwd: string, enabledPlugins: string[], c
|
|
|
266
262
|
)
|
|
267
263
|
}
|
|
268
264
|
} catch (err: unknown) {
|
|
269
|
-
log.error('session-tools', 'Failed to load plugin tools', { error:
|
|
265
|
+
log.error('session-tools', 'Failed to load plugin tools', { error: errorMessage(err) })
|
|
270
266
|
}
|
|
271
267
|
|
|
272
268
|
// 3. MCP server tools
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
replyMailboxMessage,
|
|
13
13
|
} from '../mailbox-utils'
|
|
14
14
|
import { createWatchJob } from '../watch-jobs'
|
|
15
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
15
16
|
|
|
16
17
|
function parseMessageUid(value: unknown): number {
|
|
17
18
|
const parsed = typeof value === 'number' ? value : typeof value === 'string' ? Number.parseInt(value, 10) : Number.NaN
|
|
@@ -191,7 +192,7 @@ async function executeMailboxAction(args: Record<string, unknown>, bctx: { cwd:
|
|
|
191
192
|
|
|
192
193
|
return `Error: Unknown action "${action}".`
|
|
193
194
|
} catch (err: unknown) {
|
|
194
|
-
return `Error: ${
|
|
195
|
+
return `Error: ${errorMessage(err)}`
|
|
195
196
|
}
|
|
196
197
|
}
|
|
197
198
|
|
|
@@ -35,8 +35,8 @@ function runWithTempDataDir(script: string) {
|
|
|
35
35
|
describe('manage_connectors tool', () => {
|
|
36
36
|
it('drops transient outbound-send args on create', () => {
|
|
37
37
|
const output = runWithTempDataDir(`
|
|
38
|
-
const storageMod = await import('./src/lib/server/storage
|
|
39
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
38
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
39
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
40
40
|
const storage = storageMod.default || storageMod
|
|
41
41
|
const crud = crudMod.default || crudMod
|
|
42
42
|
|
|
@@ -84,8 +84,8 @@ describe('manage_connectors tool', () => {
|
|
|
84
84
|
|
|
85
85
|
it('ignores send-like update payloads instead of mutating connector routing state', () => {
|
|
86
86
|
const output = runWithTempDataDir(`
|
|
87
|
-
const storageMod = await import('./src/lib/server/storage
|
|
88
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
87
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
88
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
89
89
|
const storage = storageMod.default || storageMod
|
|
90
90
|
const crud = crudMod.default || crudMod
|
|
91
91
|
|
|
@@ -37,8 +37,8 @@ describe('manage_schedules tool', () => {
|
|
|
37
37
|
const output = runWithTempDataDir(`
|
|
38
38
|
import fs from 'node:fs'
|
|
39
39
|
import path from 'node:path'
|
|
40
|
-
const storageMod = await import('./src/lib/server/storage
|
|
41
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
40
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
41
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
42
42
|
const storage = storageMod.default || storageMod
|
|
43
43
|
const crud = crudMod.default || crudMod
|
|
44
44
|
|
|
@@ -93,8 +93,8 @@ describe('manage_schedules tool', () => {
|
|
|
93
93
|
|
|
94
94
|
it('stores the current connector recipient on new schedules created from a connector session', () => {
|
|
95
95
|
const output = runWithTempDataDir(`
|
|
96
|
-
const storageMod = await import('./src/lib/server/storage
|
|
97
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
96
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
97
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
98
98
|
const storage = storageMod.default || storageMod
|
|
99
99
|
const crud = crudMod.default || crudMod
|
|
100
100
|
|
|
@@ -170,8 +170,8 @@ describe('manage_schedules tool', () => {
|
|
|
170
170
|
|
|
171
171
|
it('rejects schedules whose referenced script path does not exist', () => {
|
|
172
172
|
const output = runWithTempDataDir(`
|
|
173
|
-
const storageMod = await import('./src/lib/server/storage
|
|
174
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
173
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
174
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
175
175
|
const storage = storageMod.default || storageMod
|
|
176
176
|
const crud = crudMod.default || crudMod
|
|
177
177
|
|
|
@@ -214,8 +214,8 @@ describe('manage_schedules tool', () => {
|
|
|
214
214
|
|
|
215
215
|
it('reuses a same-session recurring reminder instead of creating a near-duplicate', () => {
|
|
216
216
|
const output = runWithTempDataDir(`
|
|
217
|
-
const storageMod = await import('./src/lib/server/storage
|
|
218
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
217
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
218
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
219
219
|
const storage = storageMod.default || storageMod
|
|
220
220
|
const crud = crudMod.default || crudMod
|
|
221
221
|
|
|
@@ -274,8 +274,8 @@ describe('manage_schedules tool', () => {
|
|
|
274
274
|
|
|
275
275
|
it('pauses matching duplicate schedules together when an agent stops a reminder', () => {
|
|
276
276
|
const output = runWithTempDataDir(`
|
|
277
|
-
const storageMod = await import('./src/lib/server/storage
|
|
278
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
277
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
278
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
279
279
|
const storage = storageMod.default || storageMod
|
|
280
280
|
const crud = crudMod.default || crudMod
|
|
281
281
|
|
|
@@ -348,8 +348,8 @@ describe('manage_schedules tool', () => {
|
|
|
348
348
|
|
|
349
349
|
it('deletes matching duplicate schedules together when an agent removes a reminder cluster', () => {
|
|
350
350
|
const output = runWithTempDataDir(`
|
|
351
|
-
const storageMod = await import('./src/lib/server/storage
|
|
352
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
351
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
352
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
353
353
|
const storage = storageMod.default || storageMod
|
|
354
354
|
const crud = crudMod.default || crudMod
|
|
355
355
|
|
|
@@ -35,8 +35,8 @@ function runWithTempDataDir(script: string) {
|
|
|
35
35
|
|
|
36
36
|
/** Helper: seed agents + return manage_tasks / manage_projects tool invocation boilerplate. */
|
|
37
37
|
const AGENT_SETUP = `
|
|
38
|
-
const storageMod = await import('./src/lib/server/storage
|
|
39
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
38
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
39
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
40
40
|
const storage = storageMod.default || storageMod
|
|
41
41
|
const crud = crudMod.default || crudMod
|
|
42
42
|
|
|
@@ -76,7 +76,7 @@ const AGENT_SETUP = `
|
|
|
76
76
|
|
|
77
77
|
/** Helper to import dequeueNextRunnableTask (CJS-compatible). */
|
|
78
78
|
const QUEUE_IMPORT = `
|
|
79
|
-
const _queueMod = await import('./src/lib/server/queue
|
|
79
|
+
const _queueMod = await import('./src/lib/server/queue')
|
|
80
80
|
const _queue = _queueMod.default || _queueMod
|
|
81
81
|
const dequeueNextRunnableTask = _queue.dequeueNextRunnableTask
|
|
82
82
|
`
|
|
@@ -782,8 +782,8 @@ describe('manage_tasks: fingerprint dedup', () => {
|
|
|
782
782
|
|
|
783
783
|
it('29. different agents → not duplicates', () => {
|
|
784
784
|
const output = runWithTempDataDir(`
|
|
785
|
-
const storageMod = await import('./src/lib/server/storage
|
|
786
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
785
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
786
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
787
787
|
const storage = storageMod.default || storageMod
|
|
788
788
|
const crud = crudMod.default || crudMod
|
|
789
789
|
|
|
@@ -37,8 +37,8 @@ describe('manage_tasks tool', () => {
|
|
|
37
37
|
const output = runWithTempDataDir(`
|
|
38
38
|
import fs from 'node:fs'
|
|
39
39
|
import path from 'node:path'
|
|
40
|
-
const storageMod = await import('./src/lib/server/storage
|
|
41
|
-
const crudMod = await import('./src/lib/server/session-tools/crud
|
|
40
|
+
const storageMod = await import('./src/lib/server/storage')
|
|
41
|
+
const crudMod = await import('./src/lib/server/session-tools/crud')
|
|
42
42
|
const storage = storageMod.default || storageMod
|
|
43
43
|
const crud = crudMod.default || crudMod
|
|
44
44
|
|
|
@@ -9,6 +9,7 @@ import { safePath, truncate } from './context'
|
|
|
9
9
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
10
10
|
import { cancelWatchJob, createWatchJob, getWatchJob, listWatchJobs } from '../watch-jobs'
|
|
11
11
|
import { ensureSessionBrowserProfileId, loadBrowserSessionRecord } from '../browser-state'
|
|
12
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
12
13
|
|
|
13
14
|
type WatchKind = 'time' | 'http' | 'file' | 'task' | 'webhook' | 'page'
|
|
14
15
|
|
|
@@ -89,7 +90,7 @@ async function createDurableWatch(
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
function getErrorMessage(err: unknown): string {
|
|
92
|
-
return
|
|
93
|
+
return errorMessage(err)
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
/**
|
|
@@ -9,6 +9,7 @@ import { loadSettings } from '../storage'
|
|
|
9
9
|
import { resolveSessionToolPolicy } from '../tool-capability-policy'
|
|
10
10
|
import { loadRuntimeSettings } from '../runtime-settings'
|
|
11
11
|
import { expandPluginIds } from '../tool-aliases'
|
|
12
|
+
import { dedup } from '@/lib/shared-utils'
|
|
12
13
|
|
|
13
14
|
function parsePlatformData(value: unknown): Record<string, unknown> | null {
|
|
14
15
|
if (!value) return null
|
|
@@ -146,7 +147,7 @@ export function normalizePlatformActionArgs(rawArgs: Record<string, unknown>): R
|
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
function uniqueStrings(values: Array<string | undefined>): string[] {
|
|
149
|
-
return
|
|
150
|
+
return dedup(values.filter((value): value is string => Boolean(value)))
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
function resolvePlatformResourceAccess(toolId: string, bctx: ToolBuildContext): { allowed: boolean; reason: string | null } {
|
|
@@ -7,6 +7,7 @@ import type { ToolBuildContext } from './context'
|
|
|
7
7
|
import type { ApprovalRequest, Plugin, PluginHooks } from '@/types'
|
|
8
8
|
import { getPluginManager } from '../plugins'
|
|
9
9
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
10
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
10
11
|
|
|
11
12
|
const PLUGINS_DIR = path.join(DATA_DIR, 'plugins')
|
|
12
13
|
|
|
@@ -236,7 +237,7 @@ Key rules:
|
|
|
236
237
|
|
|
237
238
|
return `Unknown action "${action}". Valid actions: get_spec, scaffold, read, edit, delete, install_dependencies`
|
|
238
239
|
} catch (err: unknown) {
|
|
239
|
-
return `Error: ${
|
|
240
|
+
return `Error: ${errorMessage(err)}`
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
|