@swarmclawai/swarmclaw 0.3.1 → 0.4.5
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 +33 -13
- package/bin/server-cmd.js +14 -7
- package/bin/swarmclaw.js +3 -1
- package/bin/update-cmd.js +120 -0
- package/next.config.ts +10 -0
- package/package.json +4 -1
- package/src/app/api/agents/[id]/route.ts +20 -18
- package/src/app/api/agents/[id]/thread/route.ts +4 -3
- package/src/app/api/agents/route.ts +8 -3
- package/src/app/api/auth/route.ts +3 -1
- package/src/app/api/claude-skills/route.ts +3 -1
- package/src/app/api/clawhub/install/route.ts +2 -2
- package/src/app/api/connectors/[id]/route.ts +14 -3
- package/src/app/api/connectors/[id]/webhook/route.ts +99 -0
- package/src/app/api/connectors/route.ts +12 -4
- package/src/app/api/credentials/[id]/route.ts +2 -1
- package/src/app/api/credentials/route.ts +5 -3
- package/src/app/api/daemon/route.ts +6 -1
- package/src/app/api/documents/route.ts +2 -2
- package/src/app/api/files/serve/route.ts +8 -0
- package/src/app/api/ip/route.ts +3 -1
- package/src/app/api/knowledge/[id]/route.ts +5 -4
- package/src/app/api/knowledge/upload/route.ts +2 -2
- package/src/app/api/mcp-servers/[id]/route.ts +11 -14
- package/src/app/api/mcp-servers/[id]/test/route.ts +2 -1
- package/src/app/api/mcp-servers/[id]/tools/route.ts +2 -1
- package/src/app/api/mcp-servers/route.ts +5 -3
- package/src/app/api/memory/[id]/route.ts +9 -8
- package/src/app/api/memory/route.ts +2 -2
- package/src/app/api/memory-images/[filename]/route.ts +2 -1
- package/src/app/api/openclaw/directory/route.ts +26 -0
- package/src/app/api/openclaw/discover/route.ts +61 -0
- package/src/app/api/openclaw/sync/route.ts +30 -0
- package/src/app/api/orchestrator/graph/route.ts +25 -0
- package/src/app/api/orchestrator/run/route.ts +2 -2
- package/src/app/api/plugins/marketplace/route.ts +3 -1
- package/src/app/api/plugins/route.ts +3 -1
- package/src/app/api/projects/[id]/route.ts +55 -0
- package/src/app/api/projects/route.ts +27 -0
- package/src/app/api/providers/[id]/models/route.ts +2 -1
- package/src/app/api/providers/[id]/route.ts +13 -12
- package/src/app/api/providers/configs/route.ts +3 -1
- package/src/app/api/providers/route.ts +7 -3
- package/src/app/api/schedules/[id]/route.ts +16 -15
- package/src/app/api/schedules/[id]/run/route.ts +4 -3
- package/src/app/api/schedules/route.ts +8 -3
- package/src/app/api/secrets/[id]/route.ts +16 -17
- package/src/app/api/secrets/route.ts +5 -3
- package/src/app/api/sessions/[id]/chat/route.ts +5 -2
- package/src/app/api/sessions/[id]/clear/route.ts +2 -1
- package/src/app/api/sessions/[id]/deploy/route.ts +2 -1
- package/src/app/api/sessions/[id]/devserver/route.ts +2 -1
- package/src/app/api/sessions/[id]/messages/route.ts +2 -1
- package/src/app/api/sessions/[id]/retry/route.ts +2 -1
- package/src/app/api/sessions/[id]/route.ts +2 -1
- package/src/app/api/sessions/route.ts +11 -4
- package/src/app/api/settings/route.ts +3 -1
- package/src/app/api/setup/doctor/route.ts +1 -0
- package/src/app/api/setup/openclaw-device/route.ts +3 -1
- package/src/app/api/skills/[id]/route.ts +23 -21
- package/src/app/api/skills/import/route.ts +2 -2
- package/src/app/api/skills/route.ts +5 -3
- package/src/app/api/tasks/[id]/approve/route.ts +74 -0
- package/src/app/api/tasks/[id]/route.ts +9 -5
- package/src/app/api/tasks/route.ts +5 -2
- package/src/app/api/tts/stream/route.ts +48 -0
- package/src/app/api/upload/route.ts +2 -2
- package/src/app/api/uploads/[filename]/route.ts +4 -1
- package/src/app/api/usage/route.ts +3 -1
- package/src/app/api/version/route.ts +3 -1
- package/src/app/api/webhooks/[id]/route.ts +31 -32
- package/src/app/api/webhooks/route.ts +5 -3
- package/src/app/icon.svg +58 -0
- package/src/app/page.tsx +11 -26
- package/src/cli/index.js +28 -9
- package/src/cli/index.ts +45 -2
- package/src/cli/spec.js +2 -8
- package/src/components/agents/agent-card.tsx +1 -1
- package/src/components/agents/agent-list.tsx +3 -1
- package/src/components/agents/agent-sheet.tsx +166 -81
- package/src/components/chat/chat-area.tsx +71 -34
- package/src/components/chat/chat-header.tsx +141 -29
- package/src/components/chat/chat-tool-toggles.tsx +12 -53
- package/src/components/chat/message-bubble.tsx +110 -42
- package/src/components/chat/tool-call-bubble.tsx +50 -6
- package/src/components/chat/tool-request-banner.tsx +1 -9
- package/src/components/chat/voice-overlay.tsx +80 -0
- package/src/components/connectors/connector-list.tsx +9 -10
- package/src/components/connectors/connector-sheet.tsx +55 -36
- package/src/components/input/chat-input.tsx +72 -56
- package/src/components/knowledge/knowledge-list.tsx +27 -31
- package/src/components/layout/app-layout.tsx +133 -90
- package/src/components/layout/daemon-indicator.tsx +3 -5
- package/src/components/logs/log-list.tsx +5 -9
- package/src/components/mcp-servers/mcp-server-list.tsx +24 -2
- package/src/components/memory/memory-detail.tsx +1 -1
- package/src/components/plugins/plugin-list.tsx +227 -27
- package/src/components/projects/project-list.tsx +122 -0
- package/src/components/projects/project-sheet.tsx +135 -0
- package/src/components/providers/provider-list.tsx +46 -13
- package/src/components/providers/provider-sheet.tsx +0 -45
- package/src/components/runs/run-list.tsx +6 -15
- package/src/components/schedules/schedule-card.tsx +54 -4
- package/src/components/schedules/schedule-list.tsx +9 -4
- package/src/components/schedules/schedule-sheet.tsx +0 -47
- package/src/components/secrets/secrets-list.tsx +20 -2
- package/src/components/sessions/new-session-sheet.tsx +14 -15
- package/src/components/sessions/session-card.tsx +1 -1
- package/src/components/sessions/session-list.tsx +7 -7
- package/src/components/shared/connector-platform-icon.tsx +26 -20
- package/src/components/shared/model-combobox.tsx +148 -0
- package/src/components/shared/settings/section-heartbeat.tsx +8 -40
- package/src/components/shared/settings/section-orchestrator.tsx +9 -11
- package/src/components/shared/settings/section-web-search.tsx +56 -0
- package/src/components/shared/settings/settings-page.tsx +73 -0
- package/src/components/skills/skill-list.tsx +262 -35
- package/src/components/skills/skill-sheet.tsx +0 -45
- package/src/components/tasks/task-board.tsx +3 -6
- package/src/components/tasks/task-card.tsx +43 -1
- package/src/components/tasks/task-list.tsx +8 -7
- package/src/components/tasks/task-sheet.tsx +0 -44
- package/src/components/usage/usage-list.tsx +12 -4
- package/src/hooks/use-continuous-speech.ts +144 -0
- package/src/hooks/use-view-router.ts +52 -0
- package/src/hooks/use-voice-conversation.ts +80 -0
- package/src/hooks/use-ws.ts +66 -0
- package/src/instrumentation.ts +2 -0
- package/src/lib/chat.ts +14 -2
- package/src/lib/id.ts +6 -0
- package/src/lib/projects.ts +13 -0
- package/src/lib/provider-sets.ts +5 -0
- package/src/lib/providers/anthropic.ts +15 -2
- package/src/lib/providers/index.ts +8 -0
- package/src/lib/providers/ollama.ts +10 -2
- package/src/lib/providers/openai.ts +42 -13
- package/src/lib/providers/openclaw.ts +11 -0
- package/src/lib/server/api-routes.test.ts +5 -6
- package/src/lib/server/build-llm.ts +17 -4
- package/src/lib/server/chat-execution.ts +57 -8
- package/src/lib/server/collection-helpers.ts +54 -0
- package/src/lib/server/connectors/bluebubbles.test.ts +208 -0
- package/src/lib/server/connectors/bluebubbles.ts +357 -0
- package/src/lib/server/connectors/connector-routing.test.ts +1 -1
- package/src/lib/server/connectors/googlechat.ts +46 -7
- package/src/lib/server/connectors/manager.ts +401 -6
- package/src/lib/server/connectors/media.ts +2 -2
- package/src/lib/server/connectors/openclaw.ts +64 -0
- package/src/lib/server/connectors/pairing.test.ts +99 -0
- package/src/lib/server/connectors/pairing.ts +256 -0
- package/src/lib/server/connectors/signal.ts +1 -0
- package/src/lib/server/connectors/teams.ts +5 -5
- package/src/lib/server/connectors/types.ts +10 -0
- package/src/lib/server/context-manager.ts +1 -1
- package/src/lib/server/daemon-state.ts +3 -0
- package/src/lib/server/data-dir.ts +1 -0
- package/src/lib/server/execution-log.ts +3 -3
- package/src/lib/server/heartbeat-service.ts +67 -3
- package/src/lib/server/knowledge-db.test.ts +2 -33
- package/src/lib/server/langgraph-checkpoint.ts +274 -0
- package/src/lib/server/main-agent-loop.ts +67 -8
- package/src/lib/server/memory-db.ts +6 -6
- package/src/lib/server/openclaw-approvals.ts +105 -0
- package/src/lib/server/openclaw-sync.ts +496 -0
- package/src/lib/server/orchestrator-lg.ts +422 -20
- package/src/lib/server/orchestrator.ts +29 -9
- package/src/lib/server/process-manager.ts +2 -2
- package/src/lib/server/queue.ts +39 -13
- package/src/lib/server/scheduler.ts +2 -2
- package/src/lib/server/session-mailbox.ts +2 -2
- package/src/lib/server/session-run-manager.ts +8 -3
- package/src/lib/server/session-tools/connector.ts +51 -4
- package/src/lib/server/session-tools/crud.ts +3 -3
- package/src/lib/server/session-tools/delegate.ts +5 -5
- package/src/lib/server/session-tools/file.ts +176 -3
- package/src/lib/server/session-tools/index.ts +4 -0
- package/src/lib/server/session-tools/memory.ts +2 -2
- package/src/lib/server/session-tools/openclaw-nodes.ts +112 -0
- package/src/lib/server/session-tools/sandbox.ts +197 -0
- package/src/lib/server/session-tools/search-providers.ts +270 -0
- package/src/lib/server/session-tools/session-info.ts +2 -2
- package/src/lib/server/session-tools/web.ts +47 -66
- package/src/lib/server/storage-mcp.test.ts +25 -2
- package/src/lib/server/storage.ts +36 -7
- package/src/lib/server/stream-agent-chat.ts +106 -22
- package/src/lib/server/task-result.test.ts +44 -0
- package/src/lib/server/task-result.ts +14 -0
- package/src/lib/server/task-validation.test.ts +23 -0
- package/src/lib/server/task-validation.ts +5 -3
- package/src/lib/server/ws-hub.ts +85 -0
- package/src/lib/tool-definitions.ts +44 -0
- package/src/lib/tts-stream.ts +130 -0
- package/src/lib/upload.ts +7 -1
- package/src/lib/view-routes.ts +28 -0
- package/src/lib/ws-client.ts +124 -0
- package/src/proxy.ts +3 -0
- package/src/stores/use-app-store.ts +28 -1
- package/src/stores/use-chat-store.ts +42 -14
- package/src/types/index.ts +34 -2
- package/src/app/api/agents/generate/route.ts +0 -42
- package/src/app/api/generate/info/route.ts +0 -12
- package/src/app/api/generate/route.ts +0 -106
- package/src/app/favicon.ico +0 -0
- package/src/components/shared/ai-gen-block.tsx +0 -77
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
-
import
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
3
|
import { loadAgents, loadTasks, saveTasks } from '@/lib/server/storage'
|
|
4
4
|
import { enqueueTask } from '@/lib/server/queue'
|
|
5
5
|
|
|
@@ -16,7 +16,7 @@ export async function POST(req: Request) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// Create a board task and enqueue it
|
|
19
|
-
const taskId =
|
|
19
|
+
const taskId = genId()
|
|
20
20
|
const now = Date.now()
|
|
21
21
|
const tasks = loadTasks()
|
|
22
22
|
tasks[taskId] = {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
+
export const dynamic = 'force-dynamic'
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
const REGISTRY_URL = 'https://swarmclaw.ai/registry/plugins.json'
|
|
4
6
|
const CACHE_TTL = 5 * 60 * 1000 // 5 minutes
|
|
5
7
|
|
|
6
8
|
let cache: { data: any; fetchedAt: number } | null = null
|
|
7
9
|
|
|
8
|
-
export async function GET() {
|
|
10
|
+
export async function GET(_req: Request) {
|
|
9
11
|
const now = Date.now()
|
|
10
12
|
|
|
11
13
|
if (cache && now - cache.fetchedAt < CACHE_TTL) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getPluginManager } from '@/lib/server/plugins'
|
|
3
|
+
export const dynamic = 'force-dynamic'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
export async function GET(_req: Request) {
|
|
5
7
|
const manager = getPluginManager()
|
|
6
8
|
return NextResponse.json(manager.listPlugins())
|
|
7
9
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { loadProjects, saveProjects, deleteProject, loadAgents, saveAgents, loadTasks, saveTasks, loadSchedules, saveSchedules, loadSkills, saveSkills } from '@/lib/server/storage'
|
|
3
|
+
import { mutateItem, deleteItem, notFound, type CollectionOps } from '@/lib/server/collection-helpers'
|
|
4
|
+
import { notify } from '@/lib/server/ws-hub'
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
const ops: CollectionOps<any> = { load: loadProjects, save: saveProjects, deleteFn: deleteProject, topic: 'projects' }
|
|
8
|
+
|
|
9
|
+
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
10
|
+
const { id } = await params
|
|
11
|
+
const projects = loadProjects()
|
|
12
|
+
if (!projects[id]) return notFound()
|
|
13
|
+
return NextResponse.json(projects[id])
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
17
|
+
const { id } = await params
|
|
18
|
+
const body = await req.json()
|
|
19
|
+
const result = mutateItem(ops, id, (project) => {
|
|
20
|
+
Object.assign(project, body, { updatedAt: Date.now() })
|
|
21
|
+
delete (project as Record<string, unknown>).id
|
|
22
|
+
project.id = id
|
|
23
|
+
return project
|
|
24
|
+
})
|
|
25
|
+
if (!result) return notFound()
|
|
26
|
+
return NextResponse.json(result)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
30
|
+
const { id } = await params
|
|
31
|
+
if (!deleteItem(ops, id)) return notFound()
|
|
32
|
+
|
|
33
|
+
// Clear projectId from referencing entities
|
|
34
|
+
const clearProjectId = (load: () => Record<string, any>, save: (d: Record<string, any>) => void, topic: string) => {
|
|
35
|
+
const items = load()
|
|
36
|
+
let changed = false
|
|
37
|
+
for (const item of Object.values(items)) {
|
|
38
|
+
if (item.projectId === id) {
|
|
39
|
+
item.projectId = undefined
|
|
40
|
+
changed = true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (changed) {
|
|
44
|
+
save(items)
|
|
45
|
+
notify(topic)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
clearProjectId(loadAgents, saveAgents, 'agents')
|
|
50
|
+
clearProjectId(loadTasks, saveTasks, 'tasks')
|
|
51
|
+
clearProjectId(loadSchedules, saveSchedules, 'schedules')
|
|
52
|
+
clearProjectId(loadSkills, saveSkills, 'skills')
|
|
53
|
+
|
|
54
|
+
return NextResponse.json({ ok: true })
|
|
55
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
|
+
import { loadProjects, saveProjects } from '@/lib/server/storage'
|
|
4
|
+
import { notify } from '@/lib/server/ws-hub'
|
|
5
|
+
export const dynamic = 'force-dynamic'
|
|
6
|
+
|
|
7
|
+
export async function GET(_req: Request) {
|
|
8
|
+
return NextResponse.json(loadProjects())
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function POST(req: Request) {
|
|
12
|
+
const body = await req.json()
|
|
13
|
+
const id = genId()
|
|
14
|
+
const now = Date.now()
|
|
15
|
+
const projects = loadProjects()
|
|
16
|
+
projects[id] = {
|
|
17
|
+
id,
|
|
18
|
+
name: body.name || 'Unnamed Project',
|
|
19
|
+
description: body.description || '',
|
|
20
|
+
color: body.color || undefined,
|
|
21
|
+
createdAt: now,
|
|
22
|
+
updatedAt: now,
|
|
23
|
+
}
|
|
24
|
+
saveProjects(projects)
|
|
25
|
+
notify('projects')
|
|
26
|
+
return NextResponse.json(projects[id])
|
|
27
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadModelOverrides, saveModelOverrides } from '@/lib/server/storage'
|
|
3
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
3
4
|
import { getProviderList } from '@/lib/providers'
|
|
4
5
|
|
|
5
6
|
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
@@ -7,7 +8,7 @@ export async function GET(_req: Request, { params }: { params: Promise<{ id: str
|
|
|
7
8
|
const overrides = loadModelOverrides()
|
|
8
9
|
const providers = getProviderList()
|
|
9
10
|
const provider = providers.find((p) => p.id === id)
|
|
10
|
-
if (!provider) return
|
|
11
|
+
if (!provider) return notFound()
|
|
11
12
|
return NextResponse.json({ models: provider.models, hasOverride: !!overrides[id] })
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadProviderConfigs, saveProviderConfigs } from '@/lib/server/storage'
|
|
3
|
+
import { mutateItem, deleteItem, notFound, badRequest, type CollectionOps } from '@/lib/server/collection-helpers'
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
const ops: CollectionOps<any> = { load: loadProviderConfigs, save: saveProviderConfigs, topic: 'providers' }
|
|
3
7
|
|
|
4
8
|
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
5
9
|
const { id } = await params
|
|
6
10
|
const configs = loadProviderConfigs()
|
|
7
11
|
const config = configs[id]
|
|
8
|
-
if (!config) return
|
|
12
|
+
if (!config) return notFound()
|
|
9
13
|
return NextResponse.json(config)
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
13
17
|
const { id } = await params
|
|
14
18
|
const body = await req.json()
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return NextResponse.json(configs[id])
|
|
19
|
+
const result = mutateItem(ops, id, (existing) => ({
|
|
20
|
+
...existing, ...body, id, updatedAt: Date.now(),
|
|
21
|
+
}))
|
|
22
|
+
if (!result) return notFound()
|
|
23
|
+
return NextResponse.json(result)
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
24
27
|
const { id } = await params
|
|
25
28
|
const configs = loadProviderConfigs()
|
|
26
|
-
if (!configs[id]) return
|
|
27
|
-
// Only allow deleting custom providers
|
|
29
|
+
if (!configs[id]) return notFound()
|
|
28
30
|
if (configs[id].type === 'builtin') {
|
|
29
|
-
return
|
|
31
|
+
return badRequest('Cannot delete built-in providers')
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
saveProviderConfigs(configs)
|
|
33
|
+
if (!deleteItem(ops, id)) return notFound()
|
|
33
34
|
return NextResponse.json({ ok: true })
|
|
34
35
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadProviderConfigs } from '@/lib/server/storage'
|
|
3
|
+
export const dynamic = 'force-dynamic'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
export async function GET(_req: Request) {
|
|
5
7
|
const configs = loadProviderConfigs()
|
|
6
8
|
return NextResponse.json(Object.values(configs))
|
|
7
9
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
-
import
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
3
|
import { getProviderList } from '@/lib/providers'
|
|
4
4
|
import { loadProviderConfigs, saveProviderConfigs } from '@/lib/server/storage'
|
|
5
|
+
import { notify } from '@/lib/server/ws-hub'
|
|
6
|
+
export const dynamic = 'force-dynamic'
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
|
|
9
|
+
export async function GET(_req: Request) {
|
|
7
10
|
return NextResponse.json(getProviderList())
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export async function POST(req: Request) {
|
|
11
14
|
const body = await req.json()
|
|
12
15
|
const configs = loadProviderConfigs()
|
|
13
|
-
const id = body.id || `custom-${
|
|
16
|
+
const id = body.id || `custom-${genId()}`
|
|
14
17
|
configs[id] = {
|
|
15
18
|
id,
|
|
16
19
|
name: body.name || 'Custom Provider',
|
|
@@ -24,5 +27,6 @@ export async function POST(req: Request) {
|
|
|
24
27
|
updatedAt: Date.now(),
|
|
25
28
|
}
|
|
26
29
|
saveProviderConfigs(configs)
|
|
30
|
+
notify('providers')
|
|
27
31
|
return NextResponse.json(configs[id])
|
|
28
32
|
}
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSchedules, saveSchedules, deleteSchedule } from '@/lib/server/storage'
|
|
3
3
|
import { resolveScheduleName } from '@/lib/schedule-name'
|
|
4
|
+
import { mutateItem, deleteItem, notFound, type CollectionOps } from '@/lib/server/collection-helpers'
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
const ops: CollectionOps<any> = { load: loadSchedules, save: saveSchedules, deleteFn: deleteSchedule, topic: 'schedules' }
|
|
4
8
|
|
|
5
9
|
export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
6
10
|
const { id } = await params
|
|
7
11
|
const body = await req.json()
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
taskPrompt: schedules[id].taskPrompt,
|
|
12
|
+
const result = mutateItem(ops, id, (schedule) => {
|
|
13
|
+
Object.assign(schedule, body)
|
|
14
|
+
schedule.id = id
|
|
15
|
+
schedule.name = resolveScheduleName({
|
|
16
|
+
name: schedule.name,
|
|
17
|
+
taskPrompt: schedule.taskPrompt,
|
|
18
|
+
})
|
|
19
|
+
return schedule
|
|
17
20
|
})
|
|
18
|
-
|
|
19
|
-
return NextResponse.json(
|
|
21
|
+
if (!result) return notFound()
|
|
22
|
+
return NextResponse.json(result)
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
23
26
|
const { id } = await params
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
deleteSchedule(id)
|
|
27
|
-
return NextResponse.json('ok')
|
|
27
|
+
if (!deleteItem(ops, id)) return notFound()
|
|
28
|
+
return NextResponse.json({ ok: true })
|
|
28
29
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
-
import
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
3
4
|
import { loadSchedules, saveSchedules, loadAgents, loadTasks, saveTasks } from '@/lib/server/storage'
|
|
4
5
|
import { enqueueTask } from '@/lib/server/queue'
|
|
5
6
|
import { pushMainLoopEventToMainSessions } from '@/lib/server/main-agent-loop'
|
|
@@ -14,7 +15,7 @@ export async function POST(_req: Request, { params }: { params: Promise<{ id: st
|
|
|
14
15
|
const { id } = await params
|
|
15
16
|
const schedules = loadSchedules()
|
|
16
17
|
const schedule = schedules[id]
|
|
17
|
-
if (!schedule) return
|
|
18
|
+
if (!schedule) return notFound()
|
|
18
19
|
|
|
19
20
|
const agents = loadAgents()
|
|
20
21
|
const agent = agents[schedule.agentId]
|
|
@@ -64,7 +65,7 @@ export async function POST(_req: Request, { params }: { params: Promise<{ id: st
|
|
|
64
65
|
existingTask.validation = null
|
|
65
66
|
prev.runNumber = schedule.runNumber
|
|
66
67
|
} else {
|
|
67
|
-
taskId =
|
|
68
|
+
taskId = genId()
|
|
68
69
|
tasks[taskId] = {
|
|
69
70
|
id: taskId,
|
|
70
71
|
title: `[Sched] ${schedule.name} (run #${schedule.runNumber})`,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
-
import
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
3
|
import { loadSchedules, saveSchedules } from '@/lib/server/storage'
|
|
4
4
|
import { resolveScheduleName } from '@/lib/schedule-name'
|
|
5
5
|
import { findDuplicateSchedule } from '@/lib/schedule-dedupe'
|
|
6
|
+
import { notify } from '@/lib/server/ws-hub'
|
|
7
|
+
export const dynamic = 'force-dynamic'
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
export async function GET(_req: Request) {
|
|
8
11
|
return NextResponse.json(loadSchedules())
|
|
9
12
|
}
|
|
10
13
|
|
|
@@ -43,11 +46,12 @@ export async function POST(req: Request) {
|
|
|
43
46
|
mutableDuplicate.updatedAt = now
|
|
44
47
|
if (duplicateId) schedules[duplicateId] = duplicate
|
|
45
48
|
saveSchedules(schedules)
|
|
49
|
+
notify('schedules')
|
|
46
50
|
}
|
|
47
51
|
return NextResponse.json(duplicate)
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
const id =
|
|
54
|
+
const id = genId()
|
|
51
55
|
|
|
52
56
|
let nextRunAt: number | undefined
|
|
53
57
|
if (scheduleType === 'once' && body.runAt) {
|
|
@@ -74,5 +78,6 @@ export async function POST(req: Request) {
|
|
|
74
78
|
createdAt: now,
|
|
75
79
|
}
|
|
76
80
|
saveSchedules(schedules)
|
|
81
|
+
notify('schedules')
|
|
77
82
|
return NextResponse.json(schedules[id])
|
|
78
83
|
}
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSecrets, saveSecrets } from '@/lib/server/storage'
|
|
3
|
+
import { mutateItem, deleteItem, notFound, type CollectionOps } from '@/lib/server/collection-helpers'
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
const ops: CollectionOps<any> = { load: loadSecrets, save: saveSecrets }
|
|
3
7
|
|
|
4
8
|
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
5
9
|
const { id } = await params
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
delete secrets[id]
|
|
9
|
-
saveSecrets(secrets)
|
|
10
|
-
return NextResponse.json('ok')
|
|
10
|
+
if (!deleteItem(ops, id)) return notFound()
|
|
11
|
+
return NextResponse.json({ ok: true })
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
14
15
|
const { id } = await params
|
|
15
16
|
const body = await req.json()
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const { encryptedValue, ...safe } = secrets[id]
|
|
17
|
+
const result = mutateItem(ops, id, (secret) => {
|
|
18
|
+
if (body.name !== undefined) secret.name = body.name
|
|
19
|
+
if (body.service !== undefined) secret.service = body.service
|
|
20
|
+
if (body.scope !== undefined) secret.scope = body.scope
|
|
21
|
+
if (body.agentIds !== undefined) secret.agentIds = body.agentIds
|
|
22
|
+
secret.updatedAt = Date.now()
|
|
23
|
+
return secret
|
|
24
|
+
})
|
|
25
|
+
if (!result) return notFound()
|
|
26
|
+
const { encryptedValue, ...safe } = result as Record<string, any>
|
|
28
27
|
return NextResponse.json(safe)
|
|
29
28
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
-
import
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
3
|
import { loadSecrets, saveSecrets, encryptKey } from '@/lib/server/storage'
|
|
4
|
+
export const dynamic = 'force-dynamic'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
export async function GET(_req: Request) {
|
|
6
8
|
// Return secrets WITHOUT the encrypted values (just metadata)
|
|
7
9
|
const secrets = loadSecrets()
|
|
8
10
|
const safe = Object.fromEntries(
|
|
@@ -16,7 +18,7 @@ export async function GET() {
|
|
|
16
18
|
|
|
17
19
|
export async function POST(req: Request) {
|
|
18
20
|
const body = await req.json()
|
|
19
|
-
const id =
|
|
21
|
+
const id = genId()
|
|
20
22
|
const now = Date.now()
|
|
21
23
|
const secrets = loadSecrets()
|
|
22
24
|
|
|
@@ -14,11 +14,13 @@ export async function POST(req: Request, { params }: { params: Promise<{ id: str
|
|
|
14
14
|
const message = typeof body.message === 'string' ? body.message : ''
|
|
15
15
|
const imagePath = typeof body.imagePath === 'string' ? body.imagePath : undefined
|
|
16
16
|
const imageUrl = typeof body.imageUrl === 'string' ? body.imageUrl : undefined
|
|
17
|
+
const attachedFiles = Array.isArray(body.attachedFiles) ? body.attachedFiles.filter((f: unknown) => typeof f === 'string') as string[] : undefined
|
|
17
18
|
const internal = body.internal === true
|
|
18
19
|
const queueMode = normalizeQueueMode(body.queueMode, internal)
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
const hasFiles = !!(imagePath || imageUrl || (attachedFiles && attachedFiles.length > 0))
|
|
22
|
+
if (!message.trim() && !hasFiles) {
|
|
23
|
+
return NextResponse.json({ error: 'message or file is required' }, { status: 400 })
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
const encoder = new TextEncoder()
|
|
@@ -39,6 +41,7 @@ export async function POST(req: Request, { params }: { params: Promise<{ id: str
|
|
|
39
41
|
message,
|
|
40
42
|
imagePath,
|
|
41
43
|
imageUrl,
|
|
44
|
+
attachedFiles,
|
|
42
45
|
internal,
|
|
43
46
|
source: internal ? 'heartbeat' : 'chat',
|
|
44
47
|
mode: queueMode,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSessions, saveSessions } from '@/lib/server/storage'
|
|
3
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
3
4
|
|
|
4
5
|
export async function POST(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
5
6
|
const { id } = await params
|
|
6
7
|
const sessions = loadSessions()
|
|
7
|
-
if (!sessions[id]) return
|
|
8
|
+
if (!sessions[id]) return notFound()
|
|
8
9
|
sessions[id].messages = []
|
|
9
10
|
sessions[id].claudeSessionId = null
|
|
10
11
|
sessions[id].codexThreadId = null
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { execSync } from 'child_process'
|
|
3
3
|
import { loadSessions } from '@/lib/server/storage'
|
|
4
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
4
5
|
|
|
5
6
|
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
6
7
|
const { id } = await params
|
|
7
8
|
const sessions = loadSessions()
|
|
8
9
|
const session = sessions[id]
|
|
9
|
-
if (!session) return
|
|
10
|
+
if (!session) return notFound()
|
|
10
11
|
|
|
11
12
|
const body = await req.json()
|
|
12
13
|
const msg = body.message || 'Deploy from SwarmClaw'
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { spawn } from 'child_process'
|
|
3
3
|
import { loadSessions, devServers, localIP } from '@/lib/server/storage'
|
|
4
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
4
5
|
|
|
5
6
|
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
6
7
|
const { id } = await params
|
|
7
8
|
const sessions = loadSessions()
|
|
8
9
|
const session = sessions[id]
|
|
9
|
-
if (!session) return
|
|
10
|
+
if (!session) return notFound()
|
|
10
11
|
|
|
11
12
|
const { action } = await req.json()
|
|
12
13
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSessions } from '@/lib/server/storage'
|
|
3
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
3
4
|
|
|
4
5
|
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
5
6
|
const { id } = await params
|
|
6
7
|
const sessions = loadSessions()
|
|
7
|
-
if (!sessions[id]) return
|
|
8
|
+
if (!sessions[id]) return notFound()
|
|
8
9
|
return NextResponse.json(sessions[id].messages)
|
|
9
10
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSessions, saveSessions } from '@/lib/server/storage'
|
|
3
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
3
4
|
|
|
4
5
|
export async function POST(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
5
6
|
const { id } = await params
|
|
6
7
|
const sessions = loadSessions()
|
|
7
8
|
const session = sessions[id]
|
|
8
|
-
if (!session) return
|
|
9
|
+
if (!session) return notFound()
|
|
9
10
|
|
|
10
11
|
const msgs = session.messages
|
|
11
12
|
// Pop trailing assistant messages to find the last user message
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSessions, saveSessions, deleteSession, active, loadAgents } from '@/lib/server/storage'
|
|
3
|
+
import { notFound } from '@/lib/server/collection-helpers'
|
|
3
4
|
import { enqueueSessionRun } from '@/lib/server/session-run-manager'
|
|
4
5
|
import { normalizeProviderEndpoint } from '@/lib/openclaw-endpoint'
|
|
5
6
|
|
|
@@ -20,7 +21,7 @@ export async function PUT(req: Request, { params }: { params: Promise<{ id: stri
|
|
|
20
21
|
const { id } = await params
|
|
21
22
|
const updates = await req.json()
|
|
22
23
|
const sessions = loadSessions()
|
|
23
|
-
if (!sessions[id]) return
|
|
24
|
+
if (!sessions[id]) return notFound()
|
|
24
25
|
const hadMessagesBefore = Array.isArray(sessions[id].messages) && sessions[id].messages.length > 0
|
|
25
26
|
|
|
26
27
|
const agentIdUpdateProvided = updates.agentId !== undefined
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
|
-
import
|
|
2
|
+
import { genId } from '@/lib/id'
|
|
3
3
|
import os from 'os'
|
|
4
4
|
import path from 'path'
|
|
5
5
|
import { loadSessions, saveSessions, deleteSession, active, loadAgents } from '@/lib/server/storage'
|
|
6
|
+
import { WORKSPACE_DIR } from '@/lib/server/data-dir'
|
|
7
|
+
import { notify } from '@/lib/server/ws-hub'
|
|
6
8
|
import { getSessionRunState } from '@/lib/server/session-run-manager'
|
|
7
9
|
import { normalizeProviderEndpoint } from '@/lib/openclaw-endpoint'
|
|
10
|
+
export const dynamic = 'force-dynamic'
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
|
|
13
|
+
export async function GET(_req: Request) {
|
|
10
14
|
const sessions = loadSessions()
|
|
11
15
|
for (const id of Object.keys(sessions)) {
|
|
12
16
|
const run = getSessionRunState(id)
|
|
@@ -31,6 +35,7 @@ export async function DELETE(req: Request) {
|
|
|
31
35
|
}
|
|
32
36
|
deleteSession(id)
|
|
33
37
|
}
|
|
38
|
+
notify('sessions')
|
|
34
39
|
return NextResponse.json({ deleted: ids.length })
|
|
35
40
|
}
|
|
36
41
|
|
|
@@ -38,9 +43,10 @@ export async function POST(req: Request) {
|
|
|
38
43
|
const body = await req.json()
|
|
39
44
|
let cwd = (body.cwd || '').trim()
|
|
40
45
|
if (cwd.startsWith('~/')) cwd = path.join(os.homedir(), cwd.slice(2))
|
|
41
|
-
else if (cwd === '~'
|
|
46
|
+
else if (cwd === '~') cwd = os.homedir()
|
|
47
|
+
else if (!cwd) cwd = WORKSPACE_DIR
|
|
42
48
|
|
|
43
|
-
const id = body.id ||
|
|
49
|
+
const id = body.id || genId()
|
|
44
50
|
const sessions = loadSessions()
|
|
45
51
|
const agent = body.agentId ? loadAgents()[body.agentId] : null
|
|
46
52
|
const requestedTools = Array.isArray(body.tools) ? body.tools : null
|
|
@@ -81,5 +87,6 @@ export async function POST(req: Request) {
|
|
|
81
87
|
heartbeatIntervalSec: body.heartbeatIntervalSec ?? null,
|
|
82
88
|
}
|
|
83
89
|
saveSessions(sessions)
|
|
90
|
+
notify('sessions')
|
|
84
91
|
return NextResponse.json(sessions[id])
|
|
85
92
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { loadSettings, saveSettings } from '@/lib/server/storage'
|
|
3
|
+
export const dynamic = 'force-dynamic'
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
const MEMORY_DEPTH_MIN = 0
|
|
5
7
|
const MEMORY_DEPTH_MAX = 12
|
|
@@ -18,7 +20,7 @@ function parseIntSetting(value: unknown, fallback: number, min: number, max: num
|
|
|
18
20
|
return Math.max(min, Math.min(max, Math.trunc(parsed)))
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
export async function GET() {
|
|
23
|
+
export async function GET(_req: Request) {
|
|
22
24
|
return NextResponse.json(loadSettings())
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -165,6 +165,7 @@ export async function GET(req: Request) {
|
|
|
165
165
|
{ id: 'claude-cli', label: 'Claude Code CLI', command: 'claude' },
|
|
166
166
|
{ id: 'codex-cli', label: 'OpenAI Codex CLI', command: 'codex' },
|
|
167
167
|
{ id: 'opencode-cli', label: 'OpenCode CLI', command: 'opencode' },
|
|
168
|
+
{ id: 'deno', label: 'Deno (sandbox runtime)', command: 'deno' },
|
|
168
169
|
]
|
|
169
170
|
|
|
170
171
|
for (const binary of optionalBinaries) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getDeviceId } from '@/lib/providers/openclaw'
|
|
3
|
+
export const dynamic = 'force-dynamic'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
export async function GET(_req: Request) {
|
|
5
7
|
try {
|
|
6
8
|
const deviceId = getDeviceId()
|
|
7
9
|
return NextResponse.json({ deviceId })
|