@swarmclawai/swarmclaw 0.6.0 → 0.6.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 (118) hide show
  1. package/README.md +56 -42
  2. package/bin/server-cmd.js +1 -0
  3. package/package.json +2 -1
  4. package/src/app/api/canvas/[sessionId]/route.ts +31 -0
  5. package/src/app/api/chatrooms/[id]/chat/route.ts +10 -136
  6. package/src/app/api/connectors/[id]/route.ts +1 -0
  7. package/src/app/api/connectors/route.ts +2 -1
  8. package/src/app/api/files/open/route.ts +43 -0
  9. package/src/app/api/search/route.ts +9 -7
  10. package/src/app/api/sessions/[id]/messages/route.ts +70 -2
  11. package/src/app/api/sessions/[id]/route.ts +4 -0
  12. package/src/app/api/tasks/metrics/route.ts +101 -0
  13. package/src/app/api/tasks/route.ts +17 -2
  14. package/src/app/api/tts/route.ts +16 -35
  15. package/src/app/api/tts/stream/route.ts +14 -42
  16. package/src/app/api/uploads/[filename]/route.ts +19 -34
  17. package/src/app/api/uploads/route.ts +94 -0
  18. package/src/app/globals.css +5 -0
  19. package/src/cli/index.js +16 -1
  20. package/src/cli/spec.js +26 -0
  21. package/src/components/agents/agent-card.tsx +3 -3
  22. package/src/components/agents/agent-chat-list.tsx +29 -6
  23. package/src/components/agents/agent-sheet.tsx +66 -4
  24. package/src/components/agents/inspector-panel.tsx +81 -6
  25. package/src/components/agents/openclaw-skills-panel.tsx +32 -3
  26. package/src/components/agents/personality-builder.tsx +42 -14
  27. package/src/components/agents/soul-library-picker.tsx +89 -0
  28. package/src/components/canvas/canvas-panel.tsx +96 -0
  29. package/src/components/chat/activity-moment.tsx +8 -4
  30. package/src/components/chat/chat-area.tsx +76 -24
  31. package/src/components/chat/chat-header.tsx +522 -286
  32. package/src/components/chat/chat-preview-panel.tsx +1 -2
  33. package/src/components/chat/delegation-banner.tsx +371 -0
  34. package/src/components/chat/file-path-chip.tsx +23 -2
  35. package/src/components/chat/heartbeat-history-panel.tsx +269 -0
  36. package/src/components/chat/message-bubble.tsx +315 -25
  37. package/src/components/chat/message-list.tsx +113 -8
  38. package/src/components/chat/streaming-bubble.tsx +68 -1
  39. package/src/components/chat/tool-call-bubble.tsx +45 -3
  40. package/src/components/chat/transfer-agent-picker.tsx +1 -1
  41. package/src/components/chatrooms/chatroom-list.tsx +8 -1
  42. package/src/components/chatrooms/chatroom-message.tsx +8 -3
  43. package/src/components/chatrooms/chatroom-view.tsx +3 -3
  44. package/src/components/connectors/connector-list.tsx +168 -90
  45. package/src/components/connectors/connector-sheet.tsx +84 -17
  46. package/src/components/home/home-view.tsx +1 -1
  47. package/src/components/input/chat-input.tsx +28 -2
  48. package/src/components/layout/app-layout.tsx +19 -2
  49. package/src/components/projects/project-detail.tsx +1 -1
  50. package/src/components/schedules/schedule-sheet.tsx +260 -127
  51. package/src/components/settings/gateway-disconnect-overlay.tsx +80 -0
  52. package/src/components/shared/agent-switch-dialog.tsx +1 -1
  53. package/src/components/shared/chatroom-picker-list.tsx +61 -0
  54. package/src/components/shared/connector-platform-icon.tsx +51 -4
  55. package/src/components/shared/icon-button.tsx +16 -2
  56. package/src/components/shared/keyboard-shortcuts-dialog.tsx +1 -1
  57. package/src/components/shared/search-dialog.tsx +17 -10
  58. package/src/components/shared/settings/section-embedding.tsx +48 -13
  59. package/src/components/shared/settings/section-orchestrator.tsx +46 -15
  60. package/src/components/shared/settings/section-storage.tsx +206 -0
  61. package/src/components/shared/settings/section-user-preferences.tsx +18 -0
  62. package/src/components/shared/settings/section-voice.tsx +42 -21
  63. package/src/components/shared/settings/section-web-search.tsx +30 -6
  64. package/src/components/shared/settings/settings-page.tsx +3 -1
  65. package/src/components/shared/settings/storage-browser.tsx +259 -0
  66. package/src/components/tasks/task-card.tsx +14 -1
  67. package/src/components/tasks/task-sheet.tsx +328 -3
  68. package/src/components/usage/metrics-dashboard.tsx +90 -6
  69. package/src/hooks/use-continuous-speech.ts +10 -4
  70. package/src/hooks/use-voice-conversation.ts +53 -10
  71. package/src/hooks/use-ws.ts +4 -2
  72. package/src/lib/providers/anthropic.ts +13 -7
  73. package/src/lib/providers/index.ts +1 -0
  74. package/src/lib/providers/openai.ts +13 -7
  75. package/src/lib/server/chat-execution.ts +125 -14
  76. package/src/lib/server/chatroom-helpers.ts +146 -0
  77. package/src/lib/server/connectors/connector-routing.test.ts +118 -1
  78. package/src/lib/server/connectors/discord.ts +31 -8
  79. package/src/lib/server/connectors/manager.ts +594 -16
  80. package/src/lib/server/connectors/media.ts +5 -0
  81. package/src/lib/server/connectors/telegram.ts +12 -2
  82. package/src/lib/server/connectors/types.ts +2 -0
  83. package/src/lib/server/connectors/whatsapp.ts +28 -2
  84. package/src/lib/server/elevenlabs.test.ts +60 -0
  85. package/src/lib/server/elevenlabs.ts +103 -0
  86. package/src/lib/server/heartbeat-service.ts +8 -1
  87. package/src/lib/server/main-agent-loop.ts +1 -1
  88. package/src/lib/server/memory-consolidation.ts +15 -2
  89. package/src/lib/server/memory-db.ts +134 -6
  90. package/src/lib/server/mime.ts +51 -0
  91. package/src/lib/server/openclaw-gateway.ts +2 -2
  92. package/src/lib/server/orchestrator-lg.ts +2 -0
  93. package/src/lib/server/orchestrator.ts +5 -2
  94. package/src/lib/server/playwright-proxy.mjs +2 -3
  95. package/src/lib/server/prompt-runtime-context.ts +53 -0
  96. package/src/lib/server/queue.ts +182 -8
  97. package/src/lib/server/session-tools/canvas.ts +67 -0
  98. package/src/lib/server/session-tools/connector.ts +583 -63
  99. package/src/lib/server/session-tools/crud.ts +21 -0
  100. package/src/lib/server/session-tools/delegate.ts +68 -4
  101. package/src/lib/server/session-tools/file.ts +26 -7
  102. package/src/lib/server/session-tools/git.ts +71 -0
  103. package/src/lib/server/session-tools/http.ts +57 -0
  104. package/src/lib/server/session-tools/index.ts +8 -0
  105. package/src/lib/server/session-tools/memory.ts +1 -0
  106. package/src/lib/server/session-tools/search-providers.ts +16 -8
  107. package/src/lib/server/session-tools/subagent.ts +106 -0
  108. package/src/lib/server/session-tools/web.ts +118 -8
  109. package/src/lib/server/stream-agent-chat.ts +39 -10
  110. package/src/lib/server/task-mention.ts +41 -0
  111. package/src/lib/sessions.ts +10 -0
  112. package/src/lib/soul-library.ts +103 -0
  113. package/src/lib/task-dedupe.ts +26 -0
  114. package/src/lib/tool-definitions.ts +2 -0
  115. package/src/lib/tts.ts +2 -2
  116. package/src/stores/use-app-store.ts +5 -1
  117. package/src/stores/use-chat-store.ts +65 -2
  118. package/src/types/index.ts +32 -2
