@swarmclawai/swarmclaw 0.7.2 → 0.7.4
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 +116 -50
- package/bin/package-manager.js +157 -0
- package/bin/package-manager.test.js +90 -0
- package/bin/server-cmd.js +38 -7
- package/bin/swarmclaw.js +54 -4
- package/bin/update-cmd.js +48 -10
- package/bin/update-cmd.test.js +55 -0
- package/package.json +8 -3
- package/scripts/postinstall.mjs +26 -0
- package/src/app/api/agents/[id]/route.ts +43 -0
- package/src/app/api/agents/[id]/thread/route.ts +39 -8
- package/src/app/api/agents/route.ts +35 -2
- package/src/app/api/auth/route.ts +77 -8
- package/src/app/api/chatrooms/[id]/chat/route.ts +22 -6
- package/src/app/api/chatrooms/[id]/pins/route.ts +2 -1
- package/src/app/api/chatrooms/[id]/reactions/route.ts +2 -1
- package/src/app/api/chatrooms/[id]/route.ts +6 -0
- package/src/app/api/chats/[id]/browser/route.ts +5 -1
- package/src/app/api/chats/[id]/chat/route.ts +7 -3
- package/src/app/api/chats/[id]/messages/route.ts +19 -13
- package/src/app/api/chats/[id]/route.ts +30 -0
- package/src/app/api/chats/[id]/stop/route.ts +6 -1
- package/src/app/api/chats/heartbeat/route.ts +2 -1
- package/src/app/api/chats/route.ts +23 -1
- package/src/app/api/connectors/[id]/doctor/route.ts +26 -0
- package/src/app/api/connectors/doctor/route.ts +13 -0
- package/src/app/api/external-agents/[id]/heartbeat/route.ts +33 -0
- package/src/app/api/external-agents/[id]/route.ts +31 -0
- package/src/app/api/external-agents/register/route.ts +3 -0
- package/src/app/api/external-agents/route.ts +66 -0
- package/src/app/api/files/open/route.ts +16 -14
- package/src/app/api/gateways/[id]/health/route.ts +28 -0
- package/src/app/api/gateways/[id]/route.ts +79 -0
- package/src/app/api/gateways/route.ts +57 -0
- package/src/app/api/memory/maintenance/route.ts +11 -1
- package/src/app/api/openclaw/agent-files/route.ts +27 -4
- package/src/app/api/openclaw/gateway/route.ts +10 -7
- package/src/app/api/openclaw/skills/route.ts +12 -4
- package/src/app/api/plugins/dependencies/route.ts +24 -0
- package/src/app/api/plugins/install/route.ts +15 -92
- package/src/app/api/plugins/route.ts +3 -26
- package/src/app/api/plugins/settings/route.ts +17 -12
- package/src/app/api/plugins/ui/route.ts +1 -0
- package/src/app/api/providers/[id]/discover-models/route.ts +27 -0
- package/src/app/api/schedules/[id]/route.ts +38 -9
- package/src/app/api/schedules/route.ts +51 -28
- package/src/app/api/settings/route.ts +55 -17
- package/src/app/api/setup/doctor/route.ts +6 -4
- package/src/app/api/tasks/[id]/route.ts +16 -6
- package/src/app/api/tasks/bulk/route.ts +3 -3
- package/src/app/api/tasks/route.ts +9 -4
- package/src/app/api/webhooks/[id]/route.ts +8 -1
- package/src/app/page.tsx +135 -17
- package/src/cli/binary.test.js +142 -0
- package/src/cli/index.js +38 -11
- package/src/cli/index.test.js +195 -0
- package/src/cli/index.ts +21 -12
- package/src/cli/server-cmd.test.js +59 -0
- package/src/cli/spec.js +20 -2
- package/src/components/agents/agent-card.tsx +15 -12
- package/src/components/agents/agent-chat-list.tsx +101 -1
- package/src/components/agents/agent-list.tsx +46 -9
- package/src/components/agents/agent-sheet.tsx +456 -23
- package/src/components/agents/inspector-panel.tsx +110 -49
- package/src/components/agents/sandbox-env-panel.tsx +4 -1
- package/src/components/auth/access-key-gate.tsx +36 -97
- package/src/components/auth/setup-wizard.tsx +970 -275
- package/src/components/chat/chat-area.tsx +70 -27
- package/src/components/chat/chat-card.tsx +6 -21
- package/src/components/chat/chat-header.tsx +263 -366
- package/src/components/chat/chat-list.tsx +62 -26
- package/src/components/chat/checkpoint-timeline.tsx +1 -1
- package/src/components/chat/message-list.tsx +145 -19
- package/src/components/chatrooms/chatroom-input.tsx +96 -33
- package/src/components/chatrooms/chatroom-list.tsx +141 -72
- package/src/components/chatrooms/chatroom-message.tsx +7 -6
- package/src/components/chatrooms/chatroom-sheet.tsx +13 -1
- package/src/components/chatrooms/chatroom-tool-request-banner.tsx +5 -2
- package/src/components/chatrooms/chatroom-view.tsx +422 -209
- package/src/components/chatrooms/reaction-picker.tsx +38 -33
- package/src/components/connectors/connector-list.tsx +265 -127
- package/src/components/connectors/connector-sheet.tsx +217 -0
- package/src/components/gateways/gateway-sheet.tsx +567 -0
- package/src/components/home/home-view.tsx +128 -4
- package/src/components/input/chat-input.tsx +135 -86
- package/src/components/layout/app-layout.tsx +385 -194
- package/src/components/layout/mobile-header.tsx +26 -8
- package/src/components/memory/memory-browser.tsx +71 -6
- package/src/components/memory/memory-card.tsx +18 -0
- package/src/components/memory/memory-detail.tsx +58 -31
- package/src/components/memory/memory-sheet.tsx +32 -4
- package/src/components/plugins/plugin-list.tsx +15 -3
- package/src/components/plugins/plugin-sheet.tsx +118 -9
- package/src/components/projects/project-detail.tsx +189 -1
- package/src/components/providers/provider-list.tsx +158 -2
- package/src/components/providers/provider-sheet.tsx +81 -70
- package/src/components/shared/agent-picker-list.tsx +2 -2
- package/src/components/shared/bottom-sheet.tsx +31 -15
- package/src/components/shared/command-palette.tsx +111 -24
- package/src/components/shared/confirm-dialog.tsx +45 -30
- package/src/components/shared/model-combobox.tsx +90 -8
- package/src/components/shared/settings/plugin-manager.tsx +20 -4
- package/src/components/shared/settings/section-capability-policy.tsx +105 -0
- package/src/components/shared/settings/section-heartbeat.tsx +88 -6
- package/src/components/shared/settings/section-orchestrator.tsx +6 -3
- package/src/components/shared/settings/section-runtime-loop.tsx +5 -5
- package/src/components/shared/settings/section-secrets.tsx +6 -6
- package/src/components/shared/settings/section-user-preferences.tsx +1 -1
- package/src/components/shared/settings/section-voice.tsx +5 -1
- package/src/components/shared/settings/section-web-search.tsx +10 -2
- package/src/components/shared/settings/settings-page.tsx +248 -47
- package/src/components/tasks/approvals-panel.tsx +211 -18
- package/src/components/tasks/task-board.tsx +242 -46
- package/src/components/ui/dialog.tsx +2 -2
- package/src/components/usage/metrics-dashboard.tsx +74 -1
- package/src/components/wallets/wallet-approval-dialog.tsx +59 -54
- package/src/components/wallets/wallet-panel.tsx +17 -5
- package/src/components/webhooks/webhook-sheet.tsx +7 -7
- package/src/lib/auth.ts +17 -0
- package/src/lib/chat-streaming-state.test.ts +108 -0
- package/src/lib/chat-streaming-state.ts +108 -0
- package/src/lib/heartbeat-defaults.ts +48 -0
- package/src/lib/memory-presentation.ts +59 -0
- package/src/lib/openclaw-agent-id.test.ts +14 -0
- package/src/lib/openclaw-agent-id.ts +31 -0
- package/src/lib/provider-model-discovery-client.ts +29 -0
- package/src/lib/providers/index.ts +12 -5
- package/src/lib/runtime-loop.ts +105 -3
- package/src/lib/safe-storage.ts +6 -1
- package/src/lib/server/agent-assignment.test.ts +112 -0
- package/src/lib/server/agent-assignment.ts +169 -0
- package/src/lib/server/agent-runtime-config.test.ts +141 -0
- package/src/lib/server/agent-runtime-config.ts +277 -0
- package/src/lib/server/approval-connector-notify.test.ts +253 -0
- package/src/lib/server/approvals-auto-approve.test.ts +264 -0
- package/src/lib/server/approvals.ts +483 -75
- package/src/lib/server/autonomy-runtime.test.ts +341 -0
- package/src/lib/server/browser-state.test.ts +118 -0
- package/src/lib/server/browser-state.ts +123 -0
- package/src/lib/server/build-llm.test.ts +44 -0
- package/src/lib/server/build-llm.ts +11 -4
- package/src/lib/server/builtin-plugins.ts +34 -0
- package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
- package/src/lib/server/chat-execution-tool-events.test.ts +219 -0
- package/src/lib/server/chat-execution.ts +402 -125
- package/src/lib/server/chatroom-health.test.ts +26 -0
- package/src/lib/server/chatroom-health.ts +2 -3
- package/src/lib/server/chatroom-helpers.test.ts +74 -2
- package/src/lib/server/chatroom-helpers.ts +144 -11
- package/src/lib/server/chatroom-session-persistence.test.ts +87 -0
- package/src/lib/server/connectors/discord.ts +175 -11
- package/src/lib/server/connectors/doctor.test.ts +80 -0
- package/src/lib/server/connectors/doctor.ts +116 -0
- package/src/lib/server/connectors/manager.ts +994 -130
- package/src/lib/server/connectors/policy.test.ts +222 -0
- package/src/lib/server/connectors/policy.ts +452 -0
- package/src/lib/server/connectors/slack.ts +189 -10
- package/src/lib/server/connectors/telegram.ts +65 -15
- package/src/lib/server/connectors/thread-context.test.ts +44 -0
- package/src/lib/server/connectors/thread-context.ts +72 -0
- package/src/lib/server/connectors/types.ts +41 -11
- package/src/lib/server/daemon-state.ts +62 -3
- package/src/lib/server/data-dir.ts +13 -0
- package/src/lib/server/delegation-jobs.test.ts +140 -0
- package/src/lib/server/delegation-jobs.ts +248 -0
- package/src/lib/server/document-utils.test.ts +47 -0
- package/src/lib/server/document-utils.ts +397 -0
- package/src/lib/server/eval/agent-regression.test.ts +47 -0
- package/src/lib/server/eval/agent-regression.ts +1742 -0
- package/src/lib/server/eval/runner.ts +11 -1
- package/src/lib/server/eval/store.ts +2 -1
- package/src/lib/server/heartbeat-service.ts +23 -43
- package/src/lib/server/heartbeat-source.test.ts +22 -0
- package/src/lib/server/heartbeat-source.ts +7 -0
- package/src/lib/server/identity-continuity.test.ts +77 -0
- package/src/lib/server/identity-continuity.ts +127 -0
- package/src/lib/server/mailbox-utils.ts +347 -0
- package/src/lib/server/main-agent-loop.ts +31 -964
- package/src/lib/server/memory-db.ts +4 -6
- package/src/lib/server/memory-tiers.ts +40 -0
- package/src/lib/server/openclaw-agent-resolver.test.ts +70 -0
- package/src/lib/server/openclaw-agent-resolver.ts +128 -0
- package/src/lib/server/openclaw-exec-config.ts +6 -5
- package/src/lib/server/openclaw-gateway.ts +123 -36
- package/src/lib/server/openclaw-skills-normalize.test.ts +56 -0
- package/src/lib/server/openclaw-skills-normalize.ts +136 -0
- package/src/lib/server/openclaw-sync.ts +3 -2
- package/src/lib/server/orchestrator-lg.ts +18 -8
- package/src/lib/server/orchestrator.ts +5 -4
- package/src/lib/server/playwright-proxy.mjs +27 -3
- package/src/lib/server/plugins.test.ts +215 -0
- package/src/lib/server/plugins.ts +832 -69
- package/src/lib/server/provider-health.ts +33 -3
- package/src/lib/server/provider-model-discovery.ts +481 -0
- package/src/lib/server/queue.ts +4 -21
- package/src/lib/server/runtime-settings.test.ts +119 -0
- package/src/lib/server/runtime-settings.ts +12 -92
- package/src/lib/server/schedule-normalization.ts +187 -0
- package/src/lib/server/scheduler.ts +2 -0
- package/src/lib/server/session-archive-memory.test.ts +85 -0
- package/src/lib/server/session-archive-memory.ts +230 -0
- package/src/lib/server/session-mailbox.ts +8 -18
- package/src/lib/server/session-reset-policy.test.ts +99 -0
- package/src/lib/server/session-reset-policy.ts +311 -0
- package/src/lib/server/session-run-manager.ts +33 -80
- package/src/lib/server/session-tools/autonomy-tools.test.ts +128 -0
- package/src/lib/server/session-tools/calendar.ts +2 -12
- package/src/lib/server/session-tools/connector.ts +109 -8
- package/src/lib/server/session-tools/context.ts +14 -2
- package/src/lib/server/session-tools/crawl.ts +447 -0
- package/src/lib/server/session-tools/crud.ts +96 -34
- package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
- package/src/lib/server/session-tools/delegate.ts +406 -20
- package/src/lib/server/session-tools/discovery-approvals.test.ts +170 -0
- package/src/lib/server/session-tools/discovery.ts +40 -12
- package/src/lib/server/session-tools/document.ts +283 -0
- package/src/lib/server/session-tools/email.ts +1 -3
- package/src/lib/server/session-tools/extract.ts +137 -0
- package/src/lib/server/session-tools/file-normalize.test.ts +98 -0
- package/src/lib/server/session-tools/file-send.test.ts +84 -1
- package/src/lib/server/session-tools/file.ts +243 -24
- package/src/lib/server/session-tools/http.ts +9 -3
- package/src/lib/server/session-tools/human-loop.ts +227 -0
- package/src/lib/server/session-tools/image-gen.ts +1 -3
- package/src/lib/server/session-tools/index.ts +87 -2
- package/src/lib/server/session-tools/mailbox.ts +276 -0
- package/src/lib/server/session-tools/manage-schedules.test.ts +137 -0
- package/src/lib/server/session-tools/memory.ts +35 -3
- package/src/lib/server/session-tools/monitor.ts +162 -12
- package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
- package/src/lib/server/session-tools/openclaw-nodes.test.ts +111 -0
- package/src/lib/server/session-tools/openclaw-nodes.ts +86 -20
- package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
- package/src/lib/server/session-tools/platform.ts +142 -4
- package/src/lib/server/session-tools/plugin-creator.ts +95 -25
- package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
- package/src/lib/server/session-tools/replicate.ts +1 -3
- package/src/lib/server/session-tools/sandbox.ts +51 -92
- package/src/lib/server/session-tools/schedule.ts +20 -10
- package/src/lib/server/session-tools/session-info.ts +58 -4
- package/src/lib/server/session-tools/session-tools-wiring.test.ts +54 -17
- package/src/lib/server/session-tools/shell.ts +2 -2
- package/src/lib/server/session-tools/subagent.ts +195 -27
- package/src/lib/server/session-tools/table.ts +587 -0
- package/src/lib/server/session-tools/wallet.ts +13 -10
- package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
- package/src/lib/server/session-tools/web.ts +947 -108
- package/src/lib/server/storage.ts +255 -10
- package/src/lib/server/stream-agent-chat.test.ts +61 -0
- package/src/lib/server/stream-agent-chat.ts +185 -25
- package/src/lib/server/structured-extract.test.ts +72 -0
- package/src/lib/server/structured-extract.ts +373 -0
- package/src/lib/server/task-mention.test.ts +16 -2
- package/src/lib/server/task-mention.ts +61 -11
- package/src/lib/server/tool-aliases.ts +80 -12
- package/src/lib/server/tool-capability-policy.ts +7 -1
- package/src/lib/server/tool-retry.ts +2 -0
- package/src/lib/server/watch-jobs.test.ts +173 -0
- package/src/lib/server/watch-jobs.ts +532 -0
- package/src/lib/server/ws-hub.ts +5 -3
- package/src/lib/setup-defaults.ts +352 -11
- package/src/lib/tool-definitions.ts +3 -4
- package/src/lib/validation/schemas.test.ts +26 -0
- package/src/lib/validation/schemas.ts +62 -1
- package/src/lib/ws-client.ts +14 -12
- package/src/proxy.ts +5 -5
- package/src/stores/use-app-store.ts +43 -7
- package/src/stores/use-chat-store.ts +31 -2
- package/src/stores/use-chatroom-store.ts +153 -26
- package/src/types/index.ts +470 -44
- package/src/app/api/chats/[id]/main-loop/route.ts +0 -94
- package/src/components/chat/new-chat-sheet.tsx +0 -253
- package/src/lib/server/main-session.ts +0 -17
- package/src/lib/server/session-run-manager.test.ts +0 -26
|
@@ -22,12 +22,20 @@ import { Dropdown, DropdownItem } from '@/components/shared/dropdown'
|
|
|
22
22
|
import { ConfirmDialog } from '@/components/shared/confirm-dialog'
|
|
23
23
|
import { speak } from '@/lib/tts'
|
|
24
24
|
import { api } from '@/lib/api-client'
|
|
25
|
+
import { messagesDiffer } from '@/lib/chat-streaming-state'
|
|
25
26
|
|
|
26
|
-
const
|
|
27
|
+
const DIRECT_PROMPT_SUGGESTIONS = [
|
|
27
28
|
{ text: 'What can you help me with?', icon: 'book', gradient: 'from-[#6366F1]/10 to-[#818CF8]/5' },
|
|
29
|
+
{ text: 'Help me choose the right agent for this', icon: 'bot', gradient: 'from-[#34D399]/10 to-[#6EE7B7]/5' },
|
|
28
30
|
{ text: 'Help me set up a new connector', icon: 'link', gradient: 'from-[#EC4899]/10 to-[#F472B6]/5' },
|
|
29
|
-
{ text: '
|
|
30
|
-
|
|
31
|
+
{ text: 'Summarize what needs attention in this workspace', icon: 'check', gradient: 'from-[#F59E0B]/10 to-[#FBBF24]/5' },
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
const AGENT_PROMPT_SUGGESTIONS = [
|
|
35
|
+
{ text: 'Give me a quick overview of what you can help with', icon: 'book', gradient: 'from-[#6366F1]/10 to-[#818CF8]/5' },
|
|
36
|
+
{ text: 'Review what needs attention right now', icon: 'check', gradient: 'from-[#F59E0B]/10 to-[#FBBF24]/5' },
|
|
37
|
+
{ text: 'Summarize our recent context before we continue', icon: 'link', gradient: 'from-[#EC4899]/10 to-[#F472B6]/5' },
|
|
38
|
+
{ text: 'Help me map the next best step', icon: 'bot', gradient: 'from-[#34D399]/10 to-[#6EE7B7]/5' },
|
|
31
39
|
]
|
|
32
40
|
|
|
33
41
|
export function ChatArea() {
|
|
@@ -52,6 +60,10 @@ export function ChatArea() {
|
|
|
52
60
|
const sidebarOpen = useAppStore((s) => s.sidebarOpen)
|
|
53
61
|
const setSidebarOpen = useAppStore((s) => s.setSidebarOpen)
|
|
54
62
|
const currentAgent = session?.agentId ? agents[session.agentId] ?? null : null
|
|
63
|
+
const promptSuggestions = useMemo(
|
|
64
|
+
() => (currentAgent ? AGENT_PROMPT_SUGGESTIONS : DIRECT_PROMPT_SUGGESTIONS),
|
|
65
|
+
[currentAgent],
|
|
66
|
+
)
|
|
55
67
|
|
|
56
68
|
const voice = useVoiceConversation()
|
|
57
69
|
const handleVoiceToggle = useCallback(() => {
|
|
@@ -68,6 +80,7 @@ export function ChatArea() {
|
|
|
68
80
|
const [messagesLoading, setMessagesLoading] = useState(true)
|
|
69
81
|
const [connectorFilter, setConnectorFilter] = useState<string | null>(null)
|
|
70
82
|
const [pluginChatActions, setPluginChatActions] = useState<Array<{ id: string; label: string; action: string; value: string; tooltip?: string }>>([])
|
|
83
|
+
const sessionHasBrowserPlugin = session?.plugins?.includes('browser') === true
|
|
71
84
|
|
|
72
85
|
useEffect(() => {
|
|
73
86
|
if (sessionId) {
|
|
@@ -101,52 +114,71 @@ export function ChatArea() {
|
|
|
101
114
|
|
|
102
115
|
useEffect(() => {
|
|
103
116
|
if (!sessionId) return
|
|
117
|
+
let cancelled = false
|
|
118
|
+
const requestedSessionId = sessionId
|
|
104
119
|
const chatState = useChatStore.getState()
|
|
105
|
-
const preserveLocalStream = chatState.streaming && chatState.streamingSessionId ===
|
|
106
|
-
//
|
|
120
|
+
const preserveLocalStream = chatState.streaming && chatState.streamingSessionId === requestedSessionId
|
|
121
|
+
// Keep the previous thread visible while the next one loads to avoid blank flashes.
|
|
107
122
|
setMessagesLoading(true)
|
|
108
|
-
setMessages([])
|
|
109
123
|
if (!preserveLocalStream) {
|
|
110
124
|
useChatStore.setState({ streaming: false, streamingSessionId: null, streamText: '', toolEvents: [] })
|
|
111
125
|
}
|
|
112
|
-
fetchMessagesPaginated(
|
|
126
|
+
fetchMessagesPaginated(requestedSessionId, 100).then((data) => {
|
|
127
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
113
128
|
setMessages(data.messages)
|
|
114
129
|
useChatStore.setState({ hasMoreMessages: data.hasMore, totalMessages: data.total })
|
|
115
130
|
}).catch((err) => {
|
|
131
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
116
132
|
console.error('Failed to load messages:', err)
|
|
117
|
-
|
|
133
|
+
const fallbackSession = useAppStore.getState().sessions[requestedSessionId]
|
|
134
|
+
setMessages(fallbackSession?.messages || [])
|
|
118
135
|
}).finally(() => {
|
|
136
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
119
137
|
setMessagesLoading(false)
|
|
120
138
|
})
|
|
121
139
|
// If server reports session is still active, show streaming state
|
|
122
140
|
if (session?.active) {
|
|
123
|
-
useChatStore.setState({ streaming: true, streamingSessionId:
|
|
141
|
+
useChatStore.setState({ streaming: true, streamingSessionId: requestedSessionId, streamText: '' })
|
|
124
142
|
}
|
|
125
143
|
// Refresh active state from server so returning to a session restores typing indicator.
|
|
126
144
|
loadSessions().then(() => {
|
|
127
|
-
|
|
145
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
146
|
+
const refreshed = useAppStore.getState().sessions[requestedSessionId]
|
|
128
147
|
if (refreshed?.active) {
|
|
129
|
-
useChatStore.setState({ streaming: true, streamingSessionId:
|
|
148
|
+
useChatStore.setState({ streaming: true, streamingSessionId: requestedSessionId, streamText: '' })
|
|
130
149
|
}
|
|
131
150
|
}).catch((err) => console.error('Failed to refresh messages:', err))
|
|
132
|
-
devServer(
|
|
151
|
+
devServer(requestedSessionId, 'status').then((r) => {
|
|
152
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
133
153
|
setDevServer(r.running ? r : null)
|
|
134
|
-
}).catch(() =>
|
|
154
|
+
}).catch(() => {
|
|
155
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
156
|
+
setDevServer(null)
|
|
157
|
+
})
|
|
135
158
|
// Check browser status
|
|
136
|
-
if (
|
|
137
|
-
checkBrowser(
|
|
159
|
+
if (sessionHasBrowserPlugin) {
|
|
160
|
+
checkBrowser(requestedSessionId).then((r) => {
|
|
161
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
162
|
+
setBrowserActive(r.active)
|
|
163
|
+
}).catch((err) => {
|
|
164
|
+
if (cancelled || useAppStore.getState().currentSessionId !== requestedSessionId) return
|
|
165
|
+
console.error('Browser check failed:', err)
|
|
166
|
+
setBrowserActive(false)
|
|
167
|
+
})
|
|
138
168
|
} else {
|
|
139
169
|
setBrowserActive(false)
|
|
140
170
|
}
|
|
141
|
-
|
|
171
|
+
return () => {
|
|
172
|
+
cancelled = true
|
|
173
|
+
}
|
|
174
|
+
}, [loadSessions, session?.active, sessionHasBrowserPlugin, sessionId, setDevServer, setMessages])
|
|
142
175
|
|
|
143
|
-
// Auto-poll messages for
|
|
144
|
-
const isOrchestrated = session?.sessionType === 'orchestrated'
|
|
176
|
+
// Auto-poll messages for sessions that are actively running on the server
|
|
145
177
|
const isServerActive = session?.active === true
|
|
146
178
|
const isOngoingMonitored = appSettings.loopMode === 'ongoing' && !!session?.plugins?.length
|
|
147
|
-
const shouldPollMessages = !!sessionId && (
|
|
148
|
-
const
|
|
149
|
-
|
|
179
|
+
const shouldPollMessages = !!sessionId && (isServerActive || isOngoingMonitored)
|
|
180
|
+
const messagesRef = useRef(messages)
|
|
181
|
+
messagesRef.current = messages
|
|
150
182
|
const isServerActiveRef = useRef(isServerActive)
|
|
151
183
|
isServerActiveRef.current = isServerActive
|
|
152
184
|
const ttsEnabledRef = useRef(ttsEnabled)
|
|
@@ -156,8 +188,9 @@ export function ChatArea() {
|
|
|
156
188
|
if (!sessionId) return
|
|
157
189
|
try {
|
|
158
190
|
const msgs = await fetchMessages(sessionId)
|
|
159
|
-
|
|
160
|
-
|
|
191
|
+
const previous = messagesRef.current
|
|
192
|
+
if (messagesDiffer(msgs, previous)) {
|
|
193
|
+
const newMsgs = msgs.length > previous.length ? msgs.slice(previous.length) : []
|
|
161
194
|
setMessages(msgs)
|
|
162
195
|
if (ttsEnabledRef.current && typeof document !== 'undefined' && document.visibilityState === 'visible') {
|
|
163
196
|
const latestAssistant = [...newMsgs].reverse().find((m) => {
|
|
@@ -385,15 +418,19 @@ export function ChatArea() {
|
|
|
385
418
|
<h1 className="font-display text-[28px] md:text-[36px] font-800 leading-[1.1] tracking-[-0.04em] mb-3">
|
|
386
419
|
Hi{currentUser ? ', ' : ' '}<span className="text-accent-bright">{currentUser || 'there'}</span>
|
|
387
420
|
<br />
|
|
388
|
-
<span className="text-text-2">
|
|
421
|
+
<span className="text-text-2">
|
|
422
|
+
{currentAgent ? `Start with ${currentAgent.name}` : 'Start the conversation'}
|
|
423
|
+
</span>
|
|
389
424
|
</h1>
|
|
390
425
|
<p className="text-[13px] text-text-3 mt-2">
|
|
391
|
-
|
|
426
|
+
{currentAgent
|
|
427
|
+
? `Ask ${currentAgent.name} anything, hand over work, or start with one of these openers.`
|
|
428
|
+
: 'Pick a prompt or type your own below.'}
|
|
392
429
|
</p>
|
|
393
430
|
</div>
|
|
394
431
|
|
|
395
432
|
<div className="relative grid grid-cols-2 md:grid-cols-4 gap-3 max-w-[640px] w-full mb-6">
|
|
396
|
-
{
|
|
433
|
+
{promptSuggestions.map((prompt, i) => (
|
|
397
434
|
<button
|
|
398
435
|
key={prompt.text}
|
|
399
436
|
onClick={() => handlePrompt(prompt.text)}
|
|
@@ -408,7 +445,7 @@ export function ChatArea() {
|
|
|
408
445
|
</div>
|
|
409
446
|
</div>
|
|
410
447
|
) : (
|
|
411
|
-
<MessageList messages={messages} streaming={streamingForThisSession} connectorFilter={connectorFilter} />
|
|
448
|
+
<MessageList messages={messages} streaming={streamingForThisSession} connectorFilter={connectorFilter} loading={messagesLoading} />
|
|
412
449
|
)}
|
|
413
450
|
|
|
414
451
|
{voice.active && (
|
|
@@ -434,6 +471,12 @@ export function ChatArea() {
|
|
|
434
471
|
/>
|
|
435
472
|
|
|
436
473
|
<Dropdown open={menuOpen} onClose={() => setMenuOpen(false)}>
|
|
474
|
+
<DropdownItem onClick={() => {
|
|
475
|
+
setMenuOpen(false)
|
|
476
|
+
setDebugOpen(!debugOpen)
|
|
477
|
+
}}>
|
|
478
|
+
{debugOpen ? 'Hide Debug Panel' : 'Show Debug Panel'}
|
|
479
|
+
</DropdownItem>
|
|
437
480
|
<DropdownItem onClick={() => { setMenuOpen(false); setConfirmClear(true) }}>
|
|
438
481
|
Clear History
|
|
439
482
|
</DropdownItem>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
+
import { DEFAULT_HEARTBEAT_INTERVAL_SEC } from '@/lib/heartbeat-defaults'
|
|
3
4
|
import type { Session } from '@/types'
|
|
4
5
|
import { api } from '@/lib/api-client'
|
|
5
6
|
import { useAppStore } from '@/stores/use-app-store'
|
|
@@ -66,10 +67,13 @@ export function ChatCard({ session, active, onClick }: Props) {
|
|
|
66
67
|
: 'No messages'
|
|
67
68
|
const providerLabel = PROVIDER_LABELS[session.provider] || session.provider
|
|
68
69
|
const agent = session.agentId ? agents[session.agentId] : null
|
|
70
|
+
const displayName = session.shortcutForAgentId && agent?.id === session.shortcutForAgentId
|
|
71
|
+
? agent.name
|
|
72
|
+
: session.name
|
|
69
73
|
const connector = getSessionConnector(session, connectors)
|
|
70
74
|
const loopIsOngoing = appSettings.loopMode === 'ongoing'
|
|
71
75
|
const explicitOptIn = session.heartbeatEnabled === true || agent?.heartbeatEnabled === true
|
|
72
|
-
const intervalRaw = session.heartbeatIntervalSec ?? agent?.heartbeatIntervalSec ?? appSettings.heartbeatIntervalSec ??
|
|
76
|
+
const intervalRaw = session.heartbeatIntervalSec ?? agent?.heartbeatIntervalSec ?? appSettings.heartbeatIntervalSec ?? DEFAULT_HEARTBEAT_INTERVAL_SEC
|
|
73
77
|
const intervalNum = typeof intervalRaw === 'number' ? intervalRaw : Number.parseInt(String(intervalRaw), 10)
|
|
74
78
|
const intervalEnabled = Number.isFinite(intervalNum) ? intervalNum > 0 : true
|
|
75
79
|
const heartbeatEnabled =
|
|
@@ -109,26 +113,7 @@ export function ChatCard({ session, active, onClick }: Props) {
|
|
|
109
113
|
title={`${connector.name} (${connector.platform})`}
|
|
110
114
|
/>
|
|
111
115
|
)}
|
|
112
|
-
<span className="font-display text-[14px] font-600 truncate flex-1 tracking-[-0.01em]">{
|
|
113
|
-
{session.mainLoopState?.status && session.mainLoopState.status !== 'idle' && (
|
|
114
|
-
<span className={`shrink-0 flex items-center gap-1 text-[9px] font-600 uppercase tracking-wider px-1.5 py-0.5 rounded-[5px] ${
|
|
115
|
-
session.mainLoopState.status === 'progress' ? 'text-blue-400/90 bg-blue-400/[0.08]'
|
|
116
|
-
: session.mainLoopState.status === 'blocked' ? 'text-amber-400/90 bg-amber-400/[0.08]'
|
|
117
|
-
: 'text-emerald-400/90 bg-emerald-400/[0.08]'
|
|
118
|
-
}`}>
|
|
119
|
-
<span className={`w-[5px] h-[5px] rounded-full ${
|
|
120
|
-
session.mainLoopState.status === 'progress' ? 'bg-blue-400'
|
|
121
|
-
: session.mainLoopState.status === 'blocked' ? 'bg-amber-400'
|
|
122
|
-
: 'bg-emerald-400'
|
|
123
|
-
}`} />
|
|
124
|
-
{session.mainLoopState.status}
|
|
125
|
-
</span>
|
|
126
|
-
)}
|
|
127
|
-
{session.sessionType === 'orchestrated' && (
|
|
128
|
-
<span className="shrink-0 text-[10px] font-600 uppercase tracking-wider text-amber-400/80 bg-amber-400/[0.08] px-2 py-0.5 rounded-[6px]">
|
|
129
|
-
AI
|
|
130
|
-
</span>
|
|
131
|
-
)}
|
|
116
|
+
<span className="font-display text-[14px] font-600 truncate flex-1 tracking-[-0.01em]">{displayName}</span>
|
|
132
117
|
{providerLabel && (
|
|
133
118
|
<span className="shrink-0 text-[10px] font-600 uppercase tracking-wider text-text-3/70 bg-white/[0.03] px-2 py-0.5 rounded-[6px]">
|
|
134
119
|
{providerLabel}
|