@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Message, MessageToolEvent } from '@/types'
|
|
2
2
|
import { loadSessions, saveSessions } from './storage'
|
|
3
|
+
import { appendMessage } from '@/lib/server/messages/message-repository'
|
|
3
4
|
import { notify } from './ws-hub'
|
|
4
5
|
|
|
5
6
|
export interface SessionNoteInput {
|
|
@@ -27,16 +28,14 @@ export function appendSessionNote(input: SessionNoteInput): Message | null {
|
|
|
27
28
|
const sessions = loadSessions()
|
|
28
29
|
const session = sessions[input.sessionId]
|
|
29
30
|
if (!session) return null
|
|
30
|
-
if (!Array.isArray(session.messages)) session.messages = []
|
|
31
31
|
|
|
32
32
|
const next = buildSessionNoteMessage(input)
|
|
33
33
|
if (!next) return null
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
appendMessage(input.sessionId, next)
|
|
36
36
|
session.lastActiveAt = next.time
|
|
37
37
|
sessions[input.sessionId] = session
|
|
38
38
|
saveSessions(sessions)
|
|
39
39
|
notify('sessions')
|
|
40
|
-
notify(`messages:${input.sessionId}`)
|
|
41
40
|
return next
|
|
42
41
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Agent, AppSettings, Session, SessionResetMode, SessionResetType } from '@/types'
|
|
2
2
|
import { isDirectConnectorSession } from '@/lib/server/connectors/session-kind'
|
|
3
|
+
import { clearMessages, getMessageCount } from '@/lib/server/messages/message-repository'
|
|
3
4
|
|
|
4
5
|
export interface ResolvedSessionResetPolicy {
|
|
5
6
|
type: SessionResetType
|
|
@@ -190,7 +191,7 @@ export function evaluateSessionFreshness(params: {
|
|
|
190
191
|
const now = typeof params.now === 'number' ? params.now : Date.now()
|
|
191
192
|
const session = params.session
|
|
192
193
|
const policy = params.policy
|
|
193
|
-
const messageCount =
|
|
194
|
+
const messageCount = typeof session?.id === 'string' ? getMessageCount(session.id) : 0
|
|
194
195
|
const createdAt = typeof session?.createdAt === 'number' ? session.createdAt : now
|
|
195
196
|
const lastActiveAt = typeof session?.lastActiveAt === 'number' ? session.lastActiveAt : createdAt
|
|
196
197
|
const idleExpiresAt = typeof policy.idleTimeoutSec === 'number' && policy.idleTimeoutSec > 0
|
|
@@ -275,9 +276,9 @@ export function resetSessionRuntime(
|
|
|
275
276
|
opts?: { now?: number },
|
|
276
277
|
): number {
|
|
277
278
|
const now = typeof opts?.now === 'number' ? opts.now : Date.now()
|
|
278
|
-
const cleared =
|
|
279
|
+
const cleared = getMessageCount(session.id)
|
|
279
280
|
|
|
280
|
-
session.
|
|
281
|
+
clearMessages(session.id)
|
|
281
282
|
session.claudeSessionId = null
|
|
282
283
|
session.codexThreadId = null
|
|
283
284
|
session.opencodeSessionId = null
|
|
@@ -10,6 +10,7 @@ import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
|
10
10
|
import { safeJsonParseObject } from '../json-utils'
|
|
11
11
|
import { tryResolvePathWithinBaseDir } from '../path-utils'
|
|
12
12
|
import { dedup, errorMessage } from '@/lib/shared-utils'
|
|
13
|
+
import { getMessages } from '@/lib/server/messages/message-repository'
|
|
13
14
|
import { isDirectConnectorSession } from '../connectors/session-kind'
|
|
14
15
|
import {
|
|
15
16
|
prepareConnectorVoiceNotePayload,
|
|
@@ -135,9 +136,10 @@ function pruneOldConnectorToolState(now: number): void {
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
function parseLatestUserTurn(
|
|
138
|
-
|
|
139
|
+
sessionId: string | null | undefined,
|
|
139
140
|
): { text: string; time: number } {
|
|
140
|
-
|
|
141
|
+
if (!sessionId) return { text: '', time: 0 }
|
|
142
|
+
const msgs = getMessages(sessionId)
|
|
141
143
|
for (let i = msgs.length - 1; i >= 0; i -= 1) {
|
|
142
144
|
const msg = msgs[i]
|
|
143
145
|
if (String(msg?.role || '') !== 'user') continue
|
|
@@ -435,10 +437,10 @@ function trimToString(value: unknown): string {
|
|
|
435
437
|
|
|
436
438
|
function resolveSessionConnectorTargets(
|
|
437
439
|
session: {
|
|
440
|
+
id?: string
|
|
438
441
|
user?: string
|
|
439
442
|
name?: string
|
|
440
443
|
connectorContext?: Record<string, unknown>
|
|
441
|
-
messages?: Array<Record<string, unknown>>
|
|
442
444
|
} | null | undefined,
|
|
443
445
|
connectorId: string,
|
|
444
446
|
): Array<{ channelId: string; senderId?: string; senderName?: string }> {
|
|
@@ -463,7 +465,8 @@ function resolveSessionConnectorTargets(
|
|
|
463
465
|
: null)
|
|
464
466
|
}
|
|
465
467
|
|
|
466
|
-
const
|
|
468
|
+
const sessionId = typeof session?.id === 'string' ? session.id : ''
|
|
469
|
+
const messages = sessionId ? getMessages(sessionId) : []
|
|
467
470
|
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
468
471
|
if (messages[i]?.historyExcluded === true) continue
|
|
469
472
|
const source = messages[i]?.source as Record<string, unknown> | undefined
|
|
@@ -485,10 +488,10 @@ function pickChannelTarget(params: {
|
|
|
485
488
|
connectorId: string
|
|
486
489
|
to?: string
|
|
487
490
|
currentSession?: {
|
|
491
|
+
id?: string
|
|
488
492
|
user?: string
|
|
489
493
|
name?: string
|
|
490
494
|
connectorContext?: Record<string, unknown>
|
|
491
|
-
messages?: Array<Record<string, unknown>>
|
|
492
495
|
} | null
|
|
493
496
|
}): { channelId: string; error?: string } {
|
|
494
497
|
let channelId = params.to?.trim() || ''
|
|
@@ -694,7 +697,7 @@ async function executeConnectorAction(input: ConnectorActionInput, bctx: Connect
|
|
|
694
697
|
const currentSession = bctx.resolveCurrentSession?.()
|
|
695
698
|
const sessionId = bctx.ctx?.sessionId || currentSession?.id || undefined
|
|
696
699
|
const connectorScopedSessionId = isDirectConnectorSession(currentSession) ? sessionId : undefined
|
|
697
|
-
const latestUserTurn = parseLatestUserTurn(
|
|
700
|
+
const latestUserTurn = parseLatestUserTurn(sessionId)
|
|
698
701
|
const turnKey = buildConnectorActionKey([sessionId, latestUserTurn.time || 'no-user-turn'])
|
|
699
702
|
|
|
700
703
|
if (actionName === 'list_running' || actionName === 'list_targets') {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
import { tool, type StructuredToolInterface } from '@langchain/core/tools'
|
|
3
3
|
import { HumanMessage } from '@langchain/core/messages'
|
|
4
|
-
import { loadSessions, saveSessions } from '../storage'
|
|
5
4
|
import { buildChatModel } from '../build-llm'
|
|
6
5
|
import type { ToolBuildContext } from './context'
|
|
7
6
|
import type { Extension, ExtensionHooks, Session } from '@/types'
|
|
8
7
|
import { registerNativeCapability } from '../native-capabilities'
|
|
9
8
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
10
9
|
import { errorMessage } from '@/lib/shared-utils'
|
|
10
|
+
import { updateSessionRunContext } from '@/lib/server/run-context'
|
|
11
|
+
import { getMessages, replaceAllMessages } from '@/lib/server/messages/message-repository'
|
|
11
12
|
|
|
12
13
|
interface ContextToolContext {
|
|
13
14
|
ctx?: { agentId?: string | null; sessionId?: string | null }
|
|
@@ -22,7 +23,7 @@ async function executeContextStatus(bctx: ContextToolContext) {
|
|
|
22
23
|
const { getContextStatus } = await import('../context-manager')
|
|
23
24
|
const session = bctx.resolveCurrentSession?.()
|
|
24
25
|
if (!session) return 'Error: no current session context.'
|
|
25
|
-
const status = getContextStatus(session.
|
|
26
|
+
const status = getContextStatus(getMessages(session.id), 2000, session.provider as string, session.model as string, {
|
|
26
27
|
includeToolEvents: false,
|
|
27
28
|
})
|
|
28
29
|
return JSON.stringify(status)
|
|
@@ -36,7 +37,7 @@ async function executeContextSummarize(args: { keepLastN?: number }, bctx: Conte
|
|
|
36
37
|
const session = bctx.resolveCurrentSession?.()
|
|
37
38
|
if (!session || !bctx.ctx?.sessionId) return 'Error: no session context.'
|
|
38
39
|
|
|
39
|
-
const messages = session.
|
|
40
|
+
const messages = getMessages(session.id)
|
|
40
41
|
const keepLastN = normalized.keepLastN as number | undefined
|
|
41
42
|
const keep = Math.max(2, Math.min(keepLastN || 10, messages.length))
|
|
42
43
|
if (messages.length <= keep) return JSON.stringify({ status: 'no_action' })
|
|
@@ -58,15 +59,39 @@ async function executeContextSummarize(args: { keepLastN?: number }, bctx: Conte
|
|
|
58
59
|
provider: session.provider, model: session.model, generateSummary
|
|
59
60
|
})
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
if (sessions[bctx.ctx.sessionId]) {
|
|
63
|
-
sessions[bctx.ctx.sessionId].messages = result.messages
|
|
64
|
-
saveSessions(sessions)
|
|
65
|
-
}
|
|
62
|
+
replaceAllMessages(bctx.ctx.sessionId ?? '', result.messages)
|
|
66
63
|
return JSON.stringify({ status: 'compacted', remaining: result.messages.length })
|
|
67
64
|
} catch (err: unknown) { return `Error: ${errorMessage(err)}` }
|
|
68
65
|
}
|
|
69
66
|
|
|
67
|
+
const PIN_CONTEXT_TYPE_MAP: Record<string, 'keyFacts' | 'failedApproaches' | 'blockers' | 'discoveries'> = {
|
|
68
|
+
fact: 'keyFacts',
|
|
69
|
+
failed_approach: 'failedApproaches',
|
|
70
|
+
blocker: 'blockers',
|
|
71
|
+
discovery: 'discoveries',
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function executePinContext(
|
|
75
|
+
args: { type?: string; content?: string },
|
|
76
|
+
bctx: ContextToolContext,
|
|
77
|
+
) {
|
|
78
|
+
try {
|
|
79
|
+
const normalized = normalizeToolInputArgs((args ?? {}) as Record<string, unknown>)
|
|
80
|
+
const type = String(normalized.type || '').toLowerCase()
|
|
81
|
+
const content = String(normalized.content || '').slice(0, 300).trim()
|
|
82
|
+
if (!content) return 'Error: content is required.'
|
|
83
|
+
const field = PIN_CONTEXT_TYPE_MAP[type]
|
|
84
|
+
if (!field) return `Error: type must be one of: ${Object.keys(PIN_CONTEXT_TYPE_MAP).join(', ')}`
|
|
85
|
+
const sessionId = bctx.ctx?.sessionId
|
|
86
|
+
if (!sessionId) return 'Error: no session context.'
|
|
87
|
+
updateSessionRunContext(sessionId, (ctx) => {
|
|
88
|
+
ctx[field] = [...ctx[field], content]
|
|
89
|
+
return ctx
|
|
90
|
+
})
|
|
91
|
+
return JSON.stringify({ status: 'pinned', type, field })
|
|
92
|
+
} catch (err: unknown) { return `Error: ${errorMessage(err)}` }
|
|
93
|
+
}
|
|
94
|
+
|
|
70
95
|
/**
|
|
71
96
|
* Register as a Built-in Extension
|
|
72
97
|
*/
|
|
@@ -89,6 +114,19 @@ const ContextExtension: Extension = {
|
|
|
89
114
|
properties: { keepLastN: { type: 'number' } }
|
|
90
115
|
},
|
|
91
116
|
execute: async (args, context) => executeContextSummarize(args as { keepLastN?: number }, { ctx: { sessionId: context.session.id, agentId: context.session.agentId ?? null }, resolveCurrentSession: () => context.session as unknown as Session })
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'pin_context',
|
|
120
|
+
description: 'Pin a fact, failed approach, blocker, or discovery to working memory so it survives context compaction and flows to subagents.',
|
|
121
|
+
parameters: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
type: { type: 'string', enum: ['fact', 'failed_approach', 'blocker', 'discovery'], description: 'What kind of context to pin.' },
|
|
125
|
+
content: { type: 'string', description: 'The content to pin (max 300 chars).' },
|
|
126
|
+
},
|
|
127
|
+
required: ['type', 'content'],
|
|
128
|
+
},
|
|
129
|
+
execute: async (args, context) => executePinContext(args as { type?: string; content?: string }, { ctx: { sessionId: context.session.id, agentId: context.session.agentId ?? null }, resolveCurrentSession: () => context.session as unknown as Session })
|
|
92
130
|
}
|
|
93
131
|
]
|
|
94
132
|
}
|
|
@@ -107,6 +145,17 @@ export function buildContextTools(bctx: ToolBuildContext): StructuredToolInterfa
|
|
|
107
145
|
tool(
|
|
108
146
|
async (args) => executeContextSummarize(args as { keepLastN?: number }, bctx),
|
|
109
147
|
{ name: 'context_summarize', description: ContextExtension.tools![1].description, schema: z.object({}).passthrough() }
|
|
110
|
-
)
|
|
148
|
+
),
|
|
149
|
+
tool(
|
|
150
|
+
async (args) => executePinContext(args as { type?: string; content?: string }, bctx),
|
|
151
|
+
{
|
|
152
|
+
name: 'pin_context',
|
|
153
|
+
description: ContextExtension.tools![2].description,
|
|
154
|
+
schema: z.object({
|
|
155
|
+
type: z.enum(['fact', 'failed_approach', 'blocker', 'discovery']).describe('What kind of context to pin.'),
|
|
156
|
+
content: z.string().describe('The content to pin (max 300 chars).'),
|
|
157
|
+
}),
|
|
158
|
+
}
|
|
159
|
+
),
|
|
111
160
|
]
|
|
112
161
|
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
encryptKey,
|
|
16
16
|
decryptKey,
|
|
17
17
|
} from '../storage'
|
|
18
|
+
import { getMessages } from '@/lib/server/messages/message-repository'
|
|
18
19
|
import { resolveScheduleName } from '@/lib/schedules/schedule-name'
|
|
19
20
|
import type { ScheduleLike } from '@/lib/schedules/schedule-dedupe'
|
|
20
21
|
import {
|
|
@@ -38,6 +39,12 @@ import {
|
|
|
38
39
|
prepareTaskCreation,
|
|
39
40
|
} from '@/lib/server/tasks/task-service'
|
|
40
41
|
import { ensureMissionForTask, enrichTaskWithMissionSummary } from '@/lib/server/missions/mission-service'
|
|
42
|
+
import { classifyMessage } from '@/lib/server/chat-execution/message-classifier'
|
|
43
|
+
import {
|
|
44
|
+
buildDelegationTaskProfile,
|
|
45
|
+
formatDelegationRationale,
|
|
46
|
+
resolveDelegationAdvisory,
|
|
47
|
+
} from '@/lib/server/agents/delegation-advisory'
|
|
41
48
|
import type { ToolBuildContext } from './context'
|
|
42
49
|
import { normalizeToolInputArgs } from './normalize-tool-args'
|
|
43
50
|
import type { BoardTask } from '@/types'
|
|
@@ -76,6 +83,99 @@ function findDuplicateManagedAgent(
|
|
|
76
83
|
return null
|
|
77
84
|
}
|
|
78
85
|
|
|
86
|
+
function normalizeStringList(value: unknown): string[] {
|
|
87
|
+
if (!Array.isArray(value)) return []
|
|
88
|
+
const seen = new Set<string>()
|
|
89
|
+
const out: string[] = []
|
|
90
|
+
for (const entry of value) {
|
|
91
|
+
const trimmed = typeof entry === 'string' ? entry.trim() : ''
|
|
92
|
+
const key = trimmed.toLowerCase()
|
|
93
|
+
if (!trimmed || seen.has(key)) continue
|
|
94
|
+
seen.add(key)
|
|
95
|
+
out.push(trimmed)
|
|
96
|
+
}
|
|
97
|
+
return out
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function buildTaskDelegationText(parsed: Record<string, unknown>): string {
|
|
101
|
+
const title = typeof parsed.title === 'string' ? parsed.title.trim() : ''
|
|
102
|
+
const description = typeof parsed.description === 'string' ? parsed.description.trim() : ''
|
|
103
|
+
return [title, description].filter(Boolean).join('\n\n').trim()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function resolveManagedTaskDelegation(params: {
|
|
107
|
+
parsed: Record<string, unknown>
|
|
108
|
+
agents: ReturnType<typeof loadAgents>
|
|
109
|
+
ctx?: ToolBuildContext['ctx']
|
|
110
|
+
assignedAgentId: string | null
|
|
111
|
+
explicitAssignment: boolean
|
|
112
|
+
allowAutoAssignment: boolean
|
|
113
|
+
}): Promise<{
|
|
114
|
+
assignedAgentId: string | null
|
|
115
|
+
advisory: Record<string, unknown> | null
|
|
116
|
+
}> {
|
|
117
|
+
const currentAgentId = typeof params.ctx?.agentId === 'string' ? params.ctx.agentId.trim() : ''
|
|
118
|
+
if (!currentAgentId || params.ctx?.delegationEnabled !== true) {
|
|
119
|
+
return { assignedAgentId: params.assignedAgentId, advisory: null }
|
|
120
|
+
}
|
|
121
|
+
const currentAgent = params.agents[currentAgentId]
|
|
122
|
+
if (!currentAgent) {
|
|
123
|
+
return { assignedAgentId: params.assignedAgentId, advisory: null }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const explicitCapabilities = normalizeStringList(params.parsed.requiredCapabilities)
|
|
127
|
+
const classificationText = buildTaskDelegationText(params.parsed)
|
|
128
|
+
const classification = (!explicitCapabilities.length && classificationText && params.ctx?.sessionId)
|
|
129
|
+
? await classifyMessage({
|
|
130
|
+
sessionId: params.ctx.sessionId,
|
|
131
|
+
agentId: currentAgentId,
|
|
132
|
+
message: classificationText,
|
|
133
|
+
}).catch(() => null)
|
|
134
|
+
: null
|
|
135
|
+
|
|
136
|
+
const profile = buildDelegationTaskProfile({
|
|
137
|
+
classification,
|
|
138
|
+
requiredCapabilities: explicitCapabilities,
|
|
139
|
+
})
|
|
140
|
+
if (!profile.substantial) {
|
|
141
|
+
return { assignedAgentId: params.assignedAgentId, advisory: null }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const delegationAdvisory = resolveDelegationAdvisory({
|
|
145
|
+
currentAgent,
|
|
146
|
+
agents: params.agents,
|
|
147
|
+
profile,
|
|
148
|
+
delegationTargetMode: params.ctx?.delegationTargetMode === 'selected' ? 'selected' : 'all',
|
|
149
|
+
delegationTargetAgentIds: params.ctx?.delegationTargetAgentIds || [],
|
|
150
|
+
})
|
|
151
|
+
const recommended = delegationAdvisory.recommended
|
|
152
|
+
if (!delegationAdvisory.shouldDelegate || !recommended) {
|
|
153
|
+
return { assignedAgentId: params.assignedAgentId, advisory: null }
|
|
154
|
+
}
|
|
155
|
+
if (params.explicitAssignment && params.assignedAgentId === recommended.agentId) {
|
|
156
|
+
return { assignedAgentId: params.assignedAgentId, advisory: null }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let assignedAgentId = params.assignedAgentId
|
|
160
|
+
let autoAssigned = false
|
|
161
|
+
if (!params.explicitAssignment && params.allowAutoAssignment) {
|
|
162
|
+
assignedAgentId = recommended.agentId
|
|
163
|
+
autoAssigned = true
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
assignedAgentId,
|
|
168
|
+
advisory: {
|
|
169
|
+
recommendedAgentId: recommended.agentId,
|
|
170
|
+
recommendedAgentName: recommended.agentName,
|
|
171
|
+
rationale: formatDelegationRationale(recommended),
|
|
172
|
+
workType: profile.workType,
|
|
173
|
+
requiredCapabilities: profile.requiredCapabilities,
|
|
174
|
+
autoAssigned,
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
79
179
|
const VALID_CONNECTOR_PLATFORMS = new Set([
|
|
80
180
|
'discord',
|
|
81
181
|
'telegram',
|
|
@@ -208,7 +308,7 @@ function deriveScheduleFollowupTarget(sessionId: string | null | undefined): {
|
|
|
208
308
|
|
|
209
309
|
if (isMainSession(session)) return {}
|
|
210
310
|
|
|
211
|
-
const messages =
|
|
311
|
+
const messages = getMessages(normalizedSessionId)
|
|
212
312
|
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
213
313
|
const message = messages[i]
|
|
214
314
|
if ((typeof message?.role === 'string' ? message.role : '') !== 'user') continue
|
|
@@ -365,6 +465,9 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
365
465
|
description += `\n\nYou may create tasks for yourself, leave them unassigned, or delegate them to other agents. Your agent ID is "${ctx?.agentId || 'unknown'}". When delegating, set a target agent using "agentId", "assignee", "agent", "assignedAgentId", or "assigned_agent_id". Use the target agent's exact ID when possible. Valid manual statuses: backlog, queued, completed, failed, archived. "running" is runtime-only and set automatically when execution starts.` + agentSummary
|
|
366
466
|
}
|
|
367
467
|
description += '\n\nCreate/update calls accept either `data` as a JSON string or direct top-level fields like `title`, `description`, `status`, `agentId`, and `projectId`.'
|
|
468
|
+
if (canAssignOtherAgents) {
|
|
469
|
+
description += '\n\nWhen you omit an assignee, the runtime may auto-assign the task to a materially better-fit teammate based on `requiredCapabilities` or the classified work type. If you set an explicit assignee, it is respected in v1, but the response may include `delegationAdvisory` when another teammate is a better fit.'
|
|
470
|
+
}
|
|
368
471
|
description += '\n\nFor follow-up work, set `continueFromTaskId` (or `followUpToTaskId`) to a prior task ID. The new task will inherit the predecessor\'s project/agent/session context, block on that task by default, and reuse its execution session when possible.'
|
|
369
472
|
if (ctx?.projectId) {
|
|
370
473
|
description += `\n\nCurrent project context: "${ctx.projectName || ctx.projectId}" (projectId "${ctx.projectId}"). Omit "projectId" to use this active project by default.`
|
|
@@ -492,6 +595,7 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
492
595
|
if ((toolKey === 'manage_tasks' || toolKey === 'manage_schedules' || toolKey === 'manage_secrets') && !Object.prototype.hasOwnProperty.call(parsed, 'projectId') && ctx?.projectId) {
|
|
493
596
|
parsed.projectId = ctx.projectId
|
|
494
597
|
}
|
|
598
|
+
let taskDelegationAdvisory: Record<string, unknown> | null = null
|
|
495
599
|
if (toolKey === 'manage_tasks' || toolKey === 'manage_schedules') {
|
|
496
600
|
const agents = loadAgents()
|
|
497
601
|
const resolution = resolveManagedAgentAssignment(
|
|
@@ -502,12 +606,12 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
502
606
|
: null,
|
|
503
607
|
{ allowDescription: toolKey === 'manage_tasks' },
|
|
504
608
|
)
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
609
|
+
const assignmentError = validateManagedAgentAssignment({
|
|
610
|
+
resourceLabel: res.label,
|
|
611
|
+
agents,
|
|
612
|
+
assignScope: canAssignOtherAgents ? 'all' : 'self',
|
|
613
|
+
currentAgentId: ctx?.agentId || null,
|
|
614
|
+
targetAgentId: resolution.agentId,
|
|
511
615
|
unresolvedReference: resolution.unresolvedReference,
|
|
512
616
|
isDelegation: toolKey === 'manage_tasks' ? isDelegationTaskPayload(parsed as Record<string, unknown>) : false,
|
|
513
617
|
delegatorAgentId: toolKey === 'manage_tasks'
|
|
@@ -516,6 +620,18 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
516
620
|
})
|
|
517
621
|
if (assignmentError) return assignmentError
|
|
518
622
|
parsed.agentId = resolution.agentId
|
|
623
|
+
if (toolKey === 'manage_tasks') {
|
|
624
|
+
const delegated = await resolveManagedTaskDelegation({
|
|
625
|
+
parsed: parsed as Record<string, unknown>,
|
|
626
|
+
agents,
|
|
627
|
+
ctx,
|
|
628
|
+
assignedAgentId: resolution.agentId,
|
|
629
|
+
explicitAssignment: resolution.source === 'explicit',
|
|
630
|
+
allowAutoAssignment: true,
|
|
631
|
+
})
|
|
632
|
+
parsed.agentId = delegated.assignedAgentId
|
|
633
|
+
taskDelegationAdvisory = delegated.advisory
|
|
634
|
+
}
|
|
519
635
|
}
|
|
520
636
|
let preparedManagedTask: BoardTask | null = null
|
|
521
637
|
let preparedManagedSchedule: any = null
|
|
@@ -639,6 +755,12 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
639
755
|
missionId: mission.id,
|
|
640
756
|
})
|
|
641
757
|
}
|
|
758
|
+
if (taskDelegationAdvisory && responseEntry && typeof responseEntry === 'object') {
|
|
759
|
+
responseEntry = {
|
|
760
|
+
...(responseEntry as Record<string, unknown>),
|
|
761
|
+
delegationAdvisory: taskDelegationAdvisory,
|
|
762
|
+
}
|
|
763
|
+
}
|
|
642
764
|
}
|
|
643
765
|
if (toolKey === 'manage_tasks' && entry.status === 'queued') {
|
|
644
766
|
const { enqueueTask } = await import('@/lib/server/runtime/queue')
|
|
@@ -675,6 +797,7 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
675
797
|
if (continuationError) return continuationError
|
|
676
798
|
}
|
|
677
799
|
const prevStatus = all[effectiveId]?.status
|
|
800
|
+
let taskDelegationAdvisory: Record<string, unknown> | null = null
|
|
678
801
|
const managedAgents = toolKey === 'manage_tasks' || toolKey === 'manage_schedules'
|
|
679
802
|
? loadAgents()
|
|
680
803
|
: null
|
|
@@ -682,6 +805,10 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
682
805
|
const requestedClear = Object.prototype.hasOwnProperty.call(parsedRecord, 'agentId') && parsedRecord.agentId == null
|
|
683
806
|
const shouldResolveAssignment = requestedClear
|
|
684
807
|
|| hasManagedAgentAssignmentInput(parsedRecord)
|
|
808
|
+
let resolvedAgentId: string | null = requestedClear
|
|
809
|
+
? null
|
|
810
|
+
: (typeof all[effectiveId]?.agentId === 'string' ? all[effectiveId].agentId : null)
|
|
811
|
+
let explicitAssignment = false
|
|
685
812
|
if (shouldResolveAssignment) {
|
|
686
813
|
const resolution = resolveManagedAgentAssignment(
|
|
687
814
|
parsedRecord,
|
|
@@ -689,18 +816,20 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
689
816
|
null,
|
|
690
817
|
{ allowDescription: false },
|
|
691
818
|
)
|
|
819
|
+
resolvedAgentId = requestedClear ? null : resolution.agentId
|
|
820
|
+
explicitAssignment = resolution.hadExplicitInput
|
|
692
821
|
const assignmentError = validateManagedAgentAssignment({
|
|
693
822
|
resourceLabel: res.label,
|
|
694
823
|
agents: managedAgents,
|
|
695
824
|
assignScope: canAssignOtherAgents ? 'all' : 'self',
|
|
696
825
|
currentAgentId: ctx?.agentId || null,
|
|
697
|
-
targetAgentId:
|
|
826
|
+
targetAgentId: resolvedAgentId,
|
|
698
827
|
unresolvedReference: requestedClear ? null : resolution.unresolvedReference,
|
|
699
828
|
isDelegation: toolKey === 'manage_tasks'
|
|
700
829
|
? isDelegationTaskPayload({
|
|
701
830
|
...all[effectiveId],
|
|
702
831
|
...parsedRecord,
|
|
703
|
-
agentId:
|
|
832
|
+
agentId: resolvedAgentId,
|
|
704
833
|
} as Record<string, unknown>)
|
|
705
834
|
: false,
|
|
706
835
|
delegatorAgentId: toolKey === 'manage_tasks'
|
|
@@ -711,7 +840,24 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
711
840
|
: null,
|
|
712
841
|
})
|
|
713
842
|
if (assignmentError) return assignmentError
|
|
714
|
-
if (!requestedClear) parsedRecord.agentId =
|
|
843
|
+
if (!requestedClear) parsedRecord.agentId = resolvedAgentId
|
|
844
|
+
}
|
|
845
|
+
if (toolKey === 'manage_tasks') {
|
|
846
|
+
const delegated = await resolveManagedTaskDelegation({
|
|
847
|
+
parsed: {
|
|
848
|
+
...all[effectiveId],
|
|
849
|
+
...parsedRecord,
|
|
850
|
+
},
|
|
851
|
+
agents: managedAgents,
|
|
852
|
+
ctx,
|
|
853
|
+
assignedAgentId: resolvedAgentId,
|
|
854
|
+
explicitAssignment,
|
|
855
|
+
allowAutoAssignment: !resolvedAgentId || resolvedAgentId === ctx?.agentId,
|
|
856
|
+
})
|
|
857
|
+
if (delegated.assignedAgentId !== resolvedAgentId) {
|
|
858
|
+
parsedRecord.agentId = delegated.assignedAgentId
|
|
859
|
+
}
|
|
860
|
+
taskDelegationAdvisory = delegated.advisory
|
|
715
861
|
}
|
|
716
862
|
}
|
|
717
863
|
if (toolKey === 'manage_schedules') {
|
|
@@ -797,6 +943,12 @@ export function buildCrudTools(bctx: ToolBuildContext): StructuredToolInterface[
|
|
|
797
943
|
if (toolKey === 'manage_projects') {
|
|
798
944
|
return JSON.stringify(buildProjectSnapshot(all[effectiveId]))
|
|
799
945
|
}
|
|
946
|
+
if (toolKey === 'manage_tasks' && taskDelegationAdvisory) {
|
|
947
|
+
return JSON.stringify({
|
|
948
|
+
...(all[effectiveId] as Record<string, unknown>),
|
|
949
|
+
delegationAdvisory: taskDelegationAdvisory,
|
|
950
|
+
})
|
|
951
|
+
}
|
|
800
952
|
if (toolKey === 'manage_schedules' && affectedScheduleIds?.length) {
|
|
801
953
|
return JSON.stringify({
|
|
802
954
|
...all[effectiveId],
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
registerDelegationRuntime,
|
|
22
22
|
startDelegationJob,
|
|
23
23
|
} from '@/lib/server/agents/delegation-jobs'
|
|
24
|
-
import { loadSession } from '@/lib/server/
|
|
24
|
+
import { loadSession } from '@/lib/server/sessions/session-repository'
|
|
25
25
|
import { markProviderFailure, markProviderSuccess } from '../provider-health'
|
|
26
26
|
import { loadRuntimeSettings } from '../runtime/runtime-settings'
|
|
27
27
|
import { getSessionDepth } from '../agents/subagent-runtime'
|