@swarmclawai/swarmclaw 1.2.1 → 1.2.3

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.
Files changed (149) hide show
  1. package/README.md +16 -85
  2. package/bin/server-cmd.js +64 -1
  3. package/package.json +2 -2
  4. package/skills/coding-agent/SKILL.md +111 -0
  5. package/skills/github/SKILL.md +140 -0
  6. package/skills/nano-banana-pro/SKILL.md +62 -0
  7. package/skills/nano-banana-pro/scripts/generate_image.py +235 -0
  8. package/skills/nano-pdf/SKILL.md +53 -0
  9. package/skills/openai-image-gen/SKILL.md +78 -0
  10. package/skills/openai-image-gen/scripts/gen.py +328 -0
  11. package/skills/resourceful-problem-solving/SKILL.md +49 -0
  12. package/skills/skill-creator/SKILL.md +147 -0
  13. package/skills/skill-creator/scripts/init_skill.py +378 -0
  14. package/skills/skill-creator/scripts/quick_validate.py +159 -0
  15. package/skills/summarize/SKILL.md +77 -0
  16. package/src/app/api/auth/route.ts +20 -5
  17. package/src/app/api/chats/[id]/devserver/route.ts +13 -19
  18. package/src/app/api/chats/[id]/messages/route.ts +13 -15
  19. package/src/app/api/chats/[id]/route.ts +9 -10
  20. package/src/app/api/chats/[id]/stop/route.ts +5 -7
  21. package/src/app/api/chats/messages-route.test.ts +8 -6
  22. package/src/app/api/chats/route.ts +9 -10
  23. package/src/app/api/ip/route.ts +2 -2
  24. package/src/app/api/preview-server/route.ts +1 -1
  25. package/src/app/api/projects/[id]/route.ts +7 -46
  26. package/src/cli/server-cmd.test.js +74 -0
  27. package/src/components/chat/chat-area.tsx +45 -23
  28. package/src/components/chat/message-bubble.test.ts +35 -0
  29. package/src/components/chat/message-bubble.tsx +19 -9
  30. package/src/components/chat/message-list.tsx +37 -3
  31. package/src/components/input/chat-input.tsx +34 -14
  32. package/src/components/openclaw/openclaw-deploy-panel.tsx +4 -0
  33. package/src/instrumentation.ts +1 -1
  34. package/src/lib/chat/assistant-render-id.ts +3 -0
  35. package/src/lib/chat/chat-streaming-state.test.ts +42 -3
  36. package/src/lib/chat/chat-streaming-state.ts +20 -8
  37. package/src/lib/chat/queued-message-queue.test.ts +23 -1
  38. package/src/lib/chat/queued-message-queue.ts +11 -2
  39. package/src/lib/providers/cli-utils.test.ts +124 -0
  40. package/src/lib/server/activity/activity-log.ts +21 -0
  41. package/src/lib/server/agents/agent-availability.test.ts +10 -5
  42. package/src/lib/server/agents/agent-cascade.ts +79 -59
  43. package/src/lib/server/agents/agent-registry.ts +3 -1
  44. package/src/lib/server/agents/agent-repository.ts +90 -0
  45. package/src/lib/server/agents/delegation-job-repository.ts +53 -0
  46. package/src/lib/server/agents/delegation-jobs.ts +11 -4
  47. package/src/lib/server/agents/guardian-checkpoint-repository.ts +35 -0
  48. package/src/lib/server/agents/guardian.ts +2 -2
  49. package/src/lib/server/agents/main-agent-loop.ts +10 -3
  50. package/src/lib/server/agents/main-loop-state-repository.ts +38 -0
  51. package/src/lib/server/agents/subagent-runtime.ts +9 -6
  52. package/src/lib/server/agents/subagent-swarm.ts +3 -2
  53. package/src/lib/server/agents/task-session.ts +3 -4
  54. package/src/lib/server/approvals/approval-repository.ts +30 -0
  55. package/src/lib/server/autonomy/supervisor-incident-repository.ts +42 -0
  56. package/src/lib/server/chat-execution/chat-execution-types.ts +38 -0
  57. package/src/lib/server/chat-execution/chat-execution-utils.ts +1 -1
  58. package/src/lib/server/chat-execution/chat-execution.ts +84 -1926
  59. package/src/lib/server/chat-execution/chat-turn-finalization.ts +620 -0
  60. package/src/lib/server/chat-execution/chat-turn-partial-persistence.ts +221 -0
  61. package/src/lib/server/chat-execution/chat-turn-preflight.ts +133 -0
  62. package/src/lib/server/chat-execution/chat-turn-preparation.ts +817 -0
  63. package/src/lib/server/chat-execution/chat-turn-stream-execution.ts +296 -0
  64. package/src/lib/server/chat-execution/chat-turn-tool-routing.ts +5 -5
  65. package/src/lib/server/chat-execution/message-classifier.test.ts +329 -0
  66. package/src/lib/server/chat-execution/post-stream-finalization.ts +1 -1
  67. package/src/lib/server/chat-execution/prompt-builder.ts +11 -0
  68. package/src/lib/server/chat-execution/prompt-sections.ts +5 -6
  69. package/src/lib/server/chat-execution/situational-awareness.ts +12 -7
  70. package/src/lib/server/chat-execution/stream-agent-chat.ts +16 -13
  71. package/src/lib/server/chatrooms/chatroom-repository.ts +32 -0
  72. package/src/lib/server/connectors/connector-repository.ts +58 -0
  73. package/src/lib/server/connectors/runtime-state.test.ts +117 -0
  74. package/src/lib/server/credentials/credential-repository.ts +7 -0
  75. package/src/lib/server/gateways/gateway-profile-repository.ts +4 -0
  76. package/src/lib/server/memory/memory-abstract.test.ts +59 -0
  77. package/src/lib/server/missions/mission-repository.ts +74 -0
  78. package/src/lib/server/missions/mission-service/actions.ts +6 -0
  79. package/src/lib/server/missions/mission-service/bindings.ts +9 -0
  80. package/src/lib/server/missions/mission-service/context.ts +4 -0
  81. package/src/lib/server/missions/mission-service/core.ts +2269 -0
  82. package/src/lib/server/missions/mission-service/queries.ts +12 -0
  83. package/src/lib/server/missions/mission-service/recovery.ts +5 -0
  84. package/src/lib/server/missions/mission-service/ticks.ts +9 -0
  85. package/src/lib/server/missions/mission-service.test.ts +9 -2
  86. package/src/lib/server/missions/mission-service.ts +6 -2266
  87. package/src/lib/server/openclaw/deploy.test.ts +42 -3
  88. package/src/lib/server/openclaw/deploy.ts +26 -12
  89. package/src/lib/server/persistence/repository-utils.ts +154 -0
  90. package/src/lib/server/persistence/storage-context.ts +51 -0
  91. package/src/lib/server/persistence/transaction.ts +1 -0
  92. package/src/lib/server/projects/project-repository.ts +36 -0
  93. package/src/lib/server/projects/project-service.ts +79 -0
  94. package/src/lib/server/protocols/protocol-normalization.test.ts +6 -4
  95. package/src/lib/server/runtime/alert-dispatch.ts +1 -1
  96. package/src/lib/server/runtime/daemon-policy.ts +1 -1
  97. package/src/lib/server/runtime/daemon-state/core.ts +1570 -0
  98. package/src/lib/server/runtime/daemon-state/health.ts +6 -0
  99. package/src/lib/server/runtime/daemon-state/policy.ts +7 -0
  100. package/src/lib/server/runtime/daemon-state/supervisor.ts +6 -0
  101. package/src/lib/server/runtime/daemon-state.test.ts +48 -0
  102. package/src/lib/server/runtime/daemon-state.ts +3 -1470
  103. package/src/lib/server/runtime/estop-repository.ts +4 -0
  104. package/src/lib/server/runtime/estop.ts +3 -1
  105. package/src/lib/server/runtime/heartbeat-service.test.ts +2 -2
  106. package/src/lib/server/runtime/heartbeat-service.ts +55 -34
  107. package/src/lib/server/runtime/heartbeat-wake.ts +6 -4
  108. package/src/lib/server/runtime/idle-window.ts +2 -2
  109. package/src/lib/server/runtime/network.ts +11 -0
  110. package/src/lib/server/runtime/orchestrator-events.ts +2 -2
  111. package/src/lib/server/runtime/queue/claims.ts +4 -0
  112. package/src/lib/server/runtime/queue/core.ts +2079 -0
  113. package/src/lib/server/runtime/queue/execution.ts +7 -0
  114. package/src/lib/server/runtime/queue/followups.ts +4 -0
  115. package/src/lib/server/runtime/queue/queries.ts +12 -0
  116. package/src/lib/server/runtime/queue/recovery.ts +7 -0
  117. package/src/lib/server/runtime/queue-recovery.test.ts +48 -13
  118. package/src/lib/server/runtime/queue-repository.ts +17 -0
  119. package/src/lib/server/runtime/queue.ts +5 -2061
  120. package/src/lib/server/runtime/run-ledger.ts +6 -5
  121. package/src/lib/server/runtime/run-repository.ts +73 -0
  122. package/src/lib/server/runtime/runtime-lock-repository.ts +8 -0
  123. package/src/lib/server/runtime/runtime-settings.ts +1 -1
  124. package/src/lib/server/runtime/runtime-state.ts +99 -0
  125. package/src/lib/server/runtime/scheduler.ts +4 -2
  126. package/src/lib/server/runtime/session-run-manager/cancellation.ts +157 -0
  127. package/src/lib/server/runtime/session-run-manager/drain.ts +246 -0
  128. package/src/lib/server/runtime/session-run-manager/enqueue.ts +287 -0
  129. package/src/lib/server/runtime/session-run-manager/queries.ts +117 -0
  130. package/src/lib/server/runtime/session-run-manager/recovery.ts +238 -0
  131. package/src/lib/server/runtime/session-run-manager/state.ts +441 -0
  132. package/src/lib/server/runtime/session-run-manager/types.ts +74 -0
  133. package/src/lib/server/runtime/session-run-manager.ts +72 -1377
  134. package/src/lib/server/runtime/watch-job-repository.ts +35 -0
  135. package/src/lib/server/runtime/watch-jobs.ts +3 -1
  136. package/src/lib/server/schedules/schedule-repository.ts +42 -0
  137. package/src/lib/server/sessions/session-repository.ts +85 -0
  138. package/src/lib/server/settings/settings-repository.ts +25 -0
  139. package/src/lib/server/skills/skill-discovery.test.ts +2 -2
  140. package/src/lib/server/skills/skill-discovery.ts +2 -2
  141. package/src/lib/server/skills/skill-repository.ts +14 -0
  142. package/src/lib/server/storage.ts +13 -24
  143. package/src/lib/server/tasks/task-repository.ts +54 -0
  144. package/src/lib/server/usage/usage-repository.ts +30 -0
  145. package/src/lib/server/webhooks/webhook-repository.ts +10 -0
  146. package/src/lib/strip-internal-metadata.test.ts +42 -41
  147. package/src/stores/use-chat-store.test.ts +54 -0
  148. package/src/stores/use-chat-store.ts +21 -5
  149. /package/{bundled-skills → skills}/google-workspace/SKILL.md +0 -0
