@swarmclawai/swarmclaw 1.1.6 → 1.1.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 +28 -12
- package/package.json +1 -1
- package/src/app/activity/page.tsx +9 -1
- package/src/app/api/chats/[id]/route.ts +2 -0
- package/src/app/api/delegation-jobs/route.ts +19 -0
- package/src/app/api/files/open/route.ts +5 -5
- package/src/app/api/files/serve/route.ts +9 -6
- package/src/app/globals.css +14 -0
- package/src/app/missions/page.tsx +3 -2
- package/src/cli/index.js +3 -3
- package/src/cli/spec.js +3 -3
- package/src/components/agents/agent-chat-list.tsx +26 -11
- package/src/components/agents/agent-sheet.tsx +267 -161
- package/src/components/agents/inspector-panel.tsx +1116 -303
- package/src/components/chat/chat-area.tsx +27 -3
- package/src/components/chat/chat-header.tsx +23 -672
- package/src/components/chat/file-path-chip.tsx +3 -3
- package/src/components/chat/message-bubble.tsx +59 -15
- package/src/components/chat/message-list.tsx +15 -15
- package/src/components/chat/thinking-indicator.tsx +28 -20
- package/src/components/chat/tool-events-section.tsx +240 -110
- package/src/components/input/chat-input.tsx +13 -11
- package/src/components/knowledge/knowledge-list.tsx +5 -0
- package/src/components/org-chart/mini-chat-bubble.tsx +19 -12
- package/src/components/org-chart/org-chart-context-menu.tsx +11 -8
- package/src/components/org-chart/org-chart-detail-panel.tsx +37 -0
- package/src/components/org-chart/org-chart-edge-popover.tsx +145 -0
- package/src/components/org-chart/org-chart-edge.tsx +140 -19
- package/src/components/org-chart/org-chart-node.tsx +27 -5
- package/src/components/org-chart/org-chart-sidebar.tsx +3 -2
- package/src/components/org-chart/org-chart-view.tsx +61 -4
- package/src/components/projects/assign-agent-picker.tsx +67 -0
- package/src/components/projects/project-detail-header.tsx +117 -0
- package/src/components/projects/project-detail.tsx +32 -923
- package/src/components/projects/project-list.tsx +8 -12
- package/src/components/projects/project-utils.ts +24 -0
- package/src/components/projects/tabs/activity-tab.tsx +93 -0
- package/src/components/projects/tabs/operations-tab.tsx +281 -0
- package/src/components/projects/tabs/overview-tab.tsx +198 -0
- package/src/components/projects/tabs/work-tab.tsx +246 -0
- package/src/components/schedules/schedule-console.tsx +7 -1
- package/src/components/tasks/task-sheet.tsx +3 -0
- package/src/hooks/use-delegation-edge-state.ts +126 -0
- package/src/lib/credential-registry.ts +369 -0
- package/src/lib/provider-sets.ts +3 -0
- package/src/lib/server/agents/delegation-jobs-advanced.test.ts +1 -1
- package/src/lib/server/agents/delegation-jobs.test.ts +1 -1
- package/src/lib/server/agents/delegation-jobs.ts +11 -3
- package/src/lib/server/agents/main-agent-loop.ts +28 -4
- package/src/lib/server/autonomy/supervisor-reflection.ts +7 -1
- package/src/lib/server/build-llm.ts +2 -1
- package/src/lib/server/chat-execution/chat-execution-utils.test.ts +14 -3
- package/src/lib/server/chat-execution/chat-execution-utils.ts +3 -2
- package/src/lib/server/chat-execution/chat-turn-state.ts +4 -0
- package/src/lib/server/chat-execution/continuation-evaluator.ts +60 -15
- package/src/lib/server/chat-execution/continuation-limits.ts +8 -0
- package/src/lib/server/chat-execution/message-classifier.ts +7 -1
- package/src/lib/server/chat-execution/post-stream-finalization.ts +28 -0
- package/src/lib/server/chat-execution/prompt-sections.ts +54 -1
- package/src/lib/server/chat-execution/response-completeness.test.ts +123 -0
- package/src/lib/server/chat-execution/response-completeness.ts +206 -0
- package/src/lib/server/chat-execution/stream-agent-chat.ts +40 -0
- package/src/lib/server/chat-execution/stream-continuation.ts +65 -0
- package/src/lib/server/protocols/protocol-foreach.ts +4 -74
- package/src/lib/server/protocols/protocol-step-helpers.ts +90 -7
- package/src/lib/server/query-expansion.ts +9 -2
- package/src/lib/server/resolve-workspace-path.ts +46 -0
- package/src/lib/server/runtime/daemon-state.ts +1 -1
- package/src/lib/server/runtime/heartbeat-service.ts +27 -2
- package/src/lib/server/runtime/process-manager.ts +5 -1
- package/src/lib/server/runtime/session-run-manager.ts +16 -4
- package/src/lib/server/session-tools/context.ts +11 -0
- package/src/lib/server/session-tools/crud.ts +126 -1
- package/src/lib/server/session-tools/file.ts +1 -1
- package/src/lib/server/session-tools/index.ts +0 -1
- package/src/lib/server/session-tools/session-tools-wiring.test.ts +26 -0
- package/src/lib/server/session-tools/shell.ts +35 -2
- package/src/lib/server/storage-normalization.ts +7 -0
- package/src/lib/server/storage.ts +7 -0
- package/src/lib/server/tool-loop-detection.ts +11 -0
- package/src/lib/strip-internal-metadata.test.ts +160 -0
- package/src/lib/strip-internal-metadata.ts +88 -0
- package/src/stores/slices/ui-slice.ts +18 -6
- package/src/stores/use-chat-store.ts +84 -61
- package/src/views/settings/section-runtime-loop.tsx +3 -0
- package/tsconfig.json +2 -1
- package/src/app/api/dashboard/route.ts +0 -130
- package/src/lib/server/session-tools/http.ts +0 -126
package/README.md
CHANGED
|
@@ -15,6 +15,19 @@ Docs: https://swarmclaw.ai/docs
|
|
|
15
15
|
Website: https://swarmclaw.ai
|
|
16
16
|
Extension tutorial: https://swarmclaw.ai/docs/extension-tutorial
|
|
17
17
|
|
|
18
|
+
## Screenshots
|
|
19
|
+
|
|
20
|
+
<table>
|
|
21
|
+
<tr>
|
|
22
|
+
<td width="50%"><img src="doc/assets/screenshots/org-chart.png" alt="SwarmClaw org chart view showing CEO, Developer, and Researcher agents." /></td>
|
|
23
|
+
<td width="50%"><img src="doc/assets/screenshots/agent-chat.png" alt="SwarmClaw agent chat view showing a CEO conversation." /></td>
|
|
24
|
+
</tr>
|
|
25
|
+
<tr>
|
|
26
|
+
<td align="center"><sub>Org chart for visualizing agent teams, delegation, and live activity.</sub></td>
|
|
27
|
+
<td align="center"><sub>Agent chat with durable history, tools, and operator controls.</sub></td>
|
|
28
|
+
</tr>
|
|
29
|
+
</table>
|
|
30
|
+
|
|
18
31
|
<div align="center">
|
|
19
32
|
<table>
|
|
20
33
|
<tr>
|
|
@@ -177,6 +190,21 @@ The building blocks are the same: **agents, tools, memory, delegation, schedules
|
|
|
177
190
|
|
|
178
191
|
## Release Notes
|
|
179
192
|
|
|
193
|
+
### v1.1.7 Highlights
|
|
194
|
+
|
|
195
|
+
- **Projects page redesign**: tabbed navigation (Overview, Work, Operations, Activity) with health grid, sortable task list, and timeline feed.
|
|
196
|
+
- **Delegation visualization**: live org chart edges show active delegations with status, direction, and message popover on click.
|
|
197
|
+
- **Credential self-service**: agents can check whether a credential exists and request missing ones from humans with structured messages, signup URLs, and durable wait.
|
|
198
|
+
- **Main loop state persistence**: autonomous operation state now survives server restarts via on-disk persistence.
|
|
199
|
+
- **Internal metadata stripping**: classification JSON and loop detection messages no longer leak into streamed agent output.
|
|
200
|
+
- **Response completeness evaluator**: LLM-based detection of incomplete agent responses triggers continuation nudges.
|
|
201
|
+
- **Coordinator delegation nudging**: coordinators that make 3+ direct tool calls get prompted to delegate to workers.
|
|
202
|
+
- **Inspector panel overhaul**: new dashboard/config/files tabs absorb model switcher and workspace controls from chat header.
|
|
203
|
+
- **Streaming phase indicators**: agent chat list shows queued, tool-in-use, responding, and reconnecting states.
|
|
204
|
+
- **Shell safety**: agents can no longer kill SwarmClaw's own process or port.
|
|
205
|
+
- **Worker-only providers**: CLI-backed providers (claude-cli, codex-cli, etc.) properly restricted from coordinator/heartbeat roles.
|
|
206
|
+
- **HTTP tool removed**: the built-in HTTP session tool was removed from the standard toolkit.
|
|
207
|
+
|
|
180
208
|
### v1.1.6 Highlights
|
|
181
209
|
|
|
182
210
|
- **Org chart view**: visual agent hierarchy with drag-and-drop reparenting, team grouping, and context-menu actions for managing agent relationships directly from the canvas.
|
|
@@ -203,18 +231,6 @@ The building blocks are the same: **agents, tools, memory, delegation, schedules
|
|
|
203
231
|
- **Plugin-to-extension cleanup finished**: remaining rename residue in scripts and tests was cleaned up so packaging and release tooling stay aligned with the current extensions model.
|
|
204
232
|
- **Safe body parsing utility**: shared `safeParseBody()` replaces scattered `await req.json()` try/catch blocks across API routes.
|
|
205
233
|
|
|
206
|
-
### v1.1.4 Highlights
|
|
207
|
-
|
|
208
|
-
- **Orchestrator agents as a real agent mode**: eligible agents can now run scheduled orchestrator wake cycles with their own mission, governance policy, wake interval, and cycle cap.
|
|
209
|
-
- **Runtime durability and recovery**: configurable parallel task execution, stuck-task idle timeout detection, orphaned running-task recovery on startup, and restart-safe swarm/provider-health persistence.
|
|
210
|
-
- **Failover and safety improvements**: provider errors classified for smarter routing, agent budget limits block task execution before it starts.
|
|
211
|
-
|
|
212
|
-
### v1.1.3 Highlights
|
|
213
|
-
|
|
214
|
-
- **`build:ci` repair**: fixed the langgraph checkpoint duplicate-column crash that blocked CI/build validation.
|
|
215
|
-
- **Safer storage writes**: credentials and agents use upsert-only save behavior, and a collection safety guard blocks accidental bulk-delete paths.
|
|
216
|
-
>>>>>>> Stashed changes
|
|
217
|
-
|
|
218
234
|
### v1.1.2 Highlights
|
|
219
235
|
|
|
220
236
|
- **Structured Sessions expanded into richer orchestration**: ProtocolRun-based sessions now support dependency-aware step graphs, reusable step outputs, and a broader advanced execution model on the same durable runtime instead of bringing back a separate orchestrator.
|
package/package.json
CHANGED
|
@@ -5,6 +5,7 @@ import { useAppStore } from '@/stores/use-app-store'
|
|
|
5
5
|
import { useNow } from '@/hooks/use-now'
|
|
6
6
|
import { useWs } from '@/hooks/use-ws'
|
|
7
7
|
import { MainContent } from '@/components/layout/main-content'
|
|
8
|
+
import { PageLoader } from '@/components/ui/page-loader'
|
|
8
9
|
import { timeAgo } from '@/lib/time-format'
|
|
9
10
|
import type { ActivityEntry } from '@/types'
|
|
10
11
|
|
|
@@ -34,10 +35,17 @@ export default function ActivityPage() {
|
|
|
34
35
|
const entries = useAppStore((s) => s.activityEntries)
|
|
35
36
|
const loadActivity = useAppStore((s) => s.loadActivity)
|
|
36
37
|
const [filterType, setFilterType] = useState('')
|
|
38
|
+
const [loaded, setLoaded] = useState(false)
|
|
37
39
|
|
|
38
|
-
useEffect(() => {
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
void loadActivity({ entityType: filterType || undefined, limit: 100 }).then(() => setLoaded(true))
|
|
42
|
+
}, [filterType, loadActivity])
|
|
39
43
|
useWs('activity', () => loadActivity({ entityType: filterType || undefined, limit: 100 }), 10_000)
|
|
40
44
|
|
|
45
|
+
if (!loaded) {
|
|
46
|
+
return <MainContent><PageLoader label="Loading activity..." /></MainContent>
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
return (
|
|
42
50
|
<MainContent>
|
|
43
51
|
<div className="flex-1 flex flex-col h-full overflow-hidden">
|
|
@@ -4,6 +4,7 @@ import { notFound } from '@/lib/server/collection-helpers'
|
|
|
4
4
|
import { normalizeProviderEndpoint } from '@/lib/openclaw/openclaw-endpoint'
|
|
5
5
|
import { resolvePrimaryAgentRoute } from '@/lib/server/agents/agent-runtime-config'
|
|
6
6
|
import { clearMainLoopStateForSession } from '@/lib/server/agents/main-agent-loop'
|
|
7
|
+
import { cleanupSessionProcesses } from '@/lib/server/runtime/process-manager'
|
|
7
8
|
import { getSessionQueueSnapshot, getSessionRunState } from '@/lib/server/runtime/session-run-manager'
|
|
8
9
|
import { normalizeCapabilitySelection } from '@/lib/capability-selection'
|
|
9
10
|
import { enrichSessionWithMissionSummary } from '@/lib/server/missions/mission-service'
|
|
@@ -152,6 +153,7 @@ export async function DELETE(_req: Request, { params }: { params: Promise<{ id:
|
|
|
152
153
|
try { active.get(id)?.kill() } catch {}
|
|
153
154
|
active.delete(id)
|
|
154
155
|
}
|
|
156
|
+
cleanupSessionProcesses(id)
|
|
155
157
|
deleteSession(id)
|
|
156
158
|
return new NextResponse('OK')
|
|
157
159
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { listDelegationJobs } from '@/lib/server/agents/delegation-jobs'
|
|
3
|
+
|
|
4
|
+
export const dynamic = 'force-dynamic'
|
|
5
|
+
|
|
6
|
+
const RECENT_WINDOW_MS = 30_000
|
|
7
|
+
|
|
8
|
+
export async function GET() {
|
|
9
|
+
const cutoff = Date.now() - RECENT_WINDOW_MS
|
|
10
|
+
const jobs = listDelegationJobs().filter((job) => {
|
|
11
|
+
// Active jobs always included
|
|
12
|
+
if (job.status === 'queued' || job.status === 'running') return true
|
|
13
|
+
// Recently-completed jobs (within window)
|
|
14
|
+
if (job.completedAt && job.completedAt >= cutoff) return true
|
|
15
|
+
if (job.updatedAt >= cutoff) return true
|
|
16
|
+
return false
|
|
17
|
+
})
|
|
18
|
+
return NextResponse.json(jobs)
|
|
19
|
+
}
|
|
@@ -3,19 +3,19 @@ import { spawn } from 'child_process'
|
|
|
3
3
|
import fs from 'fs'
|
|
4
4
|
import path from 'path'
|
|
5
5
|
import { safeParseBody } from '@/lib/server/safe-parse-body'
|
|
6
|
+
import { resolveWorkspacePath } from '@/lib/server/resolve-workspace-path'
|
|
6
7
|
|
|
7
8
|
export async function POST(req: Request) {
|
|
8
|
-
const { data: body, error } = await safeParseBody<{ path?: string }>(req)
|
|
9
|
+
const { data: body, error } = await safeParseBody<{ path?: string; cwd?: string }>(req)
|
|
9
10
|
if (error) return error
|
|
10
|
-
const { path: targetPath } = body
|
|
11
|
+
const { path: targetPath, cwd } = body
|
|
11
12
|
if (!targetPath || typeof targetPath !== 'string') {
|
|
12
13
|
return NextResponse.json({ error: 'path is required' }, { status: 400 })
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
const resolved =
|
|
16
|
+
const resolved = resolveWorkspacePath(targetPath, cwd)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
if (!fs.existsSync(resolved)) {
|
|
18
|
+
if (!resolved) {
|
|
19
19
|
return NextResponse.json({ error: 'Path does not exist' }, { status: 404 })
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import fs from 'fs'
|
|
3
3
|
import path from 'path'
|
|
4
|
+
import { resolveWorkspacePath } from '@/lib/server/resolve-workspace-path'
|
|
4
5
|
|
|
5
6
|
const MIME_MAP: Record<string, string> = {
|
|
6
7
|
'.html': 'text/html',
|
|
@@ -41,8 +42,14 @@ export async function GET(req: Request) {
|
|
|
41
42
|
return NextResponse.json({ error: 'Missing path parameter' }, { status: 400 })
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
const cwd = url.searchParams.get('cwd')
|
|
46
|
+
|
|
47
|
+
// Resolve the path, trying workspace-relative fallbacks
|
|
48
|
+
const resolved = resolveWorkspacePath(filePath, cwd)
|
|
49
|
+
|
|
50
|
+
if (!resolved) {
|
|
51
|
+
return NextResponse.json({ error: 'File not found' }, { status: 404 })
|
|
52
|
+
}
|
|
46
53
|
|
|
47
54
|
// Block access to sensitive paths
|
|
48
55
|
const blocked = ['.env', 'credentials', '.ssh', '.gnupg', '.aws']
|
|
@@ -50,10 +57,6 @@ export async function GET(req: Request) {
|
|
|
50
57
|
return NextResponse.json({ error: 'Access denied' }, { status: 403 })
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
if (!fs.existsSync(resolved)) {
|
|
54
|
-
return NextResponse.json({ error: 'File not found' }, { status: 404 })
|
|
55
|
-
}
|
|
56
|
-
|
|
57
60
|
const stat = fs.statSync(resolved)
|
|
58
61
|
if (!stat.isFile()) {
|
|
59
62
|
return NextResponse.json({ error: 'Not a file' }, { status: 400 })
|
package/src/app/globals.css
CHANGED
|
@@ -310,6 +310,20 @@ textarea:hover::-webkit-scrollbar { width: 6px; }
|
|
|
310
310
|
to { opacity: 1; transform: translateY(0); }
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
/* Org chart node delegation glow — shadow-only pulse, no size change */
|
|
314
|
+
@keyframes delegation-glow-pulse {
|
|
315
|
+
0%, 100% { opacity: 1; }
|
|
316
|
+
50% { opacity: 0.7; }
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* Org chart edge snippet: fade in, hold, then fade out */
|
|
320
|
+
@keyframes fadeInHold {
|
|
321
|
+
0% { opacity: 0; transform: translateY(4px); }
|
|
322
|
+
5% { opacity: 1; transform: translateY(0); }
|
|
323
|
+
85% { opacity: 1; }
|
|
324
|
+
100% { opacity: 0; }
|
|
325
|
+
}
|
|
326
|
+
|
|
313
327
|
/* ===== SwarmClaw Loader Keyframes ===== */
|
|
314
328
|
@keyframes sc-orbit {
|
|
315
329
|
from { transform: rotate(0deg); }
|
|
@@ -6,6 +6,7 @@ import { api } from '@/lib/app/api-client'
|
|
|
6
6
|
import { useWs } from '@/hooks/use-ws'
|
|
7
7
|
import { useAppStore } from '@/stores/use-app-store'
|
|
8
8
|
import { FilterPill } from '@/components/ui/filter-pill'
|
|
9
|
+
import { PageLoader } from '@/components/ui/page-loader'
|
|
9
10
|
import { StatCard } from '@/components/ui/stat-card'
|
|
10
11
|
import { StructuredSessionLauncher } from '@/components/protocols/structured-session-launcher'
|
|
11
12
|
import { timeAgo } from '@/lib/time-format'
|
|
@@ -332,7 +333,7 @@ export default function MissionsPage() {
|
|
|
332
333
|
</div>
|
|
333
334
|
<div className="max-h-[70vh] min-h-0 space-y-2 overflow-y-auto pr-1">
|
|
334
335
|
{loading ? (
|
|
335
|
-
<
|
|
336
|
+
<PageLoader label="Loading missions..." />
|
|
336
337
|
) : filtered.length === 0 ? (
|
|
337
338
|
<div className="px-3 py-4 text-[13px] text-text-3/55">No missions match the current filters.</div>
|
|
338
339
|
) : filtered.map((mission) => {
|
|
@@ -385,7 +386,7 @@ export default function MissionsPage() {
|
|
|
385
386
|
Select a mission to inspect its detail, linked work, and operator actions.
|
|
386
387
|
</div>
|
|
387
388
|
) : detailLoading && !selectedMission ? (
|
|
388
|
-
<
|
|
389
|
+
<PageLoader label="Loading mission..." />
|
|
389
390
|
) : selectedMission ? (
|
|
390
391
|
<div className="space-y-4">
|
|
391
392
|
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
package/src/cli/index.js
CHANGED
|
@@ -170,10 +170,10 @@ const COMMAND_GROUPS = [
|
|
|
170
170
|
],
|
|
171
171
|
},
|
|
172
172
|
{
|
|
173
|
-
name: '
|
|
174
|
-
description: '
|
|
173
|
+
name: 'delegation-jobs',
|
|
174
|
+
description: 'Delegation job status',
|
|
175
175
|
commands: [
|
|
176
|
-
cmd('
|
|
176
|
+
cmd('list', 'GET', '/delegation-jobs', 'List active and recent delegation jobs'),
|
|
177
177
|
],
|
|
178
178
|
},
|
|
179
179
|
{
|
package/src/cli/spec.js
CHANGED
|
@@ -124,10 +124,10 @@ const COMMAND_GROUPS = {
|
|
|
124
124
|
'health-check': { description: 'Run daemon health checks immediately', method: 'POST', path: '/daemon/health-check' },
|
|
125
125
|
},
|
|
126
126
|
},
|
|
127
|
-
|
|
128
|
-
description: '
|
|
127
|
+
'delegation-jobs': {
|
|
128
|
+
description: 'Delegation job status',
|
|
129
129
|
commands: {
|
|
130
|
-
|
|
130
|
+
list: { description: 'List active and recent delegation jobs', method: 'GET', path: '/delegation-jobs' },
|
|
131
131
|
},
|
|
132
132
|
},
|
|
133
133
|
dirs: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
|
|
4
|
+
import { useShallow } from 'zustand/react/shallow'
|
|
4
5
|
import { useAppStore } from '@/stores/use-app-store'
|
|
5
6
|
import { useChatStore } from '@/stores/use-chat-store'
|
|
6
7
|
import { useChatroomStore } from '@/stores/use-chatroom-store'
|
|
@@ -35,7 +36,13 @@ export function AgentChatList({ inSidebar, onSelect }: Props) {
|
|
|
35
36
|
const togglePinAgent = useAppStore((s) => s.togglePinAgent)
|
|
36
37
|
const appSettings = useAppStore((s) => s.appSettings)
|
|
37
38
|
const updateSettings = useAppStore((s) => s.updateSettings)
|
|
38
|
-
const streamingSessionId = useChatStore(
|
|
39
|
+
const { streamingSessionId, streamPhase, streamToolName } = useChatStore(
|
|
40
|
+
useShallow((s) => ({
|
|
41
|
+
streamingSessionId: s.streamingSessionId,
|
|
42
|
+
streamPhase: s.streamPhase,
|
|
43
|
+
streamToolName: s.streamToolName,
|
|
44
|
+
})),
|
|
45
|
+
)
|
|
39
46
|
const chatFilter = useAppStore((s) => s.chatFilter ?? 'all')
|
|
40
47
|
const setChatFilter = useAppStore((s) => s.setChatFilter)
|
|
41
48
|
const chatrooms = useChatroomStore((s) => s.chatrooms)
|
|
@@ -352,13 +359,17 @@ export function AgentChatList({ inSidebar, onSelect }: Props) {
|
|
|
352
359
|
</span>
|
|
353
360
|
</div>
|
|
354
361
|
{isTyping ? (
|
|
355
|
-
<div className=
|
|
362
|
+
<div className={`text-[12px] mt-1 flex items-center gap-1.5 ${streamPhase === 'queued' ? 'text-amber-300/80' : 'text-accent-bright/80'}`}>
|
|
356
363
|
<span className="flex gap-0.5">
|
|
357
|
-
<span className=
|
|
358
|
-
<span className=
|
|
359
|
-
<span className=
|
|
364
|
+
<span className={`w-1 h-1 rounded-full animate-bounce [animation-delay:0ms] ${streamPhase === 'queued' ? 'bg-amber-400/70' : 'bg-accent-bright/70'}`} />
|
|
365
|
+
<span className={`w-1 h-1 rounded-full animate-bounce [animation-delay:150ms] ${streamPhase === 'queued' ? 'bg-amber-400/70' : 'bg-accent-bright/70'}`} />
|
|
366
|
+
<span className={`w-1 h-1 rounded-full animate-bounce [animation-delay:300ms] ${streamPhase === 'queued' ? 'bg-amber-400/70' : 'bg-accent-bright/70'}`} />
|
|
360
367
|
</span>
|
|
361
|
-
|
|
368
|
+
{streamPhase === 'queued' ? 'Queued...'
|
|
369
|
+
: streamPhase === 'tool' && streamToolName ? `Using ${streamToolName}...`
|
|
370
|
+
: streamPhase === 'responding' ? 'Responding...'
|
|
371
|
+
: streamPhase === 'connecting' ? 'Reconnecting...'
|
|
372
|
+
: 'Thinking...'}
|
|
362
373
|
</div>
|
|
363
374
|
) : (
|
|
364
375
|
<div className="text-[12px] text-text-3/70 mt-1 truncate">
|
|
@@ -504,13 +515,17 @@ export function AgentChatList({ inSidebar, onSelect }: Props) {
|
|
|
504
515
|
</button>
|
|
505
516
|
</div>
|
|
506
517
|
{isTyping ? (
|
|
507
|
-
<div className=
|
|
518
|
+
<div className={`text-[12px] mt-0.5 flex items-center gap-1.5 ${streamPhase === 'queued' ? 'text-amber-300/70' : 'text-accent-bright/70'}`}>
|
|
508
519
|
<span className="flex gap-0.5">
|
|
509
|
-
<span className=
|
|
510
|
-
<span className=
|
|
511
|
-
<span className=
|
|
520
|
+
<span className={`w-1 h-1 rounded-full animate-bounce [animation-delay:0ms] ${streamPhase === 'queued' ? 'bg-amber-400/70' : 'bg-accent-bright/70'}`} />
|
|
521
|
+
<span className={`w-1 h-1 rounded-full animate-bounce [animation-delay:150ms] ${streamPhase === 'queued' ? 'bg-amber-400/70' : 'bg-accent-bright/70'}`} />
|
|
522
|
+
<span className={`w-1 h-1 rounded-full animate-bounce [animation-delay:300ms] ${streamPhase === 'queued' ? 'bg-amber-400/70' : 'bg-accent-bright/70'}`} />
|
|
512
523
|
</span>
|
|
513
|
-
|
|
524
|
+
{streamPhase === 'queued' ? 'Queued...'
|
|
525
|
+
: streamPhase === 'tool' && streamToolName ? `Using ${streamToolName}...`
|
|
526
|
+
: streamPhase === 'responding' ? 'Responding...'
|
|
527
|
+
: streamPhase === 'connecting' ? 'Reconnecting...'
|
|
528
|
+
: 'Thinking...'}
|
|
514
529
|
</div>
|
|
515
530
|
) : preview ? (
|
|
516
531
|
<div className="text-[12px] text-text-3/70 mt-0.5 truncate">
|