@swarmclawai/swarmclaw 1.2.0 → 1.2.1

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 (123) hide show
  1. package/README.md +10 -0
  2. package/package.json +4 -1
  3. package/src/app/api/chats/[id]/deploy/route.ts +11 -6
  4. package/src/app/api/chats/[id]/devserver/route.ts +5 -2
  5. package/src/app/api/chats/[id]/messages/route.ts +7 -1
  6. package/src/app/api/credentials/[id]/route.ts +4 -1
  7. package/src/app/api/extensions/marketplace/route.ts +5 -2
  8. package/src/app/api/memory/maintenance/route.ts +5 -2
  9. package/src/app/api/preview-server/route.ts +14 -11
  10. package/src/app/api/system/status/route.ts +11 -0
  11. package/src/app/api/upload/route.ts +4 -1
  12. package/src/cli/index.js +7 -0
  13. package/src/cli/spec.js +1 -0
  14. package/src/components/agents/agent-files-editor.tsx +44 -32
  15. package/src/components/agents/personality-builder.tsx +13 -7
  16. package/src/components/agents/trash-list.tsx +1 -1
  17. package/src/components/chat/message-bubble.tsx +1 -0
  18. package/src/components/chat/message-list.tsx +25 -39
  19. package/src/components/chat/swarm-status-card.tsx +10 -3
  20. package/src/components/layout/daemon-indicator.tsx +7 -8
  21. package/src/components/layout/update-banner.tsx +8 -13
  22. package/src/components/logs/log-list.tsx +1 -1
  23. package/src/components/memory/memory-card.tsx +3 -1
  24. package/src/components/org-chart/org-chart-view.tsx +4 -0
  25. package/src/components/projects/project-list.tsx +4 -2
  26. package/src/components/projects/tabs/overview-tab.tsx +3 -2
  27. package/src/components/secrets/secret-sheet.tsx +1 -1
  28. package/src/components/secrets/secrets-list.tsx +1 -1
  29. package/src/components/shared/agent-switch-dialog.tsx +12 -6
  30. package/src/components/shared/dir-browser.tsx +22 -18
  31. package/src/components/skills/skill-sheet.tsx +2 -3
  32. package/src/components/tasks/task-list.tsx +1 -1
  33. package/src/components/tasks/task-sheet.tsx +1 -1
  34. package/src/hooks/use-openclaw-gateway.ts +46 -27
  35. package/src/instrumentation.ts +10 -7
  36. package/src/lib/chat/chat.ts +18 -2
  37. package/src/lib/providers/anthropic.ts +6 -3
  38. package/src/lib/providers/claude-cli.ts +9 -3
  39. package/src/lib/providers/cli-utils.ts +15 -0
  40. package/src/lib/providers/codex-cli.ts +9 -3
  41. package/src/lib/providers/gemini-cli.ts +6 -2
  42. package/src/lib/providers/index.ts +4 -1
  43. package/src/lib/providers/ollama.ts +5 -2
  44. package/src/lib/providers/openai.ts +8 -5
  45. package/src/lib/providers/opencode-cli.ts +6 -2
  46. package/src/lib/server/agents/agent-registry.ts +20 -3
  47. package/src/lib/server/agents/main-agent-loop.ts +4 -3
  48. package/src/lib/server/autonomy/supervisor-reflection.ts +14 -1
  49. package/src/lib/server/chat-execution/chat-execution.ts +14 -2
  50. package/src/lib/server/chat-execution/continuation-evaluator.ts +4 -3
  51. package/src/lib/server/chat-execution/continuation-limits.ts +6 -3
  52. package/src/lib/server/chat-execution/message-classifier.ts +5 -2
  53. package/src/lib/server/chat-execution/post-stream-finalization.ts +4 -1
  54. package/src/lib/server/chat-execution/prompt-builder.ts +11 -1
  55. package/src/lib/server/chat-execution/prompt-sections.ts +52 -9
  56. package/src/lib/server/chat-execution/response-completeness.ts +5 -2
  57. package/src/lib/server/chat-execution/stream-agent-chat.ts +42 -12
  58. package/src/lib/server/chatrooms/chatroom-memory-bridge.ts +6 -3
  59. package/src/lib/server/connectors/bluebubbles.ts +7 -4
  60. package/src/lib/server/connectors/connector-inbound.ts +16 -13
  61. package/src/lib/server/connectors/connector-lifecycle.ts +11 -8
  62. package/src/lib/server/connectors/connector-outbound.ts +6 -3
  63. package/src/lib/server/connectors/discord.ts +10 -7
  64. package/src/lib/server/connectors/email.ts +17 -14
  65. package/src/lib/server/connectors/googlechat.ts +7 -4
  66. package/src/lib/server/connectors/inbound-audio-transcription.ts +5 -2
  67. package/src/lib/server/connectors/matrix.ts +6 -3
  68. package/src/lib/server/connectors/openclaw.ts +20 -17
  69. package/src/lib/server/connectors/outbox.ts +4 -1
  70. package/src/lib/server/connectors/runtime-state.ts +19 -0
  71. package/src/lib/server/connectors/session-consolidation.ts +5 -2
  72. package/src/lib/server/connectors/signal.ts +9 -6
  73. package/src/lib/server/connectors/slack.ts +13 -10
  74. package/src/lib/server/connectors/teams.ts +8 -5
  75. package/src/lib/server/connectors/telegram.ts +15 -12
  76. package/src/lib/server/connectors/whatsapp.ts +32 -29
  77. package/src/lib/server/embeddings.ts +4 -1
  78. package/src/lib/server/link-understanding.ts +4 -1
  79. package/src/lib/server/memory/memory-abstract.ts +59 -0
  80. package/src/lib/server/memory/memory-db.ts +40 -14
  81. package/src/lib/server/missions/mission-service.ts +6 -3
  82. package/src/lib/server/openclaw/gateway.ts +8 -5
  83. package/src/lib/server/project-utils.ts +13 -0
  84. package/src/lib/server/protocols/protocol-agent-turn.ts +5 -2
  85. package/src/lib/server/protocols/protocol-run-lifecycle.ts +5 -2
  86. package/src/lib/server/protocols/protocol-step-helpers.ts +4 -1
  87. package/src/lib/server/provider-health.ts +18 -0
  88. package/src/lib/server/query-expansion.ts +4 -1
  89. package/src/lib/server/runtime/alert-dispatch.ts +7 -6
  90. package/src/lib/server/runtime/daemon-state.ts +189 -50
  91. package/src/lib/server/runtime/heartbeat-service.ts +23 -0
  92. package/src/lib/server/runtime/idle-window.ts +4 -1
  93. package/src/lib/server/runtime/perf.ts +4 -1
  94. package/src/lib/server/runtime/process-manager.ts +7 -4
  95. package/src/lib/server/runtime/queue.ts +31 -28
  96. package/src/lib/server/runtime/scheduler.ts +9 -6
  97. package/src/lib/server/runtime/session-run-manager.ts +3 -0
  98. package/src/lib/server/sandbox/bridge-auth-registry.ts +6 -0
  99. package/src/lib/server/sandbox/novnc-auth.ts +10 -0
  100. package/src/lib/server/session-tools/context.ts +14 -0
  101. package/src/lib/server/session-tools/discovery.ts +9 -6
  102. package/src/lib/server/session-tools/index.ts +3 -1
  103. package/src/lib/server/session-tools/platform.ts +1 -1
  104. package/src/lib/server/session-tools/subagent.ts +23 -2
  105. package/src/lib/server/session-tools/wallet.ts +4 -1
  106. package/src/lib/server/skills/clawhub-client.ts +4 -1
  107. package/src/lib/server/skills/runtime-skill-resolver.ts +8 -2
  108. package/src/lib/server/skills/skill-eligibility.ts +6 -0
  109. package/src/lib/server/solana.ts +6 -0
  110. package/src/lib/server/storage-auth.ts +5 -5
  111. package/src/lib/server/storage-normalization.ts +4 -0
  112. package/src/lib/server/storage.ts +19 -8
  113. package/src/lib/server/tasks/task-followups.ts +4 -1
  114. package/src/lib/server/tool-loop-detection.ts +8 -3
  115. package/src/lib/server/tool-planning.ts +226 -0
  116. package/src/lib/server/tool-retry.ts +4 -3
  117. package/src/lib/server/wallet/wallet-portfolio.ts +29 -0
  118. package/src/lib/server/ws-hub.ts +5 -2
  119. package/src/lib/strip-internal-metadata.test.ts +44 -4
  120. package/src/lib/strip-internal-metadata.ts +20 -6
  121. package/src/stores/use-approval-store.ts +7 -1
  122. package/src/stores/use-chat-store.ts +5 -1
  123. package/src/types/index.ts +6 -0
