@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { genId } from '@/lib/id'
|
|
2
2
|
import type { SSEEvent } from '@/types'
|
|
3
|
-
import { active,
|
|
3
|
+
import { active, loadSession } from './storage'
|
|
4
4
|
import { executeSessionChatTurn, type ExecuteChatTurnResult } from './chat-execution'
|
|
5
5
|
import { loadRuntimeSettings } from './runtime-settings'
|
|
6
6
|
import { log } from './logger'
|
|
@@ -8,6 +8,7 @@ import { isInternalHeartbeatRun } from './heartbeat-source'
|
|
|
8
8
|
import { cleanupSessionBrowser } from './session-tools/web'
|
|
9
9
|
import { cancelDelegationJobsForParentSession } from './delegation-jobs'
|
|
10
10
|
import { handleMainLoopRunResult } from './main-agent-loop'
|
|
11
|
+
import { errorMessage, hmrSingleton } from '@/lib/shared-utils'
|
|
11
12
|
|
|
12
13
|
export type SessionRunStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'
|
|
13
14
|
export type SessionQueueMode = 'followup' | 'steer' | 'collect'
|
|
@@ -39,7 +40,13 @@ interface QueueEntry {
|
|
|
39
40
|
signalController: AbortController
|
|
40
41
|
maxRuntimeMs?: number
|
|
41
42
|
modelOverride?: string
|
|
42
|
-
heartbeatConfig?: {
|
|
43
|
+
heartbeatConfig?: {
|
|
44
|
+
ackMaxChars: number
|
|
45
|
+
showOk: boolean
|
|
46
|
+
showAlerts: boolean
|
|
47
|
+
target: string | null
|
|
48
|
+
deliveryMode?: 'default' | 'tool_only'
|
|
49
|
+
}
|
|
43
50
|
replyToId?: string
|
|
44
51
|
resolve: (value: ExecuteChatTurnResult) => void
|
|
45
52
|
reject: (error: Error) => void
|
|
@@ -56,14 +63,13 @@ interface RuntimeState {
|
|
|
56
63
|
|
|
57
64
|
const MAX_RECENT_RUNS = 500
|
|
58
65
|
const COLLECT_COALESCE_WINDOW_MS = 1500
|
|
59
|
-
const
|
|
60
|
-
const state: RuntimeState = (globalThis as any)[globalKey] ?? ((globalThis as any)[globalKey] = {
|
|
66
|
+
const state: RuntimeState = hmrSingleton<RuntimeState>('__swarmclaw_session_run_manager__', () => ({
|
|
61
67
|
runningByExecution: new Map<string, QueueEntry>(),
|
|
62
68
|
queueByExecution: new Map<string, QueueEntry[]>(),
|
|
63
69
|
runs: new Map<string, SessionRunRecord>(),
|
|
64
70
|
recentRunIds: [],
|
|
65
71
|
promises: new Map<string, Promise<ExecuteChatTurnResult>>(),
|
|
66
|
-
})
|
|
72
|
+
}))
|
|
67
73
|
|
|
68
74
|
function now() {
|
|
69
75
|
return Date.now()
|
|
@@ -305,17 +311,17 @@ async function drainExecution(executionKey: string): Promise<void> {
|
|
|
305
311
|
})
|
|
306
312
|
} catch (err: unknown) {
|
|
307
313
|
log.warn('session-run', `Main loop follow-up enqueue failed for ${next.run.sessionId}`, {
|
|
308
|
-
error:
|
|
314
|
+
error: errorMessage(err),
|
|
309
315
|
})
|
|
310
316
|
}
|
|
311
317
|
}, Math.max(0, followup.delayMs || 0))
|
|
312
318
|
}
|
|
313
319
|
next.resolve(result)
|
|
314
|
-
} catch (err:
|
|
320
|
+
} catch (err: unknown) {
|
|
315
321
|
const aborted = next.signalController.signal.aborted
|
|
316
322
|
next.run.status = aborted ? 'cancelled' : 'failed'
|
|
317
323
|
next.run.endedAt = now()
|
|
318
|
-
next.run.error =
|
|
324
|
+
next.run.error = errorMessage(err)
|
|
319
325
|
emitRunMeta(next, next.run.status, { error: next.run.error })
|
|
320
326
|
log.error('session-run', `Run failed ${next.run.id}`, {
|
|
321
327
|
sessionId: next.run.sessionId,
|
|
@@ -353,7 +359,13 @@ export interface EnqueueSessionRunInput {
|
|
|
353
359
|
dedupeKey?: string
|
|
354
360
|
maxRuntimeMs?: number
|
|
355
361
|
modelOverride?: string
|
|
356
|
-
heartbeatConfig?: {
|
|
362
|
+
heartbeatConfig?: {
|
|
363
|
+
ackMaxChars: number
|
|
364
|
+
showOk: boolean
|
|
365
|
+
showAlerts: boolean
|
|
366
|
+
target: string | null
|
|
367
|
+
deliveryMode?: 'default' | 'tool_only'
|
|
368
|
+
}
|
|
357
369
|
replyToId?: string
|
|
358
370
|
/** External abort signal (e.g. from the HTTP request) — chained to the run's internal AbortController */
|
|
359
371
|
callerSignal?: AbortSignal
|
|
@@ -367,9 +379,15 @@ export interface EnqueueSessionRunResult {
|
|
|
367
379
|
promise: Promise<ExecuteChatTurnResult>
|
|
368
380
|
/** Abort the run's internal AbortController (cancels the LLM stream). */
|
|
369
381
|
abort: () => void
|
|
382
|
+
/** Remove this caller's onEvent listener from the run (call on client disconnect). */
|
|
383
|
+
unsubscribe: () => void
|
|
370
384
|
}
|
|
371
385
|
|
|
372
386
|
const LONG_TOOL_NAMES: ReadonlySet<string> = new Set(['claude_code', 'codex_cli', 'opencode_cli'])
|
|
387
|
+
type SessionToolConfig = {
|
|
388
|
+
plugins?: string[] | null
|
|
389
|
+
tools?: string[] | null
|
|
390
|
+
}
|
|
373
391
|
|
|
374
392
|
function computeEffectiveRunTimeoutMs(
|
|
375
393
|
baseTimeoutMs: number,
|
|
@@ -389,9 +407,12 @@ export function enqueueSessionRun(input: EnqueueSessionRunInput): EnqueueSession
|
|
|
389
407
|
const executionKey = executionKeyForSession(input.sessionId)
|
|
390
408
|
const runtime = loadRuntimeSettings()
|
|
391
409
|
const defaultMaxRuntimeMs = runtime.ongoingLoopMaxRuntimeMs ?? (10 * 60_000)
|
|
392
|
-
const
|
|
393
|
-
const
|
|
394
|
-
|
|
410
|
+
const sessionData = loadSession(input.sessionId) as SessionToolConfig | null
|
|
411
|
+
const sessionTools = Array.isArray(sessionData?.plugins)
|
|
412
|
+
? sessionData.plugins
|
|
413
|
+
: Array.isArray(sessionData?.tools)
|
|
414
|
+
? sessionData.tools
|
|
415
|
+
: []
|
|
395
416
|
const adjustedDefaultMs = computeEffectiveRunTimeoutMs(defaultMaxRuntimeMs, sessionTools, runtime)
|
|
396
417
|
const effectiveMaxRuntimeMs = typeof input.maxRuntimeMs === 'number'
|
|
397
418
|
? input.maxRuntimeMs
|
|
@@ -399,7 +420,8 @@ export function enqueueSessionRun(input: EnqueueSessionRunInput): EnqueueSession
|
|
|
399
420
|
|
|
400
421
|
const dedupe = findDedupeMatch(input.sessionId, input.dedupeKey)
|
|
401
422
|
if (dedupe) {
|
|
402
|
-
|
|
423
|
+
const cb = input.onEvent
|
|
424
|
+
if (cb) dedupe.onEvents.push(cb)
|
|
403
425
|
if (input.callerSignal) chainCallerSignal(input.callerSignal, dedupe.signalController)
|
|
404
426
|
return {
|
|
405
427
|
runId: dedupe.run.id,
|
|
@@ -407,6 +429,11 @@ export function enqueueSessionRun(input: EnqueueSessionRunInput): EnqueueSession
|
|
|
407
429
|
deduped: true,
|
|
408
430
|
promise: dedupe.promise,
|
|
409
431
|
abort: () => dedupe.signalController.abort(),
|
|
432
|
+
unsubscribe: () => {
|
|
433
|
+
if (!cb) return
|
|
434
|
+
const idx = dedupe.onEvents.indexOf(cb)
|
|
435
|
+
if (idx >= 0) dedupe.onEvents.splice(idx, 1)
|
|
436
|
+
},
|
|
410
437
|
}
|
|
411
438
|
}
|
|
412
439
|
|
|
@@ -455,7 +482,8 @@ export function enqueueSessionRun(input: EnqueueSessionRunInput): EnqueueSession
|
|
|
455
482
|
candidate.run.messagePreview = messagePreview(candidate.message)
|
|
456
483
|
candidate.run.queuedAt = nowMs
|
|
457
484
|
}
|
|
458
|
-
|
|
485
|
+
const coalesceCb = input.onEvent
|
|
486
|
+
if (coalesceCb) candidate.onEvents.push(coalesceCb)
|
|
459
487
|
if (input.callerSignal) chainCallerSignal(input.callerSignal, candidate.signalController)
|
|
460
488
|
emitRunMeta(candidate, 'queued', { position: 0, coalesced: true, mergedIntoRunId: candidate.run.id })
|
|
461
489
|
return {
|
|
@@ -464,6 +492,11 @@ export function enqueueSessionRun(input: EnqueueSessionRunInput): EnqueueSession
|
|
|
464
492
|
coalesced: true,
|
|
465
493
|
promise: candidate.promise,
|
|
466
494
|
abort: () => candidate.signalController.abort(),
|
|
495
|
+
unsubscribe: () => {
|
|
496
|
+
if (!coalesceCb) return
|
|
497
|
+
const idx = candidate.onEvents.indexOf(coalesceCb)
|
|
498
|
+
if (idx >= 0) candidate.onEvents.splice(idx, 1)
|
|
499
|
+
},
|
|
467
500
|
}
|
|
468
501
|
}
|
|
469
502
|
}
|
|
@@ -515,7 +548,18 @@ export function enqueueSessionRun(input: EnqueueSessionRunInput): EnqueueSession
|
|
|
515
548
|
emitRunMeta(entry, 'queued', { position })
|
|
516
549
|
void drainExecution(executionKey)
|
|
517
550
|
|
|
518
|
-
|
|
551
|
+
const entryCb = input.onEvent
|
|
552
|
+
return {
|
|
553
|
+
runId,
|
|
554
|
+
position,
|
|
555
|
+
promise,
|
|
556
|
+
abort: () => entry.signalController.abort(),
|
|
557
|
+
unsubscribe: () => {
|
|
558
|
+
if (!entryCb) return
|
|
559
|
+
const idx = entry.onEvents.indexOf(entryCb)
|
|
560
|
+
if (idx >= 0) entry.onEvents.splice(idx, 1)
|
|
561
|
+
},
|
|
562
|
+
}
|
|
519
563
|
}
|
|
520
564
|
|
|
521
565
|
export function getSessionRunState(sessionId: string): {
|
|
@@ -16,29 +16,29 @@ function readServerSource(fileName: string): string {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
describe('browser workflow surface', () => {
|
|
19
|
-
it('advertises the higher-level browser actions in web
|
|
20
|
-
const src = readToolSource('web
|
|
19
|
+
it('advertises the higher-level browser actions in web', () => {
|
|
20
|
+
const src = readToolSource('web')
|
|
21
21
|
for (const action of ['read_page', 'extract_links', 'extract_form_fields', 'extract_table', 'fill_form', 'submit_form', 'scroll_until', 'download_file', 'complete_web_task']) {
|
|
22
22
|
assert.equal(src.includes(`'${action}'`), true, `web.ts should expose ${action}`)
|
|
23
23
|
}
|
|
24
24
|
})
|
|
25
25
|
|
|
26
26
|
it('supports the shorthand form-map path for fill_form', () => {
|
|
27
|
-
const src = readToolSource('web
|
|
27
|
+
const src = readToolSource('web')
|
|
28
28
|
assert.equal(src.includes('params.form'), true)
|
|
29
29
|
assert.equal(src.includes('fields is required for fill_form.'), true)
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
it('flags pages that require human-provided input', () => {
|
|
33
|
-
const src = readToolSource('web
|
|
33
|
+
const src = readToolSource('web')
|
|
34
34
|
assert.equal(src.includes("type: 'human_input_required'"), true)
|
|
35
35
|
assert.equal(src.includes('Ask the human instead of guessing'), true)
|
|
36
36
|
})
|
|
37
37
|
})
|
|
38
38
|
|
|
39
39
|
describe('durable wait surface', () => {
|
|
40
|
-
it('advertises the durable wait actions in monitor
|
|
41
|
-
const src = readToolSource('monitor
|
|
40
|
+
it('advertises the durable wait actions in monitor', () => {
|
|
41
|
+
const src = readToolSource('monitor')
|
|
42
42
|
for (const action of ['wait_until', 'wait_for_http', 'wait_for_file', 'wait_for_task', 'wait_for_webhook', 'wait_for_page_change']) {
|
|
43
43
|
assert.equal(src.includes(`'${action}'`), true, `monitor.ts should expose ${action}`)
|
|
44
44
|
}
|
|
@@ -46,7 +46,7 @@ describe('durable wait surface', () => {
|
|
|
46
46
|
})
|
|
47
47
|
|
|
48
48
|
it('routes schedule_wake through durable watch storage', () => {
|
|
49
|
-
const src = readToolSource('schedule
|
|
49
|
+
const src = readToolSource('schedule')
|
|
50
50
|
assert.equal(src.includes('createWatchJob'), true)
|
|
51
51
|
assert.equal(src.includes("type: 'time'"), true)
|
|
52
52
|
})
|
|
@@ -54,7 +54,7 @@ describe('durable wait surface', () => {
|
|
|
54
54
|
|
|
55
55
|
describe('sandbox surface', () => {
|
|
56
56
|
it('advertises a Deno-only sandbox and steers simple APIs to http_request', () => {
|
|
57
|
-
const src = readToolSource('sandbox
|
|
57
|
+
const src = readToolSource('sandbox')
|
|
58
58
|
assert.equal(src.includes("enum: ['javascript', 'typescript']"), true)
|
|
59
59
|
assert.equal(src.includes('http_request'), true)
|
|
60
60
|
assert.equal(src.includes('plugin_creator'), true)
|
|
@@ -65,7 +65,7 @@ describe('sandbox surface', () => {
|
|
|
65
65
|
|
|
66
66
|
describe('delegation job handles', () => {
|
|
67
67
|
it('exposes subagent control actions', () => {
|
|
68
|
-
const src = readToolSource('subagent
|
|
68
|
+
const src = readToolSource('subagent')
|
|
69
69
|
for (const action of ['status', 'list', 'wait', 'cancel']) {
|
|
70
70
|
assert.equal(src.includes(`action === '${action}'`), true, `subagent.ts should handle ${action}`)
|
|
71
71
|
}
|
|
@@ -73,15 +73,15 @@ describe('delegation job handles', () => {
|
|
|
73
73
|
})
|
|
74
74
|
|
|
75
75
|
it('builds delegate context from the invoking session and uses job records', () => {
|
|
76
|
-
const src = readToolSource('delegate
|
|
76
|
+
const src = readToolSource('delegate')
|
|
77
77
|
assert.equal(src.includes('buildDelegateContextFromSessionish'), true)
|
|
78
78
|
assert.equal(src.includes('createDelegationJob'), true)
|
|
79
79
|
assert.equal(src.includes('waitForDelegateJob'), true)
|
|
80
80
|
})
|
|
81
81
|
|
|
82
82
|
it('scheduler and daemon recover the durable autonomy jobs', () => {
|
|
83
|
-
const schedulerSrc = readServerSource('scheduler
|
|
84
|
-
const daemonSrc = readServerSource('daemon-state
|
|
83
|
+
const schedulerSrc = readServerSource('scheduler')
|
|
84
|
+
const daemonSrc = readServerSource('daemon-state')
|
|
85
85
|
assert.equal(schedulerSrc.includes('processDueWatchJobs'), true)
|
|
86
86
|
assert.equal(daemonSrc.includes('recoverStaleDelegationJobs'), true)
|
|
87
87
|
})
|
|
@@ -89,8 +89,8 @@ describe('delegation job handles', () => {
|
|
|
89
89
|
|
|
90
90
|
describe('primitive plugin surfaces', () => {
|
|
91
91
|
it('advertises mailbox and human-loop actions', () => {
|
|
92
|
-
const mailboxSrc = readToolSource('mailbox
|
|
93
|
-
const humanSrc = readToolSource('human-loop
|
|
92
|
+
const mailboxSrc = readToolSource('mailbox')
|
|
93
|
+
const humanSrc = readToolSource('human-loop')
|
|
94
94
|
for (const action of ['list_messages', 'list_threads', 'search_messages', 'read_message', 'download_attachment', 'reply', 'wait_for_email']) {
|
|
95
95
|
assert.equal(mailboxSrc.includes(`'${action}'`), true, `mailbox.ts should expose ${action}`)
|
|
96
96
|
}
|
|
@@ -100,10 +100,10 @@ describe('primitive plugin surfaces', () => {
|
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
it('advertises document, extract, table, and crawl actions', () => {
|
|
103
|
-
const documentSrc = readToolSource('document
|
|
104
|
-
const extractSrc = readToolSource('extract
|
|
105
|
-
const tableSrc = readToolSource('table
|
|
106
|
-
const crawlSrc = readToolSource('crawl
|
|
103
|
+
const documentSrc = readToolSource('document')
|
|
104
|
+
const extractSrc = readToolSource('extract')
|
|
105
|
+
const tableSrc = readToolSource('table')
|
|
106
|
+
const crawlSrc = readToolSource('crawl')
|
|
107
107
|
|
|
108
108
|
for (const action of ['read', 'metadata', 'ocr', 'extract_tables', 'store', 'list', 'search', 'get', 'delete']) {
|
|
109
109
|
assert.equal(documentSrc.includes(`'${action}'`), true, `document.ts should expose ${action}`)
|
|
@@ -119,8 +119,8 @@ describe('primitive plugin surfaces', () => {
|
|
|
119
119
|
}
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
-
it('registers the primitive plugins in builtin-plugins
|
|
123
|
-
const src = readServerSource('builtin-plugins
|
|
122
|
+
it('registers the primitive plugins in builtin-plugins', () => {
|
|
123
|
+
const src = readServerSource('builtin-plugins')
|
|
124
124
|
for (const moduleName of ['mailbox', 'human-loop', 'document', 'extract', 'table', 'crawl']) {
|
|
125
125
|
assert.equal(src.includes(`session-tools/${moduleName}`), true, `builtin-plugins.ts should import ${moduleName}`)
|
|
126
126
|
}
|
|
@@ -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
|
type CalendarProvider = 'google' | 'outlook'
|
|
9
10
|
|
|
@@ -249,7 +250,7 @@ async function executeCalendar(args: Record<string, unknown>): Promise<string> {
|
|
|
249
250
|
return `Error: Unknown action "${action}". Use: list, create, update, delete, status.`
|
|
250
251
|
}
|
|
251
252
|
} catch (err: unknown) {
|
|
252
|
-
return `Error: ${
|
|
253
|
+
return `Error: ${errorMessage(err)}`
|
|
253
254
|
}
|
|
254
255
|
}
|
|
255
256
|
|
|
@@ -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 { normalizeCanvasContent, summarizeCanvasContent } from '@/lib/canvas-content'
|
|
10
|
+
import { errorMessage } from '@/lib/shared-utils'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Core Canvas Execution Logic
|
|
@@ -55,7 +56,7 @@ async function executeCanvasAction(args: Record<string, unknown>, context: { ses
|
|
|
55
56
|
|
|
56
57
|
return `Unknown canvas action "${action}".`
|
|
57
58
|
} catch (err: unknown) {
|
|
58
|
-
return `Error: ${
|
|
59
|
+
return `Error: ${errorMessage(err)}`
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -7,6 +7,7 @@ import type { ToolBuildContext } from './context'
|
|
|
7
7
|
import type { Chatroom, 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
|
/**
|
|
12
13
|
* Core Chatroom Execution Logic
|
|
@@ -97,7 +98,7 @@ async function executeChatroomAction(args: Record<string, unknown>, context: { a
|
|
|
97
98
|
|
|
98
99
|
return `Unknown action "${action}".`
|
|
99
100
|
} catch (err: unknown) {
|
|
100
|
-
return `Error: ${
|
|
101
|
+
return `Error: ${errorMessage(err)}`
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -10,6 +10,9 @@ import type { ToolBuildContext } 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 { safeJsonParseObject } from '../json-utils'
|
|
14
|
+
import { tryResolvePathWithinBaseDir } from '../path-utils'
|
|
15
|
+
import { dedup, errorMessage } from '@/lib/shared-utils'
|
|
13
16
|
|
|
14
17
|
const CONNECTOR_ACTION_DEDUPE_TTL_MS = 30_000
|
|
15
18
|
const CONNECTOR_TURN_SEND_TTL_MS = 180_000
|
|
@@ -157,29 +160,24 @@ function buildConnectorActionKey(parts: Array<string | number | boolean | null |
|
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
function normalizeDedupedReplayResult(raw: string, fallback: { connectorId: string; platform: string; to: string }): string {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('invalid')
|
|
163
|
-
const record = parsed as Record<string, unknown>
|
|
164
|
-
if (String(record.status || '') === 'deduped') {
|
|
165
|
-
return JSON.stringify({
|
|
166
|
-
status: 'sent',
|
|
167
|
-
connectorId: String(record.connectorId || fallback.connectorId),
|
|
168
|
-
platform: String(record.platform || fallback.platform),
|
|
169
|
-
to: String(record.to || fallback.to),
|
|
170
|
-
deduped: true,
|
|
171
|
-
})
|
|
172
|
-
}
|
|
173
|
-
return raw
|
|
174
|
-
} catch {
|
|
163
|
+
const record = safeJsonParseObject(raw)
|
|
164
|
+
if (record && String(record.status || '') === 'deduped') {
|
|
175
165
|
return JSON.stringify({
|
|
176
166
|
status: 'sent',
|
|
177
|
-
connectorId: fallback.connectorId,
|
|
178
|
-
platform: fallback.platform,
|
|
179
|
-
to: fallback.to,
|
|
167
|
+
connectorId: String(record.connectorId || fallback.connectorId),
|
|
168
|
+
platform: String(record.platform || fallback.platform),
|
|
169
|
+
to: String(record.to || fallback.to),
|
|
180
170
|
deduped: true,
|
|
181
171
|
})
|
|
182
172
|
}
|
|
173
|
+
if (record) return raw
|
|
174
|
+
return JSON.stringify({
|
|
175
|
+
status: 'sent',
|
|
176
|
+
connectorId: fallback.connectorId,
|
|
177
|
+
platform: fallback.platform,
|
|
178
|
+
to: fallback.to,
|
|
179
|
+
deduped: true,
|
|
180
|
+
})
|
|
183
181
|
}
|
|
184
182
|
|
|
185
183
|
export function normalizeConnectorActionName(action: string): string {
|
|
@@ -441,7 +439,7 @@ function pickChannelTarget(params: {
|
|
|
441
439
|
...parseCsv(connector.config?.allowedJids),
|
|
442
440
|
...parseCsv(connector.config?.allowFrom),
|
|
443
441
|
].filter(Boolean) as string[]
|
|
444
|
-
const unique =
|
|
442
|
+
const unique = dedup(knownTargets)
|
|
445
443
|
if (unique.length) {
|
|
446
444
|
return {
|
|
447
445
|
channelId: '',
|
|
@@ -487,9 +485,9 @@ export function resolveConnectorMediaInput(params: {
|
|
|
487
485
|
const candidatePaths = [
|
|
488
486
|
path.resolve(params.cwd, resolvedMediaPath),
|
|
489
487
|
path.resolve(params.cwd, 'uploads', resolvedMediaPath),
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
]
|
|
488
|
+
tryResolvePathWithinBaseDir(UPLOAD_DIR, resolvedMediaPath),
|
|
489
|
+
tryResolvePathWithinBaseDir(UPLOAD_DIR, path.basename(resolvedMediaPath)),
|
|
490
|
+
].filter((candidate): candidate is string => !!candidate)
|
|
493
491
|
const found = candidatePaths.find((p) => fs.existsSync(p))
|
|
494
492
|
if (found) {
|
|
495
493
|
resolvedMediaPath = found
|
|
@@ -605,9 +603,9 @@ async function executeConnectorAction(input: ConnectorActionInput, bctx: Connect
|
|
|
605
603
|
if (!connectorId) {
|
|
606
604
|
const allConnectors = loadConnectors()
|
|
607
605
|
const stopped = Object.values(allConnectors)
|
|
608
|
-
.filter((c) => !platform || c.platform === platform)
|
|
609
|
-
.filter((c) => !running.find((r) => r.id === c.id))
|
|
610
|
-
.map((c) => ({ id: c.id, name: c.name, platform: c.platform }))
|
|
606
|
+
.filter((c: any) => !platform || c.platform === platform)
|
|
607
|
+
.filter((c: any) => !running.find((r) => r.id === c.id))
|
|
608
|
+
.map((c: any) => ({ id: c.id, name: c.name, platform: c.platform }))
|
|
611
609
|
if (!stopped.length) return 'All connectors are already running.'
|
|
612
610
|
return `Error: connectorId is required. Stopped connectors available to start: ${JSON.stringify(stopped)}`
|
|
613
611
|
}
|
|
@@ -627,8 +625,8 @@ async function executeConnectorAction(input: ConnectorActionInput, bctx: Connect
|
|
|
627
625
|
if (!running.length) {
|
|
628
626
|
const allConnectors = loadConnectors()
|
|
629
627
|
const configured = Object.values(allConnectors)
|
|
630
|
-
.filter((c) => !platform || c.platform === platform)
|
|
631
|
-
.map((c) => ({ id: c.id, name: c.name, platform: c.platform, agentId: c.agentId || null }))
|
|
628
|
+
.filter((c: any) => !platform || c.platform === platform)
|
|
629
|
+
.map((c: any) => ({ id: c.id, name: c.name, platform: c.platform, agentId: c.agentId || null }))
|
|
632
630
|
if (configured.length) {
|
|
633
631
|
return {
|
|
634
632
|
error: `Error: no running connectors found. Ask user to start one. Configured: ${JSON.stringify(configured)}`,
|
|
@@ -842,7 +840,7 @@ async function executeConnectorAction(input: ConnectorActionInput, bctx: Connect
|
|
|
842
840
|
|
|
843
841
|
return 'Unknown action.'
|
|
844
842
|
} catch (err: unknown) {
|
|
845
|
-
return `Error: ${
|
|
843
|
+
return `Error: ${errorMessage(err)}`
|
|
846
844
|
}
|
|
847
845
|
}
|
|
848
846
|
|
|
@@ -7,6 +7,7 @@ import type { ToolBuildContext } from './context'
|
|
|
7
7
|
import type { Plugin, PluginHooks, Session } 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
|
interface ContextToolContext {
|
|
12
13
|
ctx?: { agentId?: string | null; sessionId?: string | null }
|
|
@@ -23,7 +24,7 @@ async function executeContextStatus(bctx: ContextToolContext) {
|
|
|
23
24
|
if (!session) return 'Error: no current session context.'
|
|
24
25
|
const status = getContextStatus(session.messages || [], 2000, session.provider as string, session.model as string)
|
|
25
26
|
return JSON.stringify(status)
|
|
26
|
-
} catch (err: unknown) { return `Error: ${
|
|
27
|
+
} catch (err: unknown) { return `Error: ${errorMessage(err)}` }
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
async function executeContextSummarize(args: { keepLastN?: number }, bctx: ContextToolContext) {
|
|
@@ -55,7 +56,7 @@ async function executeContextSummarize(args: { keepLastN?: number }, bctx: Conte
|
|
|
55
56
|
saveSessions(sessions)
|
|
56
57
|
}
|
|
57
58
|
return JSON.stringify({ status: 'compacted', remaining: result.messages.length })
|
|
58
|
-
} catch (err: unknown) { return `Error: ${
|
|
59
|
+
} catch (err: unknown) { return `Error: ${errorMessage(err)}` }
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/**
|
|
@@ -8,6 +8,7 @@ import { getPluginManager } from '../plugins'
|
|
|
8
8
|
import { runStructuredExtraction } from '../structured-extract'
|
|
9
9
|
import type { ToolBuildContext } from './context'
|
|
10
10
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
11
|
+
import { dedup, errorMessage } from '@/lib/shared-utils'
|
|
11
12
|
|
|
12
13
|
interface CrawledPage {
|
|
13
14
|
url: string
|
|
@@ -93,7 +94,7 @@ async function fetchCrawlPage(url: string, depth: number): Promise<CrawledPage>
|
|
|
93
94
|
depth,
|
|
94
95
|
textPreview,
|
|
95
96
|
headings,
|
|
96
|
-
links:
|
|
97
|
+
links: dedup(links),
|
|
97
98
|
hash: pageHash(`${title || ''}\n${textPreview}`),
|
|
98
99
|
}
|
|
99
100
|
}
|
|
@@ -194,7 +195,7 @@ async function fetchSitemapUrls(sitemapUrl: string): Promise<string[]> {
|
|
|
194
195
|
})
|
|
195
196
|
const xml = await res.text()
|
|
196
197
|
const matches = Array.from(xml.matchAll(/<loc>\s*([^<]+)\s*<\/loc>/gi))
|
|
197
|
-
return
|
|
198
|
+
return dedup(matches.map((match) => match[1]?.trim()).filter((value): value is string => !!value))
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
function normalizeSelectorMap(value: unknown): Record<string, string> {
|
|
@@ -369,7 +370,7 @@ async function executeCrawlAction(args: Record<string, unknown>, bctx: ToolBuild
|
|
|
369
370
|
|
|
370
371
|
return `Error: Unknown action "${action}".`
|
|
371
372
|
} catch (err: unknown) {
|
|
372
|
-
return `Error: ${
|
|
373
|
+
return `Error: ${errorMessage(err)}`
|
|
373
374
|
}
|
|
374
375
|
}
|
|
375
376
|
|