@swarmclawai/swarmclaw 1.2.0 → 1.2.2

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 (241) hide show
  1. package/README.md +19 -0
  2. package/package.json +5 -2
  3. package/skills/coding-agent/SKILL.md +111 -0
  4. package/skills/github/SKILL.md +140 -0
  5. package/skills/nano-banana-pro/SKILL.md +62 -0
  6. package/skills/nano-banana-pro/scripts/generate_image.py +235 -0
  7. package/skills/nano-pdf/SKILL.md +53 -0
  8. package/skills/openai-image-gen/SKILL.md +78 -0
  9. package/skills/openai-image-gen/scripts/gen.py +328 -0
  10. package/skills/resourceful-problem-solving/SKILL.md +49 -0
  11. package/skills/skill-creator/SKILL.md +147 -0
  12. package/skills/skill-creator/scripts/init_skill.py +378 -0
  13. package/skills/skill-creator/scripts/quick_validate.py +159 -0
  14. package/skills/summarize/SKILL.md +77 -0
  15. package/src/app/api/auth/route.ts +20 -5
  16. package/src/app/api/chats/[id]/deploy/route.ts +11 -6
  17. package/src/app/api/chats/[id]/devserver/route.ts +17 -20
  18. package/src/app/api/chats/[id]/messages/route.ts +15 -11
  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/credentials/[id]/route.ts +4 -1
  24. package/src/app/api/extensions/marketplace/route.ts +5 -2
  25. package/src/app/api/ip/route.ts +2 -2
  26. package/src/app/api/memory/maintenance/route.ts +5 -2
  27. package/src/app/api/preview-server/route.ts +15 -12
  28. package/src/app/api/projects/[id]/route.ts +7 -46
  29. package/src/app/api/system/status/route.ts +11 -0
  30. package/src/app/api/upload/route.ts +4 -1
  31. package/src/cli/index.js +7 -0
  32. package/src/cli/spec.js +1 -0
  33. package/src/components/agents/agent-files-editor.tsx +44 -32
  34. package/src/components/agents/personality-builder.tsx +13 -7
  35. package/src/components/agents/trash-list.tsx +1 -1
  36. package/src/components/chat/chat-area.tsx +45 -23
  37. package/src/components/chat/message-bubble.test.ts +35 -0
  38. package/src/components/chat/message-bubble.tsx +20 -9
  39. package/src/components/chat/message-list.tsx +62 -42
  40. package/src/components/chat/swarm-status-card.tsx +10 -3
  41. package/src/components/input/chat-input.tsx +34 -14
  42. package/src/components/layout/daemon-indicator.tsx +7 -8
  43. package/src/components/layout/update-banner.tsx +8 -13
  44. package/src/components/logs/log-list.tsx +1 -1
  45. package/src/components/memory/memory-card.tsx +3 -1
  46. package/src/components/org-chart/org-chart-view.tsx +4 -0
  47. package/src/components/projects/project-list.tsx +4 -2
  48. package/src/components/projects/tabs/overview-tab.tsx +3 -2
  49. package/src/components/secrets/secret-sheet.tsx +1 -1
  50. package/src/components/secrets/secrets-list.tsx +1 -1
  51. package/src/components/shared/agent-switch-dialog.tsx +12 -6
  52. package/src/components/shared/dir-browser.tsx +22 -18
  53. package/src/components/skills/skill-sheet.tsx +2 -3
  54. package/src/components/tasks/task-list.tsx +1 -1
  55. package/src/components/tasks/task-sheet.tsx +1 -1
  56. package/src/hooks/use-openclaw-gateway.ts +46 -27
  57. package/src/instrumentation.ts +10 -7
  58. package/src/lib/chat/assistant-render-id.ts +3 -0
  59. package/src/lib/chat/chat-streaming-state.test.ts +42 -3
  60. package/src/lib/chat/chat-streaming-state.ts +20 -8
  61. package/src/lib/chat/chat.ts +18 -2
  62. package/src/lib/chat/queued-message-queue.test.ts +23 -1
  63. package/src/lib/chat/queued-message-queue.ts +11 -2
  64. package/src/lib/providers/anthropic.ts +6 -3
  65. package/src/lib/providers/claude-cli.ts +9 -3
  66. package/src/lib/providers/cli-utils.test.ts +124 -0
  67. package/src/lib/providers/cli-utils.ts +15 -0
  68. package/src/lib/providers/codex-cli.ts +9 -3
  69. package/src/lib/providers/gemini-cli.ts +6 -2
  70. package/src/lib/providers/index.ts +4 -1
  71. package/src/lib/providers/ollama.ts +5 -2
  72. package/src/lib/providers/openai.ts +8 -5
  73. package/src/lib/providers/opencode-cli.ts +6 -2
  74. package/src/lib/server/activity/activity-log.ts +21 -0
  75. package/src/lib/server/agents/agent-availability.test.ts +10 -5
  76. package/src/lib/server/agents/agent-cascade.ts +79 -59
  77. package/src/lib/server/agents/agent-registry.ts +23 -4
  78. package/src/lib/server/agents/agent-repository.ts +90 -0
  79. package/src/lib/server/agents/delegation-job-repository.ts +53 -0
  80. package/src/lib/server/agents/delegation-jobs.ts +11 -4
  81. package/src/lib/server/agents/guardian-checkpoint-repository.ts +35 -0
  82. package/src/lib/server/agents/guardian.ts +2 -2
  83. package/src/lib/server/agents/main-agent-loop.ts +14 -6
  84. package/src/lib/server/agents/main-loop-state-repository.ts +38 -0
  85. package/src/lib/server/agents/subagent-runtime.ts +9 -6
  86. package/src/lib/server/agents/subagent-swarm.ts +3 -2
  87. package/src/lib/server/agents/task-session.ts +3 -4
  88. package/src/lib/server/approvals/approval-repository.ts +30 -0
  89. package/src/lib/server/autonomy/supervisor-incident-repository.ts +42 -0
  90. package/src/lib/server/autonomy/supervisor-reflection.ts +14 -1
  91. package/src/lib/server/chat-execution/chat-execution-types.ts +38 -0
  92. package/src/lib/server/chat-execution/chat-execution-utils.ts +1 -1
  93. package/src/lib/server/chat-execution/chat-execution.ts +84 -1914
  94. package/src/lib/server/chat-execution/chat-turn-finalization.ts +620 -0
  95. package/src/lib/server/chat-execution/chat-turn-partial-persistence.ts +221 -0
  96. package/src/lib/server/chat-execution/chat-turn-preflight.ts +133 -0
  97. package/src/lib/server/chat-execution/chat-turn-preparation.ts +817 -0
  98. package/src/lib/server/chat-execution/chat-turn-stream-execution.ts +296 -0
  99. package/src/lib/server/chat-execution/chat-turn-tool-routing.ts +5 -5
  100. package/src/lib/server/chat-execution/continuation-evaluator.ts +4 -3
  101. package/src/lib/server/chat-execution/continuation-limits.ts +6 -3
  102. package/src/lib/server/chat-execution/message-classifier.test.ts +329 -0
  103. package/src/lib/server/chat-execution/message-classifier.ts +5 -2
  104. package/src/lib/server/chat-execution/post-stream-finalization.ts +5 -2
  105. package/src/lib/server/chat-execution/prompt-builder.ts +22 -1
  106. package/src/lib/server/chat-execution/prompt-sections.ts +55 -13
  107. package/src/lib/server/chat-execution/response-completeness.ts +5 -2
  108. package/src/lib/server/chat-execution/situational-awareness.ts +12 -7
  109. package/src/lib/server/chat-execution/stream-agent-chat.ts +58 -25
  110. package/src/lib/server/chatrooms/chatroom-memory-bridge.ts +6 -3
  111. package/src/lib/server/chatrooms/chatroom-repository.ts +32 -0
  112. package/src/lib/server/connectors/bluebubbles.ts +7 -4
  113. package/src/lib/server/connectors/connector-inbound.ts +16 -13
  114. package/src/lib/server/connectors/connector-lifecycle.ts +11 -8
  115. package/src/lib/server/connectors/connector-outbound.ts +6 -3
  116. package/src/lib/server/connectors/connector-repository.ts +58 -0
  117. package/src/lib/server/connectors/discord.ts +10 -7
  118. package/src/lib/server/connectors/email.ts +17 -14
  119. package/src/lib/server/connectors/googlechat.ts +7 -4
  120. package/src/lib/server/connectors/inbound-audio-transcription.ts +5 -2
  121. package/src/lib/server/connectors/matrix.ts +6 -3
  122. package/src/lib/server/connectors/openclaw.ts +20 -17
  123. package/src/lib/server/connectors/outbox.ts +4 -1
  124. package/src/lib/server/connectors/runtime-state.test.ts +117 -0
  125. package/src/lib/server/connectors/runtime-state.ts +19 -0
  126. package/src/lib/server/connectors/session-consolidation.ts +5 -2
  127. package/src/lib/server/connectors/signal.ts +9 -6
  128. package/src/lib/server/connectors/slack.ts +13 -10
  129. package/src/lib/server/connectors/teams.ts +8 -5
  130. package/src/lib/server/connectors/telegram.ts +15 -12
  131. package/src/lib/server/connectors/whatsapp.ts +32 -29
  132. package/src/lib/server/credentials/credential-repository.ts +7 -0
  133. package/src/lib/server/embeddings.ts +4 -1
  134. package/src/lib/server/gateways/gateway-profile-repository.ts +4 -0
  135. package/src/lib/server/link-understanding.ts +4 -1
  136. package/src/lib/server/memory/memory-abstract.test.ts +59 -0
  137. package/src/lib/server/memory/memory-abstract.ts +59 -0
  138. package/src/lib/server/memory/memory-db.ts +40 -14
  139. package/src/lib/server/missions/mission-repository.ts +74 -0
  140. package/src/lib/server/missions/mission-service/actions.ts +6 -0
  141. package/src/lib/server/missions/mission-service/bindings.ts +9 -0
  142. package/src/lib/server/missions/mission-service/context.ts +4 -0
  143. package/src/lib/server/missions/mission-service/core.ts +2269 -0
  144. package/src/lib/server/missions/mission-service/queries.ts +12 -0
  145. package/src/lib/server/missions/mission-service/recovery.ts +5 -0
  146. package/src/lib/server/missions/mission-service/ticks.ts +9 -0
  147. package/src/lib/server/missions/mission-service.test.ts +9 -2
  148. package/src/lib/server/missions/mission-service.ts +6 -2263
  149. package/src/lib/server/openclaw/gateway.ts +8 -5
  150. package/src/lib/server/persistence/repository-utils.ts +154 -0
  151. package/src/lib/server/persistence/storage-context.ts +51 -0
  152. package/src/lib/server/persistence/transaction.ts +1 -0
  153. package/src/lib/server/project-utils.ts +13 -0
  154. package/src/lib/server/projects/project-repository.ts +36 -0
  155. package/src/lib/server/projects/project-service.ts +79 -0
  156. package/src/lib/server/protocols/protocol-agent-turn.ts +5 -2
  157. package/src/lib/server/protocols/protocol-normalization.test.ts +6 -4
  158. package/src/lib/server/protocols/protocol-run-lifecycle.ts +5 -2
  159. package/src/lib/server/protocols/protocol-step-helpers.ts +4 -1
  160. package/src/lib/server/provider-health.ts +18 -0
  161. package/src/lib/server/query-expansion.ts +4 -1
  162. package/src/lib/server/runtime/alert-dispatch.ts +8 -7
  163. package/src/lib/server/runtime/daemon-policy.ts +1 -1
  164. package/src/lib/server/runtime/daemon-state/core.ts +1570 -0
  165. package/src/lib/server/runtime/daemon-state/health.ts +6 -0
  166. package/src/lib/server/runtime/daemon-state/policy.ts +7 -0
  167. package/src/lib/server/runtime/daemon-state/supervisor.ts +6 -0
  168. package/src/lib/server/runtime/daemon-state.test.ts +48 -0
  169. package/src/lib/server/runtime/daemon-state.ts +3 -1331
  170. package/src/lib/server/runtime/estop-repository.ts +4 -0
  171. package/src/lib/server/runtime/estop.ts +3 -1
  172. package/src/lib/server/runtime/heartbeat-service.test.ts +2 -2
  173. package/src/lib/server/runtime/heartbeat-service.ts +78 -34
  174. package/src/lib/server/runtime/heartbeat-wake.ts +6 -4
  175. package/src/lib/server/runtime/idle-window.ts +6 -3
  176. package/src/lib/server/runtime/network.ts +11 -0
  177. package/src/lib/server/runtime/orchestrator-events.ts +2 -2
  178. package/src/lib/server/runtime/perf.ts +4 -1
  179. package/src/lib/server/runtime/process-manager.ts +7 -4
  180. package/src/lib/server/runtime/queue/claims.ts +4 -0
  181. package/src/lib/server/runtime/queue/core.ts +2079 -0
  182. package/src/lib/server/runtime/queue/execution.ts +7 -0
  183. package/src/lib/server/runtime/queue/followups.ts +4 -0
  184. package/src/lib/server/runtime/queue/queries.ts +12 -0
  185. package/src/lib/server/runtime/queue/recovery.ts +7 -0
  186. package/src/lib/server/runtime/queue-recovery.test.ts +48 -13
  187. package/src/lib/server/runtime/queue-repository.ts +17 -0
  188. package/src/lib/server/runtime/queue.ts +5 -2058
  189. package/src/lib/server/runtime/run-ledger.ts +6 -5
  190. package/src/lib/server/runtime/run-repository.ts +73 -0
  191. package/src/lib/server/runtime/runtime-lock-repository.ts +8 -0
  192. package/src/lib/server/runtime/runtime-settings.ts +1 -1
  193. package/src/lib/server/runtime/runtime-state.ts +99 -0
  194. package/src/lib/server/runtime/scheduler.ts +13 -8
  195. package/src/lib/server/runtime/session-run-manager/cancellation.ts +157 -0
  196. package/src/lib/server/runtime/session-run-manager/drain.ts +246 -0
  197. package/src/lib/server/runtime/session-run-manager/enqueue.ts +287 -0
  198. package/src/lib/server/runtime/session-run-manager/queries.ts +117 -0
  199. package/src/lib/server/runtime/session-run-manager/recovery.ts +238 -0
  200. package/src/lib/server/runtime/session-run-manager/state.ts +441 -0
  201. package/src/lib/server/runtime/session-run-manager/types.ts +74 -0
  202. package/src/lib/server/runtime/session-run-manager.ts +72 -1374
  203. package/src/lib/server/runtime/watch-job-repository.ts +35 -0
  204. package/src/lib/server/runtime/watch-jobs.ts +3 -1
  205. package/src/lib/server/sandbox/bridge-auth-registry.ts +6 -0
  206. package/src/lib/server/sandbox/novnc-auth.ts +10 -0
  207. package/src/lib/server/schedules/schedule-repository.ts +42 -0
  208. package/src/lib/server/session-tools/context.ts +14 -0
  209. package/src/lib/server/session-tools/discovery.ts +9 -6
  210. package/src/lib/server/session-tools/index.ts +3 -1
  211. package/src/lib/server/session-tools/platform.ts +1 -1
  212. package/src/lib/server/session-tools/subagent.ts +23 -2
  213. package/src/lib/server/session-tools/wallet.ts +4 -1
  214. package/src/lib/server/sessions/session-repository.ts +85 -0
  215. package/src/lib/server/settings/settings-repository.ts +25 -0
  216. package/src/lib/server/skills/clawhub-client.ts +4 -1
  217. package/src/lib/server/skills/runtime-skill-resolver.ts +8 -2
  218. package/src/lib/server/skills/skill-discovery.test.ts +2 -2
  219. package/src/lib/server/skills/skill-discovery.ts +2 -2
  220. package/src/lib/server/skills/skill-eligibility.ts +6 -0
  221. package/src/lib/server/skills/skill-repository.ts +14 -0
  222. package/src/lib/server/solana.ts +6 -0
  223. package/src/lib/server/storage-auth.ts +5 -5
  224. package/src/lib/server/storage-normalization.ts +4 -0
  225. package/src/lib/server/storage.ts +32 -32
  226. package/src/lib/server/tasks/task-followups.ts +4 -1
  227. package/src/lib/server/tasks/task-repository.ts +54 -0
  228. package/src/lib/server/tool-loop-detection.ts +8 -3
  229. package/src/lib/server/tool-planning.ts +226 -0
  230. package/src/lib/server/tool-retry.ts +4 -3
  231. package/src/lib/server/usage/usage-repository.ts +30 -0
  232. package/src/lib/server/wallet/wallet-portfolio.ts +29 -0
  233. package/src/lib/server/webhooks/webhook-repository.ts +10 -0
  234. package/src/lib/server/ws-hub.ts +5 -2
  235. package/src/lib/strip-internal-metadata.test.ts +78 -37
  236. package/src/lib/strip-internal-metadata.ts +20 -6
  237. package/src/stores/use-approval-store.ts +7 -1
  238. package/src/stores/use-chat-store.test.ts +54 -0
  239. package/src/stores/use-chat-store.ts +26 -6
  240. package/src/types/index.ts +6 -0
  241. /package/{bundled-skills → skills}/google-workspace/SKILL.md +0 -0
