@swarmclawai/swarmclaw 0.6.6 → 0.6.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 +57 -27
- package/package.json +6 -1
- package/src/app/api/agents/[id]/clone/route.ts +40 -0
- package/src/app/api/agents/route.ts +39 -14
- package/src/app/api/chatrooms/[id]/chat/route.ts +17 -1
- package/src/app/api/chatrooms/[id]/moderate/route.ts +150 -0
- package/src/app/api/chatrooms/[id]/route.ts +19 -1
- package/src/app/api/chatrooms/route.ts +12 -2
- package/src/app/api/connectors/[id]/health/route.ts +64 -0
- package/src/app/api/connectors/route.ts +17 -2
- package/src/app/api/knowledge/route.ts +6 -1
- package/src/app/api/openclaw/doctor/route.ts +17 -0
- package/src/app/api/sessions/[id]/chat/route.ts +5 -1
- package/src/app/api/sessions/route.ts +11 -2
- package/src/app/api/tasks/[id]/route.ts +18 -13
- package/src/app/api/tasks/route.ts +20 -1
- package/src/app/api/usage/route.ts +16 -7
- package/src/cli/index.js +5 -0
- package/src/cli/index.ts +223 -39
- package/src/components/agents/agent-card.tsx +37 -6
- package/src/components/agents/agent-chat-list.tsx +78 -2
- package/src/components/agents/agent-sheet.tsx +79 -0
- package/src/components/auth/setup-wizard.tsx +268 -353
- package/src/components/chat/chat-area.tsx +22 -7
- package/src/components/chat/message-bubble.tsx +14 -14
- package/src/components/chat/message-list.tsx +1 -1
- package/src/components/chatrooms/chatroom-message.tsx +164 -22
- package/src/components/chatrooms/chatroom-sheet.tsx +288 -3
- package/src/components/chatrooms/chatroom-view.tsx +62 -17
- package/src/components/connectors/connector-health.tsx +120 -0
- package/src/components/connectors/connector-sheet.tsx +9 -0
- package/src/components/home/home-view.tsx +23 -2
- package/src/components/input/chat-input.tsx +8 -1
- package/src/components/layout/app-layout.tsx +17 -1
- package/src/components/schedules/schedule-list.tsx +55 -9
- package/src/components/schedules/schedule-sheet.tsx +134 -23
- package/src/components/shared/command-palette.tsx +237 -0
- package/src/components/shared/connector-platform-icon.tsx +1 -0
- package/src/components/tasks/task-card.tsx +22 -2
- package/src/components/tasks/task-sheet.tsx +91 -16
- package/src/components/usage/metrics-dashboard.tsx +13 -25
- package/src/hooks/use-swipe.ts +49 -0
- package/src/lib/providers/anthropic.ts +16 -2
- package/src/lib/providers/claude-cli.ts +7 -1
- package/src/lib/providers/index.ts +7 -0
- package/src/lib/providers/ollama.ts +16 -2
- package/src/lib/providers/openai.ts +7 -2
- package/src/lib/providers/openclaw.ts +6 -1
- package/src/lib/providers/provider-defaults.ts +7 -0
- package/src/lib/schedule-templates.ts +115 -0
- package/src/lib/server/alert-dispatch.ts +64 -0
- package/src/lib/server/chat-execution.ts +41 -1
- package/src/lib/server/chatroom-helpers.ts +22 -1
- package/src/lib/server/chatroom-routing.ts +65 -0
- package/src/lib/server/connectors/discord.ts +3 -0
- package/src/lib/server/connectors/email.ts +267 -0
- package/src/lib/server/connectors/manager.ts +159 -3
- package/src/lib/server/connectors/openclaw.ts +3 -0
- package/src/lib/server/connectors/slack.ts +6 -0
- package/src/lib/server/connectors/telegram.ts +18 -0
- package/src/lib/server/connectors/types.ts +2 -0
- package/src/lib/server/connectors/whatsapp.ts +9 -0
- package/src/lib/server/cost.ts +70 -0
- package/src/lib/server/create-notification.ts +2 -0
- package/src/lib/server/daemon-state.ts +124 -0
- package/src/lib/server/dag-validation.ts +115 -0
- package/src/lib/server/memory-db.ts +12 -7
- package/src/lib/server/openclaw-doctor.ts +48 -0
- package/src/lib/server/queue.ts +12 -0
- package/src/lib/server/session-run-manager.ts +22 -1
- package/src/lib/server/session-tools/index.ts +2 -0
- package/src/lib/server/session-tools/memory.ts +22 -3
- package/src/lib/server/session-tools/openclaw-workspace.ts +132 -0
- package/src/lib/server/storage.ts +120 -6
- package/src/lib/setup-defaults.ts +277 -0
- package/src/lib/validation/schemas.ts +69 -0
- package/src/stores/use-app-store.ts +7 -3
- package/src/stores/use-chatroom-store.ts +52 -2
- package/src/types/index.ts +38 -1
- package/tsconfig.json +2 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared setup defaults used by both the web wizard and CLI.
|
|
3
|
+
* Isomorphic — no 'use client', no server imports.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type SetupProvider =
|
|
7
|
+
| 'anthropic'
|
|
8
|
+
| 'openai'
|
|
9
|
+
| 'google'
|
|
10
|
+
| 'deepseek'
|
|
11
|
+
| 'groq'
|
|
12
|
+
| 'together'
|
|
13
|
+
| 'mistral'
|
|
14
|
+
| 'xai'
|
|
15
|
+
| 'fireworks'
|
|
16
|
+
| 'ollama'
|
|
17
|
+
| 'openclaw'
|
|
18
|
+
|
|
19
|
+
export interface SetupProviderOption {
|
|
20
|
+
id: SetupProvider
|
|
21
|
+
name: string
|
|
22
|
+
description: string
|
|
23
|
+
requiresKey: boolean
|
|
24
|
+
supportsEndpoint: boolean
|
|
25
|
+
defaultEndpoint?: string
|
|
26
|
+
keyUrl?: string
|
|
27
|
+
keyLabel?: string
|
|
28
|
+
keyPlaceholder?: string
|
|
29
|
+
optionalKey?: boolean
|
|
30
|
+
badge?: string
|
|
31
|
+
icon: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const SETUP_PROVIDERS: SetupProviderOption[] = [
|
|
35
|
+
{
|
|
36
|
+
id: 'openai',
|
|
37
|
+
name: 'OpenAI',
|
|
38
|
+
description: 'Great default for most users. Fast, reliable GPT models.',
|
|
39
|
+
requiresKey: true,
|
|
40
|
+
supportsEndpoint: true,
|
|
41
|
+
defaultEndpoint: 'https://api.openai.com/v1',
|
|
42
|
+
keyUrl: 'https://platform.openai.com/api-keys',
|
|
43
|
+
keyLabel: 'platform.openai.com',
|
|
44
|
+
badge: 'Recommended',
|
|
45
|
+
icon: 'O',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'anthropic',
|
|
49
|
+
name: 'Anthropic',
|
|
50
|
+
description: 'Claude models — strong for coding, analysis, and long-form reasoning.',
|
|
51
|
+
requiresKey: true,
|
|
52
|
+
supportsEndpoint: false,
|
|
53
|
+
keyUrl: 'https://console.anthropic.com/settings/keys',
|
|
54
|
+
keyLabel: 'console.anthropic.com',
|
|
55
|
+
icon: 'A',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'google',
|
|
59
|
+
name: 'Google Gemini',
|
|
60
|
+
description: 'Gemini models with strong multimodal and coding support.',
|
|
61
|
+
requiresKey: true,
|
|
62
|
+
supportsEndpoint: false,
|
|
63
|
+
keyUrl: 'https://aistudio.google.com/app/apikey',
|
|
64
|
+
keyLabel: 'aistudio.google.com',
|
|
65
|
+
keyPlaceholder: 'AIza...',
|
|
66
|
+
icon: 'G',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'deepseek',
|
|
70
|
+
name: 'DeepSeek',
|
|
71
|
+
description: 'High-value reasoning and coding models from DeepSeek.',
|
|
72
|
+
requiresKey: true,
|
|
73
|
+
supportsEndpoint: false,
|
|
74
|
+
keyUrl: 'https://platform.deepseek.com/api_keys',
|
|
75
|
+
keyLabel: 'platform.deepseek.com',
|
|
76
|
+
icon: 'D',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'groq',
|
|
80
|
+
name: 'Groq',
|
|
81
|
+
description: 'Very fast inference with open and reasoning model options.',
|
|
82
|
+
requiresKey: true,
|
|
83
|
+
supportsEndpoint: false,
|
|
84
|
+
keyUrl: 'https://console.groq.com/keys',
|
|
85
|
+
keyLabel: 'console.groq.com',
|
|
86
|
+
icon: 'G',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'together',
|
|
90
|
+
name: 'Together AI',
|
|
91
|
+
description: 'Broad catalog of open models with OpenAI-compatible APIs.',
|
|
92
|
+
requiresKey: true,
|
|
93
|
+
supportsEndpoint: false,
|
|
94
|
+
keyUrl: 'https://api.together.xyz/settings/api-keys',
|
|
95
|
+
keyLabel: 'api.together.xyz',
|
|
96
|
+
icon: 'T',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: 'mistral',
|
|
100
|
+
name: 'Mistral AI',
|
|
101
|
+
description: 'Efficient frontier models with strong latency and quality.',
|
|
102
|
+
requiresKey: true,
|
|
103
|
+
supportsEndpoint: false,
|
|
104
|
+
keyUrl: 'https://console.mistral.ai/api-keys/',
|
|
105
|
+
keyLabel: 'console.mistral.ai',
|
|
106
|
+
icon: 'M',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'xai',
|
|
110
|
+
name: 'xAI (Grok)',
|
|
111
|
+
description: 'Grok models for fast answers, coding, and analysis.',
|
|
112
|
+
requiresKey: true,
|
|
113
|
+
supportsEndpoint: false,
|
|
114
|
+
keyUrl: 'https://console.x.ai',
|
|
115
|
+
keyLabel: 'console.x.ai',
|
|
116
|
+
icon: 'X',
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 'fireworks',
|
|
120
|
+
name: 'Fireworks AI',
|
|
121
|
+
description: 'Serverless and optimized open-model inference endpoints.',
|
|
122
|
+
requiresKey: true,
|
|
123
|
+
supportsEndpoint: false,
|
|
124
|
+
keyUrl: 'https://fireworks.ai/account/api-keys',
|
|
125
|
+
keyLabel: 'fireworks.ai',
|
|
126
|
+
icon: 'F',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'openclaw',
|
|
130
|
+
name: 'OpenClaw',
|
|
131
|
+
description: 'Connect to your local or remote OpenClaw gateway (multi-OpenClaw ready).',
|
|
132
|
+
requiresKey: false,
|
|
133
|
+
supportsEndpoint: true,
|
|
134
|
+
defaultEndpoint: 'http://localhost:18789/v1',
|
|
135
|
+
optionalKey: true,
|
|
136
|
+
badge: 'OpenClaw',
|
|
137
|
+
icon: 'C',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'ollama',
|
|
141
|
+
name: 'Ollama',
|
|
142
|
+
description: 'Run local open-source models. No API key required.',
|
|
143
|
+
requiresKey: false,
|
|
144
|
+
supportsEndpoint: true,
|
|
145
|
+
defaultEndpoint: 'http://localhost:11434',
|
|
146
|
+
badge: 'Local',
|
|
147
|
+
icon: 'L',
|
|
148
|
+
},
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
export const STARTER_AGENT_TOOLS = [
|
|
152
|
+
'memory',
|
|
153
|
+
'files',
|
|
154
|
+
'web_search',
|
|
155
|
+
'web_fetch',
|
|
156
|
+
'browser',
|
|
157
|
+
'manage_agents',
|
|
158
|
+
'manage_tasks',
|
|
159
|
+
'manage_schedules',
|
|
160
|
+
'manage_skills',
|
|
161
|
+
'manage_connectors',
|
|
162
|
+
'manage_sessions',
|
|
163
|
+
'manage_secrets',
|
|
164
|
+
'manage_documents',
|
|
165
|
+
'manage_webhooks',
|
|
166
|
+
'claude_code',
|
|
167
|
+
'codex_cli',
|
|
168
|
+
'opencode_cli',
|
|
169
|
+
'openclaw_workspace',
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
export const SWARMCLAW_ASSISTANT_PROMPT = `You are the default SwarmClaw assistant inside the SwarmClaw dashboard.
|
|
173
|
+
|
|
174
|
+
Primary objective:
|
|
175
|
+
- Help the user operate SwarmClaw itself before anything else.
|
|
176
|
+
|
|
177
|
+
When the user asks about SwarmClaw, prioritize concrete guidance with exact UI paths and commands:
|
|
178
|
+
- Sessions: create, configure provider/model, and run chats.
|
|
179
|
+
- Agents: create specialist agents/orchestrators, set provider/model, tools, and prompts.
|
|
180
|
+
- Providers: connect API keys/endpoints, troubleshoot auth/model issues.
|
|
181
|
+
- Tasks + Schedules: queue work and automate recurring runs.
|
|
182
|
+
- Skills + Connectors + Webhooks + Secrets + Memory: explain when to use each and how to configure safely.
|
|
183
|
+
|
|
184
|
+
Behavior:
|
|
185
|
+
- Be concise, direct, and action-oriented.
|
|
186
|
+
- If the request is ambiguous, ask one focused clarifying question.
|
|
187
|
+
- Prefer step-by-step instructions that can be executed immediately.
|
|
188
|
+
- When the user asks for direct execution (for example browsing, screenshots, research, or file edits), use available tools and return real results instead of only describing what to do.
|
|
189
|
+
- If a capability depends on provider/tool configuration, call that out explicitly.`
|
|
190
|
+
|
|
191
|
+
export interface DefaultAgentConfig {
|
|
192
|
+
name: string
|
|
193
|
+
description: string
|
|
194
|
+
systemPrompt: string
|
|
195
|
+
model: string
|
|
196
|
+
tools: string[]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export const DEFAULT_AGENTS: Record<SetupProvider, DefaultAgentConfig> = {
|
|
200
|
+
anthropic: {
|
|
201
|
+
name: 'Claude',
|
|
202
|
+
description: 'A helpful Claude-powered assistant.',
|
|
203
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
204
|
+
model: 'claude-sonnet-4-6',
|
|
205
|
+
tools: STARTER_AGENT_TOOLS,
|
|
206
|
+
},
|
|
207
|
+
openai: {
|
|
208
|
+
name: 'Atlas',
|
|
209
|
+
description: 'A helpful GPT-powered assistant.',
|
|
210
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
211
|
+
model: 'gpt-4o',
|
|
212
|
+
tools: STARTER_AGENT_TOOLS,
|
|
213
|
+
},
|
|
214
|
+
google: {
|
|
215
|
+
name: 'Gemini',
|
|
216
|
+
description: 'A helpful Gemini-powered assistant.',
|
|
217
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
218
|
+
model: 'gemini-2.5-pro',
|
|
219
|
+
tools: STARTER_AGENT_TOOLS,
|
|
220
|
+
},
|
|
221
|
+
deepseek: {
|
|
222
|
+
name: 'DeepSeek',
|
|
223
|
+
description: 'A helpful DeepSeek-powered assistant.',
|
|
224
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
225
|
+
model: 'deepseek-chat',
|
|
226
|
+
tools: STARTER_AGENT_TOOLS,
|
|
227
|
+
},
|
|
228
|
+
groq: {
|
|
229
|
+
name: 'Bolt',
|
|
230
|
+
description: 'A low-latency assistant powered by Groq.',
|
|
231
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
232
|
+
model: 'llama-3.3-70b-versatile',
|
|
233
|
+
tools: STARTER_AGENT_TOOLS,
|
|
234
|
+
},
|
|
235
|
+
together: {
|
|
236
|
+
name: 'Mosaic',
|
|
237
|
+
description: 'A helpful assistant powered by Together AI.',
|
|
238
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
239
|
+
model: 'meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8',
|
|
240
|
+
tools: STARTER_AGENT_TOOLS,
|
|
241
|
+
},
|
|
242
|
+
mistral: {
|
|
243
|
+
name: 'Mistral',
|
|
244
|
+
description: 'A helpful assistant powered by Mistral.',
|
|
245
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
246
|
+
model: 'mistral-large-latest',
|
|
247
|
+
tools: STARTER_AGENT_TOOLS,
|
|
248
|
+
},
|
|
249
|
+
xai: {
|
|
250
|
+
name: 'Grok',
|
|
251
|
+
description: 'A helpful assistant powered by xAI Grok.',
|
|
252
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
253
|
+
model: 'grok-3',
|
|
254
|
+
tools: STARTER_AGENT_TOOLS,
|
|
255
|
+
},
|
|
256
|
+
fireworks: {
|
|
257
|
+
name: 'Spark',
|
|
258
|
+
description: 'A helpful assistant powered by Fireworks AI.',
|
|
259
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
260
|
+
model: 'accounts/fireworks/models/deepseek-r1-0528',
|
|
261
|
+
tools: STARTER_AGENT_TOOLS,
|
|
262
|
+
},
|
|
263
|
+
ollama: {
|
|
264
|
+
name: 'Local',
|
|
265
|
+
description: 'A local assistant running through Ollama.',
|
|
266
|
+
systemPrompt: SWARMCLAW_ASSISTANT_PROMPT,
|
|
267
|
+
model: 'llama3',
|
|
268
|
+
tools: STARTER_AGENT_TOOLS,
|
|
269
|
+
},
|
|
270
|
+
openclaw: {
|
|
271
|
+
name: 'OpenClaw Operator',
|
|
272
|
+
description: 'A manager agent for talking to and coordinating OpenClaw instances.',
|
|
273
|
+
systemPrompt: 'You are an operator focused on reliable execution, clear status updates, and task completion.',
|
|
274
|
+
model: 'default',
|
|
275
|
+
tools: STARTER_AGENT_TOOLS,
|
|
276
|
+
},
|
|
277
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
export const AgentCreateSchema = z.object({
|
|
4
|
+
name: z.string().min(1, 'Agent name is required'),
|
|
5
|
+
provider: z.string().min(1, 'Provider is required'),
|
|
6
|
+
description: z.string().optional().default(''),
|
|
7
|
+
systemPrompt: z.string().optional().default(''),
|
|
8
|
+
model: z.string().optional().default(''),
|
|
9
|
+
credentialId: z.string().nullable().optional().default(null),
|
|
10
|
+
apiEndpoint: z.string().nullable().optional().default(null),
|
|
11
|
+
isOrchestrator: z.boolean().optional().default(false),
|
|
12
|
+
subAgentIds: z.array(z.string()).optional().default([]),
|
|
13
|
+
tools: z.array(z.string()).optional().default([]),
|
|
14
|
+
capabilities: z.array(z.string()).optional().default([]),
|
|
15
|
+
thinkingLevel: z.string().optional(),
|
|
16
|
+
soul: z.string().optional(),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export const ConnectorCreateSchema = z.object({
|
|
20
|
+
name: z.string().min(1, 'Connector name is required').optional(),
|
|
21
|
+
platform: z.enum([
|
|
22
|
+
'discord', 'telegram', 'slack', 'whatsapp', 'openclaw',
|
|
23
|
+
'bluebubbles', 'signal', 'teams', 'googlechat', 'matrix', 'email',
|
|
24
|
+
]),
|
|
25
|
+
agentId: z.string().nullable().optional().default(null),
|
|
26
|
+
chatroomId: z.string().nullable().optional().default(null),
|
|
27
|
+
credentialId: z.string().nullable().optional().default(null),
|
|
28
|
+
config: z.record(z.string(), z.string()).optional().default({}),
|
|
29
|
+
autoStart: z.boolean().optional(),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
export const TaskCreateSchema = z.object({
|
|
33
|
+
title: z.string().min(1, 'Task title is required'),
|
|
34
|
+
description: z.string().optional().default(''),
|
|
35
|
+
status: z.string().optional(),
|
|
36
|
+
agentId: z.string().optional().default(''),
|
|
37
|
+
projectId: z.string().nullable().optional(),
|
|
38
|
+
goalContract: z.string().nullable().optional(),
|
|
39
|
+
cwd: z.string().nullable().optional(),
|
|
40
|
+
file: z.string().nullable().optional(),
|
|
41
|
+
blockedBy: z.array(z.string()).optional(),
|
|
42
|
+
blocks: z.array(z.string()).optional(),
|
|
43
|
+
tags: z.array(z.string()).optional(),
|
|
44
|
+
maxAttempts: z.number().optional(),
|
|
45
|
+
retryBackoffSec: z.number().optional(),
|
|
46
|
+
priority: z.enum(['low', 'medium', 'high', 'critical']).optional(),
|
|
47
|
+
dueAt: z.number().nullable().optional(),
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
export const ChatroomCreateSchema = z.object({
|
|
51
|
+
name: z.string().min(1, 'Chatroom name is required'),
|
|
52
|
+
agentIds: z.array(z.string()).default([]),
|
|
53
|
+
description: z.string().optional().default(''),
|
|
54
|
+
chatMode: z.enum(['sequential', 'parallel']).optional(),
|
|
55
|
+
autoAddress: z.boolean().optional(),
|
|
56
|
+
routingRules: z.array(z.object({
|
|
57
|
+
id: z.string(),
|
|
58
|
+
type: z.enum(['keyword', 'capability']),
|
|
59
|
+
pattern: z.string().optional(),
|
|
60
|
+
keywords: z.array(z.string()).optional(),
|
|
61
|
+
agentId: z.string(),
|
|
62
|
+
priority: z.number(),
|
|
63
|
+
})).optional(),
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
/** Format ZodError into a 400-friendly payload */
|
|
67
|
+
export function formatZodError(err: z.ZodError) {
|
|
68
|
+
return { error: 'Validation failed', issues: err.issues.map((i) => ({ path: i.path.join('.'), message: i.message })) }
|
|
69
|
+
}
|
|
@@ -68,6 +68,8 @@ interface AppState {
|
|
|
68
68
|
setScheduleSheetOpen: (open: boolean) => void
|
|
69
69
|
editingScheduleId: string | null
|
|
70
70
|
setEditingScheduleId: (id: string | null) => void
|
|
71
|
+
scheduleTemplatePrefill: { name: string; taskPrompt: string; scheduleType: 'cron' | 'interval'; cron?: string; intervalMs?: number } | null
|
|
72
|
+
setScheduleTemplatePrefill: (prefill: { name: string; taskPrompt: string; scheduleType: 'cron' | 'interval'; cron?: string; intervalMs?: number } | null) => void
|
|
71
73
|
|
|
72
74
|
memorySheetOpen: boolean
|
|
73
75
|
setMemorySheetOpen: (open: boolean) => void
|
|
@@ -382,6 +384,8 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
382
384
|
setScheduleSheetOpen: (open) => set({ scheduleSheetOpen: open }),
|
|
383
385
|
editingScheduleId: null,
|
|
384
386
|
setEditingScheduleId: (id) => set({ editingScheduleId: id }),
|
|
387
|
+
scheduleTemplatePrefill: null,
|
|
388
|
+
setScheduleTemplatePrefill: (prefill) => set({ scheduleTemplatePrefill: prefill }),
|
|
385
389
|
|
|
386
390
|
memorySheetOpen: false,
|
|
387
391
|
setMemorySheetOpen: (open) => set({ memorySheetOpen: open }),
|
|
@@ -608,9 +612,9 @@ export const useAppStore = create<AppState>((set, get) => ({
|
|
|
608
612
|
inspectorTab: 'overview',
|
|
609
613
|
setInspectorTab: (tab) => set({ inspectorTab: tab }),
|
|
610
614
|
|
|
611
|
-
// Fleet sidebar filter
|
|
612
|
-
fleetFilter: 'all',
|
|
613
|
-
setFleetFilter: (filter) => set({ fleetFilter: filter }),
|
|
615
|
+
// Fleet sidebar filter (persisted to localStorage)
|
|
616
|
+
fleetFilter: (safeStorageGet('sc_fleet_filter') as FleetFilter) || 'all',
|
|
617
|
+
setFleetFilter: (filter) => { safeStorageSet('sc_fleet_filter', filter); set({ fleetFilter: filter }) },
|
|
614
618
|
|
|
615
619
|
// Chat list filter
|
|
616
620
|
chatFilter: 'all' as const,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { create } from 'zustand'
|
|
4
4
|
import { api, getStoredAccessKey } from '@/lib/api-client'
|
|
5
|
-
import type { Chatroom, ChatroomMessage, SSEEvent } from '@/types'
|
|
5
|
+
import type { Chatroom, ChatroomMessage, ChatroomRoutingRule, SSEEvent } from '@/types'
|
|
6
6
|
import type { PendingFile } from '@/stores/use-chat-store'
|
|
7
7
|
|
|
8
8
|
interface ToolEvent {
|
|
@@ -37,7 +37,7 @@ interface ChatroomState {
|
|
|
37
37
|
setReplyingTo: (msg: ChatroomMessage | null) => void
|
|
38
38
|
|
|
39
39
|
loadChatrooms: () => Promise<void>
|
|
40
|
-
createChatroom: (data: { name: string; description?: string; agentIds?: string[]; chatMode?: 'sequential' | 'parallel'; autoAddress?: boolean }) => Promise<Chatroom>
|
|
40
|
+
createChatroom: (data: { name: string; description?: string; agentIds?: string[]; chatMode?: 'sequential' | 'parallel'; autoAddress?: boolean; routingRules?: ChatroomRoutingRule[] }) => Promise<Chatroom>
|
|
41
41
|
updateChatroom: (id: string, data: Partial<Chatroom>) => Promise<void>
|
|
42
42
|
deleteChatroom: (id: string) => Promise<void>
|
|
43
43
|
setCurrentChatroom: (id: string | null) => void
|
|
@@ -48,6 +48,12 @@ interface ChatroomState {
|
|
|
48
48
|
removeMember: (agentId: string) => Promise<void>
|
|
49
49
|
setChatroomSheetOpen: (open: boolean) => void
|
|
50
50
|
setEditingChatroomId: (id: string | null) => void
|
|
51
|
+
|
|
52
|
+
// Moderation
|
|
53
|
+
deleteMessage: (messageId: string, targetAgentId: string) => Promise<void>
|
|
54
|
+
muteAgent: (targetAgentId: string, minutes?: number) => Promise<void>
|
|
55
|
+
unmuteAgent: (targetAgentId: string) => Promise<void>
|
|
56
|
+
setMemberRole: (targetAgentId: string, role: 'admin' | 'moderator' | 'member') => Promise<void>
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
export const useChatroomStore = create<ChatroomState>((set, get) => ({
|
|
@@ -273,4 +279,48 @@ export const useChatroomStore = create<ChatroomState>((set, get) => ({
|
|
|
273
279
|
|
|
274
280
|
setChatroomSheetOpen: (open) => set({ chatroomSheetOpen: open }),
|
|
275
281
|
setEditingChatroomId: (id) => set({ editingChatroomId: id }),
|
|
282
|
+
|
|
283
|
+
// Moderation
|
|
284
|
+
deleteMessage: async (messageId, targetAgentId) => {
|
|
285
|
+
const { currentChatroomId } = get()
|
|
286
|
+
if (!currentChatroomId) return
|
|
287
|
+
const chatroom = await api<Chatroom>('POST', `/chatrooms/${currentChatroomId}/moderate`, {
|
|
288
|
+
action: 'delete-message',
|
|
289
|
+
targetAgentId,
|
|
290
|
+
messageId,
|
|
291
|
+
})
|
|
292
|
+
set((s) => ({ chatrooms: { ...s.chatrooms, [currentChatroomId]: chatroom } }))
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
muteAgent: async (targetAgentId, minutes = 30) => {
|
|
296
|
+
const { currentChatroomId } = get()
|
|
297
|
+
if (!currentChatroomId) return
|
|
298
|
+
const chatroom = await api<Chatroom>('POST', `/chatrooms/${currentChatroomId}/moderate`, {
|
|
299
|
+
action: 'mute',
|
|
300
|
+
targetAgentId,
|
|
301
|
+
muteDurationMinutes: minutes,
|
|
302
|
+
})
|
|
303
|
+
set((s) => ({ chatrooms: { ...s.chatrooms, [currentChatroomId]: chatroom } }))
|
|
304
|
+
},
|
|
305
|
+
|
|
306
|
+
unmuteAgent: async (targetAgentId) => {
|
|
307
|
+
const { currentChatroomId } = get()
|
|
308
|
+
if (!currentChatroomId) return
|
|
309
|
+
const chatroom = await api<Chatroom>('POST', `/chatrooms/${currentChatroomId}/moderate`, {
|
|
310
|
+
action: 'unmute',
|
|
311
|
+
targetAgentId,
|
|
312
|
+
})
|
|
313
|
+
set((s) => ({ chatrooms: { ...s.chatrooms, [currentChatroomId]: chatroom } }))
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
setMemberRole: async (targetAgentId, role) => {
|
|
317
|
+
const { currentChatroomId } = get()
|
|
318
|
+
if (!currentChatroomId) return
|
|
319
|
+
const chatroom = await api<Chatroom>('POST', `/chatrooms/${currentChatroomId}/moderate`, {
|
|
320
|
+
action: 'set-role',
|
|
321
|
+
targetAgentId,
|
|
322
|
+
role,
|
|
323
|
+
})
|
|
324
|
+
set((s) => ({ chatrooms: { ...s.chatrooms, [currentChatroomId]: chatroom } }))
|
|
325
|
+
},
|
|
276
326
|
}))
|
package/src/types/index.ts
CHANGED
|
@@ -272,6 +272,10 @@ export interface Agent {
|
|
|
272
272
|
openclawSkillMode?: SkillAllowlistMode
|
|
273
273
|
openclawAllowedSkills?: string[]
|
|
274
274
|
walletId?: string | null
|
|
275
|
+
monthlyBudget?: number | null
|
|
276
|
+
budgetAction?: 'warn' | 'block'
|
|
277
|
+
/** Runtime-enriched: current month's spend. Populated by GET /api/agents when monthlyBudget is set. */
|
|
278
|
+
monthlySpend?: number
|
|
275
279
|
createdAt: number
|
|
276
280
|
updatedAt: number
|
|
277
281
|
}
|
|
@@ -408,6 +412,21 @@ export type AppView = 'home' | 'agents' | 'chatrooms' | 'schedules' | 'memory' |
|
|
|
408
412
|
|
|
409
413
|
// --- Chatrooms ---
|
|
410
414
|
|
|
415
|
+
export interface ChatroomRoutingRule {
|
|
416
|
+
id: string
|
|
417
|
+
type: 'keyword' | 'capability'
|
|
418
|
+
pattern?: string
|
|
419
|
+
keywords?: string[]
|
|
420
|
+
agentId: string
|
|
421
|
+
priority: number
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export interface ChatroomMember {
|
|
425
|
+
agentId: string
|
|
426
|
+
role: 'admin' | 'moderator' | 'member'
|
|
427
|
+
mutedUntil?: string
|
|
428
|
+
}
|
|
429
|
+
|
|
411
430
|
export interface ChatroomReaction {
|
|
412
431
|
emoji: string
|
|
413
432
|
reactorId: string // 'user' or agentId
|
|
@@ -435,10 +454,12 @@ export interface Chatroom {
|
|
|
435
454
|
name: string
|
|
436
455
|
description?: string
|
|
437
456
|
agentIds: string[]
|
|
457
|
+
members?: ChatroomMember[]
|
|
438
458
|
messages: ChatroomMessage[]
|
|
439
459
|
pinnedMessageIds?: string[]
|
|
440
460
|
chatMode?: 'sequential' | 'parallel'
|
|
441
461
|
autoAddress?: boolean
|
|
462
|
+
routingRules?: ChatroomRoutingRule[]
|
|
442
463
|
createdAt: number
|
|
443
464
|
updatedAt: number
|
|
444
465
|
}
|
|
@@ -626,6 +647,10 @@ export interface AppSettings {
|
|
|
626
647
|
openclawWorkspacePath?: string | null
|
|
627
648
|
openclawAutoSyncMemory?: boolean
|
|
628
649
|
openclawAutoSyncSchedules?: boolean
|
|
650
|
+
// Outbound ops alert webhook
|
|
651
|
+
alertWebhookUrl?: string | null
|
|
652
|
+
alertWebhookType?: 'discord' | 'slack' | 'custom' | null
|
|
653
|
+
alertWebhookEvents?: ('error' | 'warning')[]
|
|
629
654
|
}
|
|
630
655
|
|
|
631
656
|
// --- Orchestrator Secrets ---
|
|
@@ -685,9 +710,21 @@ export interface Skill {
|
|
|
685
710
|
updatedAt: number
|
|
686
711
|
}
|
|
687
712
|
|
|
713
|
+
// --- Connector Health Events ---
|
|
714
|
+
|
|
715
|
+
export type ConnectorHealthEventType = 'started' | 'stopped' | 'error' | 'reconnected' | 'disconnected'
|
|
716
|
+
|
|
717
|
+
export interface ConnectorHealthEvent {
|
|
718
|
+
id: string
|
|
719
|
+
connectorId: string
|
|
720
|
+
event: ConnectorHealthEventType
|
|
721
|
+
message?: string
|
|
722
|
+
timestamp: string
|
|
723
|
+
}
|
|
724
|
+
|
|
688
725
|
// --- Connectors (Chat Platform Bridges) ---
|
|
689
726
|
|
|
690
|
-
export type ConnectorPlatform = 'discord' | 'telegram' | 'slack' | 'whatsapp' | 'openclaw' | 'bluebubbles' | 'signal' | 'teams' | 'googlechat' | 'matrix'
|
|
727
|
+
export type ConnectorPlatform = 'discord' | 'telegram' | 'slack' | 'whatsapp' | 'openclaw' | 'bluebubbles' | 'signal' | 'teams' | 'googlechat' | 'matrix' | 'email'
|
|
691
728
|
export type ConnectorStatus = 'stopped' | 'running' | 'error'
|
|
692
729
|
|
|
693
730
|
export interface MessageSource {
|