@swarmclawai/swarmclaw 1.2.3 → 1.2.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 +20 -0
- package/bin/daemon-cmd.js +169 -0
- package/bin/server-cmd.js +3 -0
- package/bin/swarmclaw.js +11 -0
- package/package.json +17 -16
- package/src/app/api/agents/[id]/clone/route.ts +3 -32
- package/src/app/api/agents/[id]/route.ts +6 -158
- package/src/app/api/agents/[id]/status/route.ts +2 -3
- package/src/app/api/agents/[id]/thread/route.ts +4 -17
- package/src/app/api/agents/bulk/route.ts +5 -47
- package/src/app/api/agents/route.ts +5 -119
- package/src/app/api/agents/trash/route.ts +13 -24
- package/src/app/api/auth/route.ts +3 -9
- package/src/app/api/autonomy/estop/route.ts +5 -5
- package/src/app/api/chatrooms/[id]/chat/route.ts +11 -5
- package/src/app/api/chatrooms/[id]/route.ts +23 -2
- package/src/app/api/chatrooms/route.ts +13 -2
- package/src/app/api/chats/[id]/clear/route.ts +2 -13
- package/src/app/api/chats/[id]/deploy/route.ts +2 -3
- package/src/app/api/chats/[id]/edit-resend/route.ts +7 -13
- package/src/app/api/chats/[id]/mailbox/route.ts +6 -8
- package/src/app/api/chats/[id]/queue/route.ts +17 -64
- package/src/app/api/chats/[id]/retry/route.ts +4 -22
- package/src/app/api/chats/[id]/route.ts +10 -138
- package/src/app/api/chats/heartbeat/route.ts +2 -1
- package/src/app/api/chats/migrate-messages/route.ts +7 -0
- package/src/app/api/chats/route.ts +13 -134
- package/src/app/api/connectors/[id]/access/route.ts +12 -229
- package/src/app/api/connectors/[id]/doctor/route.ts +1 -1
- package/src/app/api/connectors/[id]/health/route.ts +12 -39
- package/src/app/api/connectors/[id]/route.ts +14 -122
- package/src/app/api/connectors/[id]/webhook/route.ts +1 -1
- package/src/app/api/connectors/doctor/route.ts +1 -1
- package/src/app/api/connectors/route.ts +12 -70
- package/src/app/api/credentials/[id]/route.ts +2 -4
- package/src/app/api/credentials/route.ts +10 -19
- package/src/app/api/daemon/health-check/route.ts +3 -4
- package/src/app/api/daemon/route.ts +10 -8
- package/src/app/api/documents/route.ts +11 -10
- package/src/app/api/external-agents/route.ts +3 -3
- package/src/app/api/gateways/[id]/health/route.ts +2 -3
- package/src/app/api/gateways/[id]/route.ts +7 -122
- package/src/app/api/gateways/route.ts +3 -103
- package/src/app/api/mcp-servers/[id]/tools/route.ts +5 -5
- package/src/app/api/openclaw/dashboard-url/route.ts +8 -16
- package/src/app/api/openclaw/directory/route.ts +2 -2
- package/src/app/api/openclaw/history/route.ts +3 -5
- package/src/app/api/providers/[id]/models/route.test.ts +60 -0
- package/src/app/api/providers/[id]/models/route.ts +33 -1
- package/src/app/api/providers/[id]/route.test.ts +49 -0
- package/src/app/api/providers/[id]/route.ts +30 -1
- package/src/app/api/providers/ollama/route.ts +6 -5
- package/src/app/api/schedules/[id]/route.ts +14 -108
- package/src/app/api/schedules/[id]/run/route.ts +6 -67
- package/src/app/api/schedules/route.ts +9 -51
- package/src/app/api/settings/route.ts +4 -3
- package/src/app/api/setup/check-provider/route.ts +15 -1
- package/src/app/api/setup/openclaw-device/route.ts +2 -2
- package/src/app/api/system/status/route.ts +2 -2
- package/src/app/api/tasks/[id]/route.ts +16 -202
- package/src/app/api/tasks/bulk/route.ts +5 -86
- package/src/app/api/tasks/metrics/route.ts +2 -1
- package/src/app/api/tasks/route.ts +11 -171
- package/src/app/api/upload/route.ts +1 -1
- package/src/app/api/uploads/[filename]/route.ts +1 -1
- package/src/app/api/uploads/route.ts +1 -1
- package/src/app/api/webhooks/[id]/history/route.ts +2 -2
- package/src/app/layout.tsx +9 -6
- package/src/app/protocols/page.tsx +71 -89
- package/src/app/tasks/page.tsx +32 -32
- package/src/cli/index.js +1 -0
- package/src/cli/spec.js +1 -0
- package/src/components/agents/agent-sheet.tsx +51 -25
- package/src/components/agents/inspector-panel.tsx +15 -4
- package/src/components/auth/setup-wizard/index.tsx +27 -18
- package/src/components/auth/setup-wizard/shared.tsx +2 -2
- package/src/components/auth/setup-wizard/step-agents.tsx +51 -38
- package/src/components/auth/setup-wizard/step-connect.tsx +48 -17
- package/src/components/auth/setup-wizard/types.ts +6 -4
- package/src/components/auth/setup-wizard/utils.test.ts +38 -8
- package/src/components/auth/setup-wizard/utils.ts +14 -8
- package/src/components/chatrooms/chatroom-sheet.tsx +16 -276
- package/src/components/connectors/connector-list.tsx +26 -40
- package/src/components/connectors/connector-sheet.tsx +95 -149
- package/src/components/gateways/gateway-sheet.tsx +61 -110
- package/src/components/layout/live-query-sync.tsx +121 -0
- package/src/components/protocols/structured-session-launcher.tsx +24 -45
- package/src/components/providers/app-query-provider.tsx +17 -0
- package/src/components/providers/provider-list.tsx +150 -77
- package/src/components/providers/provider-sheet.tsx +102 -77
- package/src/components/shared/model-combobox.tsx +5 -4
- package/src/components/skills/skill-list.tsx +5 -18
- package/src/components/skills/skill-sheet.tsx +21 -20
- package/src/components/skills/skills-workspace.tsx +48 -87
- package/src/components/tasks/task-card.tsx +20 -13
- package/src/components/tasks/task-column.tsx +22 -7
- package/src/components/tasks/task-list.tsx +8 -11
- package/src/components/tasks/task-sheet.tsx +111 -103
- package/src/features/agents/queries.ts +20 -0
- package/src/features/chatrooms/queries.ts +20 -0
- package/src/features/chats/queries.ts +27 -0
- package/src/features/connectors/queries.ts +145 -0
- package/src/features/credentials/queries.ts +37 -0
- package/src/features/extensions/queries.ts +26 -0
- package/src/features/external-agents/queries.ts +36 -0
- package/src/features/gateways/queries.ts +274 -0
- package/src/features/missions/queries.ts +23 -0
- package/src/features/projects/queries.ts +20 -0
- package/src/features/protocols/queries.ts +149 -0
- package/src/features/providers/queries.ts +142 -0
- package/src/features/settings/queries.ts +20 -0
- package/src/features/skills/queries.ts +182 -0
- package/src/features/tasks/queries.ts +189 -0
- package/src/hooks/use-ws.ts +3 -2
- package/src/lib/agent-provider-options.test.ts +152 -0
- package/src/lib/agent-provider-options.ts +84 -0
- package/src/lib/app/api-client.ts +2 -2
- package/src/lib/providers/index.test.ts +78 -0
- package/src/lib/providers/index.ts +13 -10
- package/src/lib/query/client.ts +17 -0
- package/src/lib/server/agents/agent-runtime-config.ts +6 -6
- package/src/lib/server/agents/agent-service.ts +429 -0
- package/src/lib/server/agents/agent-thread-session.ts +6 -5
- package/src/lib/server/agents/autonomy-contract.ts +1 -4
- package/src/lib/server/agents/delegation-advisory.test.ts +206 -0
- package/src/lib/server/agents/delegation-advisory.ts +251 -0
- package/src/lib/server/agents/main-agent-loop.ts +98 -40
- package/src/lib/server/agents/subagent-runtime.ts +12 -0
- package/src/lib/server/autonomy/supervisor-reflection.test.ts +20 -1
- package/src/lib/server/autonomy/supervisor-reflection.ts +39 -19
- package/src/lib/server/build-llm.ts +7 -15
- package/src/lib/server/capability-router.test.ts +70 -1
- package/src/lib/server/capability-router.ts +24 -99
- package/src/lib/server/chat-execution/chat-execution-utils.ts +0 -15
- package/src/lib/server/chat-execution/chat-streaming-utils.ts +2 -4
- package/src/lib/server/chat-execution/chat-turn-finalization.ts +77 -12
- package/src/lib/server/chat-execution/chat-turn-partial-persistence.ts +4 -4
- package/src/lib/server/chat-execution/chat-turn-preflight.ts +2 -2
- package/src/lib/server/chat-execution/chat-turn-preparation.ts +41 -17
- package/src/lib/server/chat-execution/chat-turn-stream-execution.ts +4 -2
- package/src/lib/server/chat-execution/chat-turn-tool-routing.test.ts +45 -0
- package/src/lib/server/chat-execution/chat-turn-tool-routing.ts +48 -17
- package/src/lib/server/chat-execution/continuation-evaluator.ts +4 -1
- package/src/lib/server/chat-execution/direct-memory-intent.test.ts +9 -0
- package/src/lib/server/chat-execution/direct-memory-intent.ts +12 -2
- package/src/lib/server/chat-execution/message-classifier.test.ts +35 -23
- package/src/lib/server/chat-execution/message-classifier.ts +74 -32
- package/src/lib/server/chat-execution/prompt-builder.test.ts +29 -0
- package/src/lib/server/chat-execution/prompt-builder.ts +37 -2
- package/src/lib/server/chat-execution/prompt-sections.test.ts +56 -0
- package/src/lib/server/chat-execution/prompt-sections.ts +193 -0
- package/src/lib/server/chat-execution/stream-agent-chat.ts +63 -7
- package/src/lib/server/chat-execution/stream-continuation.test.ts +36 -0
- package/src/lib/server/chat-execution/stream-continuation.ts +28 -13
- package/src/lib/server/chatrooms/chatroom-agent-signals.ts +26 -18
- package/src/lib/server/chatrooms/chatroom-helpers.ts +19 -18
- package/src/lib/server/chatrooms/chatroom-repository.ts +16 -0
- package/src/lib/server/chatrooms/chatroom-routing.test.ts +96 -0
- package/src/lib/server/chatrooms/chatroom-routing.ts +207 -53
- package/src/lib/server/chatrooms/mailbox-utils.ts +4 -2
- package/src/lib/server/chatrooms/session-mailbox.ts +50 -40
- package/src/lib/server/chats/chat-session-service.ts +410 -0
- package/src/lib/server/connectors/access.ts +1 -1
- package/src/lib/server/connectors/commands.ts +7 -6
- package/src/lib/server/connectors/connector-inbound.ts +14 -7
- package/src/lib/server/connectors/connector-outbound.ts +16 -11
- package/src/lib/server/connectors/connector-service.ts +453 -0
- package/src/lib/server/connectors/delivery.ts +17 -12
- package/src/lib/server/connectors/inbound-audio-transcription.ts +5 -14
- package/src/lib/server/connectors/media.ts +1 -1
- package/src/lib/server/connectors/response-media.ts +1 -1
- package/src/lib/server/connectors/session-consolidation.ts +11 -7
- package/src/lib/server/connectors/session.ts +9 -7
- package/src/lib/server/connectors/voice-note.ts +2 -1
- package/src/lib/server/context-manager.ts +20 -1
- package/src/lib/server/cost.ts +2 -3
- package/src/lib/server/credentials/credential-repository.ts +43 -4
- package/src/lib/server/credentials/credential-service.ts +112 -0
- package/src/lib/server/daemon/admin-metadata.ts +64 -0
- package/src/lib/server/daemon/controller.ts +577 -0
- package/src/lib/server/daemon/daemon-runtime.ts +352 -0
- package/src/lib/server/daemon/daemon-status-repository.ts +63 -0
- package/src/lib/server/daemon/types.ts +101 -0
- package/src/lib/server/embeddings.ts +3 -9
- package/src/lib/server/eval/agent-regression.ts +3 -2
- package/src/lib/server/eval/runner.ts +2 -2
- package/src/lib/server/execution-brief.test.ts +167 -0
- package/src/lib/server/execution-brief.ts +295 -0
- package/src/lib/server/execution-engine/chat-turn.ts +9 -0
- package/src/lib/server/execution-engine/import-boundary.test.ts +44 -0
- package/src/lib/server/execution-engine/index.ts +35 -0
- package/src/lib/server/execution-engine/task-attempt.ts +303 -0
- package/src/lib/server/execution-engine/types.ts +33 -0
- package/src/lib/server/gateways/gateway-profile-repository.ts +47 -3
- package/src/lib/server/gateways/gateway-profile-service.ts +200 -0
- package/src/lib/server/memory/session-archive-memory.ts +12 -10
- package/src/lib/server/messages/message-repository.ts +330 -0
- package/src/lib/server/missions/mission-service/core.ts +8 -6
- package/src/lib/server/openclaw/agent-resolver.ts +2 -3
- package/src/lib/server/openclaw/doctor.ts +1 -1
- package/src/lib/server/openclaw/gateway.test.ts +10 -1
- package/src/lib/server/openclaw/gateway.ts +5 -14
- package/src/lib/server/openclaw/health.ts +3 -11
- package/src/lib/server/openclaw/sync.ts +8 -6
- package/src/lib/server/persistence/storage-context.ts +3 -0
- package/src/lib/server/protocols/protocol-agent-turn.ts +25 -17
- package/src/lib/server/protocols/protocol-normalization.ts +1 -1
- package/src/lib/server/protocols/protocol-queries.ts +13 -7
- package/src/lib/server/protocols/protocol-run-lifecycle.ts +16 -20
- package/src/lib/server/protocols/protocol-run-repository.ts +81 -0
- package/src/lib/server/protocols/protocol-step-processors.ts +23 -31
- package/src/lib/server/protocols/protocol-swarm.ts +8 -8
- package/src/lib/server/protocols/protocol-template-repository.ts +42 -0
- package/src/lib/server/protocols/protocol-templates.ts +4 -2
- package/src/lib/server/protocols/protocol-types.ts +10 -7
- package/src/lib/server/provider-endpoint.ts +7 -12
- package/src/lib/server/provider-model-discovery.ts +2 -11
- package/src/lib/server/query-expansion.ts +5 -6
- package/src/lib/server/run-context.test.ts +365 -0
- package/src/lib/server/run-context.ts +367 -0
- package/src/lib/server/runtime/heartbeat-service.ts +7 -5
- package/src/lib/server/runtime/queue/core.ts +61 -190
- package/src/lib/server/runtime/run-ledger.ts +8 -0
- package/src/lib/server/runtime/session-run-manager/drain.ts +2 -2
- package/src/lib/server/runtime/session-run-manager/enqueue.ts +6 -0
- package/src/lib/server/runtime/session-run-manager/state.ts +4 -0
- package/src/lib/server/schedules/schedule-route-service.ts +230 -0
- package/src/lib/server/service-result.ts +16 -0
- package/src/lib/server/session-note.ts +2 -3
- package/src/lib/server/session-reset-policy.ts +4 -3
- package/src/lib/server/session-tools/connector.ts +9 -6
- package/src/lib/server/session-tools/context-mgmt.ts +58 -9
- package/src/lib/server/session-tools/crud.ts +162 -10
- package/src/lib/server/session-tools/delegate.ts +1 -1
- package/src/lib/server/session-tools/manage-tasks.test.ts +152 -0
- package/src/lib/server/session-tools/memory.ts +6 -4
- package/src/lib/server/session-tools/session-info.test.ts +56 -0
- package/src/lib/server/session-tools/session-info.ts +119 -12
- package/src/lib/server/session-tools/skill-runtime.ts +3 -1
- package/src/lib/server/session-tools/skills.ts +15 -15
- package/src/lib/server/session-tools/subagent.test.ts +115 -1
- package/src/lib/server/session-tools/subagent.ts +125 -7
- package/src/lib/server/session-tools/team-context.ts +4 -3
- package/src/lib/server/session-tools/wallet.ts +0 -58
- package/src/lib/server/sessions/session-lineage.ts +55 -0
- package/src/lib/server/sessions/session-repository.ts +2 -2
- package/src/lib/server/skills/learned-skills.ts +24 -23
- package/src/lib/server/skills/runtime-skill-resolver.ts +2 -1
- package/src/lib/server/skills/skill-repository.ts +136 -13
- package/src/lib/server/skills/skill-suggestions.ts +25 -28
- package/src/lib/server/storage-normalization.test.ts +42 -215
- package/src/lib/server/storage-normalization.ts +98 -0
- package/src/lib/server/storage.ts +19 -0
- package/src/lib/server/structured-extract.ts +3 -14
- package/src/lib/server/tasks/task-followups.ts +16 -11
- package/src/lib/server/tasks/task-result.test.ts +25 -29
- package/src/lib/server/tasks/task-result.ts +5 -9
- package/src/lib/server/tasks/task-route-service.ts +449 -0
- package/src/lib/server/text-normalization.ts +41 -0
- package/src/lib/server/tool-planning.ts +6 -42
- package/src/lib/server/upload-path.ts +5 -0
- package/src/lib/server/working-state/extraction.ts +614 -0
- package/src/lib/server/working-state/normalization.ts +866 -0
- package/src/lib/server/working-state/prompt.ts +60 -0
- package/src/lib/server/working-state/repository.ts +38 -0
- package/src/lib/server/working-state/service.test.ts +253 -0
- package/src/lib/server/working-state/service.ts +293 -0
- package/src/lib/validation/schemas.ts +1 -0
- package/src/lib/ws-client.ts +3 -3
- package/src/stores/slices/task-slice.ts +1 -4
- package/src/stores/use-chatroom-store.ts +2 -2
- package/src/types/index.ts +288 -22
- package/src/views/settings/section-providers.tsx +2 -2
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* Populates the field from existing senderId, senderIdAlt, channelId, channelIdAlt, peerKey.
|
|
4
4
|
*/
|
|
5
5
|
import { log } from '@/lib/server/logger'
|
|
6
|
-
import {
|
|
6
|
+
import { saveSession, loadSessions } from '@/lib/server/sessions/session-repository'
|
|
7
|
+
import { getMessages, getMessageCount, replaceAllMessages } from '@/lib/server/messages/message-repository'
|
|
8
|
+
import { loadSettings, saveSettings } from '../settings/settings-repository'
|
|
7
9
|
import type { Session } from '@/types'
|
|
8
10
|
import { isDirectConnectorSession } from './session-kind'
|
|
9
11
|
|
|
@@ -38,7 +40,7 @@ export function backfillAllKnownPeerIds(): { migrated: number; skipped: boolean
|
|
|
38
40
|
...ctx,
|
|
39
41
|
allKnownPeerIds: [...ids],
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
saveSession(session.id, session)
|
|
42
44
|
migrated++
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -63,19 +65,21 @@ export function pruneThreadConnectorMirrors(): { cleanedSessions: number; remove
|
|
|
63
65
|
|
|
64
66
|
for (const session of Object.values(sessions)) {
|
|
65
67
|
if (isDirectConnectorSession(session)) continue
|
|
66
|
-
|
|
68
|
+
const msgCount = getMessageCount(session.id)
|
|
69
|
+
if (msgCount === 0) continue
|
|
67
70
|
|
|
68
|
-
const
|
|
71
|
+
const allMessages = getMessages(session.id)
|
|
72
|
+
const filteredMessages = allMessages.filter((message) => !(
|
|
69
73
|
message?.historyExcluded === true
|
|
70
74
|
&& typeof message?.source?.connectorId === 'string'
|
|
71
75
|
&& message.source.connectorId.trim().length > 0
|
|
72
76
|
))
|
|
73
77
|
|
|
74
|
-
const removed =
|
|
78
|
+
const removed = allMessages.length - filteredMessages.length
|
|
75
79
|
if (removed <= 0) continue
|
|
76
80
|
|
|
77
|
-
session.
|
|
78
|
-
|
|
81
|
+
replaceAllMessages(session.id, filteredMessages)
|
|
82
|
+
saveSession(session.id, session)
|
|
79
83
|
cleanedSessions += 1
|
|
80
84
|
removedMessages += removed
|
|
81
85
|
}
|
|
@@ -5,6 +5,10 @@ import { WORKSPACE_DIR } from '../data-dir'
|
|
|
5
5
|
import { ensureAgentThreadSession } from '@/lib/server/agents/agent-thread-session'
|
|
6
6
|
import { resolveEffectiveSessionMemoryScopeMode } from '@/lib/server/memory/session-memory-scope'
|
|
7
7
|
import { syncSessionArchiveMemory } from '@/lib/server/memory/session-archive-memory'
|
|
8
|
+
import {
|
|
9
|
+
appendMessage,
|
|
10
|
+
getLastMessage,
|
|
11
|
+
} from '@/lib/server/messages/message-repository'
|
|
8
12
|
import { loadAgents, loadSessions, loadStoredItem, upsertStoredItem } from '../storage'
|
|
9
13
|
import { notify } from '../ws-hub'
|
|
10
14
|
import {
|
|
@@ -416,7 +420,7 @@ function mirrorConnectorMessageToAgentThread(
|
|
|
416
420
|
: ensureAgentThreadSession(session.agentId)
|
|
417
421
|
if (!threadSession || threadSession.id === session.id) return
|
|
418
422
|
|
|
419
|
-
const last =
|
|
423
|
+
const last = getLastMessage(threadSession.id)
|
|
420
424
|
const source = message.source as MessageSource | undefined
|
|
421
425
|
const lastSource = (last?.source || null) as MessageSource | null
|
|
422
426
|
if (
|
|
@@ -431,17 +435,16 @@ function mirrorConnectorMessageToAgentThread(
|
|
|
431
435
|
return
|
|
432
436
|
}
|
|
433
437
|
|
|
434
|
-
|
|
435
|
-
threadSession.messages.push({
|
|
438
|
+
const mirrorMsg = {
|
|
436
439
|
...message,
|
|
437
440
|
time: typeof message.time === 'number' ? message.time : Date.now(),
|
|
438
441
|
historyExcluded: true,
|
|
439
|
-
} as Session['messages'][number]
|
|
442
|
+
} as Session['messages'][number]
|
|
443
|
+
appendMessage(threadSession.id, mirrorMsg)
|
|
440
444
|
threadSession.lastActiveAt = Date.now()
|
|
441
445
|
|
|
442
446
|
upsertStoredItem('sessions', threadSession.id, threadSession)
|
|
443
447
|
notify('sessions')
|
|
444
|
-
notify(`messages:${threadSession.id}`)
|
|
445
448
|
}
|
|
446
449
|
|
|
447
450
|
export function pushSessionMessage(
|
|
@@ -451,9 +454,8 @@ export function pushSessionMessage(
|
|
|
451
454
|
extra: Record<string, unknown> = {},
|
|
452
455
|
): void {
|
|
453
456
|
if (!text.trim()) return
|
|
454
|
-
if (!Array.isArray(session.messages)) session.messages = []
|
|
455
457
|
const message = { role, text: text.trim(), time: Date.now(), ...extra }
|
|
456
|
-
session.messages
|
|
458
|
+
appendMessage(session.id, message as Session['messages'][number])
|
|
457
459
|
session.lastActiveAt = Date.now()
|
|
458
460
|
mirrorConnectorMessageToAgentThread(session, message)
|
|
459
461
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import path from 'path'
|
|
3
3
|
import { genId } from '@/lib/id'
|
|
4
|
-
import { loadAgent
|
|
4
|
+
import { loadAgent } from '@/lib/server/agents/agent-repository'
|
|
5
5
|
import { synthesizeElevenLabsMp3 } from '../elevenlabs'
|
|
6
|
+
import { UPLOAD_DIR } from '../upload-path'
|
|
6
7
|
import { isAudioMime, mimeFromPath } from './media'
|
|
7
8
|
|
|
8
9
|
export function resolveConnectorVoiceId(params: {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type { Message } from '@/types'
|
|
1
|
+
import type { Message, Session } from '@/types'
|
|
2
2
|
import { getMemoryDb } from '@/lib/server/memory/memory-db'
|
|
3
|
+
import { extractFactsFromMessages, ensureRunContext, pruneRunContext } from '@/lib/server/run-context'
|
|
4
|
+
import { getSession, saveSession } from '@/lib/server/sessions/session-repository'
|
|
3
5
|
|
|
4
6
|
import { repairTranscriptConsistency } from './transcript-repair'
|
|
5
7
|
|
|
@@ -549,6 +551,23 @@ export async function llmCompact(opts: {
|
|
|
549
551
|
const oldMessages = repaired.slice(0, -keepLastN)
|
|
550
552
|
const recentMessages = repaired.slice(-keepLastN)
|
|
551
553
|
|
|
554
|
+
// 0. Extract facts from messages about to be dropped into RunContext (non-critical)
|
|
555
|
+
try {
|
|
556
|
+
const session = getSession(sessionId) as Session | undefined
|
|
557
|
+
if (session && oldMessages.length > 0) {
|
|
558
|
+
const extracted = extractFactsFromMessages(oldMessages)
|
|
559
|
+
if (extracted.keyFacts.length > 0 || extracted.failedApproaches.length > 0) {
|
|
560
|
+
const ctx = ensureRunContext(session.runContext)
|
|
561
|
+
ctx.keyFacts = [...ctx.keyFacts, ...extracted.keyFacts]
|
|
562
|
+
ctx.failedApproaches = [...ctx.failedApproaches, ...extracted.failedApproaches]
|
|
563
|
+
ctx.version++
|
|
564
|
+
ctx.updatedAt = Date.now()
|
|
565
|
+
session.runContext = pruneRunContext(ctx)
|
|
566
|
+
saveSession(sessionId, session)
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
} catch { /* non-critical — compaction continues even if extraction fails */ }
|
|
570
|
+
|
|
552
571
|
// 1. Consolidate important info to memory
|
|
553
572
|
const memoriesStored = consolidateToMemory(oldMessages, agentId, sessionId)
|
|
554
573
|
|
package/src/lib/server/cost.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Agent, UsageRecord, ExtensionDefinitionCost } from '@/types'
|
|
1
|
+
import type { Agent, Session, UsageRecord, ExtensionDefinitionCost } from '@/types'
|
|
2
2
|
import type { StructuredToolInterface } from '@langchain/core/tools'
|
|
3
3
|
import { loadSessions, loadUsage } from './storage'
|
|
4
4
|
|
|
@@ -26,8 +26,7 @@ const MODEL_COSTS: Record<string, [number, number]> = {
|
|
|
26
26
|
const ONE_HOUR_MS = 60 * 60 * 1000
|
|
27
27
|
const WARNING_RATIO = 0.8
|
|
28
28
|
|
|
29
|
-
type
|
|
30
|
-
type SessionsMap = Record<string, GenericRecord>
|
|
29
|
+
type SessionsMap = Record<string, Session | Record<string, unknown>>
|
|
31
30
|
type UsageMap = Record<string, unknown>
|
|
32
31
|
|
|
33
32
|
function parsePositiveBudget(value: unknown): number | null {
|
|
@@ -1,7 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Credential } from '@/types'
|
|
2
|
+
|
|
3
|
+
import {
|
|
2
4
|
decryptKey,
|
|
3
|
-
deleteCredential,
|
|
5
|
+
deleteCredential as deleteStoredCredential,
|
|
4
6
|
encryptKey,
|
|
5
|
-
loadCredentials,
|
|
6
|
-
saveCredentials,
|
|
7
|
+
loadCredentials as loadStoredCredentials,
|
|
8
|
+
saveCredentials as saveStoredCredentials,
|
|
9
|
+
upsertStoredItem,
|
|
7
10
|
} from '@/lib/server/storage'
|
|
11
|
+
import { createRecordRepository } from '@/lib/server/persistence/repository-utils'
|
|
12
|
+
|
|
13
|
+
export type StoredCredential = Credential & {
|
|
14
|
+
encryptedKey?: string | null
|
|
15
|
+
updatedAt?: number
|
|
16
|
+
[key: string]: unknown
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const credentialRepository = createRecordRepository<StoredCredential>(
|
|
20
|
+
'credentials',
|
|
21
|
+
{
|
|
22
|
+
get(id) {
|
|
23
|
+
return (loadStoredCredentials() as Record<string, StoredCredential>)[id] || null
|
|
24
|
+
},
|
|
25
|
+
list() {
|
|
26
|
+
return loadStoredCredentials() as Record<string, StoredCredential>
|
|
27
|
+
},
|
|
28
|
+
upsert(id, value) {
|
|
29
|
+
upsertStoredItem('credentials', id, value)
|
|
30
|
+
},
|
|
31
|
+
replace(data) {
|
|
32
|
+
saveStoredCredentials(data)
|
|
33
|
+
},
|
|
34
|
+
delete(id) {
|
|
35
|
+
deleteStoredCredential(id)
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
export const loadCredentials = () => credentialRepository.list()
|
|
41
|
+
export const loadCredential = (id: string) => credentialRepository.get(id)
|
|
42
|
+
export const saveCredentials = (items: Record<string, StoredCredential | Record<string, unknown>>) => credentialRepository.replace(items as Record<string, StoredCredential>)
|
|
43
|
+
export const saveCredential = (id: string, value: StoredCredential | Record<string, unknown>) => credentialRepository.upsert(id, value as StoredCredential)
|
|
44
|
+
export const deleteCredential = (id: string) => credentialRepository.delete(id)
|
|
45
|
+
|
|
46
|
+
export { decryptKey, encryptKey }
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { Credential } from '@/types'
|
|
2
|
+
|
|
3
|
+
import { genId } from '@/lib/id'
|
|
4
|
+
import {
|
|
5
|
+
deleteCredential,
|
|
6
|
+
decryptKey,
|
|
7
|
+
encryptKey,
|
|
8
|
+
loadCredential,
|
|
9
|
+
loadCredentials,
|
|
10
|
+
saveCredential,
|
|
11
|
+
} from '@/lib/server/credentials/credential-repository'
|
|
12
|
+
|
|
13
|
+
export type CredentialSummary = Pick<Credential, 'id' | 'provider' | 'name' | 'createdAt'>
|
|
14
|
+
|
|
15
|
+
function clean(value: string | null | undefined): string {
|
|
16
|
+
return typeof value === 'string' ? value.trim() : ''
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function toCredentialSummary(credential: Credential | null | undefined): CredentialSummary | null {
|
|
20
|
+
if (!credential) return null
|
|
21
|
+
return {
|
|
22
|
+
id: credential.id,
|
|
23
|
+
provider: credential.provider,
|
|
24
|
+
name: credential.name,
|
|
25
|
+
createdAt: credential.createdAt,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function listCredentialSummaries(): Record<string, CredentialSummary> {
|
|
30
|
+
const credentials = loadCredentials()
|
|
31
|
+
const summaries: Record<string, CredentialSummary> = {}
|
|
32
|
+
for (const [id, credential] of Object.entries(credentials)) {
|
|
33
|
+
const summary = toCredentialSummary(credential)
|
|
34
|
+
if (summary) summaries[id] = summary
|
|
35
|
+
}
|
|
36
|
+
return summaries
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getCredentialSummary(id: string): CredentialSummary | null {
|
|
40
|
+
return toCredentialSummary(loadCredential(id))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function listCredentialIdsByProvider(provider: string): string[] {
|
|
44
|
+
const normalizedProvider = clean(provider)
|
|
45
|
+
if (!normalizedProvider) return []
|
|
46
|
+
return Object.entries(loadCredentials())
|
|
47
|
+
.filter(([, credential]) => credential?.provider === normalizedProvider)
|
|
48
|
+
.map(([id]) => id)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function resolveCredentialSecret(credentialId: string | null | undefined): string | null {
|
|
52
|
+
const id = clean(credentialId)
|
|
53
|
+
if (!id) return null
|
|
54
|
+
const credential = loadCredential(id)
|
|
55
|
+
if (!credential?.encryptedKey) return null
|
|
56
|
+
try {
|
|
57
|
+
return decryptKey(credential.encryptedKey)
|
|
58
|
+
} catch {
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function requireCredentialSecret(
|
|
64
|
+
credentialId: string | null | undefined,
|
|
65
|
+
missingMessage = 'Credential secret not found.',
|
|
66
|
+
): string {
|
|
67
|
+
const id = clean(credentialId)
|
|
68
|
+
if (!id) throw new Error(missingMessage)
|
|
69
|
+
const credential = loadCredential(id)
|
|
70
|
+
if (!credential?.encryptedKey) throw new Error(missingMessage)
|
|
71
|
+
try {
|
|
72
|
+
return decryptKey(credential.encryptedKey)
|
|
73
|
+
} catch {
|
|
74
|
+
throw new Error(missingMessage)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function createCredentialRecord(input: {
|
|
79
|
+
provider: string
|
|
80
|
+
name?: string | null
|
|
81
|
+
apiKey: string
|
|
82
|
+
}): CredentialSummary {
|
|
83
|
+
const provider = clean(input.provider)
|
|
84
|
+
const apiKey = clean(input.apiKey)
|
|
85
|
+
if (!provider || !apiKey) {
|
|
86
|
+
throw new Error('provider and apiKey are required')
|
|
87
|
+
}
|
|
88
|
+
const id = `cred_${genId(6)}`
|
|
89
|
+
const createdAt = Date.now()
|
|
90
|
+
const credentialName = clean(input.name) || `${provider} key`
|
|
91
|
+
saveCredential(id, {
|
|
92
|
+
id,
|
|
93
|
+
provider,
|
|
94
|
+
name: credentialName,
|
|
95
|
+
encryptedKey: encryptKey(apiKey),
|
|
96
|
+
createdAt,
|
|
97
|
+
})
|
|
98
|
+
return {
|
|
99
|
+
id,
|
|
100
|
+
provider,
|
|
101
|
+
name: credentialName,
|
|
102
|
+
createdAt,
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function deleteCredentialRecord(id: string): boolean {
|
|
107
|
+
const credentialId = clean(id)
|
|
108
|
+
if (!credentialId) return false
|
|
109
|
+
if (!loadCredential(credentialId)) return false
|
|
110
|
+
deleteCredential(credentialId)
|
|
111
|
+
return true
|
|
112
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import { DATA_DIR } from '@/lib/server/data-dir'
|
|
5
|
+
import type { DaemonAdminMetadata } from '@/lib/server/daemon/types'
|
|
6
|
+
|
|
7
|
+
function resolveHomeDir(): string {
|
|
8
|
+
const configured = process.env.SWARMCLAW_HOME?.trim()
|
|
9
|
+
if (configured) return path.resolve(configured)
|
|
10
|
+
return path.dirname(DATA_DIR)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const DAEMON_ADMIN_METADATA_PATH = path.join(resolveHomeDir(), 'daemon-admin.json')
|
|
14
|
+
export const DAEMON_LOG_PATH = path.join(resolveHomeDir(), 'daemon.log')
|
|
15
|
+
|
|
16
|
+
export function isProcessRunning(pid: number | null | undefined): boolean {
|
|
17
|
+
if (typeof pid !== 'number' || !Number.isFinite(pid) || pid <= 0) return false
|
|
18
|
+
try {
|
|
19
|
+
process.kill(pid, 0)
|
|
20
|
+
return true
|
|
21
|
+
} catch {
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function normalizeMetadata(value: unknown): DaemonAdminMetadata | null {
|
|
27
|
+
if (!value || typeof value !== 'object') return null
|
|
28
|
+
const candidate = value as Partial<DaemonAdminMetadata>
|
|
29
|
+
const pid = typeof candidate.pid === 'number' && Number.isFinite(candidate.pid) ? Math.trunc(candidate.pid) : null
|
|
30
|
+
const port = typeof candidate.port === 'number' && Number.isFinite(candidate.port) ? Math.trunc(candidate.port) : null
|
|
31
|
+
const token = typeof candidate.token === 'string' ? candidate.token.trim() : ''
|
|
32
|
+
if (!pid || !port || !token) return null
|
|
33
|
+
return {
|
|
34
|
+
pid,
|
|
35
|
+
port,
|
|
36
|
+
token,
|
|
37
|
+
launchedAt: typeof candidate.launchedAt === 'number' && Number.isFinite(candidate.launchedAt)
|
|
38
|
+
? Math.trunc(candidate.launchedAt)
|
|
39
|
+
: Date.now(),
|
|
40
|
+
source: typeof candidate.source === 'string' ? candidate.source : null,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function readDaemonAdminMetadata(): DaemonAdminMetadata | null {
|
|
45
|
+
try {
|
|
46
|
+
const raw = JSON.parse(fs.readFileSync(DAEMON_ADMIN_METADATA_PATH, 'utf8'))
|
|
47
|
+
return normalizeMetadata(raw)
|
|
48
|
+
} catch {
|
|
49
|
+
return null
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function writeDaemonAdminMetadata(metadata: DaemonAdminMetadata): void {
|
|
54
|
+
fs.mkdirSync(path.dirname(DAEMON_ADMIN_METADATA_PATH), { recursive: true })
|
|
55
|
+
fs.writeFileSync(DAEMON_ADMIN_METADATA_PATH, `${JSON.stringify(metadata, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function clearDaemonAdminMetadata(): void {
|
|
59
|
+
try {
|
|
60
|
+
fs.unlinkSync(DAEMON_ADMIN_METADATA_PATH)
|
|
61
|
+
} catch {
|
|
62
|
+
// Ignore missing metadata file.
|
|
63
|
+
}
|
|
64
|
+
}
|