@@ -103,6 +103,15 @@ interface ChatState {
103
103
  addQueuedMessage: (text: string) => void
104
104
  removeQueuedMessage: (index: number) => void
105
105
  shiftQueuedMessage: () => string | undefined
106
+
107
+ // Context clearing
108
+ clearContext: () => Promise<void>
109
+
110
+ // Pagination
111
+ hasMoreMessages: boolean
112
+ loadingMore: boolean
113
+ totalMessages: number
114
+ loadMoreMessages: () => Promise<void>
106
115
  }
107
116
 
108
117
  // Module-level cadence interval (not in state to avoid re-renders)
@@ -130,7 +139,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
130
139
  displayText: '',
131
140
  agentStatus: null,
132
141
  messages: [],
133
- setMessages: (msgs) => set({ messages: msgs, toolEvents: [] }),
142
+ setMessages: (msgs) => set({ messages: msgs, toolEvents: [], hasMoreMessages: false, totalMessages: msgs.length }),
134
143
  toolEvents: [],
135
144
  clearToolEvents: () => set({ toolEvents: [] }),
136
145
  lastUsage: null,
@@ -276,7 +285,7 @@ export const useChatStore = create<ChatState>((set, get) => ({
276
285
  set({ displayText: fullText })
277
286
  }
278
287
  } else if (event.t === 'md') {
279
- // Parse metadata events (usage/run/queue). Ignore unknown keys.
288
+ // Parse metadata events (usage/run/queue/thinking). Ignore unknown keys.
280
289
  try {
281
290
  const meta = JSON.parse(event.text || '{}')
282
291
  if (meta.usage) {
@@ -285,6 +294,9 @@ export const useChatStore = create<ChatState>((set, get) => ({
285
294
  if (meta.suggestions) {
286
295
  suggestions = meta.suggestions
287
296
  }
297
+ if (meta.thinking && typeof meta.thinking === 'string') {
298
+ set({ thinkingText: meta.thinking })
299
+ }
288
300
  } catch {
289
301
  // Ignore non-JSON metadata payloads.
290
302
  }
@@ -349,11 +361,13 @@ export const useChatStore = create<ChatState>((set, get) => ({
349
361
  if (get().soundEnabled && soundFiredStart) playStreamEnd()
350
362
  if (fullText.trim()) {
351
363
  const currentToolEvents = get().toolEvents
364
+ const thinkingSnapshot = get().thinkingText || undefined
352
365
  const assistantMsg: Message = {
353
366
  role: 'assistant',
354
367
  text: fullText.trim(),
355
368
  time: Date.now(),
356
369
  kind: 'chat',
370
+ thinking: thinkingSnapshot,
357
371
  toolEvents: currentToolEvents.length ? currentToolEvents.map(e => ({
358
372
  name: e.name,
359
373
  input: e.input,
@@ -525,6 +539,55 @@ export const useChatStore = create<ChatState>((set, get) => ({
525
539
  useAppStore.getState().loadSessions()
526
540
  },
527
541
 
542
+ clearContext: async () => {
543
+ const sessionId = useAppStore.getState().currentSessionId
544
+ if (!sessionId || get().streaming) return
545
+ const marker: Message = { role: 'user', text: '', kind: 'context-clear', time: Date.now() }
546
+ set((s) => ({ messages: [...s.messages, marker] }))
547
+ try {
548
+ const key = getStoredAccessKey()
549
+ await fetch(`/api/sessions/${sessionId}/messages`, {
550
+ method: 'POST',
551
+ headers: { 'Content-Type': 'application/json', ...(key ? { 'X-Access-Key': key } : {}) },
552
+ body: JSON.stringify({ kind: 'context-clear' }),
553
+ })
554
+ } catch {
555
+ // Ignore — marker is already in local state
556
+ }
557
+ },
558
+
559
+ hasMoreMessages: false,
560
+ loadingMore: false,
561
+ totalMessages: 0,
562
+ loadMoreMessages: async () => {
563
+ const { messages, loadingMore, hasMoreMessages, totalMessages } = get()
564
+ if (loadingMore || !hasMoreMessages) return
565
+ const sessionId = useAppStore.getState().currentSessionId
566
+ if (!sessionId) return
567
+ set({ loadingMore: true })
568
+ try {
569
+ const key = getStoredAccessKey()
570
+ // Find the earliest message's original index (startIndex tracked on initial load)
571
+ const currentStartIndex = totalMessages - messages.length
572
+ const res = await fetch(`/api/sessions/${sessionId}/messages?limit=100&before=${currentStartIndex}`, {
573
+ headers: key ? { 'X-Access-Key': key } : undefined,
574
+ })
575
+ if (res.ok) {
576
+ const data = await res.json() as { messages: Message[]; total: number; hasMore: boolean; startIndex: number }
577
+ set((s) => ({
578
+ messages: [...data.messages, ...s.messages],
579
+ hasMoreMessages: data.hasMore,
580
+ totalMessages: data.total,
581
+ loadingMore: false,
582
+ }))
583
+ } else {
584
+ set({ loadingMore: false })
585
+ }
586
+ } catch {
587
+ set({ loadingMore: false })
588
+ }
589
+ },
590
+
528
591
  stopStreaming: async () => {
529
592
  const sessionId = useAppStore.getState().currentSessionId
530
593
  if (sessionId) {
@@ -13,11 +13,13 @@ export interface Message {
13
13
  imageUrl?: string
14
14
  attachedFiles?: string[]
15
15
  toolEvents?: MessageToolEvent[]
16
- kind?: 'chat' | 'heartbeat' | 'system'
16
+ thinking?: string
17
+ kind?: 'chat' | 'heartbeat' | 'system' | 'context-clear'
17
18
  suppressed?: boolean
18
19
  bookmarked?: boolean
19
20
  suggestions?: string[]
20
21
  replyToId?: string
22
+ source?: MessageSource
21
23
  }
22
24
 
23
25
  export type ProviderType = 'claude-cli' | 'codex-cli' | 'opencode-cli' | 'openai' | 'ollama' | 'anthropic' | 'openclaw' | 'google' | 'deepseek' | 'groq' | 'together' | 'mistral' | 'xai' | 'fireworks'
@@ -114,6 +116,7 @@ export interface Session {
114
116
  queuedCount?: number
115
117
  currentRunId?: string | null
116
118
  conversationTone?: string
119
+ canvasContent?: string | null
117
120
  }
118
121
 
119
122
  export type Sessions = Record<string, Session>
@@ -128,6 +131,10 @@ export type SessionTool =
128
131
  | 'web_fetch'
129
132
  | 'edit_file'
130
133
  | 'process'
134
+ | 'spawn_subagent'
135
+ | 'canvas'
136
+ | 'http_request'
137
+ | 'git'
131
138
 
132
139
  // --- Cost Tracking ---
133
140
 
@@ -254,6 +261,7 @@ export interface Agent {
254
261
  heartbeatGoal?: string | null
255
262
  heartbeatNextAction?: string | null
256
263
  thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high'
264
+ elevenLabsVoiceId?: string | null
257
265
  projectId?: string
258
266
  avatarSeed?: string
259
267
  pinned?: boolean
@@ -339,6 +347,10 @@ export interface MemoryEntry {
339
347
  linkedMemoryIds?: string[]
340
348
  pinned?: boolean
341
349
  sharedWith?: string[]
350
+ accessCount?: number
351
+ lastAccessedAt?: number
352
+ contentHash?: string
353
+ reinforcementCount?: number
342
354
  createdAt: number
343
355
  updatedAt: number
344
356
  }
@@ -367,6 +379,7 @@ export interface ChatroomMessage {
367
379
  attachedFiles?: string[]
368
380
  imagePath?: string
369
381
  replyToId?: string
382
+ source?: MessageSource
370
383
  }
371
384
 
372
385
  export interface Chatroom {
@@ -503,9 +516,12 @@ export interface AppSettings {
503
516
  claudeCodeTimeoutSec?: number
504
517
  cliProcessTimeoutSec?: number
505
518
  userAvatarSeed?: string
519
+ elevenLabsEnabled?: boolean
506
520
  elevenLabsApiKey?: string | null
507
521
  elevenLabsVoiceId?: string | null
508
522
  speechRecognitionLang?: string | null
523
+ tavilyApiKey?: string | null
524
+ braveApiKey?: string | null
509
525
  heartbeatPrompt?: string | null
510
526
  heartbeatIntervalSec?: number | null
511
527
  heartbeatInterval?: string | number | null
@@ -545,6 +561,8 @@ export interface AppSettings {
545
561
  maxLinkedMemoriesExpanded?: number
546
562
  memoryMaxDepth?: number
547
563
  memoryMaxPerLookup?: number
564
+ // Chat UX
565
+ suggestionsEnabled?: boolean
548
566
  // Voice conversation
549
567
  voiceAutoSendDelaySec?: number
550
568
  // Default agent for main chat on startup
@@ -624,11 +642,19 @@ export interface Skill {
624
642
  export type ConnectorPlatform = 'discord' | 'telegram' | 'slack' | 'whatsapp' | 'openclaw' | 'bluebubbles' | 'signal' | 'teams' | 'googlechat' | 'matrix'
625
643
  export type ConnectorStatus = 'stopped' | 'running' | 'error'
626
644
 
645
+ export interface MessageSource {
646
+ platform: ConnectorPlatform
647
+ connectorId: string
648
+ connectorName: string
649
+ senderName?: string
650
+ }
651
+
627
652
  export interface Connector {
628
653
  id: string
629
654
  name: string
630
655
  platform: ConnectorPlatform
631
- agentId: string // which agent handles incoming messages
656
+ agentId?: string | null // which agent handles incoming messages (optional if using chatroomId)
657
+ chatroomId?: string | null // route to a chatroom instead of a single agent
632
658
  credentialId?: string | null // bot token stored as encrypted credential
633
659
  config: Record<string, string> // platform-specific settings
634
660
  isEnabled: boolean
@@ -736,6 +762,10 @@ export interface BoardTask {
736
762
  dueAt?: number | null
737
763
  // Custom fields
738
764
  customFields?: Record<string, string | number | boolean>
765
+ // Priority
766
+ priority?: 'low' | 'medium' | 'high' | 'critical'
767
+ // Dedup fingerprint
768
+ fingerprint?: string
739
769
  }
740
770
 
741
771
  // --- MCP Servers ---