@@ -0,0 +1,38 @@
1
+ import { perf } from '@/lib/server/runtime/perf'
2
+ import {
3
+ deletePersistedMainLoopState as deleteStoredMainLoopState,
4
+ loadPersistedMainLoopState as loadStoredMainLoopState,
5
+ upsertPersistedMainLoopState as upsertStoredMainLoopState,
6
+ } from '@/lib/server/storage'
7
+
8
+ export type PersistedMainLoopState = Record<string, unknown>
9
+
10
+ export function loadPersistedMainLoopState(sessionId: string): PersistedMainLoopState | null {
11
+ return perf.measureSync(
12
+ 'repository',
13
+ 'main-loop-state.get',
14
+ () => loadStoredMainLoopState(sessionId) as PersistedMainLoopState | null,
15
+ { sessionId },
16
+ )
17
+ }
18
+
19
+ export function upsertPersistedMainLoopState(
20
+ sessionId: string,
21
+ value: PersistedMainLoopState,
22
+ ): void {
23
+ perf.measureSync(
24
+ 'repository',
25
+ 'main-loop-state.upsert',
26
+ () => upsertStoredMainLoopState(sessionId, value),
27
+ { sessionId },
28
+ )
29
+ }
30
+
31
+ export function deletePersistedMainLoopState(sessionId: string): void {
32
+ perf.measureSync(
33
+ 'repository',
34
+ 'main-loop-state.delete',
35
+ () => deleteStoredMainLoopState(sessionId),
36
+ { sessionId },
37
+ )
38
+ }
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { genId } from '@/lib/id'
10
10
  import { DEFAULT_DELEGATION_MAX_DEPTH } from '@/lib/runtime/runtime-loop'