@@ -62,18 +62,23 @@ describe('stripLoopDetectionMessages', () => {
62
62
  expect(stripLoopDetectionMessages(input).trim()).toBe('')
63
63
  })
64
64
 
65
- it('strips generic repeat "has been called" messages', () => {
66
- const input = 'Tool "search" has been called 12 times with the same input. This appears to be a stuck loop.'
65
+ it('strips generic repeat "You called" messages', () => {
66
+ const input = 'You called "browser" 6 times with identical input. Input: "{"action":"screenshot"}" State your blocker or deliver what you have.'
67
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
68
+ })
69
+
70
+ it('strips generic repeat "You called" warning messages', () => {
71
+ const input = 'You called "search" 4 times with identical input. Input: "query" — Try a fundamentally different approach or deliver partial results.'
67
72
  expect(stripLoopDetectionMessages(input).trim()).toBe('')
68
73
  })
69
74
 
70
75
  it('strips "would repeat the same input" messages', () => {
71
- const input = 'Tool "search" would repeat the same input 12 times. Blocking before it becomes a stuck loop.'
76
+ const input = '"search" would repeat the same input 12 times. Input: "query" State your blocker or deliver what you have.'
72
77
  expect(stripLoopDetectionMessages(input).trim()).toBe('')
73
78
  })
74
79
 
75
80
  it('strips "is about to repeat the same input" messages', () => {
76
- const input = 'Tool "search" is about to repeat the same input 6 times. Consider a different approach.'
81
+ const input = '"search" is about to repeat the same input 6 times. Input: "query" — Try a different approach.'
77
82
  expect(stripLoopDetectionMessages(input).trim()).toBe('')
78
83
  })
79
84
 
@@ -102,6 +107,41 @@ describe('stripLoopDetectionMessages', () => {
102
107
  expect(stripLoopDetectionMessages(input).trim()).toBe('')
103
108
  })
104
109
 
110
+ it('strips output stagnation messages', () => {
111
+ const input = 'Output stagnation: last 8 tool calls all produced identical output. The approach is not working — try something fundamentally different or report the blocker.'
112
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
113
+ })
114
+
115
+ it('strips output stagnation warning messages', () => {
116
+ const input = 'Output stagnation: 6 of the last 8 tool calls produced identical output. Your tools may not be making progress.'
117
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
118
+ })
119
+
120
+ it('strips error convergence messages', () => {
121
+ const input = 'Error convergence: 5 of the last 6 tool calls returned errors. Stop retrying and report the underlying issue (likely an infrastructure or configuration problem).'
122
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
123
+ })
124
+
125
+ it('strips error convergence warning messages', () => {
126
+ const input = 'Error convergence: 4 of the last 6 tool calls returned errors. You may be hitting a systemic issue — consider a different approach or report the blocker.'
127
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
128
+ })
129
+
130
+ it('strips messages wrapped in [Error: ...] brackets', () => {
131
+ const input = '[Error: You called "browser" 6 times with identical input. Input: "{"action":"screenshot"}" — State your blocker or deliver what you have.]'
132
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
133
+ })
134
+
135
+ it('strips [Error: ...] wrapped tool frequency messages', () => {
136
+ const input = '[Error: Tool "shell" called 30 times this turn. Excessive repetition — wrap up with available results.]'
137
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
138
+ })
139
+
140
+ it('strips [Error: ...] wrapped output stagnation messages', () => {
141
+ const input = '[Error: Output stagnation: last 8 tool calls all produced identical output.]'
142
+ expect(stripLoopDetectionMessages(input).trim()).toBe('')
143
+ })
144
+
105
145
  it('preserves normal text that mentions tools', () => {
106
146
  const input = 'I used the shell tool to run the command.'
107
147
  expect(stripLoopDetectionMessages(input)).toBe(input)
@@ -43,35 +43,49 @@ export function stripInternalJson(text: string): string {
43
43
  * - Tool "X" called N times ...
44
44
  * - Tool "X" would be called N times ...
45
45
  * - Tool "X" is nearing overuse ...
46
- * - Tool "X" has been called N times with the same input ...
47
- * - Tool "X" would repeat the same input N times ...
48
- * - Tool "X" is about to repeat the same input N times ...
46
+ * - You called "X" N times with identical input ...
47
+ * - "X" would repeat the same input N times ...
48
+ * - "X" is about to repeat the same input N times ...
49
49
  * - Circuit breaker: "X" called N times ...
50
50
  * - Circuit breaker: "X" would be called N times ...
51
51
  * - Polling stall: "X" returned identical output N times ...
52
52
  * - Ping-pong: "X" and "Y" are alternating ...
53
53
  * - Ping-pong: "X" and "Y" may be stuck ...
54
+ * - Output stagnation: last N / N of the last N ...
55
+ * - Error convergence: N of the last N ...
54
56
  */
55
57
  const LOOP_DETECTION_RE = new RegExp(
56
58
  [
57
59
  // Tool frequency: called / would be called / nearing overuse
58
60
  String.raw`Tool "[^"]*" (?:called|would be called) \d+ times[^\n]*`,
59
61
  String.raw`Tool "[^"]*" is nearing overuse[^\n]*`,
60
- // Generic repeat: has been called / would repeat / is about to repeat
61
- String.raw`Tool "[^"]*" (?:has been called|would repeat the same input|is about to repeat the same input) \d+ times[^\n]*`,
62
+ // Generic repeat: "You called" (post-call) / "X" would repeat / is about to repeat (preview)
63
+ String.raw`You called "[^"]*" \d+ times[^\n]*`,
64
+ String.raw`"[^"]*" (?:would repeat the same input|is about to repeat the same input) \d+ times[^\n]*`,
62
65
  // Circuit breaker
63
66
  String.raw`Circuit breaker: "[^"]*" (?:called|would be called) \d+ times[^\n]*`,
64
67
  // Polling stall
65
68
  String.raw`Polling stall: "[^"]*" returned identical output \d+ times[^\n]*`,
66
69
  // Ping-pong
67
70
  String.raw`Ping-pong: "[^"]*" and "[^"]*" (?:are alternating|may be stuck)[^\n]*`,
71
+ // Output stagnation
72
+ String.raw`Output stagnation:[^\n]*`,
73
+ // Error convergence
74
+ String.raw`Error convergence:[^\n]*`,
68
75
  ].join('|'),
69
76
  'g',
70
77
  )
71
78
 
79
+ /**
80
+ * Matches loop detection messages wrapped in `[Error: ...]` brackets
81
+ * (from the err SSE event handler in use-chat-store.ts).
82
+ */
83
+ const LOOP_DETECTION_WRAPPED_RE = /\[Error: (?:Tool "[^"]*" (?:called|would be called) \d+ times|Tool "[^"]*" is nearing overuse|You called "[^"]*" \d+ times|"[^"]*" (?:would repeat the same input|is about to repeat the same input) \d+ times|Circuit breaker: "[^"]*" (?:called|would be called) \d+ times|Polling stall: "[^"]*" returned identical output \d+ times|Ping-pong: "[^"]*" and "[^"]*" (?:are alternating|may be stuck)|Output stagnation:|Error convergence:)[^\]]*\]/g
84
+
72
85
  /** Remove loop detection messages that the LLM echoed from tool error results. */
73
86
  export function stripLoopDetectionMessages(text: string): string {
74
- return text.replace(LOOP_DETECTION_RE, '')
87
+ // Strip [Error: ...] wrapped versions first, before the inner regex eats the content
88
+ return text.replace(LOOP_DETECTION_WRAPPED_RE, '').replace(LOOP_DETECTION_RE, '')
75
89
  }
76
90
 
77
91
  // ---------------------------------------------------------------------------
@@ -76,7 +76,13 @@ export const useApprovalStore = create<ApprovalState>((set) => ({
76
76
  for (const [id, a] of Object.entries(s.approvals)) {
77
77
  if (a.expiresAtMs > now && !s.resolvedIds.has(id)) next[id] = a
78
78
  }
79
- return { approvals: next }
79
+ // Prune resolvedIds for IDs no longer in the approval set
80
+ const liveIds = new Set(Object.keys(next))
81
+ const nextResolved = new Set<string>()
82
+ for (const id of s.resolvedIds) {
83
+ if (liveIds.has(id)) nextResolved.add(id)
84
+ }
85
+ return { approvals: next, resolvedIds: nextResolved }
80
86
  })
81
87
  },
82
88
 
@@ -418,7 +418,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
418
418
  let toolCallCounter = 0
419
419
  let soundFiredStart = false
420
420
  const shouldIgnoreTransientError = (msg: string) =>
421
- /cancelled by steer mode|stopped by user/i.test(msg || '')
421
+ /cancelled by steer mode|stopped by user|stream timed out/i.test(msg || '')
422
422
 
423
423
  try { await streamChat(sessionId, text, imagePath, imageUrl, (event: SSEEvent) => {
424
424
  // Forward events to voice conversation handler if active
@@ -860,6 +860,10 @@ export const useChatStore = create<ChatState>((set, get) => ({
860
860
  displayText: '',
861
861
  streamPhase: 'thinking' as const,
862
862
  streamToolName: '',
863
+ thinkingText: '',
864
+ thinkingStartTime: 0,
865
+ toolEvents: [],
866
+ agentStatus: null,
863
867
  })
864
868
  },
865
869
  }))
@@ -452,6 +452,8 @@ export interface Session {
452
452
  theme?: string
453
453
  avatar?: string
454
454
  canvasContent?: CanvasContent
455
+ /** Tracks how many times each memory ID has been injected via proactive recall in this session. */
456
+ injectedMemoryIds?: Record<string, number>
455
457
  }
456
458
 
457
459
  export type Sessions = Record<string, Session>
@@ -1545,6 +1547,7 @@ export interface MemoryEntry {
1545
1547
  lastAccessedAt?: number
1546
1548
  contentHash?: string
1547
1549
  reinforcementCount?: number
1550
+ abstract?: string | null
1548
1551
  createdAt: number
1549
1552
  updatedAt: number
1550
1553
  }
@@ -2147,6 +2150,9 @@ export interface SessionRunRecord {
2147
2150
  recoveredFromRestart?: boolean
2148
2151
  recoveredFromRunId?: string
2149
2152
  recoveryPayload?: SessionRunRecoveryPayload
2153
+ totalInputTokens?: number
2154
+ totalOutputTokens?: number
2155
+ estimatedCost?: number
2150
2156
  }
2151
2157
 
2152
2158
  export interface SessionQueuedTurn {