@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.
- package/README.md +10 -0
- package/package.json +4 -1
- package/src/app/api/chats/[id]/deploy/route.ts +11 -6
- package/src/app/api/chats/[id]/devserver/route.ts +5 -2
- package/src/app/api/chats/[id]/messages/route.ts +7 -1
- package/src/app/api/credentials/[id]/route.ts +4 -1
- package/src/app/api/extensions/marketplace/route.ts +5 -2
- package/src/app/api/memory/maintenance/route.ts +5 -2
- package/src/app/api/preview-server/route.ts +14 -11
- package/src/app/api/system/status/route.ts +11 -0
- package/src/app/api/upload/route.ts +4 -1
- package/src/cli/index.js +7 -0
- package/src/cli/spec.js +1 -0
- package/src/components/agents/agent-files-editor.tsx +44 -32
- package/src/components/agents/personality-builder.tsx +13 -7
- package/src/components/agents/trash-list.tsx +1 -1
- package/src/components/chat/message-bubble.tsx +1 -0
- package/src/components/chat/message-list.tsx +25 -39
- package/src/components/chat/swarm-status-card.tsx +10 -3
- package/src/components/layout/daemon-indicator.tsx +7 -8
- package/src/components/layout/update-banner.tsx +8 -13
- package/src/components/logs/log-list.tsx +1 -1
- package/src/components/memory/memory-card.tsx +3 -1
- package/src/components/org-chart/org-chart-view.tsx +4 -0
- package/src/components/projects/project-list.tsx +4 -2
- package/src/components/projects/tabs/overview-tab.tsx +3 -2
- package/src/components/secrets/secret-sheet.tsx +1 -1
- package/src/components/secrets/secrets-list.tsx +1 -1
- package/src/components/shared/agent-switch-dialog.tsx +12 -6
- package/src/components/shared/dir-browser.tsx +22 -18
- package/src/components/skills/skill-sheet.tsx +2 -3
- package/src/components/tasks/task-list.tsx +1 -1
- package/src/components/tasks/task-sheet.tsx +1 -1
- package/src/hooks/use-openclaw-gateway.ts +46 -27
- package/src/instrumentation.ts +10 -7
- package/src/lib/chat/chat.ts +18 -2
- package/src/lib/providers/anthropic.ts +6 -3
- package/src/lib/providers/claude-cli.ts +9 -3
- package/src/lib/providers/cli-utils.ts +15 -0
- package/src/lib/providers/codex-cli.ts +9 -3
- package/src/lib/providers/gemini-cli.ts +6 -2
- package/src/lib/providers/index.ts +4 -1
- package/src/lib/providers/ollama.ts +5 -2
- package/src/lib/providers/openai.ts +8 -5
- package/src/lib/providers/opencode-cli.ts +6 -2
- package/src/lib/server/agents/agent-registry.ts +20 -3
- package/src/lib/server/agents/main-agent-loop.ts +4 -3
- package/src/lib/server/autonomy/supervisor-reflection.ts +14 -1
- package/src/lib/server/chat-execution/chat-execution.ts +14 -2
- package/src/lib/server/chat-execution/continuation-evaluator.ts +4 -3
- package/src/lib/server/chat-execution/continuation-limits.ts +6 -3
- package/src/lib/server/chat-execution/message-classifier.ts +5 -2
- package/src/lib/server/chat-execution/post-stream-finalization.ts +4 -1
- package/src/lib/server/chat-execution/prompt-builder.ts +11 -1
- package/src/lib/server/chat-execution/prompt-sections.ts +52 -9
- package/src/lib/server/chat-execution/response-completeness.ts +5 -2
- package/src/lib/server/chat-execution/stream-agent-chat.ts +42 -12
- package/src/lib/server/chatrooms/chatroom-memory-bridge.ts +6 -3
- package/src/lib/server/connectors/bluebubbles.ts +7 -4
- package/src/lib/server/connectors/connector-inbound.ts +16 -13
- package/src/lib/server/connectors/connector-lifecycle.ts +11 -8
- package/src/lib/server/connectors/connector-outbound.ts +6 -3
- package/src/lib/server/connectors/discord.ts +10 -7
- package/src/lib/server/connectors/email.ts +17 -14
- package/src/lib/server/connectors/googlechat.ts +7 -4
- package/src/lib/server/connectors/inbound-audio-transcription.ts +5 -2
- package/src/lib/server/connectors/matrix.ts +6 -3
- package/src/lib/server/connectors/openclaw.ts +20 -17
- package/src/lib/server/connectors/outbox.ts +4 -1
- package/src/lib/server/connectors/runtime-state.ts +19 -0
- package/src/lib/server/connectors/session-consolidation.ts +5 -2
- package/src/lib/server/connectors/signal.ts +9 -6
- package/src/lib/server/connectors/slack.ts +13 -10
- package/src/lib/server/connectors/teams.ts +8 -5
- package/src/lib/server/connectors/telegram.ts +15 -12
- package/src/lib/server/connectors/whatsapp.ts +32 -29
- package/src/lib/server/embeddings.ts +4 -1
- package/src/lib/server/link-understanding.ts +4 -1
- package/src/lib/server/memory/memory-abstract.ts +59 -0
- package/src/lib/server/memory/memory-db.ts +40 -14
- package/src/lib/server/missions/mission-service.ts +6 -3
- package/src/lib/server/openclaw/gateway.ts +8 -5
- package/src/lib/server/project-utils.ts +13 -0
- package/src/lib/server/protocols/protocol-agent-turn.ts +5 -2
- package/src/lib/server/protocols/protocol-run-lifecycle.ts +5 -2
- package/src/lib/server/protocols/protocol-step-helpers.ts +4 -1
- package/src/lib/server/provider-health.ts +18 -0
- package/src/lib/server/query-expansion.ts +4 -1
- package/src/lib/server/runtime/alert-dispatch.ts +7 -6
- package/src/lib/server/runtime/daemon-state.ts +189 -50
- package/src/lib/server/runtime/heartbeat-service.ts +23 -0
- package/src/lib/server/runtime/idle-window.ts +4 -1
- package/src/lib/server/runtime/perf.ts +4 -1
- package/src/lib/server/runtime/process-manager.ts +7 -4
- package/src/lib/server/runtime/queue.ts +31 -28
- package/src/lib/server/runtime/scheduler.ts +9 -6
- package/src/lib/server/runtime/session-run-manager.ts +3 -0
- package/src/lib/server/sandbox/bridge-auth-registry.ts +6 -0
- package/src/lib/server/sandbox/novnc-auth.ts +10 -0
- package/src/lib/server/session-tools/context.ts +14 -0
- package/src/lib/server/session-tools/discovery.ts +9 -6
- package/src/lib/server/session-tools/index.ts +3 -1
- package/src/lib/server/session-tools/platform.ts +1 -1
- package/src/lib/server/session-tools/subagent.ts +23 -2
- package/src/lib/server/session-tools/wallet.ts +4 -1
- package/src/lib/server/skills/clawhub-client.ts +4 -1
- package/src/lib/server/skills/runtime-skill-resolver.ts +8 -2
- package/src/lib/server/skills/skill-eligibility.ts +6 -0
- package/src/lib/server/solana.ts +6 -0
- package/src/lib/server/storage-auth.ts +5 -5
- package/src/lib/server/storage-normalization.ts +4 -0
- package/src/lib/server/storage.ts +19 -8
- package/src/lib/server/tasks/task-followups.ts +4 -1
- package/src/lib/server/tool-loop-detection.ts +8 -3
- package/src/lib/server/tool-planning.ts +226 -0
- package/src/lib/server/tool-retry.ts +4 -3
- package/src/lib/server/wallet/wallet-portfolio.ts +29 -0
- package/src/lib/server/ws-hub.ts +5 -2
- package/src/lib/strip-internal-metadata.test.ts +44 -4
- package/src/lib/strip-internal-metadata.ts +20 -6
- package/src/stores/use-approval-store.ts +7 -1
- package/src/stores/use-chat-store.ts +5 -1
- 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 "
|
|
66
|
-
const input = '
|
|
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 = '
|
|
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 = '
|
|
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
|
-
* -
|
|
47
|
-
* -
|
|
48
|
-
* -
|
|
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:
|
|
61
|
-
String.raw`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}))
|
package/src/types/index.ts
CHANGED
|
@@ -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 {
|