11
- import { loadAgents, loadSessions, saveSessions } from '@/lib/server/storage'
11
+ import { loadAgents } from '@/lib/server/agents/agent-repository'
12
12
  import { enqueueSessionRun, type EnqueueSessionRunResult } from '@/lib/server/runtime/session-run-manager'
13
13
  import { loadRuntimeSettings } from '@/lib/server/runtime/runtime-settings'
14
14
  import { applyResolvedRoute, resolvePrimaryAgentRoute } from '@/lib/server/agents/agent-runtime-config'
@@ -48,6 +48,7 @@ import { debug } from '@/lib/server/debug'
48
48
  import { logExecution } from '@/lib/server/execution-log'
49
49
  import { enqueueSystemEvent } from '@/lib/server/runtime/system-events'
50
50
  import { getEnabledCapabilityIds, splitCapabilityIds } from '@/lib/capability-selection'
51
+ import { getSession, loadSessions, saveSession } from '@/lib/server/sessions/session-repository'
51
52
 
52
53
  // ---------------------------------------------------------------------------
53
54
  // Types
@@ -276,7 +277,7 @@ async function spawnSubagentImpl(
276
277
  browserProfileId,
277
278
  }
278
279
  sessions[sid] = applyResolvedRoute(nextSession, resolvePrimaryAgentRoute(agent))
