@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
|
@@ -9,6 +9,7 @@ import { Avatar } from '@/components/shared/avatar'
|
|
|
9
9
|
import { SettingsPage } from '@/components/shared/settings/settings-page'
|
|
10
10
|
import { AgentList } from '@/components/agents/agent-list'
|
|
11
11
|
import { AgentChatList } from '@/components/agents/agent-chat-list'
|
|
12
|
+
import { AgentAvatar } from '@/components/agents/agent-avatar'
|
|
12
13
|
import { AgentSheet } from '@/components/agents/agent-sheet'
|
|
13
14
|
import { ScheduleList } from '@/components/schedules/schedule-list'
|
|
14
15
|
import { ScheduleSheet } from '@/components/schedules/schedule-sheet'
|
|
@@ -23,6 +24,7 @@ import { SecretsList } from '@/components/secrets/secrets-list'
|
|
|
23
24
|
import { SecretSheet } from '@/components/secrets/secret-sheet'
|
|
24
25
|
import { ProviderList } from '@/components/providers/provider-list'
|
|
25
26
|
import { ProviderSheet } from '@/components/providers/provider-sheet'
|
|
27
|
+
import { GatewaySheet } from '@/components/gateways/gateway-sheet'
|
|
26
28
|
import { SkillList } from '@/components/skills/skill-list'
|
|
27
29
|
import { SkillSheet } from '@/components/skills/skill-sheet'
|
|
28
30
|
import { ConnectorList } from '@/components/connectors/connector-list'
|
|
@@ -71,6 +73,46 @@ const RAIL_EXPANDED_KEY = 'sc_rail_expanded'
|
|
|
71
73
|
const STAR_NOTIFICATION_KEY = 'sc_star_notification_v1'
|
|
72
74
|
const GITHUB_REPO_URL = 'https://github.com/swarmclawai/swarmclaw'
|
|
73
75
|
|
|
76
|
+
const VIEW_LABELS: Record<AppView, string> = {
|
|
77
|
+
home: 'Home',
|
|
78
|
+
agents: 'Agents',
|
|
79
|
+
chatrooms: 'Chatrooms',
|
|
80
|
+
schedules: 'Schedules',
|
|
81
|
+
memory: 'Memory',
|
|
82
|
+
tasks: 'Tasks',
|
|
83
|
+
approvals: 'Approvals',
|
|
84
|
+
secrets: 'Secrets',
|
|
85
|
+
providers: 'Providers',
|
|
86
|
+
skills: 'Skills',
|
|
87
|
+
connectors: 'Connectors',
|
|
88
|
+
webhooks: 'Webhooks',
|
|
89
|
+
mcp_servers: 'MCP Servers',
|
|
90
|
+
knowledge: 'Knowledge',
|
|
91
|
+
logs: 'Logs',
|
|
92
|
+
plugins: 'Plugins',
|
|
93
|
+
usage: 'Usage',
|
|
94
|
+
wallets: 'Wallets',
|
|
95
|
+
runs: 'Runs',
|
|
96
|
+
settings: 'Settings',
|
|
97
|
+
projects: 'Projects',
|
|
98
|
+
activity: 'Activity',
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const CREATE_LABELS: Partial<Record<AppView, string>> = {
|
|
102
|
+
agents: 'Agent',
|
|
103
|
+
schedules: 'Schedule',
|
|
104
|
+
tasks: 'Task',
|
|
105
|
+
secrets: 'Secret',
|
|
106
|
+
providers: 'Provider',
|
|
107
|
+
skills: 'Skill',
|
|
108
|
+
connectors: 'Connector',
|
|
109
|
+
webhooks: 'Webhook',
|
|
110
|
+
mcp_servers: 'MCP Server',
|
|
111
|
+
knowledge: 'Knowledge Entry',
|
|
112
|
+
plugins: 'Plugin',
|
|
113
|
+
projects: 'Project',
|
|
114
|
+
}
|
|
115
|
+
|
|
74
116
|
export function AppLayout() {
|
|
75
117
|
const currentUser = useAppStore((s) => s.currentUser)
|
|
76
118
|
const sessions = useAppStore((s) => s.sessions)
|
|
@@ -133,13 +175,15 @@ export function AppLayout() {
|
|
|
133
175
|
|
|
134
176
|
const handleShortcutKey = useCallback((e: KeyboardEvent) => {
|
|
135
177
|
const mod = e.metaKey || e.ctrlKey
|
|
136
|
-
// Cmd+N / Ctrl+N —
|
|
178
|
+
// Cmd+N / Ctrl+N — jump to the default agent shortcut
|
|
137
179
|
if (mod && !e.shiftKey && e.key.toLowerCase() === 'n') {
|
|
138
180
|
e.preventDefault()
|
|
139
181
|
const state = useAppStore.getState()
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
182
|
+
const defaultAgentId = state.appSettings.defaultAgentId && state.agents[state.appSettings.defaultAgentId]
|
|
183
|
+
? state.appSettings.defaultAgentId
|
|
184
|
+
: Object.values(state.agents)[0]?.id || null
|
|
185
|
+
if (defaultAgentId) void state.setCurrentAgent(defaultAgentId)
|
|
186
|
+
else state.setActiveView('agents')
|
|
143
187
|
return
|
|
144
188
|
}
|
|
145
189
|
// Cmd+Shift+T / Ctrl+Shift+T — jump to tasks
|
|
@@ -191,6 +235,17 @@ export function AppLayout() {
|
|
|
191
235
|
|
|
192
236
|
useWs('plugins', refreshPluginState)
|
|
193
237
|
|
|
238
|
+
const isViewEnabled = useCallback((view: AppView) => {
|
|
239
|
+
if (view === 'chatrooms') return plugins['chatroom']?.enabled !== false
|
|
240
|
+
if (view === 'schedules') return plugins['schedule']?.enabled !== false
|
|
241
|
+
if (view === 'memory') return plugins['memory']?.enabled !== false
|
|
242
|
+
if (view === 'connectors') return plugins['connectors']?.enabled !== false
|
|
243
|
+
if (view === 'webhooks') return plugins['http']?.enabled !== false
|
|
244
|
+
if (view === 'wallets') return plugins['wallet']?.enabled !== false
|
|
245
|
+
if (view === 'logs') return plugins['monitor']?.enabled !== false
|
|
246
|
+
return true
|
|
247
|
+
}, [plugins])
|
|
248
|
+
|
|
194
249
|
const [railExpanded, setRailExpanded] = useState(() => {
|
|
195
250
|
const stored = safeStorageGet(RAIL_EXPANDED_KEY)
|
|
196
251
|
return stored === null ? true : stored === 'true'
|
|
@@ -237,10 +292,11 @@ export function AppLayout() {
|
|
|
237
292
|
const agents = useAppStore((s) => s.agents)
|
|
238
293
|
const currentAgentId = useAppStore((s) => s.currentAgentId)
|
|
239
294
|
const setCurrentAgent = useAppStore((s) => s.setCurrentAgent)
|
|
240
|
-
const
|
|
241
|
-
? appSettings.defaultAgentId
|
|
242
|
-
: Object.values(agents)[0]
|
|
243
|
-
const
|
|
295
|
+
const defaultAgent = appSettings.defaultAgentId && agents[appSettings.defaultAgentId]
|
|
296
|
+
? agents[appSettings.defaultAgentId]
|
|
297
|
+
: Object.values(agents)[0] || null
|
|
298
|
+
const defaultAgentId = defaultAgent?.id || null
|
|
299
|
+
const isDefaultChat = activeView === 'agents' && currentAgentId === defaultAgentId
|
|
244
300
|
|
|
245
301
|
const swipeHandlers = useSwipe({
|
|
246
302
|
onSwipe: (dir) => {
|
|
@@ -255,9 +311,11 @@ export function AppLayout() {
|
|
|
255
311
|
const hasCanvas = !!(currentSession?.canvasContent && canvasDismissedFor !== currentSessionId)
|
|
256
312
|
const canvasAgentName = currentSession?.agentId && agents[currentSession.agentId] ? agents[currentSession.agentId].name : undefined
|
|
257
313
|
|
|
258
|
-
const
|
|
314
|
+
const goToDefaultChat = async () => {
|
|
259
315
|
if (defaultAgentId) {
|
|
260
316
|
await setCurrentAgent(defaultAgentId)
|
|
317
|
+
} else {
|
|
318
|
+
setActiveView('agents')
|
|
261
319
|
}
|
|
262
320
|
setActiveView('agents')
|
|
263
321
|
setSidebarOpen(false)
|
|
@@ -317,32 +375,60 @@ export function AppLayout() {
|
|
|
317
375
|
</div>
|
|
318
376
|
)}
|
|
319
377
|
|
|
320
|
-
{/*
|
|
378
|
+
{/* Default agent shortcut */}
|
|
321
379
|
{railExpanded ? (
|
|
322
|
-
<div className="px-3 mb-2">
|
|
380
|
+
<div className="px-3 mb-2.5">
|
|
323
381
|
<button
|
|
324
|
-
onClick={
|
|
325
|
-
className={`w-full flex items-center gap-
|
|
326
|
-
${
|
|
382
|
+
onClick={goToDefaultChat}
|
|
383
|
+
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-[12px] text-[13px] font-600 cursor-pointer transition-all text-left
|
|
384
|
+
${isDefaultChat
|
|
327
385
|
? 'bg-accent-bright/15 border border-[#6366F1]/25 text-accent-bright'
|
|
328
386
|
: 'bg-accent-bright/10 border border-[#6366F1]/20 text-accent-bright hover:bg-accent-bright/15'}`}
|
|
329
387
|
style={{ fontFamily: 'inherit' }}
|
|
330
388
|
>
|
|
331
|
-
|
|
332
|
-
<
|
|
333
|
-
|
|
334
|
-
|
|
389
|
+
{defaultAgent ? (
|
|
390
|
+
<AgentAvatar
|
|
391
|
+
seed={defaultAgent.avatarSeed || null}
|
|
392
|
+
avatarUrl={defaultAgent.avatarUrl}
|
|
393
|
+
name={defaultAgent.name}
|
|
394
|
+
size={28}
|
|
395
|
+
/>
|
|
396
|
+
) : (
|
|
397
|
+
<div className="w-7 h-7 rounded-full bg-accent-bright/15 flex items-center justify-center shrink-0">
|
|
398
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
399
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
400
|
+
</svg>
|
|
401
|
+
</div>
|
|
402
|
+
)}
|
|
403
|
+
<div className="min-w-0">
|
|
404
|
+
<div className="truncate">{defaultAgent?.name || 'Choose Agent'}</div>
|
|
405
|
+
<div className="text-[10px] font-500 text-accent-bright/75 mt-0.5">
|
|
406
|
+
{defaultAgent ? 'Default shortcut' : 'Pick an agent to open its thread'}
|
|
407
|
+
</div>
|
|
408
|
+
</div>
|
|
335
409
|
</button>
|
|
336
410
|
</div>
|
|
337
411
|
) : (
|
|
338
|
-
<RailTooltip
|
|
412
|
+
<RailTooltip
|
|
413
|
+
label={defaultAgent?.name || 'Choose Agent'}
|
|
414
|
+
description={defaultAgent ? 'Open your default agent shortcut chat' : 'Choose an agent thread'}
|
|
415
|
+
>
|
|
339
416
|
<button
|
|
340
|
-
onClick={
|
|
341
|
-
className={`rail-btn self-center mb-2 ${
|
|
417
|
+
onClick={goToDefaultChat}
|
|
418
|
+
className={`rail-btn self-center mb-2 ${isDefaultChat ? 'active' : ''}`}
|
|
342
419
|
>
|
|
343
|
-
|
|
344
|
-
<
|
|
345
|
-
|
|
420
|
+
{defaultAgent ? (
|
|
421
|
+
<AgentAvatar
|
|
422
|
+
seed={defaultAgent.avatarSeed || null}
|
|
423
|
+
avatarUrl={defaultAgent.avatarUrl}
|
|
424
|
+
name={defaultAgent.name}
|
|
425
|
+
size={20}
|
|
426
|
+
/>
|
|
427
|
+
) : (
|
|
428
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
429
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
430
|
+
</svg>
|
|
431
|
+
)}
|
|
346
432
|
</button>
|
|
347
433
|
</RailTooltip>
|
|
348
434
|
)}
|
|
@@ -380,128 +466,159 @@ export function AppLayout() {
|
|
|
380
466
|
|
|
381
467
|
<div className="flex-1 min-h-0 flex flex-col overflow-y-auto overscroll-contain touch-pan-y">
|
|
382
468
|
{/* Nav items */}
|
|
383
|
-
<div className={`flex flex-col gap-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
</
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
<
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
469
|
+
<div className={`flex flex-col gap-3 ${railExpanded ? 'px-3' : 'items-center'}`}>
|
|
470
|
+
<div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
|
|
471
|
+
{railExpanded ? (
|
|
472
|
+
<div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Workspace</div>
|
|
473
|
+
) : (
|
|
474
|
+
<div className="my-1 h-px w-6 bg-white/[0.06]" />
|
|
475
|
+
)}
|
|
476
|
+
<NavItem view="home" label="Home" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('home')}>
|
|
477
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
478
|
+
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /><polyline points="9 22 9 12 15 12 15 22" />
|
|
479
|
+
</svg>
|
|
480
|
+
</NavItem>
|
|
481
|
+
<NavItem view="agents" label="Agents" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('agents')}>
|
|
482
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
483
|
+
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" />
|
|
484
|
+
</svg>
|
|
485
|
+
</NavItem>
|
|
486
|
+
{isViewEnabled('chatrooms') && (
|
|
487
|
+
<NavItem view="chatrooms" label="Chatrooms" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('chatrooms')}>
|
|
488
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
489
|
+
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
490
|
+
<path d="M8 10h8" /><path d="M8 14h4" />
|
|
491
|
+
</svg>
|
|
492
|
+
</NavItem>
|
|
493
|
+
)}
|
|
494
|
+
<NavItem view="projects" label="Projects" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('projects')}>
|
|
495
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
496
|
+
<path d="M2 20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8l-7-7H4a2 2 0 0 0-2 2v17Z" /><path d="M14 2v7h7" />
|
|
497
|
+
</svg>
|
|
498
|
+
</NavItem>
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
<div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
|
|
502
|
+
{railExpanded ? (
|
|
503
|
+
<div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Execution</div>
|
|
504
|
+
) : (
|
|
505
|
+
<div className="my-1 h-px w-6 bg-white/[0.06]" />
|
|
506
|
+
)}
|
|
507
|
+
<NavItem view="tasks" label="Tasks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('tasks')} badge={pendingApprovalCount}>
|
|
508
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
509
|
+
<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" /><rect x="9" y="3" width="6" height="4" rx="1" /><path d="M9 14l2 2 4-4" />
|
|
510
|
+
</svg>
|
|
511
|
+
</NavItem>
|
|
512
|
+
<NavItem view="approvals" label="Approvals" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('approvals')} badge={pendingApprovalCount}>
|
|
513
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
514
|
+
<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
|
|
515
|
+
<path d="m9 12 2 2 4-4"/>
|
|
516
|
+
</svg>
|
|
517
|
+
</NavItem>
|
|
518
|
+
{isViewEnabled('schedules') && (
|
|
519
|
+
<NavItem view="schedules" label="Schedules" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('schedules')}>
|
|
520
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
521
|
+
<circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" />
|
|
522
|
+
</svg>
|
|
523
|
+
</NavItem>
|
|
524
|
+
)}
|
|
525
|
+
{isViewEnabled('memory') && (
|
|
526
|
+
<NavItem view="memory" label="Memory" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('memory')}>
|
|
527
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
528
|
+
<ellipse cx="12" cy="5" rx="9" ry="3" /><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3" /><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5" />
|
|
529
|
+
</svg>
|
|
530
|
+
</NavItem>
|
|
531
|
+
)}
|
|
532
|
+
<NavItem view="runs" label="Runs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('runs')}>
|
|
533
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
534
|
+
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
|
|
535
|
+
</svg>
|
|
536
|
+
</NavItem>
|
|
537
|
+
</div>
|
|
538
|
+
|
|
539
|
+
<div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
|
|
540
|
+
{railExpanded ? (
|
|
541
|
+
<div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">Knowledge</div>
|
|
542
|
+
) : (
|
|
543
|
+
<div className="my-1 h-px w-6 bg-white/[0.06]" />
|
|
544
|
+
)}
|
|
545
|
+
<NavItem view="knowledge" label="Knowledge" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('knowledge')}>
|
|
546
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
547
|
+
<circle cx="12" cy="12" r="10" /><line x1="2" y1="12" x2="22" y2="12" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
|
|
548
|
+
</svg>
|
|
549
|
+
</NavItem>
|
|
550
|
+
<NavItem view="skills" label="Skills" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('skills')}>
|
|
551
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
552
|
+
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
|
553
|
+
</svg>
|
|
554
|
+
</NavItem>
|
|
555
|
+
{isViewEnabled('connectors') && (
|
|
556
|
+
<NavItem view="connectors" label="Connectors" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('connectors')}>
|
|
557
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
558
|
+
<path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3" /><line x1="8" y1="12" x2="16" y2="12" />
|
|
559
|
+
</svg>
|
|
560
|
+
</NavItem>
|
|
561
|
+
)}
|
|
562
|
+
{isViewEnabled('webhooks') && (
|
|
563
|
+
<NavItem view="webhooks" label="Webhooks" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('webhooks')}>
|
|
564
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
565
|
+
<path d="M22 12h-4l-3 7L9 5l-3 7H2" />
|
|
566
|
+
</svg>
|
|
567
|
+
</NavItem>
|
|
568
|
+
)}
|
|
569
|
+
<NavItem view="mcp_servers" label="MCP Servers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('mcp_servers')}>
|
|
570
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
571
|
+
<rect x="2" y="2" width="20" height="8" rx="2" /><rect x="2" y="14" width="20" height="8" rx="2" /><line x1="6" y1="6" x2="6.01" y2="6" /><line x1="6" y1="18" x2="6.01" y2="18" />
|
|
572
|
+
</svg>
|
|
573
|
+
</NavItem>
|
|
574
|
+
<NavItem view="plugins" label="Plugins" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('plugins')}>
|
|
575
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
576
|
+
<path d="M12 2v4m0 12v4M2 12h4m12 0h4" /><circle cx="12" cy="12" r="4" /><path d="M8 8L5.5 5.5M16 8l2.5-2.5M8 16l-2.5 2.5M16 16l2.5 2.5" />
|
|
577
|
+
</svg>
|
|
578
|
+
</NavItem>
|
|
579
|
+
</div>
|
|
580
|
+
|
|
581
|
+
<div className={`flex flex-col gap-0.5 ${railExpanded ? '' : 'items-center'}`}>
|
|
582
|
+
{railExpanded ? (
|
|
583
|
+
<div className="px-3 pb-1 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">System</div>
|
|
584
|
+
) : (
|
|
585
|
+
<div className="my-1 h-px w-6 bg-white/[0.06]" />
|
|
586
|
+
)}
|
|
587
|
+
<NavItem view="secrets" label="Secrets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('secrets')}>
|
|
588
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
589
|
+
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
590
|
+
</svg>
|
|
591
|
+
</NavItem>
|
|
592
|
+
<NavItem view="providers" label="Providers" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('providers')}>
|
|
593
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
594
|
+
<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" />
|
|
595
|
+
</svg>
|
|
596
|
+
</NavItem>
|
|
597
|
+
<NavItem view="usage" label="Usage" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('usage')}>
|
|
598
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
599
|
+
<line x1="18" y1="20" x2="18" y2="10" /><line x1="12" y1="20" x2="12" y2="4" /><line x1="6" y1="20" x2="6" y2="14" />
|
|
600
|
+
</svg>
|
|
601
|
+
</NavItem>
|
|
602
|
+
<NavItem view="activity" label="Activity" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('activity')}>
|
|
603
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
604
|
+
<path d="M12 8v4l3 3" /><circle cx="12" cy="12" r="10" />
|
|
605
|
+
</svg>
|
|
606
|
+
</NavItem>
|
|
607
|
+
{isViewEnabled('wallets') && (
|
|
608
|
+
<NavItem view="wallets" label="Wallets" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('wallets')}>
|
|
609
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
610
|
+
<rect x="2" y="6" width="20" height="14" rx="2" /><path d="M22 10H18a2 2 0 0 0 0 4h4" /><path d="M6 6V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v2" />
|
|
611
|
+
</svg>
|
|
612
|
+
</NavItem>
|
|
613
|
+
)}
|
|
614
|
+
{isViewEnabled('logs') && (
|
|
615
|
+
<NavItem view="logs" label="Logs" expanded={railExpanded} active={activeView} sidebarOpen={sidebarOpen} onClick={() => handleNavClick('logs')}>
|
|
616
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
|
|
617
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" />
|
|
618
|
+
</svg>
|
|
619
|
+
</NavItem>
|
|
620
|
+
)}
|
|
621
|
+
</div>
|
|
505
622
|
</div>
|
|
506
623
|
|
|
507
624
|
<div className="flex-1" />
|
|
@@ -616,7 +733,7 @@ export function AppLayout() {
|
|
|
616
733
|
style={{ animation: 'panel-in 0.3s var(--ease-spring)' }}
|
|
617
734
|
>
|
|
618
735
|
<div className="flex items-center px-5 pt-5 pb-3 shrink-0">
|
|
619
|
-
<h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em]
|
|
736
|
+
<h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] flex-1">{VIEW_LABELS[activeView]}</h2>
|
|
620
737
|
{activeView === 'logs' || activeView === 'usage' || activeView === 'runs' ? null : activeView === 'memory' ? (
|
|
621
738
|
<button
|
|
622
739
|
onClick={() => useAppStore.getState().setMemorySheetOpen(true)}
|
|
@@ -638,7 +755,7 @@ export function AppLayout() {
|
|
|
638
755
|
<line x1="12" y1="5" x2="12" y2="19" />
|
|
639
756
|
<line x1="5" y1="12" x2="19" y2="12" />
|
|
640
757
|
</svg>
|
|
641
|
-
{activeView
|
|
758
|
+
{CREATE_LABELS[activeView] || 'New'}
|
|
642
759
|
</button>
|
|
643
760
|
)}
|
|
644
761
|
</div>
|
|
@@ -706,32 +823,89 @@ export function AppLayout() {
|
|
|
706
823
|
<Avatar user={currentUser!} size="sm" avatarSeed={appSettings.userAvatarSeed} />
|
|
707
824
|
</button>
|
|
708
825
|
</div>
|
|
709
|
-
{
|
|
710
|
-
|
|
711
|
-
{(['agents', 'chatrooms', 'schedules', 'memory', 'tasks', 'secrets', 'providers', 'skills', 'connectors', 'webhooks', 'mcp_servers', 'knowledge', 'plugins', 'usage', 'runs', 'logs'] as AppView[]).map((v) => (
|
|
712
|
-
<button
|
|
713
|
-
key={v}
|
|
714
|
-
onClick={() => setActiveView(v)}
|
|
715
|
-
className={`py-2 px-2.5 rounded-[10px] text-[11px] font-600 capitalize cursor-pointer transition-all
|
|
716
|
-
${activeView === v
|
|
717
|
-
? 'bg-accent-soft text-accent-bright'
|
|
718
|
-
: 'bg-transparent text-text-3 hover:text-text-2'}`}
|
|
719
|
-
style={{ fontFamily: 'inherit' }}
|
|
720
|
-
>
|
|
721
|
-
{v}
|
|
722
|
-
</button>
|
|
723
|
-
))}
|
|
724
|
-
{/* Dynamic Plugin Items */}
|
|
725
|
-
{pluginSidebarItems.map((item) => (
|
|
826
|
+
{defaultAgent && (
|
|
827
|
+
<div className="px-4 pt-1 pb-3 shrink-0">
|
|
726
828
|
<button
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
829
|
+
onClick={goToDefaultChat}
|
|
830
|
+
className={`w-full flex items-center gap-3 rounded-[14px] border px-4 py-3 text-left transition-all cursor-pointer ${
|
|
831
|
+
isDefaultChat
|
|
832
|
+
? 'bg-accent-soft border-accent-bright/25 text-accent-bright'
|
|
833
|
+
: 'bg-accent-soft/50 border-accent-bright/15 text-accent-bright hover:bg-accent-soft/65'
|
|
834
|
+
}`}
|
|
730
835
|
style={{ fontFamily: 'inherit' }}
|
|
731
836
|
>
|
|
732
|
-
|
|
837
|
+
<AgentAvatar
|
|
838
|
+
seed={defaultAgent.avatarSeed || null}
|
|
839
|
+
avatarUrl={defaultAgent.avatarUrl}
|
|
840
|
+
name={defaultAgent.name}
|
|
841
|
+
size={32}
|
|
842
|
+
/>
|
|
843
|
+
<div className="min-w-0">
|
|
844
|
+
<div className="text-[13px] font-700 truncate">{defaultAgent.name}</div>
|
|
845
|
+
<div className="text-[11px] text-accent-bright/70">Default shortcut</div>
|
|
846
|
+
</div>
|
|
733
847
|
</button>
|
|
734
|
-
|
|
848
|
+
</div>
|
|
849
|
+
)}
|
|
850
|
+
<div className="px-4 pb-3 shrink-0 max-h-[260px] overflow-y-auto">
|
|
851
|
+
<div className="space-y-4">
|
|
852
|
+
{([
|
|
853
|
+
{ label: 'Workspace', views: ['agents', 'chatrooms', 'projects'] as AppView[] },
|
|
854
|
+
{ label: 'Execution', views: ['tasks', 'approvals', 'schedules', 'memory', 'runs'] as AppView[] },
|
|
855
|
+
{ label: 'Knowledge', views: ['knowledge', 'skills', 'connectors', 'webhooks', 'mcp_servers', 'plugins'] as AppView[] },
|
|
856
|
+
{ label: 'System', views: ['secrets', 'providers', 'usage', 'logs'] as AppView[] },
|
|
857
|
+
]).map((section) => {
|
|
858
|
+
const visibleViews = section.views.filter((view) => isViewEnabled(view))
|
|
859
|
+
if (!visibleViews.length) return null
|
|
860
|
+
return (
|
|
861
|
+
<div key={section.label}>
|
|
862
|
+
<div className="px-1 pb-2 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">
|
|
863
|
+
{section.label}
|
|
864
|
+
</div>
|
|
865
|
+
<div className="grid grid-cols-2 gap-2">
|
|
866
|
+
{visibleViews.map((view) => (
|
|
867
|
+
<button
|
|
868
|
+
key={view}
|
|
869
|
+
onClick={() => {
|
|
870
|
+
setActiveView(view)
|
|
871
|
+
if (FULL_WIDTH_VIEWS.has(view)) setSidebarOpen(false)
|
|
872
|
+
}}
|
|
873
|
+
className={`rounded-[12px] border px-3 py-2.5 text-left transition-all cursor-pointer ${
|
|
874
|
+
activeView === view
|
|
875
|
+
? 'bg-accent-soft border-accent-bright/20 text-accent-bright'
|
|
876
|
+
: 'bg-transparent border-white/[0.06] text-text-3 hover:text-text hover:bg-white/[0.04]'
|
|
877
|
+
}`}
|
|
878
|
+
style={{ fontFamily: 'inherit' }}
|
|
879
|
+
>
|
|
880
|
+
<div className="text-[12px] font-600">{VIEW_LABELS[view]}</div>
|
|
881
|
+
<div className="text-[10px] text-current/60 mt-1">{VIEW_DESCRIPTIONS[view]}</div>
|
|
882
|
+
</button>
|
|
883
|
+
))}
|
|
884
|
+
</div>
|
|
885
|
+
</div>
|
|
886
|
+
)
|
|
887
|
+
})}
|
|
888
|
+
{pluginSidebarItems.length > 0 && (
|
|
889
|
+
<div>
|
|
890
|
+
<div className="px-1 pb-2 text-[10px] font-700 uppercase tracking-[0.12em] text-text-3/45">
|
|
891
|
+
Extensions
|
|
892
|
+
</div>
|
|
893
|
+
<div className="grid grid-cols-2 gap-2">
|
|
894
|
+
{pluginSidebarItems.map((item) => (
|
|
895
|
+
<button
|
|
896
|
+
key={item.id}
|
|
897
|
+
onClick={() => window.open(item.href, '_blank')}
|
|
898
|
+
className="rounded-[12px] border border-emerald-400/10 bg-emerald-500/[0.05] px-3 py-2.5 text-left text-emerald-400/85 hover:text-emerald-300 transition-colors cursor-pointer"
|
|
899
|
+
style={{ fontFamily: 'inherit' }}
|
|
900
|
+
>
|
|
901
|
+
<div className="text-[12px] font-600">{item.label}</div>
|
|
902
|
+
<div className="text-[10px] text-emerald-300/60 mt-1">Open plugin view</div>
|
|
903
|
+
</button>
|
|
904
|
+
))}
|
|
905
|
+
</div>
|
|
906
|
+
</div>
|
|
907
|
+
)}
|
|
908
|
+
</div>
|
|
735
909
|
</div>
|
|
736
910
|
{activeView !== 'logs' && activeView !== 'usage' && activeView !== 'runs' && activeView !== 'settings' && (
|
|
737
911
|
<div className="px-4 py-2.5 shrink-0">
|
|
@@ -745,7 +919,7 @@ export function AppLayout() {
|
|
|
745
919
|
shadow-[0_2px_12px_rgba(99,102,241,0.15)]"
|
|
746
920
|
style={{ fontFamily: 'inherit' }}
|
|
747
921
|
>
|
|
748
|
-
+ New {activeView
|
|
922
|
+
+ New {CREATE_LABELS[activeView] || 'Entry'}
|
|
749
923
|
</button>
|
|
750
924
|
</div>
|
|
751
925
|
)}
|
|
@@ -811,11 +985,27 @@ export function AppLayout() {
|
|
|
811
985
|
<div className="flex-1 flex items-center justify-center px-8">
|
|
812
986
|
<div className="text-center max-w-[420px]">
|
|
813
987
|
<h2 className="font-display text-[24px] font-700 text-text mb-2 tracking-[-0.02em]">
|
|
814
|
-
|
|
988
|
+
Open a Chat
|
|
815
989
|
</h2>
|
|
816
990
|
<p className="text-[14px] text-text-3">
|
|
817
|
-
Choose
|
|
991
|
+
Choose a chat from the sidebar, or jump straight into your default agent shortcut.
|
|
818
992
|
</p>
|
|
993
|
+
<div className="mt-5 flex items-center justify-center gap-3">
|
|
994
|
+
<button
|
|
995
|
+
onClick={defaultAgent ? goToDefaultChat : () => setAgentSheetOpen(true)}
|
|
996
|
+
className="inline-flex items-center gap-2 px-4 py-2.5 rounded-[12px] border-none bg-accent-bright text-white text-[13px] font-600 cursor-pointer hover:brightness-110 transition-all"
|
|
997
|
+
style={{ fontFamily: 'inherit' }}
|
|
998
|
+
>
|
|
999
|
+
{defaultAgent ? `Open ${defaultAgent.name}` : 'Create Agent'}
|
|
1000
|
+
</button>
|
|
1001
|
+
<button
|
|
1002
|
+
onClick={() => setAgentSheetOpen(true)}
|
|
1003
|
+
className="inline-flex items-center gap-2 px-4 py-2.5 rounded-[12px] border border-white/[0.08] bg-transparent text-[13px] font-600 text-text-2 cursor-pointer hover:bg-white/[0.04] transition-all"
|
|
1004
|
+
style={{ fontFamily: 'inherit' }}
|
|
1005
|
+
>
|
|
1006
|
+
Create Agent
|
|
1007
|
+
</button>
|
|
1008
|
+
</div>
|
|
819
1009
|
</div>
|
|
820
1010
|
</div>
|
|
821
1011
|
)}
|
|
@@ -865,7 +1055,7 @@ export function AppLayout() {
|
|
|
865
1055
|
<div className="flex-1 flex flex-col h-full">
|
|
866
1056
|
<div className="flex items-center px-6 pt-5 pb-3 shrink-0">
|
|
867
1057
|
<h2 className="font-display text-[14px] font-600 text-text-2 tracking-[-0.01em] capitalize flex-1">
|
|
868
|
-
{activeView
|
|
1058
|
+
{VIEW_LABELS[activeView]}
|
|
869
1059
|
</h2>
|
|
870
1060
|
{activeView !== 'runs' && activeView !== 'logs' && (
|
|
871
1061
|
<button
|
|
@@ -876,7 +1066,7 @@ export function AppLayout() {
|
|
|
876
1066
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
|
|
877
1067
|
<line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" />
|
|
878
1068
|
</svg>
|
|
879
|
-
{activeView
|
|
1069
|
+
{CREATE_LABELS[activeView] || 'New'}
|
|
880
1070
|
</button>
|
|
881
1071
|
)}
|
|
882
1072
|
</div>
|
|
@@ -908,6 +1098,7 @@ export function AppLayout() {
|
|
|
908
1098
|
<TaskSheet />
|
|
909
1099
|
<SecretSheet />
|
|
910
1100
|
<ProviderSheet />
|
|
1101
|
+
<GatewaySheet />
|
|
911
1102
|
<SkillSheet />
|
|
912
1103
|
<ConnectorSheet />
|
|
913
1104
|
<ChatroomSheet />
|
|
@@ -981,9 +1172,9 @@ const VIEW_DESCRIPTIONS: Record<AppView, string> = {
|
|
|
981
1172
|
chatrooms: 'Multi-agent collaborative chatrooms',
|
|
982
1173
|
schedules: 'Automated task schedules',
|
|
983
1174
|
memory: 'Long-term agent memory store',
|
|
984
|
-
tasks: 'Task board for
|
|
1175
|
+
tasks: 'Task board for agent work and queued runs',
|
|
985
1176
|
approvals: 'Pending tool execution approvals',
|
|
986
|
-
secrets: 'API keys
|
|
1177
|
+
secrets: 'API keys, tokens, and encrypted credentials',
|
|
987
1178
|
providers: 'LLM providers & custom endpoints',
|
|
988
1179
|
skills: 'Reusable instruction sets for agents',
|
|
989
1180
|
connectors: 'Chat platform bridges (Discord, Slack, etc.)',
|
|
@@ -995,7 +1186,7 @@ const VIEW_DESCRIPTIONS: Record<AppView, string> = {
|
|
|
995
1186
|
usage: 'Usage metrics, cost tracking & agent performance',
|
|
996
1187
|
wallets: 'Agent crypto wallets — hold funds, send SOL, manage spending',
|
|
997
1188
|
runs: 'Live run monitoring & history',
|
|
998
|
-
settings: 'Manage providers,
|
|
1189
|
+
settings: 'Manage defaults, providers, secrets, and automation settings',
|
|
999
1190
|
projects: 'Group agents, tasks & schedules into projects',
|
|
1000
1191
|
activity: 'Audit trail of all entity mutations',
|
|
1001
1192
|
}
|
|
@@ -1016,26 +1207,26 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
|
|
|
1016
1207
|
schedules: {
|
|
1017
1208
|
icon: 'clock',
|
|
1018
1209
|
title: 'Schedules',
|
|
1019
|
-
description: 'Automate recurring
|
|
1020
|
-
features: ['Set up cron expressions for precise timing', 'Run
|
|
1210
|
+
description: 'Automate recurring work with cron, interval, or one-time schedules that launch agent tasks.',
|
|
1211
|
+
features: ['Set up cron expressions for precise timing', 'Run agents automatically on intervals', 'Schedule one-time future tasks', 'View execution history and results'],
|
|
1021
1212
|
},
|
|
1022
1213
|
memory: {
|
|
1023
1214
|
icon: 'database',
|
|
1024
1215
|
title: 'Memory',
|
|
1025
|
-
description: 'Long-term memory store for AI agents
|
|
1216
|
+
description: 'Long-term memory store for AI agents so they can retain useful context across conversations.',
|
|
1026
1217
|
features: ['Agents store findings and learnings automatically', 'Full-text search across all stored memories', 'Organized by categories and agents', 'Persists across conversations for continuity'],
|
|
1027
1218
|
},
|
|
1028
1219
|
tasks: {
|
|
1029
1220
|
icon: 'clipboard',
|
|
1030
1221
|
title: 'Task Board',
|
|
1031
|
-
description: 'A
|
|
1032
|
-
features: ['Kanban columns: Backlog, Queued, Running, Completed, Failed', 'Assign tasks to specific
|
|
1222
|
+
description: 'A kanban board for managing agent work. Create tasks, assign them to agents, and track progress.',
|
|
1223
|
+
features: ['Kanban columns: Backlog, Queued, Running, Completed, Failed', 'Assign tasks to specific agents', 'Track retries, results, and logs', 'Review status without leaving the board'],
|
|
1033
1224
|
},
|
|
1034
1225
|
secrets: {
|
|
1035
1226
|
icon: 'lock',
|
|
1036
1227
|
title: 'Secrets',
|
|
1037
|
-
description: 'Manage API keys and credentials that
|
|
1038
|
-
features: ['Store keys for external services (Gmail, APIs, etc.)', 'Scope secrets globally or to specific
|
|
1228
|
+
description: 'Manage API keys and credentials that agents and integrations can access securely.',
|
|
1229
|
+
features: ['Store keys for external services (Gmail, APIs, etc.)', 'Scope secrets globally or to specific agents', 'Encrypted at rest with AES-256-GCM', 'Agents retrieve secrets through approved tools'],
|
|
1039
1230
|
},
|
|
1040
1231
|
providers: {
|
|
1041
1232
|
icon: 'zap',
|
|
@@ -1058,8 +1249,8 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
|
|
|
1058
1249
|
webhooks: {
|
|
1059
1250
|
icon: 'webhook',
|
|
1060
1251
|
title: 'Webhooks',
|
|
1061
|
-
description: 'Receive external events over HTTP and
|
|
1062
|
-
features: ['Create secure inbound webhook endpoints', 'Filter events by type or source', 'Route each webhook to a specific
|
|
1252
|
+
description: 'Receive external events over HTTP and route them into agent-driven workflows automatically.',
|
|
1253
|
+
features: ['Create secure inbound webhook endpoints', 'Filter events by type or source', 'Route each webhook to a specific agent', 'Use x-webhook-secret for request authentication'],
|
|
1063
1254
|
},
|
|
1064
1255
|
mcp_servers: {
|
|
1065
1256
|
icon: 'server',
|
|
@@ -1070,7 +1261,7 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
|
|
|
1070
1261
|
knowledge: {
|
|
1071
1262
|
icon: 'globe',
|
|
1072
1263
|
title: 'Knowledge Base',
|
|
1073
|
-
description: 'A shared knowledge graph accessible by all agents
|
|
1264
|
+
description: 'A shared knowledge graph accessible by all agents for cross-workspace information sharing.',
|
|
1074
1265
|
features: ['Create tagged knowledge entries', 'Agents can store and search knowledge via tools', 'Full-text and vector search', 'Provenance tracking per entry'],
|
|
1075
1266
|
},
|
|
1076
1267
|
logs: {
|
|
@@ -1100,8 +1291,8 @@ const VIEW_EMPTY_STATES: Record<Exclude<AppView, 'agents' | 'home'>, { icon: str
|
|
|
1100
1291
|
settings: {
|
|
1101
1292
|
icon: 'settings',
|
|
1102
1293
|
title: 'Settings',
|
|
1103
|
-
description: 'Manage providers,
|
|
1104
|
-
features: ['
|
|
1294
|
+
description: 'Manage app defaults, providers, encrypted secrets, and automation settings.',
|
|
1295
|
+
features: ['Choose your default agent shortcut', 'Configure LLM providers and credentials', 'Tune heartbeat and autonomy settings', 'Set up voice, embeddings, and search'],
|
|
1105
1296
|
},
|
|
1106
1297
|
projects: {
|
|
1107
1298
|
icon: 'folder',
|
|
@@ -1283,7 +1474,7 @@ function RailTooltip({ label, description, children }: { label: string; descript
|
|
|
1283
1474
|
}
|
|
1284
1475
|
|
|
1285
1476
|
function DesktopEmptyState({ userName }: { userName: string | null }) {
|
|
1286
|
-
const
|
|
1477
|
+
const setAgentSheetOpen = useAppStore((s) => s.setAgentSheetOpen)
|
|
1287
1478
|
|
|
1288
1479
|
return (
|
|
1289
1480
|
<div className="flex-1 flex flex-col items-center justify-center px-8 pb-20 relative overflow-hidden">
|
|
@@ -1314,10 +1505,10 @@ function DesktopEmptyState({ userName }: { userName: string | null }) {
|
|
|
1314
1505
|
<span className="text-text-2">What would you like to do?</span>
|
|
1315
1506
|
</h1>
|
|
1316
1507
|
<p className="text-[15px] text-text-3 mb-12">
|
|
1317
|
-
Create
|
|
1508
|
+
Create an agent, then keep working in its persistent thread
|
|
1318
1509
|
</p>
|
|
1319
1510
|
<button
|
|
1320
|
-
onClick={() =>
|
|
1511
|
+
onClick={() => setAgentSheetOpen(true)}
|
|
1321
1512
|
className="inline-flex items-center gap-2.5 px-12 py-4 rounded-[16px] border-none bg-accent-bright text-white text-[16px] font-display font-600
|
|
1322
1513
|
cursor-pointer hover:brightness-110 active:scale-[0.97] transition-all duration-200
|
|
1323
1514
|
shadow-[0_6px_28px_rgba(99,102,241,0.3)]"
|
|
@@ -1327,7 +1518,7 @@ function DesktopEmptyState({ userName }: { userName: string | null }) {
|
|
|
1327
1518
|
<line x1="12" y1="5" x2="12" y2="19" />
|
|
1328
1519
|
<line x1="5" y1="12" x2="19" y2="12" />
|
|
1329
1520
|
</svg>
|
|
1330
|
-
New
|
|
1521
|
+
New Agent
|
|
1331
1522
|
</button>
|
|
1332
1523
|
</div>
|
|
1333
1524
|
</div>
|