@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
|
@@ -5,10 +5,13 @@ import os from 'os'
|
|
|
5
5
|
import type { ChildProcess } from 'node:child_process'
|
|
6
6
|
import Database from 'better-sqlite3'
|
|
7
7
|
|
|
8
|
+
import { perf } from './perf'
|
|
8
9
|
import { DATA_DIR, IS_BUILD_BOOTSTRAP, WORKSPACE_DIR } from './data-dir'
|
|
10
|
+
import { safeJsonParseObject } from './json-utils'
|
|
9
11
|
import { normalizeHeartbeatSettingFields } from '@/lib/heartbeat-defaults'
|
|
10
12
|
import { normalizeRuntimeSettingFields } from '@/lib/runtime-loop'
|
|
11
|
-
import type { AppNotification, ExternalAgentRuntime, GatewayProfile, Message } from '@/types'
|
|
13
|
+
import type { AppNotification, BoardTask, ExternalAgentRuntime, GatewayProfile, Message, Session } from '@/types'
|
|
14
|
+
import { dedup, hmrSingleton } from '@/lib/shared-utils'
|
|
12
15
|
export const UPLOAD_DIR = path.join(DATA_DIR, 'uploads')
|
|
13
16
|
|
|
14
17
|
// --- TTL Cache (read-through with write-through invalidation) ---
|
|
@@ -44,23 +47,13 @@ class TTLCache<T> {
|
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
const ttlCacheKey = '__swarmclaw_ttl_caches__' as const
|
|
48
50
|
type TTLCacheStore = {
|
|
49
51
|
settings?: TTLCache<Record<string, unknown>>
|
|
50
|
-
credentials?: TTLCache<Record<string, unknown>>
|
|
51
|
-
connectors?: TTLCache<Record<string, unknown>>
|
|
52
|
-
gatewayProfiles?: TTLCache<Record<string, unknown>>
|
|
53
52
|
agents?: TTLCache<Record<string, unknown>>
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
const ttlGlobals = globalThis as TTLGlobals
|
|
57
|
-
const ttlCaches: TTLCacheStore = ttlGlobals[ttlCacheKey] ?? (ttlGlobals[ttlCacheKey] = {})
|
|
54
|
+
const ttlCaches: TTLCacheStore = hmrSingleton<TTLCacheStore>('__swarmclaw_ttl_caches__', () => ({}))
|
|
58
55
|
|
|
59
|
-
// Lazily initialize each cache with its TTL
|
|
60
56
|
function getSettingsCache() { return ttlCaches.settings ?? (ttlCaches.settings = new TTLCache(60_000)) }
|
|
61
|
-
function getCredentialsCache() { return ttlCaches.credentials ?? (ttlCaches.credentials = new TTLCache(90_000)) }
|
|
62
|
-
function getConnectorsCache() { return ttlCaches.connectors ?? (ttlCaches.connectors = new TTLCache(30_000)) }
|
|
63
|
-
function getGatewayProfilesCache() { return ttlCaches.gatewayProfiles ?? (ttlCaches.gatewayProfiles = new TTLCache(300_000)) }
|
|
64
57
|
function getAgentsCache() { return ttlCaches.agents ?? (ttlCaches.agents = new TTLCache(15_000)) }
|
|
65
58
|
|
|
66
59
|
// --- LRU Cache ---
|
|
@@ -71,17 +64,13 @@ const DEFAULT_LRU_CAPACITY = 5000
|
|
|
71
64
|
function parseCacheLimits(): Record<string, number> {
|
|
72
65
|
const raw = process.env.COLLECTION_CACHE_LIMITS
|
|
73
66
|
if (!raw) return {}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (typeof v === 'number' && v > 0) result[k] = v
|
|
80
|
-
}
|
|
81
|
-
return result
|
|
82
|
-
} catch {
|
|
83
|
-
return {}
|
|
67
|
+
const parsed = safeJsonParseObject(raw)
|
|
68
|
+
if (!parsed) return {}
|
|
69
|
+
const result: Record<string, number> = {}
|
|
70
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
71
|
+
if (typeof v === 'number' && v > 0) result[k] = v
|
|
84
72
|
}
|
|
73
|
+
return result
|
|
85
74
|
}
|
|
86
75
|
|
|
87
76
|
const cacheLimits = parseCacheLimits()
|
|
@@ -171,20 +160,14 @@ if (!IS_BUILD_BOOTSTRAP) {
|
|
|
171
160
|
}
|
|
172
161
|
db.pragma('foreign_keys = ON')
|
|
173
162
|
|
|
174
|
-
const collectionCacheKey = '__swarmclaw_storage_collection_cache__' as const
|
|
175
163
|
type StoredObject = Record<string, unknown>
|
|
176
164
|
type ActiveProcess = ChildProcess | {
|
|
177
165
|
runId?: string | null
|
|
178
166
|
source?: string
|
|
179
167
|
kill: (signal?: NodeJS.Signals | number) => boolean | void
|
|
180
168
|
}
|
|
181
|
-
type StorageGlobals = typeof globalThis & {
|
|
182
|
-
[collectionCacheKey]?: Map<string, LRUMap<string, string>>
|
|
183
|
-
}
|
|
184
|
-
const storageGlobals = globalThis as StorageGlobals
|
|
185
169
|
const collectionCache: Map<string, LRUMap<string, string>> =
|
|
186
|
-
|
|
187
|
-
?? (storageGlobals[collectionCacheKey] = new Map<string, LRUMap<string, string>>())
|
|
170
|
+
hmrSingleton('__swarmclaw_storage_collection_cache__', () => new Map<string, LRUMap<string, string>>())
|
|
188
171
|
|
|
189
172
|
// Collection tables (id → JSON blob)
|
|
190
173
|
const COLLECTIONS = [
|
|
@@ -214,6 +197,7 @@ const COLLECTIONS = [
|
|
|
214
197
|
'wallet_balance_history',
|
|
215
198
|
'moderation_logs',
|
|
216
199
|
'connector_health',
|
|
200
|
+
'connector_outbox',
|
|
217
201
|
'souls',
|
|
218
202
|
'benchmarks',
|
|
219
203
|
'approvals',
|
|
@@ -234,6 +218,12 @@ db.exec(`CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY CHECK (id =
|
|
|
234
218
|
db.exec(`CREATE TABLE IF NOT EXISTS queue (id INTEGER PRIMARY KEY CHECK (id = 1), data TEXT NOT NULL)`)
|
|
235
219
|
db.exec(`CREATE TABLE IF NOT EXISTS usage (session_id TEXT NOT NULL, data TEXT NOT NULL)`)
|
|
236
220
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_usage_session ON usage(session_id)`)
|
|
221
|
+
db.exec(`CREATE TABLE IF NOT EXISTS runtime_locks (
|
|
222
|
+
name TEXT PRIMARY KEY,
|
|
223
|
+
owner TEXT NOT NULL,
|
|
224
|
+
expires_at INTEGER NOT NULL,
|
|
225
|
+
updated_at INTEGER NOT NULL
|
|
226
|
+
)`)
|
|
237
227
|
|
|
238
228
|
function readCollectionRaw(table: string): LRUMap<string, string> {
|
|
239
229
|
const rows = db.prepare(`SELECT id, data FROM ${table}`).all() as { id: string; data: string }[]
|
|
@@ -270,11 +260,15 @@ function normalizeStoredRecord(table: string, value: unknown): unknown {
|
|
|
270
260
|
) {
|
|
271
261
|
session.shortcutForAgentId = session.agentId
|
|
272
262
|
}
|
|
263
|
+
if (Array.isArray(session.tools) && !Array.isArray(session.plugins)) {
|
|
264
|
+
session.plugins = [...session.tools]
|
|
265
|
+
}
|
|
273
266
|
if ('mainLoopState' in session) delete session.mainLoopState
|
|
274
267
|
return session
|
|
275
268
|
}
|
|
276
269
|
|
|
277
270
|
function loadCollection(table: string): Record<string, any> {
|
|
271
|
+
const endPerf = perf.start('storage', 'loadCollection', { table })
|
|
278
272
|
const raw = getCollectionRawCache(table)
|
|
279
273
|
const result: Record<string, any> = {}
|
|
280
274
|
for (const [id, data] of raw.entries()) {
|
|
@@ -284,10 +278,12 @@ function loadCollection(table: string): Record<string, any> {
|
|
|
284
278
|
// Ignore malformed records instead of crashing list endpoints.
|
|
285
279
|
}
|
|
286
280
|
}
|
|
281
|
+
endPerf({ count: raw.size })
|
|
287
282
|
return result
|
|
288
283
|
}
|
|
289
284
|
|
|
290
285
|
function saveCollection(table: string, data: Record<string, any>) {
|
|
286
|
+
const endPerf = perf.start('storage', 'saveCollection', { table })
|
|
291
287
|
const current = getCollectionRawCache(table)
|
|
292
288
|
const next = new Map<string, string>()
|
|
293
289
|
const toUpsert: Array<[string, string]> = []
|
|
@@ -307,7 +303,10 @@ function saveCollection(table: string, data: Record<string, any>) {
|
|
|
307
303
|
if (!next.has(id)) toDelete.push(id)
|
|
308
304
|
}
|
|
309
305
|
|
|
310
|
-
if (!toUpsert.length && !toDelete.length)
|
|
306
|
+
if (!toUpsert.length && !toDelete.length) {
|
|
307
|
+
endPerf({ upserts: 0, deletes: 0 })
|
|
308
|
+
return
|
|
309
|
+
}
|
|
311
310
|
|
|
312
311
|
const transaction = db.transaction(() => {
|
|
313
312
|
if (toDelete.length) {
|
|
@@ -320,6 +319,7 @@ function saveCollection(table: string, data: Record<string, any>) {
|
|
|
320
319
|
}
|
|
321
320
|
})
|
|
322
321
|
transaction()
|
|
322
|
+
endPerf({ upserts: toUpsert.length, deletes: toDelete.length })
|
|
323
323
|
|
|
324
324
|
for (const id of toDelete) {
|
|
325
325
|
current.delete(id)
|
|
@@ -395,6 +395,101 @@ export function upsertStoredItems(table: StorageCollection, entries: Array<[stri
|
|
|
395
395
|
upsertCollectionItems(table, entries)
|
|
396
396
|
}
|
|
397
397
|
|
|
398
|
+
export function patchStoredItem<T>(
|
|
399
|
+
table: StorageCollection,
|
|
400
|
+
id: string,
|
|
401
|
+
updater: (current: T | null) => T | null,
|
|
402
|
+
): T | null {
|
|
403
|
+
let nextValue: T | null = null
|
|
404
|
+
const transaction = db.transaction(() => {
|
|
405
|
+
const current = loadCollectionItem(table, id) as T | null
|
|
406
|
+
nextValue = updater(current)
|
|
407
|
+
if (nextValue === null) {
|
|
408
|
+
deleteCollectionItem(table, id)
|
|
409
|
+
return
|
|
410
|
+
}
|
|
411
|
+
upsertCollectionItem(table, id, nextValue)
|
|
412
|
+
})
|
|
413
|
+
transaction()
|
|
414
|
+
return nextValue
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export function deleteStoredItem(table: StorageCollection, id: string): void {
|
|
418
|
+
db.prepare(`DELETE FROM ${table} WHERE id = ?`).run(id)
|
|
419
|
+
const cached = collectionCache.get(table)
|
|
420
|
+
if (cached) cached.delete(id)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// --- Collection Store Factory ---
|
|
424
|
+
// Generates typed CRUD operations for any collection table, with optional TTL caching.
|
|
425
|
+
|
|
426
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- backward-compatible default; typed stores override with concrete types
|
|
427
|
+
interface CollectionStore<T = any> {
|
|
428
|
+
load(): Record<string, T>
|
|
429
|
+
save(data: Record<string, T>): void
|
|
430
|
+
loadItem(id: string): T | null
|
|
431
|
+
upsert(id: string, value: unknown): void
|
|
432
|
+
upsertMany(entries: Array<[string, unknown]>): void
|
|
433
|
+
patch(id: string, updater: (current: T | null) => T | null): T | null
|
|
434
|
+
deleteItem(id: string): void
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const factoryTtlCaches = hmrSingleton('__swarmclaw_factory_ttl__', () => new Map<string, TTLCache<Record<string, unknown>>>())
|
|
438
|
+
|
|
439
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- see CollectionStore
|
|
440
|
+
function createCollectionStore<T = any>(
|
|
441
|
+
table: StorageCollection,
|
|
442
|
+
opts?: { ttlMs?: number },
|
|
443
|
+
): CollectionStore<T> {
|
|
444
|
+
let ttlCache: TTLCache<Record<string, unknown>> | null = null
|
|
445
|
+
if (opts?.ttlMs) {
|
|
446
|
+
ttlCache = factoryTtlCaches.get(table) ?? null
|
|
447
|
+
if (!ttlCache) {
|
|
448
|
+
ttlCache = new TTLCache(opts.ttlMs)
|
|
449
|
+
factoryTtlCaches.set(table, ttlCache)
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return {
|
|
454
|
+
load(): Record<string, T> {
|
|
455
|
+
if (ttlCache) {
|
|
456
|
+
const cached = ttlCache.get()
|
|
457
|
+
if (cached) return structuredClone(cached) as Record<string, T>
|
|
458
|
+
}
|
|
459
|
+
const result = loadCollection(table)
|
|
460
|
+
if (ttlCache) {
|
|
461
|
+
ttlCache.set(result)
|
|
462
|
+
return structuredClone(result) as Record<string, T>
|
|
463
|
+
}
|
|
464
|
+
return result as Record<string, T>
|
|
465
|
+
},
|
|
466
|
+
save(data: Record<string, T>): void {
|
|
467
|
+
saveCollection(table, data as Record<string, unknown>)
|
|
468
|
+
ttlCache?.invalidate()
|
|
469
|
+
},
|
|
470
|
+
loadItem(id: string): T | null {
|
|
471
|
+
return loadCollectionItem(table, id) as T | null
|
|
472
|
+
},
|
|
473
|
+
upsert(id: string, value: unknown): void {
|
|
474
|
+
upsertCollectionItem(table, id, value)
|
|
475
|
+
ttlCache?.invalidate()
|
|
476
|
+
},
|
|
477
|
+
upsertMany(entries: Array<[string, unknown]>): void {
|
|
478
|
+
upsertCollectionItems(table, entries)
|
|
479
|
+
ttlCache?.invalidate()
|
|
480
|
+
},
|
|
481
|
+
patch(id: string, updater: (current: T | null) => T | null): T | null {
|
|
482
|
+
const result = patchStoredItem<T>(table, id, updater)
|
|
483
|
+
ttlCache?.invalidate()
|
|
484
|
+
return result
|
|
485
|
+
},
|
|
486
|
+
deleteItem(id: string): void {
|
|
487
|
+
deleteCollectionItem(table, id)
|
|
488
|
+
ttlCache?.invalidate()
|
|
489
|
+
},
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
398
493
|
function loadSingleton<T>(table: string, fallback: T): T {
|
|
399
494
|
const row = db.prepare(`SELECT data FROM ${table} WHERE id = 1`).get() as { data: string } | undefined
|
|
400
495
|
return row ? JSON.parse(row.data) as T : fallback
|
|
@@ -404,6 +499,58 @@ function saveSingleton(table: string, data: unknown) {
|
|
|
404
499
|
db.prepare(`INSERT OR REPLACE INTO ${table} (id, data) VALUES (1, ?)`).run(JSON.stringify(data))
|
|
405
500
|
}
|
|
406
501
|
|
|
502
|
+
function normalizeLockTtlMs(ttlMs: number): number {
|
|
503
|
+
if (!Number.isFinite(ttlMs)) return 1_000
|
|
504
|
+
return Math.max(1_000, Math.trunc(ttlMs))
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
export function patchQueue<T>(updater: (queue: string[]) => T): T {
|
|
508
|
+
let result!: T
|
|
509
|
+
const transaction = db.transaction(() => {
|
|
510
|
+
const current = loadSingleton('queue', [])
|
|
511
|
+
const queue = Array.isArray(current) ? [...current] : []
|
|
512
|
+
result = updater(queue)
|
|
513
|
+
saveSingleton('queue', queue)
|
|
514
|
+
})
|
|
515
|
+
transaction()
|
|
516
|
+
return result
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export function tryAcquireRuntimeLock(name: string, owner: string, ttlMs: number): boolean {
|
|
520
|
+
let acquired = false
|
|
521
|
+
const now = Date.now()
|
|
522
|
+
const expiresAt = now + normalizeLockTtlMs(ttlMs)
|
|
523
|
+
const transaction = db.transaction(() => {
|
|
524
|
+
const row = db.prepare('SELECT owner, expires_at FROM runtime_locks WHERE name = ?').get(name) as
|
|
525
|
+
| { owner: string; expires_at: number }
|
|
526
|
+
| undefined
|
|
527
|
+
if (!row || row.owner === owner || row.expires_at <= now) {
|
|
528
|
+
db.prepare(`
|
|
529
|
+
INSERT OR REPLACE INTO runtime_locks (name, owner, expires_at, updated_at)
|
|
530
|
+
VALUES (?, ?, ?, ?)
|
|
531
|
+
`).run(name, owner, expiresAt, now)
|
|
532
|
+
acquired = true
|
|
533
|
+
}
|
|
534
|
+
})
|
|
535
|
+
transaction()
|
|
536
|
+
return acquired
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
export function renewRuntimeLock(name: string, owner: string, ttlMs: number): boolean {
|
|
540
|
+
const now = Date.now()
|
|
541
|
+
const expiresAt = now + normalizeLockTtlMs(ttlMs)
|
|
542
|
+
const result = db.prepare(`
|
|
543
|
+
UPDATE runtime_locks
|
|
544
|
+
SET expires_at = ?, updated_at = ?
|
|
545
|
+
WHERE name = ? AND owner = ?
|
|
546
|
+
`).run(expiresAt, now, name, owner)
|
|
547
|
+
return result.changes > 0
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export function releaseRuntimeLock(name: string, owner: string): void {
|
|
551
|
+
db.prepare('DELETE FROM runtime_locks WHERE name = ? AND owner = ?').run(name, owner)
|
|
552
|
+
}
|
|
553
|
+
|
|
407
554
|
// --- JSON Migration ---
|
|
408
555
|
// Auto-import from JSON files on first run, then leave them as backup
|
|
409
556
|
const JSON_FILES: Record<string, string> = {
|
|
@@ -572,7 +719,7 @@ Be concise but not curt. Warmth doesn't require verbosity. When someone asks "ho
|
|
|
572
719
|
try {
|
|
573
720
|
const existing = JSON.parse(row.data) as Record<string, unknown>
|
|
574
721
|
const existingPlugins = Array.isArray(existing.plugins) ? existing.plugins : Array.isArray(existing.tools) ? existing.tools : []
|
|
575
|
-
const mergedPlugins =
|
|
722
|
+
const mergedPlugins = dedup([...existingPlugins, ...defaultStarterTools]).filter((t) => t !== 'delete_file')
|
|
576
723
|
if (JSON.stringify(existingPlugins) !== JSON.stringify(mergedPlugins)) {
|
|
577
724
|
existing.plugins = mergedPlugins
|
|
578
725
|
delete existing.tools
|
|
@@ -691,6 +838,18 @@ export function saveSessions(s: Record<string, any>) {
|
|
|
691
838
|
if (entries.length > 0) upsertCollectionItems('sessions', entries)
|
|
692
839
|
}
|
|
693
840
|
|
|
841
|
+
export function loadSession(id: string): Session | null {
|
|
842
|
+
return loadCollectionItem('sessions', id) as Session | null
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
export function upsertSession(id: string, session: Session | Record<string, unknown>) {
|
|
846
|
+
upsertCollectionItem('sessions', id, session)
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
export function patchSession(id: string, updater: (current: Session | null) => Session | null): Session | null {
|
|
850
|
+
return patchStoredItem<Session>('sessions', id, updater)
|
|
851
|
+
}
|
|
852
|
+
|
|
694
853
|
export function disableAllSessionHeartbeats(): number {
|
|
695
854
|
const rows = db.prepare('SELECT id, data FROM sessions').all() as Array<{ id: string; data: string }>
|
|
696
855
|
if (!rows.length) return 0
|
|
@@ -721,23 +880,18 @@ export function disableAllSessionHeartbeats(): number {
|
|
|
721
880
|
}
|
|
722
881
|
|
|
723
882
|
// --- Credentials ---
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
if (cached) return structuredClone(cached) as Record<string, unknown>
|
|
883
|
+
const credentialsStore = createCollectionStore('credentials', { ttlMs: 90_000 })
|
|
884
|
+
export const loadCredentials = credentialsStore.load
|
|
885
|
+
export const saveCredentials = credentialsStore.save
|
|
728
886
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
export function saveCredentials(c: Record<string, any>) {
|
|
735
|
-
saveCollection('credentials', c)
|
|
736
|
-
getCredentialsCache().invalidate()
|
|
887
|
+
function requireCredentialSecret(): Buffer {
|
|
888
|
+
const secret = process.env.CREDENTIAL_SECRET
|
|
889
|
+
if (!secret) throw new Error('CREDENTIAL_SECRET environment variable is not set. Cannot encrypt/decrypt credentials.')
|
|
890
|
+
return Buffer.from(secret, 'hex')
|
|
737
891
|
}
|
|
738
892
|
|
|
739
893
|
export function encryptKey(plaintext: string): string {
|
|
740
|
-
const key =
|
|
894
|
+
const key = requireCredentialSecret()
|
|
741
895
|
const iv = crypto.randomBytes(12)
|
|
742
896
|
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv)
|
|
743
897
|
let encrypted = cipher.update(plaintext, 'utf8', 'hex')
|
|
@@ -747,7 +901,7 @@ export function encryptKey(plaintext: string): string {
|
|
|
747
901
|
}
|
|
748
902
|
|
|
749
903
|
export function decryptKey(encrypted: string): string {
|
|
750
|
-
const key =
|
|
904
|
+
const key = requireCredentialSecret()
|
|
751
905
|
const [ivHex, tagHex, data] = encrypted.split(':')
|
|
752
906
|
const iv = Buffer.from(ivHex, 'hex')
|
|
753
907
|
const tag = Buffer.from(tagHex, 'hex')
|
|
@@ -810,41 +964,60 @@ export function saveAgents(p: Record<string, any>) {
|
|
|
810
964
|
getAgentsCache().invalidate()
|
|
811
965
|
}
|
|
812
966
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
967
|
+
export function loadAgent(id: string, opts?: { includeTrashed?: boolean }): Record<string, any> | null {
|
|
968
|
+
const agent = loadCollectionItem('agents', id) as Record<string, any> | null
|
|
969
|
+
if (!agent) return null
|
|
970
|
+
if (!opts?.includeTrashed && agent.trashedAt) return null
|
|
971
|
+
return agent
|
|
816
972
|
}
|
|
817
973
|
|
|
818
|
-
export function
|
|
819
|
-
|
|
974
|
+
export function upsertAgent(id: string, agent: unknown) {
|
|
975
|
+
upsertCollectionItem('agents', id, agent)
|
|
976
|
+
getAgentsCache().invalidate()
|
|
820
977
|
}
|
|
821
978
|
|
|
979
|
+
export function patchAgent(
|
|
980
|
+
id: string,
|
|
981
|
+
updater: (current: Record<string, any> | null) => Record<string, any> | null,
|
|
982
|
+
): Record<string, any> | null {
|
|
983
|
+
const next = patchStoredItem<Record<string, any>>('agents', id, updater)
|
|
984
|
+
getAgentsCache().invalidate()
|
|
985
|
+
return next
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// --- Schedules ---
|
|
989
|
+
const schedulesStore = createCollectionStore('schedules')
|
|
990
|
+
export const loadSchedules = schedulesStore.load
|
|
991
|
+
export const saveSchedules = schedulesStore.save
|
|
992
|
+
export const loadSchedule = schedulesStore.loadItem
|
|
993
|
+
export const upsertSchedule = schedulesStore.upsert
|
|
994
|
+
export const upsertSchedules = schedulesStore.upsertMany
|
|
995
|
+
|
|
822
996
|
// --- Souls ---
|
|
823
|
-
|
|
824
|
-
export const
|
|
825
|
-
export const
|
|
997
|
+
const soulsStore = createCollectionStore('souls')
|
|
998
|
+
export const loadSouls = soulsStore.load
|
|
999
|
+
export const saveSouls = soulsStore.save
|
|
1000
|
+
export const deleteSoul = soulsStore.deleteItem
|
|
826
1001
|
|
|
827
1002
|
// --- Benchmarks ---
|
|
828
|
-
|
|
829
|
-
export const
|
|
830
|
-
export const
|
|
1003
|
+
const benchmarksStore = createCollectionStore('benchmarks')
|
|
1004
|
+
export const loadBenchmarks = benchmarksStore.load
|
|
1005
|
+
export const saveBenchmarks = benchmarksStore.save
|
|
1006
|
+
export const deleteBenchmark = benchmarksStore.deleteItem
|
|
831
1007
|
|
|
832
1008
|
// --- Tasks ---
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
export
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
export
|
|
841
|
-
upsertCollectionItem('tasks', id, task)
|
|
842
|
-
}
|
|
843
|
-
export function deleteTask(id: string) { deleteCollectionItem('tasks', id) }
|
|
1009
|
+
const tasksStore = createCollectionStore('tasks')
|
|
1010
|
+
export const loadTasks = tasksStore.load
|
|
1011
|
+
export const saveTasks = tasksStore.save
|
|
1012
|
+
export const loadTask = tasksStore.loadItem as (id: string) => BoardTask | null
|
|
1013
|
+
export const upsertTask = tasksStore.upsert
|
|
1014
|
+
export const upsertTasks = tasksStore.upsertMany
|
|
1015
|
+
export const patchTask = tasksStore.patch as (id: string, updater: (current: BoardTask | null) => BoardTask | null) => BoardTask | null
|
|
1016
|
+
export const deleteTask = tasksStore.deleteItem
|
|
844
1017
|
export function deleteSession(id: string) { deleteCollectionItem('sessions', id) }
|
|
845
1018
|
export function deleteAgent(id: string) { deleteCollectionItem('agents', id); getAgentsCache().invalidate() }
|
|
846
|
-
export
|
|
847
|
-
export function deleteSkill(id: string) {
|
|
1019
|
+
export const deleteSchedule = schedulesStore.deleteItem
|
|
1020
|
+
export function deleteSkill(id: string) { skillsStore.deleteItem(id) }
|
|
848
1021
|
|
|
849
1022
|
// --- Queue ---
|
|
850
1023
|
export function loadQueue(): string[] {
|
|
@@ -971,13 +1144,9 @@ export function loadPublicSettings(): Record<string, any> {
|
|
|
971
1144
|
}
|
|
972
1145
|
|
|
973
1146
|
// --- Secrets (service keys for orchestrators) ---
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
export function saveSecrets(s: Record<string, any>) {
|
|
979
|
-
saveCollection('secrets', s)
|
|
980
|
-
}
|
|
1147
|
+
const secretsStore = createCollectionStore('secrets')
|
|
1148
|
+
export const loadSecrets = secretsStore.load
|
|
1149
|
+
export const saveSecrets = secretsStore.save
|
|
981
1150
|
|
|
982
1151
|
export async function getSecret(key: string): Promise<{
|
|
983
1152
|
id: string
|
|
@@ -1034,67 +1203,35 @@ export async function getSecret(key: string): Promise<{
|
|
|
1034
1203
|
}
|
|
1035
1204
|
|
|
1036
1205
|
// --- Provider Configs (custom providers) ---
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
export function saveProviderConfigs(p: Record<string, any>) {
|
|
1042
|
-
saveCollection('provider_configs', p)
|
|
1043
|
-
}
|
|
1206
|
+
const providerConfigsStore = createCollectionStore('provider_configs')
|
|
1207
|
+
export const loadProviderConfigs = providerConfigsStore.load
|
|
1208
|
+
export const saveProviderConfigs = providerConfigsStore.save
|
|
1044
1209
|
|
|
1045
1210
|
// --- Gateway Profiles ---
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
if (cached) return structuredClone(cached) as Record<string, unknown>
|
|
1050
|
-
|
|
1051
|
-
const result = loadCollection('gateway_profiles') as Record<string, GatewayProfile>
|
|
1052
|
-
cache.set(result)
|
|
1053
|
-
return result
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
export function saveGatewayProfiles(g: Record<string, GatewayProfile>) {
|
|
1057
|
-
saveCollection('gateway_profiles', g)
|
|
1058
|
-
getGatewayProfilesCache().invalidate()
|
|
1059
|
-
}
|
|
1211
|
+
const gatewayProfilesStore = createCollectionStore('gateway_profiles', { ttlMs: 300_000 })
|
|
1212
|
+
export const loadGatewayProfiles = gatewayProfilesStore.load
|
|
1213
|
+
export const saveGatewayProfiles = gatewayProfilesStore.save as (g: Record<string, GatewayProfile>) => void
|
|
1060
1214
|
|
|
1061
1215
|
// --- Model Overrides (user-added models for built-in providers) ---
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
export function saveModelOverrides(m: Record<string, string[]>) {
|
|
1067
|
-
saveCollection('model_overrides', m)
|
|
1068
|
-
}
|
|
1216
|
+
const modelOverridesStore = createCollectionStore('model_overrides')
|
|
1217
|
+
export const loadModelOverrides = modelOverridesStore.load as () => Record<string, string[]>
|
|
1218
|
+
export const saveModelOverrides = modelOverridesStore.save as (m: Record<string, string[]>) => void
|
|
1069
1219
|
|
|
1070
1220
|
// --- Projects ---
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
export function saveProjects(s: Record<string, any>) {
|
|
1076
|
-
saveCollection('projects', s)
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
export function deleteProject(id: string) { deleteCollectionItem('projects', id) }
|
|
1221
|
+
const projectsStore = createCollectionStore('projects')
|
|
1222
|
+
export const loadProjects = projectsStore.load
|
|
1223
|
+
export const saveProjects = projectsStore.save
|
|
1224
|
+
export const deleteProject = projectsStore.deleteItem
|
|
1080
1225
|
|
|
1081
1226
|
// --- Skills ---
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
export function saveSkills(s: Record<string, any>) {
|
|
1087
|
-
saveCollection('skills', s)
|
|
1088
|
-
}
|
|
1227
|
+
const skillsStore = createCollectionStore('skills')
|
|
1228
|
+
export const loadSkills = skillsStore.load
|
|
1229
|
+
export const saveSkills = skillsStore.save
|
|
1089
1230
|
|
|
1090
1231
|
// --- External Agent Runtimes ---
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
export function saveExternalAgents(items: Record<string, ExternalAgentRuntime>) {
|
|
1096
|
-
saveCollection('external_agents', items)
|
|
1097
|
-
}
|
|
1232
|
+
const externalAgentsStore = createCollectionStore('external_agents')
|
|
1233
|
+
export const loadExternalAgents = externalAgentsStore.load as () => Record<string, ExternalAgentRuntime>
|
|
1234
|
+
export const saveExternalAgents = externalAgentsStore.save as (items: Record<string, ExternalAgentRuntime>) => void
|
|
1098
1235
|
|
|
1099
1236
|
// --- Usage ---
|
|
1100
1237
|
export function loadUsage(): Record<string, any[]> {
|
|
@@ -1108,6 +1245,31 @@ export function loadUsage(): Record<string, any[]> {
|
|
|
1108
1245
|
return result
|
|
1109
1246
|
}
|
|
1110
1247
|
|
|
1248
|
+
export function getUsageSpendSince(minTimestamp: number): number {
|
|
1249
|
+
try {
|
|
1250
|
+
const row = db.prepare(`
|
|
1251
|
+
SELECT COALESCE(SUM(CAST(json_extract(data, '$.estimatedCost') AS REAL)), 0) AS total
|
|
1252
|
+
FROM usage
|
|
1253
|
+
WHERE CAST(COALESCE(json_extract(data, '$.timestamp'), 0) AS INTEGER) >= ?
|
|
1254
|
+
`).get(minTimestamp) as { total?: number | null } | undefined
|
|
1255
|
+
const total = Number(row?.total ?? 0)
|
|
1256
|
+
return Number.isFinite(total) ? total : 0
|
|
1257
|
+
} catch {
|
|
1258
|
+
let total = 0
|
|
1259
|
+
const usage = loadUsage()
|
|
1260
|
+
for (const records of Object.values(usage)) {
|
|
1261
|
+
for (const record of records || []) {
|
|
1262
|
+
const rec = record as Record<string, unknown>
|
|
1263
|
+
const ts = typeof rec?.timestamp === 'number' ? rec.timestamp : 0
|
|
1264
|
+
if (ts < minTimestamp) continue
|
|
1265
|
+
const cost = typeof rec?.estimatedCost === 'number' ? rec.estimatedCost : 0
|
|
1266
|
+
if (Number.isFinite(cost) && cost > 0) total += cost
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
return total
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1111
1273
|
export function saveUsage(u: Record<string, any[]>) {
|
|
1112
1274
|
const del = db.prepare('DELETE FROM usage')
|
|
1113
1275
|
const ins = db.prepare('INSERT INTO usage (session_id, data) VALUES (?, ?)')
|
|
@@ -1128,47 +1290,24 @@ export function appendUsage(sessionId: string, record: unknown) {
|
|
|
1128
1290
|
}
|
|
1129
1291
|
|
|
1130
1292
|
// --- Connectors ---
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
if (cached) return structuredClone(cached) as Record<string, unknown>
|
|
1135
|
-
|
|
1136
|
-
const result = loadCollection('connectors')
|
|
1137
|
-
cache.set(result)
|
|
1138
|
-
return result
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
export function saveConnectors(c: Record<string, any>) {
|
|
1142
|
-
saveCollection('connectors', c)
|
|
1143
|
-
getConnectorsCache().invalidate()
|
|
1144
|
-
}
|
|
1293
|
+
const connectorsStore = createCollectionStore('connectors', { ttlMs: 30_000 })
|
|
1294
|
+
export const loadConnectors = connectorsStore.load
|
|
1295
|
+
export const saveConnectors = connectorsStore.save
|
|
1145
1296
|
|
|
1146
1297
|
// --- Chatrooms ---
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
export function saveChatrooms(c: Record<string, any>) {
|
|
1152
|
-
saveCollection('chatrooms', c)
|
|
1153
|
-
}
|
|
1298
|
+
const chatroomsStore = createCollectionStore('chatrooms')
|
|
1299
|
+
export const loadChatrooms = chatroomsStore.load
|
|
1300
|
+
export const saveChatrooms = chatroomsStore.save
|
|
1154
1301
|
|
|
1155
1302
|
// --- Documents ---
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
export function saveDocuments(d: Record<string, any>) {
|
|
1161
|
-
saveCollection('documents', d)
|
|
1162
|
-
}
|
|
1303
|
+
const documentsStore = createCollectionStore('documents')
|
|
1304
|
+
export const loadDocuments = documentsStore.load
|
|
1305
|
+
export const saveDocuments = documentsStore.save
|
|
1163
1306
|
|
|
1164
1307
|
// --- Webhooks ---
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
export function saveWebhooks(w: Record<string, any>) {
|
|
1170
|
-
saveCollection('webhooks', w)
|
|
1171
|
-
}
|
|
1308
|
+
const webhooksStore = createCollectionStore('webhooks')
|
|
1309
|
+
export const loadWebhooks = webhooksStore.load
|
|
1310
|
+
export const saveWebhooks = webhooksStore.save
|
|
1172
1311
|
|
|
1173
1312
|
// --- Active processes ---
|
|
1174
1313
|
export const active = new Map<string, ActiveProcess>()
|
|
@@ -1186,42 +1325,25 @@ export function localIP(): string {
|
|
|
1186
1325
|
}
|
|
1187
1326
|
|
|
1188
1327
|
// --- MCP Servers ---
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
export function saveMcpServers(m: Record<string, any>) {
|
|
1194
|
-
saveCollection('mcp_servers', m)
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
export function deleteMcpServer(id: string) { deleteCollectionItem('mcp_servers', id) }
|
|
1328
|
+
const mcpServersStore = createCollectionStore('mcp_servers')
|
|
1329
|
+
export const loadMcpServers = mcpServersStore.load
|
|
1330
|
+
export const saveMcpServers = mcpServersStore.save
|
|
1331
|
+
export const deleteMcpServer = mcpServersStore.deleteItem
|
|
1198
1332
|
|
|
1199
1333
|
// --- Integrity Monitor Baselines ---
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
export function saveIntegrityBaselines(entries: Record<string, any>) {
|
|
1205
|
-
saveCollection('integrity_baselines', entries)
|
|
1206
|
-
}
|
|
1334
|
+
const integrityBaselinesStore = createCollectionStore('integrity_baselines')
|
|
1335
|
+
export const loadIntegrityBaselines = integrityBaselinesStore.load
|
|
1336
|
+
export const saveIntegrityBaselines = integrityBaselinesStore.save
|
|
1207
1337
|
|
|
1208
1338
|
// --- Webhook Logs ---
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
export function saveWebhookLogs(entries: Record<string, unknown>) {
|
|
1214
|
-
saveCollection('webhook_logs', entries)
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
export function appendWebhookLog(id: string, entry: unknown) {
|
|
1218
|
-
upsertCollectionItem('webhook_logs', id, entry)
|
|
1219
|
-
}
|
|
1339
|
+
const webhookLogsStore = createCollectionStore('webhook_logs')
|
|
1340
|
+
export const loadWebhookLogs = webhookLogsStore.load
|
|
1341
|
+
export const saveWebhookLogs = webhookLogsStore.save
|
|
1342
|
+
export const appendWebhookLog = webhookLogsStore.upsert
|
|
1220
1343
|
|
|
1221
1344
|
// --- Activity / Audit Trail ---
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
}
|
|
1345
|
+
const activityStore = createCollectionStore('activity')
|
|
1346
|
+
export const loadActivity = activityStore.load
|
|
1225
1347
|
|
|
1226
1348
|
export function logActivity(entry: {
|
|
1227
1349
|
entityType: string
|
|
@@ -1234,38 +1356,21 @@ export function logActivity(entry: {
|
|
|
1234
1356
|
}) {
|
|
1235
1357
|
const id = crypto.randomBytes(8).toString('hex')
|
|
1236
1358
|
const record = { id, ...entry, timestamp: Date.now() }
|
|
1237
|
-
|
|
1359
|
+
activityStore.upsert(id, record)
|
|
1238
1360
|
}
|
|
1239
1361
|
|
|
1240
1362
|
// --- Webhook Retry Queue ---
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
export
|
|
1246
|
-
saveCollection('webhook_retry_queue', entries)
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
export function upsertWebhookRetry(id: string, entry: unknown) {
|
|
1250
|
-
upsertCollectionItem('webhook_retry_queue', id, entry)
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
export function deleteWebhookRetry(id: string) {
|
|
1254
|
-
deleteCollectionItem('webhook_retry_queue', id)
|
|
1255
|
-
}
|
|
1363
|
+
const webhookRetryQueueStore = createCollectionStore('webhook_retry_queue')
|
|
1364
|
+
export const loadWebhookRetryQueue = webhookRetryQueueStore.load
|
|
1365
|
+
export const saveWebhookRetryQueue = webhookRetryQueueStore.save
|
|
1366
|
+
export const upsertWebhookRetry = webhookRetryQueueStore.upsert
|
|
1367
|
+
export const deleteWebhookRetry = webhookRetryQueueStore.deleteItem
|
|
1256
1368
|
|
|
1257
1369
|
// --- Notifications ---
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
export function saveNotification(id: string, data: unknown) {
|
|
1263
|
-
upsertCollectionItem('notifications', id, data)
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
export function deleteNotification(id: string) {
|
|
1267
|
-
deleteCollectionItem('notifications', id)
|
|
1268
|
-
}
|
|
1370
|
+
const notificationsStore = createCollectionStore('notifications')
|
|
1371
|
+
export const loadNotifications = notificationsStore.load
|
|
1372
|
+
export const saveNotification = notificationsStore.upsert
|
|
1373
|
+
export const deleteNotification = notificationsStore.deleteItem
|
|
1269
1374
|
|
|
1270
1375
|
export function findNotificationByDedupKey(dedupKey: string): AppNotification | null {
|
|
1271
1376
|
const raw = getCollectionRawCache('notifications')
|
|
@@ -1305,118 +1410,65 @@ export function markNotificationRead(id: string) {
|
|
|
1305
1410
|
}
|
|
1306
1411
|
|
|
1307
1412
|
// --- Wallets ---
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
export function upsertWallet(id: string, wallet: unknown) {
|
|
1313
|
-
upsertCollectionItem('wallets', id, wallet)
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
export function deleteWallet(id: string) {
|
|
1317
|
-
deleteCollectionItem('wallets', id)
|
|
1318
|
-
}
|
|
1413
|
+
const walletsStore = createCollectionStore('wallets')
|
|
1414
|
+
export const loadWallets = walletsStore.load
|
|
1415
|
+
export const upsertWallet = walletsStore.upsert
|
|
1416
|
+
export const deleteWallet = walletsStore.deleteItem
|
|
1319
1417
|
|
|
1320
1418
|
// --- Wallet Transactions ---
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
export function upsertWalletTransaction(id: string, tx: unknown) {
|
|
1326
|
-
upsertCollectionItem('wallet_transactions', id, tx)
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
export function deleteWalletTransaction(id: string) {
|
|
1330
|
-
deleteCollectionItem('wallet_transactions', id)
|
|
1331
|
-
}
|
|
1419
|
+
const walletTransactionsStore = createCollectionStore('wallet_transactions')
|
|
1420
|
+
export const loadWalletTransactions = walletTransactionsStore.load
|
|
1421
|
+
export const upsertWalletTransaction = walletTransactionsStore.upsert
|
|
1422
|
+
export const deleteWalletTransaction = walletTransactionsStore.deleteItem
|
|
1332
1423
|
|
|
1333
1424
|
// --- Wallet Balance History ---
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
export function upsertWalletBalanceSnapshot(id: string, snapshot: unknown) {
|
|
1339
|
-
upsertCollectionItem('wallet_balance_history', id, snapshot)
|
|
1340
|
-
}
|
|
1425
|
+
const walletBalanceHistoryStore = createCollectionStore('wallet_balance_history')
|
|
1426
|
+
export const loadWalletBalanceHistory = walletBalanceHistoryStore.load
|
|
1427
|
+
export const upsertWalletBalanceSnapshot = walletBalanceHistoryStore.upsert
|
|
1341
1428
|
|
|
1342
1429
|
// --- Moderation Logs ---
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
export function appendModerationLog(id: string, entry: unknown) {
|
|
1348
|
-
upsertCollectionItem('moderation_logs', id, entry)
|
|
1349
|
-
}
|
|
1430
|
+
const moderationLogsStore = createCollectionStore('moderation_logs')
|
|
1431
|
+
export const loadModerationLogs = moderationLogsStore.load
|
|
1432
|
+
export const appendModerationLog = moderationLogsStore.upsert
|
|
1350
1433
|
|
|
1351
1434
|
// --- Connector Health ---
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1435
|
+
const connectorHealthStore = createCollectionStore('connector_health')
|
|
1436
|
+
export const loadConnectorHealth = connectorHealthStore.load
|
|
1437
|
+
export const upsertConnectorHealthEvent = connectorHealthStore.upsert
|
|
1355
1438
|
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1439
|
+
// --- Connector Outbox ---
|
|
1440
|
+
const connectorOutboxStore = createCollectionStore('connector_outbox')
|
|
1441
|
+
export const loadConnectorOutbox = connectorOutboxStore.load
|
|
1442
|
+
export const upsertConnectorOutboxItem = connectorOutboxStore.upsert
|
|
1443
|
+
export const deleteConnectorOutboxItem = connectorOutboxStore.deleteItem
|
|
1359
1444
|
|
|
1360
1445
|
// --- Approvals ---
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1446
|
+
const approvalsStore = createCollectionStore('approvals')
|
|
1447
|
+
export const loadApprovals = approvalsStore.load
|
|
1448
|
+
export const upsertApproval = approvalsStore.upsert
|
|
1449
|
+
export const deleteApproval = approvalsStore.deleteItem
|
|
1364
1450
|
|
|
1365
1451
|
// --- Browser Sessions ---
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
export function upsertBrowserSession(id: string, data: unknown) {
|
|
1371
|
-
upsertCollectionItem('browser_sessions', id, data)
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
export function deleteBrowserSession(id: string) {
|
|
1375
|
-
deleteCollectionItem('browser_sessions', id)
|
|
1376
|
-
}
|
|
1452
|
+
const browserSessionsStore = createCollectionStore('browser_sessions')
|
|
1453
|
+
export const loadBrowserSessions = browserSessionsStore.load
|
|
1454
|
+
export const upsertBrowserSession = browserSessionsStore.upsert
|
|
1455
|
+
export const deleteBrowserSession = browserSessionsStore.deleteItem
|
|
1377
1456
|
|
|
1378
1457
|
// --- Watch Jobs ---
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
export
|
|
1384
|
-
upsertCollectionItem('watch_jobs', id, data)
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
export function upsertWatchJobs(entries: Array<[string, unknown]>) {
|
|
1388
|
-
upsertCollectionItems('watch_jobs', entries)
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
export function deleteWatchJob(id: string) {
|
|
1392
|
-
deleteCollectionItem('watch_jobs', id)
|
|
1393
|
-
}
|
|
1458
|
+
const watchJobsStore = createCollectionStore('watch_jobs')
|
|
1459
|
+
export const loadWatchJobs = watchJobsStore.load
|
|
1460
|
+
export const upsertWatchJob = watchJobsStore.upsert
|
|
1461
|
+
export const upsertWatchJobs = watchJobsStore.upsertMany
|
|
1462
|
+
export const deleteWatchJob = watchJobsStore.deleteItem
|
|
1394
1463
|
|
|
1395
1464
|
// --- Delegation Jobs ---
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
export
|
|
1401
|
-
upsertCollectionItem('delegation_jobs', id, data)
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
export function deleteDelegationJob(id: string) {
|
|
1405
|
-
deleteCollectionItem('delegation_jobs', id)
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
export function upsertApproval(id: string, approval: unknown) {
|
|
1409
|
-
upsertCollectionItem('approvals', id, approval)
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
export function deleteApproval(id: string) {
|
|
1413
|
-
deleteCollectionItem('approvals', id)
|
|
1414
|
-
}
|
|
1465
|
+
const delegationJobsStore = createCollectionStore('delegation_jobs')
|
|
1466
|
+
export const loadDelegationJobs = delegationJobsStore.load
|
|
1467
|
+
export const upsertDelegationJob = delegationJobsStore.upsert
|
|
1468
|
+
export const { patch: patchDelegationJob } = delegationJobsStore
|
|
1469
|
+
export const deleteDelegationJob = delegationJobsStore.deleteItem
|
|
1415
1470
|
|
|
1416
1471
|
export function getSessionMessages(sessionId: string): Message[] {
|
|
1417
|
-
const
|
|
1418
|
-
|
|
1419
|
-
if (!row) return []
|
|
1420
|
-
const session = JSON.parse(row.data)
|
|
1421
|
-
return session?.messages || []
|
|
1472
|
+
const session = loadSession(sessionId)
|
|
1473
|
+
return Array.isArray(session?.messages) ? session.messages : []
|
|
1422
1474
|
}
|