@swarmclawai/swarmclaw 0.7.1 → 0.7.3
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 +155 -150
- package/package.json +1 -1
- package/src/app/api/agents/[id]/route.ts +26 -0
- package/src/app/api/agents/[id]/thread/route.ts +37 -9
- package/src/app/api/agents/route.ts +13 -2
- package/src/app/api/auth/route.ts +76 -7
- package/src/app/api/chatrooms/[id]/chat/route.ts +7 -2
- package/src/app/api/{sessions → chats}/[id]/browser/route.ts +5 -1
- package/src/app/api/{sessions → chats}/[id]/chat/route.ts +7 -3
- package/src/app/api/{sessions → chats}/[id]/checkpoints/route.ts +1 -1
- package/src/app/api/chats/[id]/main-loop/route.ts +13 -0
- package/src/app/api/{sessions → chats}/[id]/messages/route.ts +19 -13
- package/src/app/api/{sessions → chats}/[id]/restore/route.ts +1 -1
- package/src/app/api/{sessions → chats}/[id]/route.ts +22 -52
- package/src/app/api/{sessions → chats}/[id]/stop/route.ts +6 -1
- package/src/app/api/{sessions → chats}/route.ts +21 -7
- 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/files/open/route.ts +16 -14
- 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/skills/route.ts +11 -3
- 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 +6 -26
- package/src/app/api/plugins/settings/route.ts +40 -0
- package/src/app/api/plugins/ui/route.ts +1 -0
- package/src/app/api/settings/route.ts +49 -7
- package/src/app/api/tasks/[id]/route.ts +15 -6
- package/src/app/api/tasks/bulk/route.ts +2 -2
- package/src/app/api/tasks/route.ts +9 -4
- package/src/app/api/usage/route.ts +30 -0
- package/src/app/api/webhooks/[id]/route.ts +8 -1
- package/src/app/page.tsx +9 -2
- package/src/cli/index.js +39 -33
- package/src/cli/index.ts +43 -49
- package/src/cli/spec.js +29 -27
- package/src/components/agents/agent-card.tsx +16 -13
- package/src/components/agents/agent-chat-list.tsx +104 -4
- package/src/components/agents/agent-list.tsx +54 -22
- package/src/components/agents/agent-sheet.tsx +209 -18
- package/src/components/agents/cron-job-form.tsx +3 -3
- package/src/components/agents/inspector-panel.tsx +110 -50
- package/src/components/auth/access-key-gate.tsx +36 -97
- package/src/components/auth/setup-wizard.tsx +5 -38
- package/src/components/chat/chat-area.tsx +39 -27
- package/src/components/{sessions/session-card.tsx → chat/chat-card.tsx} +7 -23
- package/src/components/chat/chat-header.tsx +299 -314
- package/src/components/{sessions/session-list.tsx → chat/chat-list.tsx} +11 -14
- package/src/components/chat/chat-tool-toggles.tsx +26 -17
- package/src/components/chat/checkpoint-timeline.tsx +4 -4
- package/src/components/chat/message-bubble.tsx +4 -1
- package/src/components/chat/message-list.tsx +5 -3
- package/src/components/chat/session-debug-panel.tsx +1 -1
- package/src/components/chat/tool-request-banner.tsx +3 -3
- package/src/components/chatrooms/agent-hover-card.tsx +3 -3
- package/src/components/chatrooms/chatroom-tool-request-banner.tsx +2 -2
- package/src/components/chatrooms/chatroom-view.tsx +347 -205
- package/src/components/connectors/connector-list.tsx +265 -127
- package/src/components/connectors/connector-sheet.tsx +218 -1
- package/src/components/home/home-view.tsx +129 -5
- package/src/components/layout/app-layout.tsx +392 -182
- package/src/components/layout/mobile-header.tsx +26 -8
- package/src/components/plugins/plugin-list.tsx +487 -254
- package/src/components/plugins/plugin-sheet.tsx +236 -13
- package/src/components/projects/project-detail.tsx +183 -0
- package/src/components/settings/gateway-connection-panel.tsx +1 -1
- package/src/components/shared/agent-picker-list.tsx +2 -2
- package/src/components/shared/command-palette.tsx +111 -25
- 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 +78 -1
- package/src/components/shared/settings/section-orchestrator.tsx +3 -3
- package/src/components/shared/settings/section-providers.tsx +1 -1
- 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 +244 -56
- package/src/components/tasks/approvals-panel.tsx +205 -18
- package/src/components/tasks/task-board.tsx +242 -46
- package/src/components/usage/metrics-dashboard.tsx +147 -1
- package/src/components/wallets/wallet-panel.tsx +17 -5
- package/src/components/webhooks/webhook-sheet.tsx +8 -8
- 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/chat.ts +1 -1
- package/src/lib/{sessions.ts → chats.ts} +28 -18
- package/src/lib/openclaw-agent-id.test.ts +14 -0
- package/src/lib/openclaw-agent-id.ts +31 -0
- package/src/lib/providers/claude-cli.ts +1 -1
- package/src/lib/server/agent-assignment.test.ts +112 -0
- package/src/lib/server/agent-assignment.ts +169 -0
- package/src/lib/server/approval-connector-notify.test.ts +253 -0
- package/src/lib/server/approvals-auto-approve.test.ts +205 -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 +36 -0
- package/src/lib/server/build-llm.ts +11 -4
- package/src/lib/server/builtin-plugins.ts +34 -0
- package/src/lib/server/capability-router.ts +10 -8
- package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
- package/src/lib/server/chat-execution-tool-events.test.ts +134 -0
- package/src/lib/server/chat-execution.ts +285 -165
- 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 +67 -2
- package/src/lib/server/chatroom-helpers.ts +48 -8
- 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 +948 -112
- 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 +188 -9
- 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/cost.ts +34 -1
- package/src/lib/server/daemon-state.ts +61 -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/heartbeat-service.ts +14 -40
- 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 +28 -1103
- 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 +5 -6
- 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 +20 -9
- package/src/lib/server/orchestrator.ts +7 -7
- package/src/lib/server/playwright-proxy.mjs +27 -3
- package/src/lib/server/plugins.test.ts +207 -0
- package/src/lib/server/plugins.ts +927 -66
- package/src/lib/server/provider-health.ts +38 -6
- package/src/lib/server/queue.ts +13 -28
- 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 -82
- package/src/lib/server/session-tools/autonomy-tools.test.ts +105 -0
- package/src/lib/server/session-tools/calendar.ts +366 -0
- package/src/lib/server/session-tools/canvas.ts +1 -1
- package/src/lib/server/session-tools/chatroom.ts +4 -2
- package/src/lib/server/session-tools/connector.ts +114 -10
- package/src/lib/server/session-tools/context.ts +21 -5
- package/src/lib/server/session-tools/crawl.ts +447 -0
- package/src/lib/server/session-tools/crud.ts +74 -28
- package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
- package/src/lib/server/session-tools/delegate.ts +497 -24
- package/src/lib/server/session-tools/discovery.ts +24 -6
- package/src/lib/server/session-tools/document.ts +283 -0
- package/src/lib/server/session-tools/edit_file.ts +4 -2
- package/src/lib/server/session-tools/email.ts +320 -0
- package/src/lib/server/session-tools/extract.ts +137 -0
- package/src/lib/server/session-tools/file-normalize.test.ts +93 -0
- package/src/lib/server/session-tools/file-send.test.ts +84 -1
- package/src/lib/server/session-tools/file.ts +241 -25
- package/src/lib/server/session-tools/git.ts +1 -1
- package/src/lib/server/session-tools/http.ts +1 -1
- package/src/lib/server/session-tools/human-loop.ts +227 -0
- package/src/lib/server/session-tools/image-gen.ts +380 -0
- package/src/lib/server/session-tools/index.ts +130 -50
- package/src/lib/server/session-tools/mailbox.ts +276 -0
- package/src/lib/server/session-tools/memory.ts +172 -3
- package/src/lib/server/session-tools/monitor.ts +151 -8
- package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
- package/src/lib/server/session-tools/openclaw-nodes.ts +1 -1
- package/src/lib/server/session-tools/openclaw-workspace.ts +1 -1
- package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
- package/src/lib/server/session-tools/platform.ts +148 -7
- package/src/lib/server/session-tools/plugin-creator.ts +89 -26
- package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
- package/src/lib/server/session-tools/replicate.ts +301 -0
- package/src/lib/server/session-tools/sample-ui.ts +1 -1
- package/src/lib/server/session-tools/sandbox.ts +4 -2
- package/src/lib/server/session-tools/schedule.ts +24 -12
- package/src/lib/server/session-tools/session-info.ts +43 -7
- package/src/lib/server/session-tools/session-tools-wiring.test.ts +31 -17
- package/src/lib/server/session-tools/shell.ts +5 -2
- package/src/lib/server/session-tools/subagent.ts +194 -28
- package/src/lib/server/session-tools/table.ts +587 -0
- package/src/lib/server/session-tools/wallet.ts +42 -12
- package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
- package/src/lib/server/session-tools/web.ts +926 -91
- package/src/lib/server/storage.ts +255 -16
- package/src/lib/server/stream-agent-chat.ts +116 -268
- 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 -10
- package/src/lib/server/tool-aliases.ts +66 -18
- package/src/lib/server/tool-capability-policy.test.ts +9 -9
- package/src/lib/server/tool-capability-policy.ts +38 -27
- 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/tool-definitions.ts +4 -0
- package/src/lib/validation/schemas.test.ts +26 -0
- package/src/lib/validation/schemas.ts +10 -1
- package/src/lib/ws-client.ts +14 -12
- package/src/proxy.ts +5 -5
- package/src/stores/use-app-store.ts +5 -11
- package/src/stores/use-chat-store.ts +38 -9
- package/src/types/index.ts +352 -47
- package/src/app/api/sessions/[id]/main-loop/route.ts +0 -94
- package/src/components/sessions/new-session-sheet.tsx +0 -253
- package/src/lib/server/main-session.ts +0 -24
- package/src/lib/server/session-run-manager.test.ts +0 -23
- /package/src/app/api/{sessions → chats}/[id]/clear/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/[id]/deploy/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/[id]/devserver/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/[id]/edit-resend/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/[id]/fork/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/[id]/mailbox/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/[id]/retry/route.ts +0 -0
- /package/src/app/api/{sessions → chats}/heartbeat/route.ts +0 -0
package/src/proxy.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import type { NextRequest } from 'next/server'
|
|
3
|
+
import { AUTH_COOKIE_NAME } from '@/lib/auth'
|
|
3
4
|
|
|
4
5
|
/* ------------------------------------------------------------------ */
|
|
5
6
|
/* Rate-limit state — HMR-safe via globalThis */
|
|
@@ -44,7 +45,7 @@ function getClientIp(request: NextRequest): string {
|
|
|
44
45
|
/* ------------------------------------------------------------------ */
|
|
45
46
|
|
|
46
47
|
/** Access key auth proxy with brute-force rate limiting.
|
|
47
|
-
* Checks X-Access-Key header or
|
|
48
|
+
* Checks X-Access-Key header or auth cookie on all /api/ routes except /api/auth.
|
|
48
49
|
* The key is validated against the ACCESS_KEY env var.
|
|
49
50
|
* After 5 failed attempts from a single IP the client is locked out for 15 minutes.
|
|
50
51
|
*/
|
|
@@ -55,11 +56,10 @@ export function proxy(request: NextRequest) {
|
|
|
55
56
|
const isConnectorWebhook = request.method === 'POST'
|
|
56
57
|
&& /^\/api\/connectors\/[^/]+\/webhook\/?$/.test(pathname)
|
|
57
58
|
|
|
58
|
-
// Only protect API routes (not auth
|
|
59
|
+
// Only protect API routes (not auth or inbound webhooks)
|
|
59
60
|
if (
|
|
60
61
|
!pathname.startsWith('/api/')
|
|
61
62
|
|| pathname === '/api/auth'
|
|
62
|
-
|| pathname.startsWith('/api/uploads/')
|
|
63
63
|
|| isWebhookTrigger
|
|
64
64
|
|| isConnectorWebhook
|
|
65
65
|
) {
|
|
@@ -88,8 +88,8 @@ export function proxy(request: NextRequest) {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
const providedKey =
|
|
91
|
-
request.headers.get('x-access-key')
|
|
92
|
-
|| request.
|
|
91
|
+
request.headers.get('x-access-key')?.trim()
|
|
92
|
+
|| request.cookies.get(AUTH_COOKIE_NAME)?.value?.trim()
|
|
93
93
|
|| ''
|
|
94
94
|
|
|
95
95
|
if (providedKey !== accessKey) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { create } from 'zustand'
|
|
4
4
|
import type { Sessions, Session, NetworkInfo, Directory, ProviderInfo, Credentials, Agent, Schedule, AppView, BoardTask, AppSettings, OrchestratorSecret, ProviderConfig, Skill, Connector, Webhook, McpServerConfig, PluginMeta, Project, FleetFilter, ActivityEntry, AppNotification, ApprovalRequest } from '../types'
|
|
5
|
-
import {
|
|
5
|
+
import { fetchChats, fetchDirs, fetchProviders, fetchCredentials } from '../lib/chats'
|
|
6
6
|
import { fetchAgents } from '../lib/agents'
|
|
7
7
|
import { fetchSchedules } from '../lib/schedules'
|
|
8
8
|
import { fetchTasks } from '../lib/tasks'
|
|
@@ -43,9 +43,6 @@ interface AppState {
|
|
|
43
43
|
settingsOpen: boolean
|
|
44
44
|
setSettingsOpen: (open: boolean) => void
|
|
45
45
|
|
|
46
|
-
newSessionOpen: boolean
|
|
47
|
-
setNewSessionOpen: (open: boolean) => void
|
|
48
|
-
|
|
49
46
|
activeView: AppView
|
|
50
47
|
setActiveView: (view: AppView) => void
|
|
51
48
|
|
|
@@ -235,7 +232,7 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
235
232
|
currentSessionId: null,
|
|
236
233
|
loadSessions: async () => {
|
|
237
234
|
try {
|
|
238
|
-
const sessions = await
|
|
235
|
+
const sessions = await fetchChats()
|
|
239
236
|
set({ sessions })
|
|
240
237
|
} catch {
|
|
241
238
|
// ignore
|
|
@@ -249,7 +246,7 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
249
246
|
},
|
|
250
247
|
clearSessions: async (ids) => {
|
|
251
248
|
if (!ids.length) return
|
|
252
|
-
await api('DELETE', '/
|
|
249
|
+
await api('DELETE', '/chats', { ids })
|
|
253
250
|
const sessions = { ...get().sessions }
|
|
254
251
|
for (const id of ids) delete sessions[id]
|
|
255
252
|
set({ sessions, currentSessionId: ids.includes(get().currentSessionId!) ? null : get().currentSessionId })
|
|
@@ -260,7 +257,7 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
260
257
|
sessions[id] = { ...sessions[id], pinned: !sessions[id].pinned }
|
|
261
258
|
set({ sessions })
|
|
262
259
|
// Persist to server
|
|
263
|
-
void api('PUT', `/
|
|
260
|
+
void api('PUT', `/chats/${id}`, { pinned: sessions[id].pinned })
|
|
264
261
|
}
|
|
265
262
|
},
|
|
266
263
|
updateSessionInStore: (session) => {
|
|
@@ -268,7 +265,7 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
268
265
|
},
|
|
269
266
|
forkSession: async (sessionId, messageIndex) => {
|
|
270
267
|
try {
|
|
271
|
-
const forked = await api<Session>('POST', `/
|
|
268
|
+
const forked = await api<Session>('POST', `/chats/${sessionId}/fork`, { messageIndex })
|
|
272
269
|
if (!forked?.id) return null
|
|
273
270
|
await get().loadSessions()
|
|
274
271
|
set({ currentSessionId: forked.id })
|
|
@@ -325,9 +322,6 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
325
322
|
settingsOpen: false,
|
|
326
323
|
setSettingsOpen: (open) => set({ settingsOpen: open }),
|
|
327
324
|
|
|
328
|
-
newSessionOpen: false,
|
|
329
|
-
setNewSessionOpen: (open) => set({ newSessionOpen: open }),
|
|
330
|
-
|
|
331
325
|
activeView: 'home',
|
|
332
326
|
setActiveView: (view) => set({ activeView: view }),
|
|
333
327
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { create } from 'zustand'
|
|
4
4
|
import type { Message, DevServerStatus, SSEEvent, ChatTraceBlock } from '../types'
|
|
5
5
|
import { streamChat } from '../lib/chat'
|
|
6
|
+
import { mergeCompletedAssistantMessage } from '../lib/chat-streaming-state'
|
|
6
7
|
import { speak } from '../lib/tts'
|
|
7
8
|
import { getStoredAccessKey } from '../lib/api-client'
|
|
8
9
|
import { useAppStore } from './use-app-store'
|
|
@@ -306,6 +307,11 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
306
307
|
} else if (event.t === 'tool_call') {
|
|
307
308
|
const id = `tc-${++toolCallCounter}`
|
|
308
309
|
set((s) => ({
|
|
310
|
+
...(s.toolEvents[s.toolEvents.length - 1]?.name === (event.toolName || 'unknown')
|
|
311
|
+
&& s.toolEvents[s.toolEvents.length - 1]?.input === (event.toolInput || '')
|
|
312
|
+
&& s.toolEvents[s.toolEvents.length - 1]?.status === 'running'
|
|
313
|
+
? {}
|
|
314
|
+
: {
|
|
309
315
|
streamPhase: 'tool' as const,
|
|
310
316
|
streamToolName: event.toolName || 'unknown',
|
|
311
317
|
toolEvents: [...s.toolEvents, {
|
|
@@ -314,6 +320,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
314
320
|
input: event.toolInput || '',
|
|
315
321
|
status: 'running',
|
|
316
322
|
}],
|
|
323
|
+
}),
|
|
317
324
|
}))
|
|
318
325
|
} else if (event.t === 'tool_result') {
|
|
319
326
|
const soundOn = get().soundEnabled
|
|
@@ -322,6 +329,22 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
322
329
|
const idx = events.findLastIndex(
|
|
323
330
|
(e) => e.name === event.toolName && e.status === 'running',
|
|
324
331
|
)
|
|
332
|
+
if (idx === -1) {
|
|
333
|
+
const last = events[events.length - 1]
|
|
334
|
+
const output = event.toolOutput || ''
|
|
335
|
+
const isError = /^(Error:|error:|ECONNREFUSED|ETIMEDOUT|timeout|failed)/i.test(output.trim())
|
|
336
|
+
|| output.includes('ECONNREFUSED')
|
|
337
|
+
|| output.includes('ETIMEDOUT')
|
|
338
|
+
|| output.includes('Error:')
|
|
339
|
+
if (
|
|
340
|
+
last
|
|
341
|
+
&& last.name === event.toolName
|
|
342
|
+
&& last.output === output
|
|
343
|
+
&& last.status === (isError ? 'error' : 'done')
|
|
344
|
+
) {
|
|
345
|
+
return { toolEvents: events }
|
|
346
|
+
}
|
|
347
|
+
}
|
|
325
348
|
if (idx !== -1) {
|
|
326
349
|
const output = event.toolOutput || ''
|
|
327
350
|
const isError = /^(Error:|error:|ECONNREFUSED|ETIMEDOUT|timeout|failed)/i.test(output.trim())
|
|
@@ -348,7 +371,13 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
348
371
|
} else if (event.t === 'status') {
|
|
349
372
|
try {
|
|
350
373
|
const parsed = JSON.parse(event.text || '{}')
|
|
351
|
-
|
|
374
|
+
if (
|
|
375
|
+
parsed
|
|
376
|
+
&& typeof parsed === 'object'
|
|
377
|
+
&& ['goal', 'status', 'summary', 'nextAction'].some((key) => key in parsed)
|
|
378
|
+
) {
|
|
379
|
+
set({ agentStatus: parsed })
|
|
380
|
+
}
|
|
352
381
|
} catch {
|
|
353
382
|
// ignore malformed status
|
|
354
383
|
}
|
|
@@ -377,7 +406,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
377
406
|
suggestions: suggestions || undefined,
|
|
378
407
|
}
|
|
379
408
|
set((s) => ({
|
|
380
|
-
messages:
|
|
409
|
+
messages: mergeCompletedAssistantMessage(s.messages, assistantMsg),
|
|
381
410
|
streaming: false,
|
|
382
411
|
streamingSessionId: null,
|
|
383
412
|
streamText: '',
|
|
@@ -407,7 +436,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
407
436
|
if (!sessionId) return
|
|
408
437
|
try {
|
|
409
438
|
const key = getStoredAccessKey()
|
|
410
|
-
const res = await fetch(`/api/
|
|
439
|
+
const res = await fetch(`/api/chats/${sessionId}/edit-resend`, {
|
|
411
440
|
method: 'POST',
|
|
412
441
|
headers: {
|
|
413
442
|
'Content-Type': 'application/json',
|
|
@@ -417,7 +446,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
417
446
|
})
|
|
418
447
|
if (!res.ok) return
|
|
419
448
|
// Reload messages from server (truncated)
|
|
420
|
-
const msgsRes = await fetch(`/api/
|
|
449
|
+
const msgsRes = await fetch(`/api/chats/${sessionId}/messages`, {
|
|
421
450
|
headers: key ? { 'X-Access-Key': key } : undefined,
|
|
422
451
|
})
|
|
423
452
|
if (msgsRes.ok) {
|
|
@@ -437,7 +466,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
437
466
|
if (!sessionId) return
|
|
438
467
|
try {
|
|
439
468
|
const key = getStoredAccessKey()
|
|
440
|
-
const res = await fetch(`/api/
|
|
469
|
+
const res = await fetch(`/api/chats/${sessionId}/retry`, {
|
|
441
470
|
method: 'POST',
|
|
442
471
|
headers: key ? { 'X-Access-Key': key } : undefined,
|
|
443
472
|
})
|
|
@@ -445,7 +474,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
445
474
|
const { message, imagePath } = await res.json()
|
|
446
475
|
if (!message) return
|
|
447
476
|
// Reload messages from server (without the popped ones)
|
|
448
|
-
const msgsRes = await fetch(`/api/
|
|
477
|
+
const msgsRes = await fetch(`/api/chats/${sessionId}/messages`, {
|
|
449
478
|
headers: key ? { 'X-Access-Key': key } : undefined,
|
|
450
479
|
})
|
|
451
480
|
if (msgsRes.ok) {
|
|
@@ -546,7 +575,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
546
575
|
set((s) => ({ messages: [...s.messages, marker] }))
|
|
547
576
|
try {
|
|
548
577
|
const key = getStoredAccessKey()
|
|
549
|
-
await fetch(`/api/
|
|
578
|
+
await fetch(`/api/chats/${sessionId}/messages`, {
|
|
550
579
|
method: 'POST',
|
|
551
580
|
headers: { 'Content-Type': 'application/json', ...(key ? { 'X-Access-Key': key } : {}) },
|
|
552
581
|
body: JSON.stringify({ kind: 'context-clear' }),
|
|
@@ -569,7 +598,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
569
598
|
const key = getStoredAccessKey()
|
|
570
599
|
// Find the earliest message's original index (startIndex tracked on initial load)
|
|
571
600
|
const currentStartIndex = totalMessages - messages.length
|
|
572
|
-
const res = await fetch(`/api/
|
|
601
|
+
const res = await fetch(`/api/chats/${sessionId}/messages?limit=100&before=${currentStartIndex}`, {
|
|
573
602
|
headers: key ? { 'X-Access-Key': key } : undefined,
|
|
574
603
|
})
|
|
575
604
|
if (res.ok) {
|
|
@@ -593,7 +622,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|
|
593
622
|
if (sessionId) {
|
|
594
623
|
try {
|
|
595
624
|
const key = getStoredAccessKey()
|
|
596
|
-
await fetch(`/api/
|
|
625
|
+
await fetch(`/api/chats/${sessionId}/stop`, {
|
|
597
626
|
method: 'POST',
|
|
598
627
|
headers: key ? { 'X-Access-Key': key } : undefined,
|
|
599
628
|
})
|