@@ -0,0 +1,221 @@
1
+ import {
2
+ getSession,
3
+ saveSession,
4
+ } from '@/lib/server/sessions/session-repository'
5
+ import { notify } from '@/lib/server/ws-hub'
6
+ import type { MessageToolEvent, SSEEvent } from '@/types'
7
+ import { upsertStreamingAssistantArtifact } from '@/lib/chat/chat-streaming-state'
8
+ import { pruneIncompleteToolEvents } from '@/lib/server/chat-execution/chat-streaming-utils'
9
+ import {
10
+ collectToolEvent,
11
+ dedupeConsecutiveToolEvents,
12
+ extractEventJson,
13
+ } from '@/lib/server/chat-execution/chat-execution-tool-events'
14
+ import {
15
+ getToolEventsSnapshotKey,
16
+ hasPersistableAssistantPayload,
17
+ } from '@/lib/server/chat-execution/chat-execution-utils'
18
+ import {
19
+ applyMessageLifecycleHooks,
20
+ type PreparedExecutableChatTurn,
21
+ } from '@/lib/server/chat-execution/chat-turn-preparation'
22
+
23
+ export interface PartialAssistantSnapshot {
24
+ thinkingText: string
25
+ toolEvents: MessageToolEvent[]
26
+ streamErrors: string[]
27
+ accumulatedUsage: {
28
+ inputTokens: number
29
+ outputTokens: number
30
+ estimatedCost: number
31
+ }
32
+ }
33
+
34
+ export interface PartialAssistantPersistence {
35
+ emit: (event: SSEEvent) => void
36
+ parseAndEmit: (raw: string) => void
37
+ stop: () => void
38
+ awaitIdle: () => Promise<void>
39
+ getToolEvents: () => MessageToolEvent[]
40
+ getSnapshot: () => PartialAssistantSnapshot
41
+ }
42
+
43
+ const PARTIAL_SAVE_INTERVAL_MS = 3500
44
+ const PARTIAL_SAVE_MIN_INTERVAL_MS = 400
45
+
46
+ export function createPartialAssistantPersistence(input: {
47
+ prepared: PreparedExecutableChatTurn
48
+ onEvent?: (event: SSEEvent) => void
49
+ }): PartialAssistantPersistence {
50
+ const { prepared, onEvent } = input
51
+ const toolEvents: MessageToolEvent[] = []
52
+ const streamErrors: string[] = []
53
+ const accumulatedUsage = { inputTokens: 0, outputTokens: 0, estimatedCost: 0 }
54
+
55
+ let thinkingText = ''
56
+ let streamingPartialText = ''
57
+ let lastPartialSaveAt = 0
58
+ let lastPartialSnapshotKey = ''
59
+ let partialSaveTimeout: ReturnType<typeof setTimeout> | null = null
60
+ let partialPersistenceClosed = false
61
+ let partialPersistChain: Promise<void> = Promise.resolve()
62
+
63
+ const persistStreamingAssistantArtifact = async () => {
64
+ if (prepared.hideAssistantTranscript) return
65
+ partialSaveTimeout = null
66
+ if (partialPersistenceClosed) return
67
+ const persistedToolEvents = toolEvents.length
68
+ ? dedupeConsecutiveToolEvents(pruneIncompleteToolEvents([...toolEvents]))
69
+ : []
70
+ if (!hasPersistableAssistantPayload(streamingPartialText, thinkingText, persistedToolEvents)) return
71
+
72
+ try {
73
+ const current = getSession(prepared.sessionId)
74
+ if (!current) return
75
+ current.messages = Array.isArray(current.messages) ? current.messages : []
76
+ const partialMsg = await applyMessageLifecycleHooks({
77
+ session: current,
78
+ message: {
79
+ role: 'assistant',
80
+ text: streamingPartialText,
81
+ time: Date.now(),
82
+ streaming: true,
83
+ runId: prepared.lifecycleRunId,
84
+ thinking: thinkingText || undefined,
85
+ toolEvents: persistedToolEvents.length ? persistedToolEvents : undefined,
86
+ },
87
+ enabledIds: prepared.extensionsForRun,
88
+ phase: 'assistant_partial',
89
+ runId: prepared.lifecycleRunId,
90
+ isSynthetic: true,
91
+ })
92
+ if (!partialMsg) return
93
+ const snapshotKey = JSON.stringify([
94
+ partialMsg.text,
95
+ partialMsg.thinking || '',
96
+ getToolEventsSnapshotKey(partialMsg.toolEvents || []),
97
+ ])
98
+ if (snapshotKey === lastPartialSnapshotKey) return
99
+ lastPartialSnapshotKey = snapshotKey
100
+ lastPartialSaveAt = Date.now()
101
+ upsertStreamingAssistantArtifact(current.messages, partialMsg, {
102
+ minIndex: prepared.runMessageStartIndex,
103
+ minTime: prepared.runStartedAt,
104
+ })
105
+ saveSession(prepared.sessionId, current)
106
+ notify(`messages:${prepared.sessionId}`)
107
+ } catch {
108
+ // Partial persistence is best-effort.
109
+ }
110
+ }
111
+
112
+ const triggerPartialAssistantPersist = () => {
113
+ partialPersistChain = partialPersistChain
114
+ .catch(() => {})
115
+ .then(async () => {
116
+ await persistStreamingAssistantArtifact()
117
+ })
118
+ }
119
+
120
+ const queuePartialAssistantPersist = (immediate = false) => {
121
+ if (partialPersistenceClosed) return
122
+ const now = Date.now()
123
+ if (immediate || now - lastPartialSaveAt >= PARTIAL_SAVE_MIN_INTERVAL_MS) {
124
+ if (partialSaveTimeout) {
125
+ clearTimeout(partialSaveTimeout)
126
+ partialSaveTimeout = null
127
+ }
128
+ triggerPartialAssistantPersist()
129
+ return
130
+ }
131
+ if (partialSaveTimeout) return
132
+ partialSaveTimeout = setTimeout(() => {
133
+ triggerPartialAssistantPersist()
134
+ }, PARTIAL_SAVE_MIN_INTERVAL_MS - (now - lastPartialSaveAt))
135
+ }
136
+
137
+ const emit = (event: SSEEvent) => {
138
+ let shouldPersistPartial = false
139
+ let immediatePartialPersist = false
140
+ if (event.t === 'reset') {
141
+ streamingPartialText = event.text || ''
142
+ thinkingText = ''
143
+ toolEvents.length = 0
144
+ shouldPersistPartial = true
145
+ immediatePartialPersist = true
146
+ }
147
+ if (event.t === 'd' && typeof event.text === 'string') {
148
+ streamingPartialText += event.text
149
+ shouldPersistPartial = true
150
+ immediatePartialPersist = streamingPartialText.length === event.text.length
151
+ }
152
+ if (event.t === 'err' && typeof event.text === 'string') {
153
+ const trimmed = event.text.trim()
154
+ if (trimmed) {
155
+ streamErrors.push(trimmed)
156
+ if (streamErrors.length > 8) streamErrors.shift()
157
+ }
158
+ }
159
+ if (event.t === 'thinking' && event.text) {
160
+ thinkingText += event.text
161
+ shouldPersistPartial = true
162
+ }
163
+ if (event.t === 'md' && event.text) {
164
+ try {
165
+ const mdPayload = JSON.parse(event.text) as Record<string, unknown>
166
+ const usage = mdPayload.usage as { inputTokens?: number; outputTokens?: number; estimatedCost?: number } | undefined
167
+ if (usage) {
168
+ if (typeof usage.inputTokens === 'number') accumulatedUsage.inputTokens += usage.inputTokens
169
+ if (typeof usage.outputTokens === 'number') accumulatedUsage.outputTokens += usage.outputTokens
170
+ if (typeof usage.estimatedCost === 'number') accumulatedUsage.estimatedCost += usage.estimatedCost
171
+ }
172
+ } catch {
173
+ // Ignore non-JSON md events.
174
+ }
175
+ }
176
+ collectToolEvent(event, toolEvents)
177
+ if (event.t === 'tool_call' || event.t === 'tool_result') {
178
+ shouldPersistPartial = true
179
+ immediatePartialPersist = true
180
+ }
181
+ if (shouldPersistPartial) queuePartialAssistantPersist(immediatePartialPersist)
182
+ onEvent?.(event)
183
+ }
184
+
185
+ const periodicTimer = setInterval(() => {
186
+ persistStreamingAssistantArtifact()
187
+ }, PARTIAL_SAVE_INTERVAL_MS)
188
+
189
+ return {
190
+ emit,
191
+ parseAndEmit(raw: string) {
192
+ const lines = raw.split('\n').filter(Boolean)
193
+ for (const line of lines) {
194
+ const event = extractEventJson(line)
195
+ if (event) emit(event)
196
+ }
197
+ },
198
+ stop() {
199
+ partialPersistenceClosed = true
200
+ if (partialSaveTimeout) {
201
+ clearTimeout(partialSaveTimeout)
202
+ partialSaveTimeout = null
203
+ }
204
+ clearInterval(periodicTimer)
205
+ },
206
+ awaitIdle() {
207
+ return partialPersistChain.catch(() => {})
208
+ },
209
+ getToolEvents() {
210
+ return toolEvents
211
+ },
212
+ getSnapshot() {
213
+ return {
214
+ thinkingText,
215
+ toolEvents: [...toolEvents],
216
+ streamErrors: [...streamErrors],
217
+ accumulatedUsage: { ...accumulatedUsage },
218
+ }
219
+ },
220
+ }
221
+ }
@@ -0,0 +1,133 @@
1
+ import { notify } from '@/lib/server/ws-hub'
2
+ import { getSession, saveSession } from '@/lib/server/sessions/session-repository'
3
+ import type { MessageToolEvent, SSEEvent } from '@/types'
4
+ import type { ExecuteChatTurnResult } from './chat-execution-types'
5
+ import {
6
+ resolveRequestedToolPreflightResponse,
7
+ runExclusiveDirectMemoryPreflight,
8
+ } from '@/lib/server/chat-execution/chat-turn-tool-routing'
9
+ import {
10
+ applyMessageLifecycleHooks,
11
+ type PreparedBlockedChatTurn,
12
+ type PreparedExecutableChatTurn,
13
+ } from '@/lib/server/chat-execution/chat-turn-preparation'
14
+
15
+ type DirectMemoryPreflightResult = Awaited<ReturnType<typeof runExclusiveDirectMemoryPreflight>>
16
+
17
+ export interface ChatTurnPreflightResult {
18
+ terminalResult?: ExecuteChatTurnResult
19
+ directMemoryResult?: DirectMemoryPreflightResult
20
+ }
21
+
22
+ async function completeSyntheticAssistantTurn(params: {
23
+ runId?: string
24
+ sessionId: string
25
+ text: string
26
+ lifecycleRunId: string
27
+ enabledIds: string[]
28
+ shouldPersist: boolean
29
+ phase: 'assistant_final' | 'heartbeat'
30
+ error?: string
31
+ notifyMessages?: boolean
32
+ notifySessions?: boolean
33
+ }): Promise<ExecuteChatTurnResult> {
34
+ const session = getSession(params.sessionId)
35
+ let persisted = false
36
+ if (session && params.shouldPersist) {
37
+ const nextAssistantMessage = await applyMessageLifecycleHooks({
38
+ session,
39
+ message: {
40
+ role: 'assistant',
41
+ text: params.text,
42
+ time: Date.now(),
43
+ },
44
+ enabledIds: params.enabledIds,
45
+ phase: params.phase,
46
+ runId: params.lifecycleRunId,
47
+ isSynthetic: true,
48
+ })
49
+ if (nextAssistantMessage) {
50
+ session.messages = Array.isArray(session.messages) ? session.messages : []
51
+ session.messages.push(nextAssistantMessage)
52
+ session.lastActiveAt = Date.now()
53
+ saveSession(params.sessionId, session)
54
+ if (params.notifyMessages) notify(`messages:${params.sessionId}`)
55
+ if (params.notifySessions) notify('sessions')
56
+ persisted = true
57
+ }
58
+ }
59
+
60
+ return {
61
+ runId: params.runId,
62
+ sessionId: params.sessionId,
63
+ text: params.text,
64
+ persisted,
65
+ toolEvents: [],
66
+ error: params.error,
67
+ }
68
+ }
69
+
70
+ export async function completeBlockedChatTurn(prepared: PreparedBlockedChatTurn): Promise<ExecuteChatTurnResult> {
71
+ return completeSyntheticAssistantTurn({
72
+ runId: prepared.runId,
73
+ sessionId: prepared.sessionId,
74
+ text: prepared.blockedMessage,
75
+ lifecycleRunId: prepared.lifecycleRunId,
76
+ enabledIds: prepared.syntheticEnabledIds,
77
+ shouldPersist: !prepared.internal,
78
+ phase: 'assistant_final',
79
+ error: prepared.blockedMessage,
80
+ })
81
+ }
82
+
83
+ export async function runChatTurnPreflight(params: {
84
+ prepared: PreparedExecutableChatTurn
85
+ emit: (event: SSEEvent) => void
86
+ toolEvents: MessageToolEvent[]
87
+ }): Promise<ChatTurnPreflightResult | null> {
88
+ const { prepared, emit, toolEvents } = params
89
+
90
+ const requestedToolPreflightResponse = resolveRequestedToolPreflightResponse({
91
+ message: prepared.message,
92
+ enabledExtensions: prepared.extensionsForRun,
93
+ toolPolicy: prepared.toolPolicy,
94
+ appSettings: prepared.appSettings,
95
+ internal: prepared.internal,
96
+ source: prepared.source,
97
+ session: prepared.sessionForRun,
98
+ })
99
+ if (requestedToolPreflightResponse) {
100
+ return {
101
+ terminalResult: await completeSyntheticAssistantTurn({
102
+ runId: prepared.runId,
103
+ sessionId: prepared.sessionId,
104
+ text: requestedToolPreflightResponse,
105
+ lifecycleRunId: prepared.lifecycleRunId,
106
+ enabledIds: prepared.extensionsForRun,
107
+ shouldPersist: !prepared.hideAssistantTranscript,
108
+ phase: 'assistant_final',
109
+ notifyMessages: true,
110
+ notifySessions: true,
111
+ }),
112
+ }
113
+ }
114
+
115
+ const directMemoryResult = await runExclusiveDirectMemoryPreflight({
116
+ session: prepared.sessionForRun,
117
+ sessionId: prepared.sessionId,
118
+ message: prepared.message,
119
+ effectiveMessage: prepared.effectiveMessage,
120
+ enabledExtensions: prepared.extensionsForRun,
121
+ toolPolicy: prepared.toolPolicy,
122
+ appSettings: prepared.appSettings,
123
+ internal: prepared.internal,
124
+ source: prepared.source,
125
+ toolEvents,
126
+ emit,
127
+ })
128
+ if (directMemoryResult) {
129
+ return { directMemoryResult }
130
+ }
131
+
132
+ return null
133
+ }