279
- saveSessions(sessions)
280
+ saveSession(sid, sessions[sid])
280
281
 
281
282
  log.info('subagent', 'Spawning', { agentId: agent.id, agentName: agent.name, depth: depth + 1, jobId: job.id, sessionId: sid })
282
283
  logExecution(sid, 'delegation_start', `Subagent spawning: ${agent.name}`, {
@@ -398,12 +399,13 @@ async function spawnSubagentImpl(
398
399
  `subagent:${job.id}`,
399
400
  )
400
401
  }
402
+ const completedSession = getSession(sid)
401
403
  await runCapabilityHook(
402
404
  'sessionEnd',
403
405
  {
404
406
  sessionId: sid,
405
- session: loadSessions()[sid] || null,
406
- messageCount: Array.isArray(loadSessions()[sid]?.messages) ? loadSessions()[sid].messages.length : 0,
407
+ session: completedSession,
408
+ messageCount: Array.isArray(completedSession?.messages) ? completedSession.messages.length : 0,
407
409
  durationMs: subagentResult.durationMs,
408
410
  reason: subagentResult.status,
409
411
  },
@@ -460,12 +462,13 @@ async function spawnSubagentImpl(
460
462
  `subagent:${job.id}`,
461
463
  )
462
464
  }
465
+ const failedSession = getSession(sid)
463
466
  await runCapabilityHook(
464
467
  'sessionEnd',
465
468
  {
466
469
  sessionId: sid,
467
- session: loadSessions()[sid] || null,
468
- messageCount: Array.isArray(loadSessions()[sid]?.messages) ? loadSessions()[sid].messages.length : 0,
470
+ session: failedSession,
471
+ messageCount: Array.isArray(failedSession?.messages) ? failedSession.messages.length : 0,
469
472
  durationMs: subagentResult.durationMs,
470
473
  reason: subagentResult.status,
471
474
  },
@@ -13,22 +13,23 @@ import { genId } from '@/lib/id'
13
13
  import { errorMessage, hmrSingleton, sleep } from '@/lib/shared-utils'
14
14
  import { log } from '@/lib/server/logger'
15
15
  import { logExecution } from '@/lib/server/execution-log'
16
- import { logActivity } from '@/lib/server/storage'
16
+ import { logActivity } from '@/lib/server/activity/activity-log'
17
17
  import { createNotification } from '@/lib/server/create-notification'
18
18
  import { notify } from '@/lib/server/ws-hub'
19
+ import { loadAgents } from '@/lib/server/agents/agent-repository'
19
20
  import {
20
21
  spawnSubagent,
21
22
  type SubagentContext,
22
23
  type SubagentHandle,
23
24
  type SubagentResult,
24
25
  } from '@/lib/server/agents/subagent-runtime'
25
- import { loadAgents, loadSessions } from '@/lib/server/storage'
26
26
  import { getDelegationJob } from '@/lib/server/agents/delegation-jobs'
27
27
  import {
28
28
  getLineageNode,
29
29
  cancelLineageNode,
30
30
  type SubagentState,
31
31
  } from '@/lib/server/agents/subagent-lineage'
32
+ import { loadSessions } from '@/lib/server/sessions/session-repository'
32
33
  import type { Agent } from '@/types'
33
34
 
34
35
  // ---------------------------------------------------------------------------
@@ -1,9 +1,9 @@
1
1
  import { genId } from '@/lib/id'
2
- import { loadSessions, saveSessions } from '@/lib/server/storage'
3
2
  import { WORKSPACE_DIR } from '@/lib/server/data-dir'
4
3
  import type { Agent } from '@/types'
5
4
  import { getEnabledCapabilitySelection } from '@/lib/capability-selection'
6
5
  import { applyResolvedRoute, resolvePrimaryAgentRoute } from '@/lib/server/agents/agent-runtime-config'
6
+ import { saveSession } from '@/lib/server/sessions/session-repository'
7
7
 
8
8
  export function createAgentTaskSession(
9
9
  agent: Agent,
@@ -15,7 +15,6 @@ export function createAgentTaskSession(
15
15
  preferredGatewayUseCase?: string | null
16
16
  } | null,
17
17
  ): string {
18
- const sessions = loadSessions()
19
18
  const sessionId = genId()
20
19
  const preferredGatewayTags = Array.isArray(routePreferences?.preferredGatewayTags)
21
20
  ? routePreferences.preferredGatewayTags.filter((tag) => typeof tag === 'string' && tag.trim())
@@ -25,7 +24,7 @@ export function createAgentTaskSession(
25
24
  preferredGatewayUseCase: routePreferences?.preferredGatewayUseCase || null,
26
25
  })
27
26
 
28
- sessions[sessionId] = applyResolvedRoute({
27
+ const session = applyResolvedRoute({
29
28
  id: sessionId,
30
29
  name: `[Task] ${agent.name}: ${task.slice(0, 40)}`,
31
30
  cwd: cwd || WORKSPACE_DIR,
@@ -57,6 +56,6 @@ export function createAgentTaskSession(
57
56
  heartbeatEnabled: false,
58
57
  }, resolvedRoute)
59
58
 
60
- saveSessions(sessions)
59
+ saveSession(sessionId, session)
61
60
  return sessionId
62
61
  }
@@ -0,0 +1,30 @@
1
+ import {
2
+ deleteApproval as deleteStoredApproval,
3
+ loadApprovals as loadStoredApprovals,
4
+ upsertApproval as upsertStoredApproval,
5
+ } from '@/lib/server/storage'
6
+ import { createRecordRepository } from '@/lib/server/persistence/repository-utils'
7
+ import type { ApprovalRequest } from '@/types'
8
+
9
+ export const approvalRepository = createRecordRepository<ApprovalRequest>(
10
+ 'approvals',
11
+ {
12
+ get(id) {
13
+ return loadStoredApprovals()[id] || null
14
+ },
15
+ list() {
16
+ return loadStoredApprovals() as Record<string, ApprovalRequest>
17
+ },
18
+ upsert(id, value) {
19
+ upsertStoredApproval(id, value)
20
+ },
21
+ delete(id) {
22
+ deleteStoredApproval(id)
23
+ },
24
+ },
25
+ )
26
+
27
+ export const loadApprovals = () => approvalRepository.list()
28
+ export const loadApproval = (id: string) => approvalRepository.get(id)
29
+ export const upsertApproval = (id: string, value: ApprovalRequest | Record<string, unknown>) => approvalRepository.upsert(id, value as ApprovalRequest)
30
+ export const deleteApproval = (id: string) => approvalRepository.delete(id)
@@ -0,0 +1,42 @@
1
+ import type { SupervisorIncident } from '@/types'
2
+
3
+ import {
4
+ loadSupervisorIncident as loadStoredSupervisorIncident,
5
+ loadSupervisorIncidents as loadStoredSupervisorIncidents,
6
+ saveSupervisorIncidents as saveStoredSupervisorIncidents,
7
+ upsertSupervisorIncident as upsertStoredSupervisorIncident,
8
+ } from '@/lib/server/storage'
9
+ import { createRecordRepository } from '@/lib/server/persistence/repository-utils'
10
+
11
+ export const supervisorIncidentRepository = createRecordRepository<SupervisorIncident>(
12
+ 'supervisor-incidents',
13
+ {
14
+ get(id) {
15
+ return loadStoredSupervisorIncident(id) as SupervisorIncident | null
16
+ },
17
+ list() {
18
+ return loadStoredSupervisorIncidents() as Record<string, SupervisorIncident>
19
+ },
20
+ upsert(id, value) {
21
+ upsertStoredSupervisorIncident(id, value as SupervisorIncident)
22
+ },
23
+ replace(data) {
24
+ saveStoredSupervisorIncidents(data as Record<string, SupervisorIncident>)
25
+ },
26
+ },
27
+ )
28
+
29
+ export const loadSupervisorIncidents = () => supervisorIncidentRepository.list()
30
+ export const loadSupervisorIncident = (id: string) => supervisorIncidentRepository.get(id)
31
+ export const saveSupervisorIncidents = (items: Record<string, SupervisorIncident | Record<string, unknown>>) => (
32
+ supervisorIncidentRepository.replace(items as Record<string, SupervisorIncident>)
33
+ )
34
+ export const upsertSupervisorIncident = (id: string, value: SupervisorIncident | Record<string, unknown>) => (
35
+ supervisorIncidentRepository.upsert(id, value as SupervisorIncident)
36
+ )
37
+
38
+ export function listAgentIncidents(agentId?: string): SupervisorIncident[] {
39
+ return Object.values(loadSupervisorIncidents())
40
+ .filter((incident) => !agentId || incident.agentId === agentId)
41
+ .sort((left, right) => right.createdAt - left.createdAt)
42
+ }
@@ -34,6 +34,8 @@ import { logExecution } from '@/lib/server/execution-log'
34
34
  import { logActivity } from '@/lib/server/storage'
35
35
  import { createNotification } from '@/lib/server/create-notification'
36
36
 
37
+ const TAG = 'supervisor-reflection'
38
+
37
39
  const MAIN_LOOP_META_LINE_RE = /\[(?:MAIN_LOOP_META|MAIN_LOOP_PLAN|MAIN_LOOP_REVIEW|AGENT_HEARTBEAT_META)\]\s*(\{[^\n]*\})?/i
38
40
  const DEFAULT_TRANSCRIPT_MESSAGES = 12
39
41
  const DEFAULT_SNIPPET_CHARS = 800
@@ -368,6 +370,17 @@ export function assessAutonomyRun(input: {
368
370
  if (strongest?.kind === 'budget_pressure' && strongest.severity === 'high') shouldBlock = true
369
371
  if (strongest?.kind === 'run_error' && (status === 'failed' || status === 'cancelled')) shouldBlock = true
370
372
 
373
+ // Block after 3+ no_progress or repeated_tool incidents within 30 minutes for the same session
374
+ if (!shouldBlock && strongest && (strongest.kind === 'no_progress' || strongest.kind === 'repeated_tool')) {
375
+ const existingIncidents = Object.values(loadSupervisorIncidents()) as SupervisorIncident[]
376
+ const recentSame = existingIncidents.filter((i) =>
377
+ i.sessionId === input.sessionId
378
+ && i.createdAt > Date.now() - 30 * 60_000
379
+ && (i.kind === 'no_progress' || i.kind === 'repeated_tool'),
380
+ )
381
+ if (recentSame.length >= 3) shouldBlock = true
382
+ }
383
+
371
384
  const seen = new Set<string>()
372
385
  const autoActions: AutonomyAssessment['autoActions'] = []
373
386
  for (const incident of incidents) {
@@ -1023,7 +1036,7 @@ export async function observeAutonomyRunOutcome(
1023
1036
  try {
1024
1037
  parsed = parseReflectionResponse(responseText)
1025
1038
  } catch {
1026
- console.warn(`[autonomy] Reflection parse failed for run ${input.runId}, skipping reflection`)
1039
+ log.warn(TAG, `Reflection parse failed for run ${input.runId}, skipping reflection`)
1027
1040
  return { incidents, reflection: null }
1028
1041
  }
1029
1042
  if (parsed.skip) return { incidents, reflection: null }
@@ -0,0 +1,38 @@
1
+ import type { MessageToolEvent, SSEEvent } from '@/types'
2
+
3
+ export interface ExecuteChatTurnInput {
4
+ sessionId: string
5
+ message: string
6
+ missionId?: string | null
7
+ imagePath?: string
8
+ imageUrl?: string
9
+ attachedFiles?: string[]
10
+ internal?: boolean
11
+ source?: string
12
+ runId?: string
13
+ signal?: AbortSignal
14
+ onEvent?: (event: SSEEvent) => void
15
+ modelOverride?: string
16
+ heartbeatConfig?: {
17
+ ackMaxChars: number
18
+ showOk: boolean
19
+ showAlerts: boolean
20
+ target: string | null
21
+ lightContext?: boolean
22
+ deliveryMode?: 'default' | 'tool_only' | 'silent'
23
+ }
24
+ replyToId?: string
25
+ }
26
+
27
+ export interface ExecuteChatTurnResult {
28
+ runId?: string
29
+ sessionId: string
30
+ missionId?: string | null
31
+ text: string
32
+ persisted: boolean
33
+ toolEvents: MessageToolEvent[]
34
+ error?: string
35
+ inputTokens?: number
36
+ outputTokens?: number
37
+ estimatedCost?: number
38
+ }
@@ -2,7 +2,7 @@ import fs from 'fs'
2
2
  import path from 'path'
3
3
  import type { Message, MessageToolEvent } from '@/types'
4
4
  import { dedup } from '@/lib/shared-utils'
5
- import { getUsageSpendSince } from '@/lib/server/storage'
5
+ import { getUsageSpendSince } from '@/lib/server/usage/usage-repository'
6
6
  import { extensionIdMatches } from '@/lib/server/tool-aliases'
7
7
  import { buildToolEventAssistantSummary } from '@/lib/chat/tool-event-summary'
8
8
  import { looksLikePositiveConnectorDeliveryText } from '@/lib/server/chat-execution/chat-execution-connector-delivery'