@swarmclawai/swarmclaw 1.2.4 → 1.2.6
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 +14 -0
- package/bin/daemon-cmd.js +169 -0
- package/bin/server-cmd.js +3 -0
- package/bin/swarmclaw.js +11 -0
- package/package.json +17 -16
- package/src/app/api/agents/[id]/clone/route.ts +3 -32
- package/src/app/api/agents/[id]/route.ts +6 -158
- package/src/app/api/agents/[id]/status/route.ts +2 -3
- package/src/app/api/agents/[id]/thread/route.ts +4 -17
- package/src/app/api/agents/bulk/route.ts +5 -47
- package/src/app/api/agents/route.ts +5 -119
- package/src/app/api/agents/trash/route.ts +13 -24
- package/src/app/api/auth/route.ts +3 -9
- package/src/app/api/autonomy/estop/route.ts +5 -5
- package/src/app/api/chatrooms/[id]/chat/route.ts +11 -5
- package/src/app/api/chatrooms/[id]/route.ts +23 -2
- package/src/app/api/chatrooms/route.ts +13 -2
- package/src/app/api/chats/[id]/clear/route.ts +2 -13
- package/src/app/api/chats/[id]/deploy/route.ts +2 -3
- package/src/app/api/chats/[id]/edit-resend/route.ts +7 -13
- package/src/app/api/chats/[id]/mailbox/route.ts +6 -8
- package/src/app/api/chats/[id]/queue/route.ts +17 -64
- package/src/app/api/chats/[id]/retry/route.ts +4 -22
- package/src/app/api/chats/[id]/route.ts +10 -138
- package/src/app/api/chats/heartbeat/route.ts +2 -1
- package/src/app/api/chats/migrate-messages/route.ts +7 -0
- package/src/app/api/chats/route.ts +13 -134
- package/src/app/api/connectors/[id]/access/route.ts +12 -229
- package/src/app/api/connectors/[id]/doctor/route.ts +1 -1
- package/src/app/api/connectors/[id]/health/route.ts +12 -39
- package/src/app/api/connectors/[id]/route.ts +14 -122
- package/src/app/api/connectors/[id]/webhook/route.ts +1 -1
- package/src/app/api/connectors/doctor/route.ts +1 -1
- package/src/app/api/connectors/route.ts +12 -70
- package/src/app/api/credentials/[id]/route.ts +2 -4
- package/src/app/api/credentials/route.ts +10 -19
- package/src/app/api/daemon/health-check/route.ts +3 -4
- package/src/app/api/daemon/route.ts +10 -8
- package/src/app/api/documents/route.ts +11 -10
- package/src/app/api/external-agents/route.ts +3 -3
- package/src/app/api/gateways/[id]/health/route.ts +2 -3
- package/src/app/api/gateways/[id]/route.ts +7 -122
- package/src/app/api/gateways/route.ts +3 -103
- package/src/app/api/mcp-servers/[id]/tools/route.ts +5 -5
- package/src/app/api/openclaw/dashboard-url/route.ts +8 -16
- package/src/app/api/openclaw/directory/route.ts +2 -2
- package/src/app/api/openclaw/history/route.ts +3 -5
- package/src/app/api/providers/[id]/route.test.ts +49 -0
- package/src/app/api/providers/ollama/route.ts +6 -5
- package/src/app/api/schedules/[id]/route.ts +14 -108
- package/src/app/api/schedules/[id]/run/route.ts +6 -67
- package/src/app/api/schedules/route.ts +9 -51
- package/src/app/api/settings/route.ts +4 -3
- package/src/app/api/setup/check-provider/route.ts +23 -1
- package/src/app/api/setup/openclaw-device/route.ts +2 -2
- package/src/app/api/system/status/route.ts +2 -2
- package/src/app/api/tasks/[id]/route.ts +16 -202
- package/src/app/api/tasks/bulk/route.ts +5 -86
- package/src/app/api/tasks/metrics/route.ts +2 -1
- package/src/app/api/tasks/route.ts +11 -171
- package/src/app/api/upload/route.ts +1 -1
- package/src/app/api/uploads/[filename]/route.ts +1 -1
- package/src/app/api/uploads/route.ts +1 -1
- package/src/app/api/webhooks/[id]/history/route.ts +2 -2
- package/src/app/layout.tsx +9 -6
- package/src/app/protocols/page.tsx +71 -89
- package/src/app/tasks/page.tsx +32 -32
- package/src/cli/index.js +1 -0
- package/src/cli/spec.js +1 -0
- package/src/components/agents/agent-sheet.tsx +5 -5
- package/src/components/auth/setup-wizard/index.tsx +4 -4
- package/src/components/auth/setup-wizard/step-agents.tsx +1 -1
- package/src/components/auth/setup-wizard/step-connect.tsx +1 -1
- package/src/components/auth/setup-wizard/utils.ts +1 -1
- package/src/components/chatrooms/chatroom-sheet.tsx +16 -276
- package/src/components/connectors/connector-list.tsx +26 -40
- package/src/components/connectors/connector-sheet.tsx +95 -149
- package/src/components/gateways/gateway-sheet.tsx +61 -110
- package/src/components/layout/live-query-sync.tsx +121 -0
- package/src/components/protocols/structured-session-launcher.tsx +24 -45
- package/src/components/providers/app-query-provider.tsx +17 -0
- package/src/components/providers/provider-list.tsx +60 -61
- package/src/components/providers/provider-sheet.tsx +74 -56
- package/src/components/skills/skill-list.tsx +5 -18
- package/src/components/skills/skill-sheet.tsx +21 -20
- package/src/components/skills/skills-workspace.tsx +48 -87
- package/src/components/tasks/task-card.tsx +20 -13
- package/src/components/tasks/task-column.tsx +22 -7
- package/src/components/tasks/task-list.tsx +8 -11
- package/src/components/tasks/task-sheet.tsx +111 -103
- package/src/features/agents/queries.ts +20 -0
- package/src/features/chatrooms/queries.ts +20 -0
- package/src/features/chats/queries.ts +27 -0
- package/src/features/connectors/queries.ts +145 -0
- package/src/features/credentials/queries.ts +37 -0
- package/src/features/extensions/queries.ts +26 -0
- package/src/features/external-agents/queries.ts +36 -0
- package/src/features/gateways/queries.ts +274 -0
- package/src/features/missions/queries.ts +23 -0
- package/src/features/projects/queries.ts +20 -0
- package/src/features/protocols/queries.ts +149 -0
- package/src/features/providers/queries.ts +142 -0
- package/src/features/settings/queries.ts +20 -0
- package/src/features/skills/queries.ts +182 -0
- package/src/features/tasks/queries.ts +189 -0
- package/src/hooks/use-ws.ts +3 -2
- package/src/lib/app/api-client.ts +2 -2
- package/src/lib/providers/index.test.ts +108 -0
- package/src/lib/providers/index.ts +38 -15
- package/src/lib/query/client.ts +17 -0
- package/src/lib/server/agents/agent-runtime-config.ts +1 -1
- package/src/lib/server/agents/agent-service.ts +429 -0
- package/src/lib/server/agents/agent-thread-session.ts +6 -5
- package/src/lib/server/agents/autonomy-contract.ts +1 -4
- package/src/lib/server/agents/delegation-advisory.test.ts +206 -0
- package/src/lib/server/agents/delegation-advisory.ts +251 -0
- package/src/lib/server/agents/main-agent-loop.ts +98 -40
- package/src/lib/server/agents/subagent-runtime.ts +12 -0
- package/src/lib/server/autonomy/supervisor-reflection.test.ts +20 -1
- package/src/lib/server/autonomy/supervisor-reflection.ts +39 -19
- package/src/lib/server/build-llm.ts +7 -15
- package/src/lib/server/capability-router.test.ts +70 -1
- package/src/lib/server/capability-router.ts +24 -99
- package/src/lib/server/chat-execution/chat-execution-utils.ts +0 -15
- package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -4
- package/src/lib/server/chat-execution/chat-turn-finalization.ts +77 -12
- package/src/lib/server/chat-execution/chat-turn-partial-persistence.ts +4 -4
- package/src/lib/server/chat-execution/chat-turn-preflight.ts +2 -2
- package/src/lib/server/chat-execution/chat-turn-preparation.ts +41 -17
- package/src/lib/server/chat-execution/chat-turn-stream-execution.ts +4 -2
- package/src/lib/server/chat-execution/chat-turn-tool-routing.test.ts +45 -0
- package/src/lib/server/chat-execution/chat-turn-tool-routing.ts +48 -17
- package/src/lib/server/chat-execution/continuation-evaluator.ts +4 -1
- package/src/lib/server/chat-execution/direct-memory-intent.test.ts +9 -0
- package/src/lib/server/chat-execution/direct-memory-intent.ts +12 -2
- package/src/lib/server/chat-execution/message-classifier.test.ts +35 -23
- package/src/lib/server/chat-execution/message-classifier.ts +74 -32
- package/src/lib/server/chat-execution/prompt-builder.test.ts +29 -0
- package/src/lib/server/chat-execution/prompt-builder.ts +37 -2
- package/src/lib/server/chat-execution/prompt-sections.test.ts +56 -0
- package/src/lib/server/chat-execution/prompt-sections.ts +193 -0
- package/src/lib/server/chat-execution/stream-agent-chat.ts +63 -7
- package/src/lib/server/chat-execution/stream-continuation.test.ts +36 -0
- package/src/lib/server/chat-execution/stream-continuation.ts +28 -13
- package/src/lib/server/chatrooms/chatroom-agent-signals.ts +26 -18
- package/src/lib/server/chatrooms/chatroom-helpers.ts +19 -18
- package/src/lib/server/chatrooms/chatroom-repository.ts +16 -0
- package/src/lib/server/chatrooms/chatroom-routing.test.ts +96 -0
- package/src/lib/server/chatrooms/chatroom-routing.ts +207 -53
- package/src/lib/server/chatrooms/mailbox-utils.ts +4 -2
- package/src/lib/server/chatrooms/session-mailbox.ts +50 -40
- package/src/lib/server/chats/chat-session-service.ts +410 -0
- package/src/lib/server/connectors/access.ts +1 -1
- package/src/lib/server/connectors/commands.ts +7 -6
- package/src/lib/server/connectors/connector-inbound.ts +14 -7
- package/src/lib/server/connectors/connector-outbound.ts +16 -11
- package/src/lib/server/connectors/connector-service.ts +453 -0
- package/src/lib/server/connectors/delivery.ts +17 -12
- package/src/lib/server/connectors/inbound-audio-transcription.ts +5 -14
- package/src/lib/server/connectors/media.ts +1 -1
- package/src/lib/server/connectors/response-media.ts +1 -1
- package/src/lib/server/connectors/session-consolidation.ts +11 -7
- package/src/lib/server/connectors/session.ts +9 -7
- package/src/lib/server/connectors/voice-note.ts +2 -1
- package/src/lib/server/context-manager.ts +20 -1
- package/src/lib/server/cost.ts +2 -3
- package/src/lib/server/credentials/credential-repository.ts +43 -4
- package/src/lib/server/credentials/credential-service.ts +112 -0
- package/src/lib/server/daemon/admin-metadata.ts +64 -0
- package/src/lib/server/daemon/controller.ts +577 -0
- package/src/lib/server/daemon/daemon-runtime.ts +352 -0
- package/src/lib/server/daemon/daemon-status-repository.ts +63 -0
- package/src/lib/server/daemon/types.ts +101 -0
- package/src/lib/server/embeddings.ts +3 -9
- package/src/lib/server/eval/agent-regression.ts +3 -2
- package/src/lib/server/eval/runner.ts +2 -2
- package/src/lib/server/execution-brief.test.ts +167 -0
- package/src/lib/server/execution-brief.ts +295 -0
- package/src/lib/server/execution-engine/chat-turn.ts +9 -0
- package/src/lib/server/execution-engine/import-boundary.test.ts +44 -0
- package/src/lib/server/execution-engine/index.ts +35 -0
- package/src/lib/server/execution-engine/task-attempt.ts +303 -0
- package/src/lib/server/execution-engine/types.ts +33 -0
- package/src/lib/server/gateways/gateway-profile-repository.ts +47 -3
- package/src/lib/server/gateways/gateway-profile-service.ts +200 -0
- package/src/lib/server/memory/session-archive-memory.ts +12 -10
- package/src/lib/server/messages/message-repository.ts +330 -0
- package/src/lib/server/missions/mission-service/core.ts +8 -6
- package/src/lib/server/openclaw/agent-resolver.ts +2 -3
- package/src/lib/server/openclaw/doctor.ts +1 -1
- package/src/lib/server/openclaw/gateway.test.ts +10 -1
- package/src/lib/server/openclaw/gateway.ts +5 -14
- package/src/lib/server/openclaw/health.ts +3 -11
- package/src/lib/server/openclaw/sync.ts +8 -6
- package/src/lib/server/persistence/storage-context.ts +3 -0
- package/src/lib/server/protocols/protocol-agent-turn.ts +25 -17
- package/src/lib/server/protocols/protocol-normalization.ts +1 -1
- package/src/lib/server/protocols/protocol-queries.ts +13 -7
- package/src/lib/server/protocols/protocol-run-lifecycle.ts +16 -20
- package/src/lib/server/protocols/protocol-run-repository.ts +81 -0
- package/src/lib/server/protocols/protocol-step-processors.ts +23 -31
- package/src/lib/server/protocols/protocol-swarm.ts +8 -8
- package/src/lib/server/protocols/protocol-template-repository.ts +42 -0
- package/src/lib/server/protocols/protocol-templates.ts +4 -2
- package/src/lib/server/protocols/protocol-types.ts +10 -7
- package/src/lib/server/provider-endpoint.ts +7 -12
- package/src/lib/server/provider-model-discovery.ts +2 -11
- package/src/lib/server/query-expansion.ts +5 -6
- package/src/lib/server/run-context.test.ts +365 -0
- package/src/lib/server/run-context.ts +367 -0
- package/src/lib/server/runtime/heartbeat-service.ts +7 -5
- package/src/lib/server/runtime/queue/core.ts +61 -190
- package/src/lib/server/runtime/run-ledger.ts +8 -0
- package/src/lib/server/runtime/session-run-manager/drain.ts +2 -2
- package/src/lib/server/runtime/session-run-manager/enqueue.ts +6 -0
- package/src/lib/server/runtime/session-run-manager/state.ts +4 -0
- package/src/lib/server/schedules/schedule-route-service.ts +230 -0
- package/src/lib/server/service-result.ts +16 -0
- package/src/lib/server/session-note.ts +2 -3
- package/src/lib/server/session-reset-policy.ts +4 -3
- package/src/lib/server/session-tools/connector.ts +9 -6
- package/src/lib/server/session-tools/context-mgmt.ts +58 -9
- package/src/lib/server/session-tools/crud.ts +162 -10
- package/src/lib/server/session-tools/delegate.ts +1 -1
- package/src/lib/server/session-tools/manage-tasks.test.ts +152 -0
- package/src/lib/server/session-tools/memory.ts +6 -4
- package/src/lib/server/session-tools/session-info.test.ts +56 -0
- package/src/lib/server/session-tools/session-info.ts +119 -12
- package/src/lib/server/session-tools/skill-runtime.ts +3 -1
- package/src/lib/server/session-tools/skills.ts +15 -15
- package/src/lib/server/session-tools/subagent.test.ts +115 -1
- package/src/lib/server/session-tools/subagent.ts +125 -7
- package/src/lib/server/session-tools/team-context.ts +4 -3
- package/src/lib/server/session-tools/wallet.ts +0 -58
- package/src/lib/server/sessions/session-lineage.ts +55 -0
- package/src/lib/server/sessions/session-repository.ts +2 -2
- package/src/lib/server/skills/learned-skills.ts +24 -23
- package/src/lib/server/skills/runtime-skill-resolver.ts +2 -1
- package/src/lib/server/skills/skill-repository.ts +136 -13
- package/src/lib/server/skills/skill-suggestions.ts +25 -28
- package/src/lib/server/storage-normalization.test.ts +44 -267
- package/src/lib/server/storage-normalization.ts +75 -0
- package/src/lib/server/storage.ts +19 -0
- package/src/lib/server/structured-extract.ts +3 -14
- package/src/lib/server/tasks/task-followups.ts +16 -11
- package/src/lib/server/tasks/task-result.test.ts +25 -29
- package/src/lib/server/tasks/task-result.ts +5 -9
- package/src/lib/server/tasks/task-route-service.ts +449 -0
- package/src/lib/server/text-normalization.ts +41 -0
- package/src/lib/server/tool-planning.ts +6 -42
- package/src/lib/server/upload-path.ts +5 -0
- package/src/lib/server/working-state/extraction.ts +614 -0
- package/src/lib/server/working-state/normalization.ts +866 -0
- package/src/lib/server/working-state/prompt.ts +60 -0
- package/src/lib/server/working-state/repository.ts +38 -0
- package/src/lib/server/working-state/service.test.ts +253 -0
- package/src/lib/server/working-state/service.ts +293 -0
- package/src/lib/validation/schemas.ts +1 -0
- package/src/lib/ws-client.ts +3 -3
- package/src/stores/slices/task-slice.ts +1 -4
- package/src/stores/use-chatroom-store.ts +2 -2
- package/src/types/index.ts +277 -12
|
@@ -1,42 +1,29 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useEffect, useRef, useState } from 'react'
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
4
4
|
import { BottomSheet } from '@/components/shared/bottom-sheet'
|
|
5
5
|
import { OpenClawDeployPanel } from '@/components/openclaw/openclaw-deploy-panel'
|
|
6
6
|
import { useAppStore } from '@/stores/use-app-store'
|
|
7
|
-
import { api } from '@/lib/app/api-client'
|
|
8
7
|
import { toast } from 'sonner'
|
|
9
8
|
import type {
|
|
10
|
-
Credential,
|
|
11
9
|
OpenClawDevicePairRequest,
|
|
12
10
|
OpenClawNode,
|
|
13
11
|
OpenClawNodePairRequest,
|
|
14
12
|
OpenClawPairedDevice,
|
|
15
13
|
GatewayProfile,
|
|
16
14
|
} from '@/types'
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
error?: string
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface NodeListResult {
|
|
33
|
-
nodes?: OpenClawNode[]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface PairingListResult<T> {
|
|
37
|
-
pending?: T[]
|
|
38
|
-
paired?: OpenClawPairedDevice[]
|
|
39
|
-
}
|
|
15
|
+
import { useCreateCredentialMutation, useCredentialsQuery } from '@/features/credentials/queries'
|
|
16
|
+
import {
|
|
17
|
+
useCheckOpenClawGatewayMutation,
|
|
18
|
+
useDiscoverOpenClawGatewaysMutation,
|
|
19
|
+
useGatewayInvokeNodeMutation,
|
|
20
|
+
useGatewayPairingDecisionMutation,
|
|
21
|
+
useGatewayProfilesQuery,
|
|
22
|
+
useGatewayRemoveDeviceMutation,
|
|
23
|
+
useRefreshGatewayTopologyMutation,
|
|
24
|
+
useSaveGatewayProfileMutation,
|
|
25
|
+
type GatewayDiscoveryResult,
|
|
26
|
+
} from '@/features/gateways/queries'
|
|
40
27
|
|
|
41
28
|
interface GatewayImportShape {
|
|
42
29
|
name?: string
|
|
@@ -54,10 +41,19 @@ export function GatewaySheet() {
|
|
|
54
41
|
const setOpen = useAppStore((s) => s.setGatewaySheetOpen)
|
|
55
42
|
const editingId = useAppStore((s) => s.editingGatewayId)
|
|
56
43
|
const setEditingId = useAppStore((s) => s.setEditingGatewayId)
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
const
|
|
44
|
+
const gatewayProfilesQuery = useGatewayProfilesQuery({ enabled: open })
|
|
45
|
+
const credentialsQuery = useCredentialsQuery({ enabled: open })
|
|
46
|
+
const createCredentialMutation = useCreateCredentialMutation()
|
|
47
|
+
const saveGatewayMutation = useSaveGatewayProfileMutation()
|
|
48
|
+
const checkGatewayMutation = useCheckOpenClawGatewayMutation()
|
|
49
|
+
const discoverGatewaysMutation = useDiscoverOpenClawGatewaysMutation()
|
|
50
|
+
const refreshGatewayTopologyMutation = useRefreshGatewayTopologyMutation()
|
|
51
|
+
const gatewayPairingDecisionMutation = useGatewayPairingDecisionMutation()
|
|
52
|
+
const gatewayRemoveDeviceMutation = useGatewayRemoveDeviceMutation()
|
|
53
|
+
const gatewayInvokeNodeMutation = useGatewayInvokeNodeMutation()
|
|
54
|
+
|
|
55
|
+
const gatewayProfiles = gatewayProfilesQuery.data ?? []
|
|
56
|
+
const credentials = credentialsQuery.data ?? {}
|
|
61
57
|
|
|
62
58
|
const editing = editingId ? gatewayProfiles.find((item) => item.id === editingId) : null
|
|
63
59
|
const openClawCredentials = Object.values(credentials).filter((item) => item.provider === 'openclaw')
|
|
@@ -73,7 +69,7 @@ export function GatewaySheet() {
|
|
|
73
69
|
const [checking, setChecking] = useState(false)
|
|
74
70
|
const [checkMessage, setCheckMessage] = useState('')
|
|
75
71
|
const [discovering, setDiscovering] = useState(false)
|
|
76
|
-
const [discoveries, setDiscoveries] = useState<
|
|
72
|
+
const [discoveries, setDiscoveries] = useState<GatewayDiscoveryResult[]>([])
|
|
77
73
|
const [nodesLoading, setNodesLoading] = useState(false)
|
|
78
74
|
const [nodesError, setNodesError] = useState('')
|
|
79
75
|
const [nodes, setNodes] = useState<OpenClawNode[]>([])
|
|
@@ -88,11 +84,6 @@ export function GatewaySheet() {
|
|
|
88
84
|
const [deployment, setDeployment] = useState<GatewayProfile['deployment'] | null>(null)
|
|
89
85
|
const importFileRef = useRef<HTMLInputElement>(null)
|
|
90
86
|
|
|
91
|
-
useEffect(() => {
|
|
92
|
-
if (!open) return
|
|
93
|
-
void Promise.all([loadGatewayProfiles(), loadCredentials()])
|
|
94
|
-
}, [open, loadGatewayProfiles, loadCredentials])
|
|
95
|
-
|
|
96
87
|
useEffect(() => {
|
|
97
88
|
if (!open) return
|
|
98
89
|
setCheckMessage('')
|
|
@@ -127,61 +118,30 @@ export function GatewaySheet() {
|
|
|
127
118
|
setInvokeParamsText('{}')
|
|
128
119
|
}, [open, editing, gatewayProfiles.length])
|
|
129
120
|
|
|
130
|
-
const loadNodesAndDevices = async (profileId: string) => {
|
|
121
|
+
const loadNodesAndDevices = useCallback(async (profileId: string) => {
|
|
131
122
|
setNodesLoading(true)
|
|
132
123
|
setNodesError('')
|
|
133
124
|
try {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}),
|
|
143
|
-
api<GatewayRpcResponse<PairingListResult<OpenClawDevicePairRequest>>>('POST', '/openclaw/gateway', {
|
|
144
|
-
method: 'device.pair.list',
|
|
145
|
-
params: { profileId },
|
|
146
|
-
}),
|
|
147
|
-
])
|
|
148
|
-
|
|
149
|
-
if (nodesRes.error) throw new Error(nodesRes.error)
|
|
150
|
-
if (nodePairRes.error) throw new Error(nodePairRes.error)
|
|
151
|
-
if (devicePairRes.error) throw new Error(devicePairRes.error)
|
|
152
|
-
|
|
153
|
-
const nextNodes = Array.isArray(nodesRes.result?.nodes) ? nodesRes.result.nodes : []
|
|
154
|
-
const nextNodePairings = Array.isArray(nodePairRes.result?.pending) ? nodePairRes.result.pending : []
|
|
155
|
-
const nextDevicePairings = Array.isArray(devicePairRes.result?.pending) ? devicePairRes.result.pending : []
|
|
156
|
-
const nextPairedDevices = Array.isArray(devicePairRes.result?.paired) ? devicePairRes.result.paired : []
|
|
157
|
-
|
|
158
|
-
setNodes(nextNodes)
|
|
159
|
-
setNodePairings(nextNodePairings)
|
|
160
|
-
setDevicePairings(nextDevicePairings)
|
|
161
|
-
setPairedDevices(nextPairedDevices)
|
|
162
|
-
const nextStats: NonNullable<GatewayProfile['stats']> = {
|
|
163
|
-
nodeCount: nextNodes.length,
|
|
164
|
-
connectedNodeCount: nextNodes.filter((node) => node.connected).length,
|
|
165
|
-
pendingNodePairings: nextNodePairings.length,
|
|
166
|
-
pairedDeviceCount: nextPairedDevices.length,
|
|
167
|
-
pendingDevicePairings: nextDevicePairings.length,
|
|
168
|
-
}
|
|
169
|
-
if (nextNodes[0]) {
|
|
170
|
-
setInvokeNodeId((current) => current || nextNodes[0].nodeId)
|
|
171
|
-
setInvokeCommand((current) => current || nextNodes[0].commands?.[0] || '')
|
|
125
|
+
const result = await refreshGatewayTopologyMutation.mutateAsync(profileId)
|
|
126
|
+
setNodes(result.nodes)
|
|
127
|
+
setNodePairings(result.nodePairings)
|
|
128
|
+
setDevicePairings(result.devicePairings)
|
|
129
|
+
setPairedDevices(result.pairedDevices)
|
|
130
|
+
if (result.nodes[0]) {
|
|
131
|
+
setInvokeNodeId((current) => current || result.nodes[0].nodeId)
|
|
132
|
+
setInvokeCommand((current) => current || result.nodes[0].commands?.[0] || '')
|
|
172
133
|
}
|
|
173
|
-
void api('PUT', `/gateways/${profileId}`, { stats: nextStats }).catch(() => {})
|
|
174
134
|
} catch (err: unknown) {
|
|
175
135
|
setNodesError(err instanceof Error ? err.message : 'Failed to load nodes for this gateway.')
|
|
176
136
|
} finally {
|
|
177
137
|
setNodesLoading(false)
|
|
178
138
|
}
|
|
179
|
-
}
|
|
139
|
+
}, [refreshGatewayTopologyMutation])
|
|
180
140
|
|
|
181
141
|
useEffect(() => {
|
|
182
142
|
if (!open || !editing?.id) return
|
|
183
143
|
void loadNodesAndDevices(editing.id)
|
|
184
|
-
}, [open, editing?.id])
|
|
144
|
+
}, [open, editing?.id, loadNodesAndDevices])
|
|
185
145
|
|
|
186
146
|
const onClose = () => {
|
|
187
147
|
setOpen(false)
|
|
@@ -193,7 +153,7 @@ export function GatewaySheet() {
|
|
|
193
153
|
try {
|
|
194
154
|
let nextCredentialId = credentialId
|
|
195
155
|
if (tokenDraft.trim()) {
|
|
196
|
-
const created = await
|
|
156
|
+
const created = await createCredentialMutation.mutateAsync({
|
|
197
157
|
provider: 'openclaw',
|
|
198
158
|
name: `${name.trim() || 'OpenClaw Gateway'} token`,
|
|
199
159
|
apiKey: tokenDraft.trim(),
|
|
@@ -209,14 +169,11 @@ export function GatewaySheet() {
|
|
|
209
169
|
deployment,
|
|
210
170
|
isDefault,
|
|
211
171
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
toast.success('Gateway added')
|
|
218
|
-
}
|
|
219
|
-
await Promise.all([loadGatewayProfiles(), loadCredentials()])
|
|
172
|
+
await saveGatewayMutation.mutateAsync({
|
|
173
|
+
id: editing?.id,
|
|
174
|
+
payload,
|
|
175
|
+
})
|
|
176
|
+
toast.success(editing ? 'Gateway updated' : 'Gateway added')
|
|
220
177
|
onClose()
|
|
221
178
|
} catch (err: unknown) {
|
|
222
179
|
toast.error(err instanceof Error ? err.message : 'Failed to save gateway')
|
|
@@ -229,11 +186,11 @@ export function GatewaySheet() {
|
|
|
229
186
|
setChecking(true)
|
|
230
187
|
setCheckMessage('')
|
|
231
188
|
try {
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
189
|
+
const result = await checkGatewayMutation.mutateAsync({
|
|
190
|
+
endpoint,
|
|
191
|
+
credentialId,
|
|
192
|
+
token: tokenDraft,
|
|
193
|
+
})
|
|
237
194
|
if (result.ok) {
|
|
238
195
|
setCheckMessage(result.message || `Connected. ${result.models?.length ? `${result.models.length} model${result.models.length === 1 ? '' : 's'} visible.` : 'Gateway responded normally.'}`)
|
|
239
196
|
} else {
|
|
@@ -249,7 +206,7 @@ export function GatewaySheet() {
|
|
|
249
206
|
const handleDiscover = async () => {
|
|
250
207
|
setDiscovering(true)
|
|
251
208
|
try {
|
|
252
|
-
const result = await
|
|
209
|
+
const result = await discoverGatewaysMutation.mutateAsync()
|
|
253
210
|
setDiscoveries((result.gateways || []).filter((item) => item.healthy))
|
|
254
211
|
} catch {
|
|
255
212
|
setDiscoveries([])
|
|
@@ -261,11 +218,11 @@ export function GatewaySheet() {
|
|
|
261
218
|
const handlePairingDecision = async (kind: 'node' | 'device', requestId: string, decision: 'approve' | 'reject') => {
|
|
262
219
|
if (!editing?.id) return
|
|
263
220
|
try {
|
|
264
|
-
await
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
221
|
+
await gatewayPairingDecisionMutation.mutateAsync({
|
|
222
|
+
profileId: editing.id,
|
|
223
|
+
kind,
|
|
224
|
+
requestId,
|
|
225
|
+
decision,
|
|
269
226
|
})
|
|
270
227
|
toast.success(`${kind === 'node' ? 'Node' : 'Device'} ${decision}d`)
|
|
271
228
|
await loadNodesAndDevices(editing.id)
|
|
@@ -277,10 +234,7 @@ export function GatewaySheet() {
|
|
|
277
234
|
const handleRemoveDevice = async (deviceId: string) => {
|
|
278
235
|
if (!editing?.id) return
|
|
279
236
|
try {
|
|
280
|
-
await
|
|
281
|
-
method: 'device.pair.remove',
|
|
282
|
-
params: { profileId: editing.id, deviceId },
|
|
283
|
-
})
|
|
237
|
+
await gatewayRemoveDeviceMutation.mutateAsync({ profileId: editing.id, deviceId })
|
|
284
238
|
toast.success('Device removed')
|
|
285
239
|
await loadNodesAndDevices(editing.id)
|
|
286
240
|
} catch (err: unknown) {
|
|
@@ -300,14 +254,11 @@ export function GatewaySheet() {
|
|
|
300
254
|
parsedParams = next as Record<string, unknown>
|
|
301
255
|
}
|
|
302
256
|
}
|
|
303
|
-
const result = await
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
command: invokeCommand.trim(),
|
|
309
|
-
params: parsedParams,
|
|
310
|
-
},
|
|
257
|
+
const result = await gatewayInvokeNodeMutation.mutateAsync({
|
|
258
|
+
profileId: editing.id,
|
|
259
|
+
nodeId: invokeNodeId.trim(),
|
|
260
|
+
command: invokeCommand.trim(),
|
|
261
|
+
params: parsedParams,
|
|
311
262
|
})
|
|
312
263
|
if (result.error) throw new Error(result.error)
|
|
313
264
|
setInvokeResult(JSON.stringify(result.result, null, 2))
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useQueryClient } from '@tanstack/react-query'
|
|
4
|
+
import { useWs } from '@/hooks/use-ws'
|
|
5
|
+
import { agentQueryKeys } from '@/features/agents/queries'
|
|
6
|
+
import { taskQueryKeys } from '@/features/tasks/queries'
|
|
7
|
+
import { protocolQueryKeys } from '@/features/protocols/queries'
|
|
8
|
+
import { providerQueryKeys } from '@/features/providers/queries'
|
|
9
|
+
import { gatewayQueryKeys } from '@/features/gateways/queries'
|
|
10
|
+
import { externalAgentQueryKeys } from '@/features/external-agents/queries'
|
|
11
|
+
import { chatQueryKeys } from '@/features/chats/queries'
|
|
12
|
+
import { connectorQueryKeys } from '@/features/connectors/queries'
|
|
13
|
+
import { skillQueryKeys, skillSuggestionQueryKeys } from '@/features/skills/queries'
|
|
14
|
+
|
|
15
|
+
function LiveQueryTopicSubscription({
|
|
16
|
+
topic,
|
|
17
|
+
fallbackMs,
|
|
18
|
+
onEvent,
|
|
19
|
+
}: {
|
|
20
|
+
topic: string
|
|
21
|
+
fallbackMs?: number
|
|
22
|
+
onEvent: () => void
|
|
23
|
+
}) {
|
|
24
|
+
useWs(topic, onEvent, fallbackMs)
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function LiveQuerySync() {
|
|
29
|
+
const queryClient = useQueryClient()
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
<LiveQueryTopicSubscription
|
|
34
|
+
topic="agents"
|
|
35
|
+
fallbackMs={60_000}
|
|
36
|
+
onEvent={() => {
|
|
37
|
+
void queryClient.invalidateQueries({ queryKey: agentQueryKeys.all })
|
|
38
|
+
}}
|
|
39
|
+
/>
|
|
40
|
+
<LiveQueryTopicSubscription
|
|
41
|
+
topic="tasks"
|
|
42
|
+
fallbackMs={5_000}
|
|
43
|
+
onEvent={() => {
|
|
44
|
+
void queryClient.invalidateQueries({ queryKey: taskQueryKeys.all })
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
<LiveQueryTopicSubscription
|
|
48
|
+
topic="protocol_runs"
|
|
49
|
+
fallbackMs={2_000}
|
|
50
|
+
onEvent={() => {
|
|
51
|
+
void queryClient.invalidateQueries({ queryKey: protocolQueryKeys.all })
|
|
52
|
+
}}
|
|
53
|
+
/>
|
|
54
|
+
<LiveQueryTopicSubscription
|
|
55
|
+
topic="protocol_templates"
|
|
56
|
+
fallbackMs={2_000}
|
|
57
|
+
onEvent={() => {
|
|
58
|
+
void queryClient.invalidateQueries({ queryKey: protocolQueryKeys.templates() })
|
|
59
|
+
}}
|
|
60
|
+
/>
|
|
61
|
+
<LiveQueryTopicSubscription
|
|
62
|
+
topic="providers"
|
|
63
|
+
fallbackMs={20_000}
|
|
64
|
+
onEvent={() => {
|
|
65
|
+
void queryClient.invalidateQueries({ queryKey: providerQueryKeys.all })
|
|
66
|
+
}}
|
|
67
|
+
/>
|
|
68
|
+
<LiveQueryTopicSubscription
|
|
69
|
+
topic="gateways"
|
|
70
|
+
fallbackMs={20_000}
|
|
71
|
+
onEvent={() => {
|
|
72
|
+
void queryClient.invalidateQueries({ queryKey: gatewayQueryKeys.all })
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
<LiveQueryTopicSubscription
|
|
76
|
+
topic="external_agents"
|
|
77
|
+
fallbackMs={20_000}
|
|
78
|
+
onEvent={() => {
|
|
79
|
+
void queryClient.invalidateQueries({ queryKey: externalAgentQueryKeys.all })
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
<LiveQueryTopicSubscription
|
|
83
|
+
topic="connectors"
|
|
84
|
+
fallbackMs={15_000}
|
|
85
|
+
onEvent={() => {
|
|
86
|
+
void queryClient.invalidateQueries({ queryKey: connectorQueryKeys.all })
|
|
87
|
+
}}
|
|
88
|
+
/>
|
|
89
|
+
<LiveQueryTopicSubscription
|
|
90
|
+
topic="sessions"
|
|
91
|
+
fallbackMs={15_000}
|
|
92
|
+
onEvent={() => {
|
|
93
|
+
void queryClient.invalidateQueries({ queryKey: chatQueryKeys.all })
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
<LiveQueryTopicSubscription
|
|
97
|
+
topic="messages"
|
|
98
|
+
fallbackMs={5_000}
|
|
99
|
+
onEvent={() => {
|
|
100
|
+
void queryClient.invalidateQueries({
|
|
101
|
+
predicate: (q) => q.queryKey[0] === 'chats' && q.queryKey[2] === 'messages',
|
|
102
|
+
})
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
<LiveQueryTopicSubscription
|
|
106
|
+
topic="skills"
|
|
107
|
+
fallbackMs={20_000}
|
|
108
|
+
onEvent={() => {
|
|
109
|
+
void queryClient.invalidateQueries({ queryKey: skillQueryKeys.all })
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
<LiveQueryTopicSubscription
|
|
113
|
+
topic="skill_suggestions"
|
|
114
|
+
fallbackMs={20_000}
|
|
115
|
+
onEvent={() => {
|
|
116
|
+
void queryClient.invalidateQueries({ queryKey: skillSuggestionQueryKeys.all })
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { useEffect, useMemo, useState } from 'react'
|
|
4
|
-
import {
|
|
4
|
+
import { useAgentsQuery } from '@/features/agents/queries'
|
|
5
|
+
import { useChatroomsQuery } from '@/features/chatrooms/queries'
|
|
6
|
+
import { useMissionsQuery } from '@/features/missions/queries'
|
|
7
|
+
import { useCreateProtocolRunMutation, useProtocolTemplatesQuery } from '@/features/protocols/queries'
|
|
8
|
+
import { useTasksQuery } from '@/features/tasks/queries'
|
|
5
9
|
import { BottomSheet } from '@/components/shared/bottom-sheet'
|
|
6
10
|
import { SheetFooter } from '@/components/shared/sheet-footer'
|
|
7
11
|
import type { BoardTask, Chatroom, Mission, ProtocolRun, ProtocolTemplate } from '@/types'
|
|
@@ -97,16 +101,28 @@ export function StructuredSessionLauncher({
|
|
|
97
101
|
allowContextSelection = false,
|
|
98
102
|
variant = 'default',
|
|
99
103
|
}: Props) {
|
|
100
|
-
const [templates, setTemplates] = useState<ProtocolTemplate[]>([])
|
|
101
|
-
const [agents, setAgents] = useState<AgentList>({})
|
|
102
|
-
const [chatrooms, setChatrooms] = useState<Record<string, Chatroom>>({})
|
|
103
|
-
const [missions, setMissions] = useState<Mission[]>([])
|
|
104
|
-
const [tasks, setTasks] = useState<TaskList>({})
|
|
105
|
-
const [loading, setLoading] = useState(false)
|
|
106
104
|
const [saving, setSaving] = useState(false)
|
|
107
105
|
const [advancedOpen, setAdvancedOpen] = useState(false)
|
|
108
106
|
const [error, setError] = useState<string | null>(null)
|
|
109
107
|
const [form, setForm] = useState<FormState>(() => buildInitialState(initialContext))
|
|
108
|
+
const templatesQuery = useProtocolTemplatesQuery({ enabled: open })
|
|
109
|
+
const agentsQuery = useAgentsQuery({ enabled: open })
|
|
110
|
+
const chatroomsQuery = useChatroomsQuery({ enabled: open && allowContextSelection })
|
|
111
|
+
const missionsQuery = useMissionsQuery({ enabled: open && allowContextSelection, limit: 80 })
|
|
112
|
+
const tasksQuery = useTasksQuery({ includeArchived: true, enabled: open && allowContextSelection })
|
|
113
|
+
const createRunMutation = useCreateProtocolRunMutation()
|
|
114
|
+
const templates = templatesQuery.data ?? []
|
|
115
|
+
const agents = agentsQuery.data ?? {}
|
|
116
|
+
const chatrooms = chatroomsQuery.data ?? {}
|
|
117
|
+
const missions = missionsQuery.data ?? []
|
|
118
|
+
const tasks = tasksQuery.data ?? {}
|
|
119
|
+
const loading = (
|
|
120
|
+
templatesQuery.isLoading
|
|
121
|
+
|| agentsQuery.isLoading
|
|
122
|
+
|| chatroomsQuery.isLoading
|
|
123
|
+
|| missionsQuery.isLoading
|
|
124
|
+
|| tasksQuery.isLoading
|
|
125
|
+
)
|
|
110
126
|
const breakoutMode = variant === 'breakout'
|
|
111
127
|
|
|
112
128
|
useEffect(() => {
|
|
@@ -117,43 +133,6 @@ export function StructuredSessionLauncher({
|
|
|
117
133
|
setSaving(false)
|
|
118
134
|
}, [initialContext, open])
|
|
119
135
|
|
|
120
|
-
useEffect(() => {
|
|
121
|
-
if (!open) return
|
|
122
|
-
let cancelled = false
|
|
123
|
-
setLoading(true)
|
|
124
|
-
void (async () => {
|
|
125
|
-
try {
|
|
126
|
-
const requests: Promise<unknown>[] = [
|
|
127
|
-
api<ProtocolTemplate[]>('GET', '/protocols/templates'),
|
|
128
|
-
api<AgentList>('GET', '/agents'),
|
|
129
|
-
]
|
|
130
|
-
if (allowContextSelection) {
|
|
131
|
-
requests.push(
|
|
132
|
-
api<Record<string, Chatroom>>('GET', '/chatrooms'),
|
|
133
|
-
api<Mission[]>('GET', '/missions?limit=80'),
|
|
134
|
-
api<TaskList>('GET', '/tasks'),
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
const result = await Promise.all(requests)
|
|
138
|
-
if (cancelled) return
|
|
139
|
-
setTemplates(Array.isArray(result[0]) ? (result[0] as ProtocolTemplate[]) : [])
|
|
140
|
-
setAgents((result[1] as AgentList) || {})
|
|
141
|
-
if (allowContextSelection) {
|
|
142
|
-
setChatrooms((result[2] as Record<string, Chatroom>) || {})
|
|
143
|
-
setMissions(Array.isArray(result[3]) ? (result[3] as Mission[]) : [])
|
|
144
|
-
setTasks((result[4] as TaskList) || {})
|
|
145
|
-
}
|
|
146
|
-
} catch (err) {
|
|
147
|
-
if (!cancelled) setError(err instanceof Error ? err.message : 'Unable to load structured-session options.')
|
|
148
|
-
} finally {
|
|
149
|
-
if (!cancelled) setLoading(false)
|
|
150
|
-
}
|
|
151
|
-
})()
|
|
152
|
-
return () => {
|
|
153
|
-
cancelled = true
|
|
154
|
-
}
|
|
155
|
-
}, [allowContextSelection, open])
|
|
156
|
-
|
|
157
136
|
const agentOptions = useMemo(
|
|
158
137
|
() => Object.values(agents).sort((a, b) => a.name.localeCompare(b.name)),
|
|
159
138
|
[agents],
|
|
@@ -194,7 +173,7 @@ export function StructuredSessionLauncher({
|
|
|
194
173
|
}
|
|
195
174
|
setSaving(true)
|
|
196
175
|
try {
|
|
197
|
-
const run = await
|
|
176
|
+
const run = await createRunMutation.mutateAsync({
|
|
198
177
|
title: form.title.trim(),
|
|
199
178
|
templateId: form.templateId,
|
|
200
179
|
participantAgentIds: form.participantAgentIds,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { QueryClientProvider } from '@tanstack/react-query'
|
|
4
|
+
import { useState } from 'react'
|
|
5
|
+
import { LiveQuerySync } from '@/components/layout/live-query-sync'
|
|
6
|
+
import { createAppQueryClient } from '@/lib/query/client'
|
|
7
|
+
|
|
8
|
+
export function AppQueryProvider({ children }: { children: React.ReactNode }) {
|
|
9
|
+
const [queryClient] = useState(createAppQueryClient)
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<QueryClientProvider client={queryClient}>
|
|
13
|
+
<LiveQuerySync />
|
|
14
|
+
{children}
|
|
15
|
+
</QueryClientProvider>
|
|
16
|
+
)
|
|
17
|
+
}
|