@swarmclawai/swarmclaw 0.7.1 → 0.7.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 (237) hide show
  1. package/README.md +155 -150
  2. package/package.json +1 -1
  3. package/src/app/api/agents/[id]/route.ts +26 -0
  4. package/src/app/api/agents/[id]/thread/route.ts +37 -9
  5. package/src/app/api/agents/route.ts +13 -2
  6. package/src/app/api/auth/route.ts +76 -7
  7. package/src/app/api/chatrooms/[id]/chat/route.ts +7 -2
  8. package/src/app/api/{sessions → chats}/[id]/browser/route.ts +5 -1
  9. package/src/app/api/{sessions → chats}/[id]/chat/route.ts +7 -3
  10. package/src/app/api/{sessions → chats}/[id]/checkpoints/route.ts +1 -1
  11. package/src/app/api/chats/[id]/main-loop/route.ts +13 -0
  12. package/src/app/api/{sessions → chats}/[id]/messages/route.ts +19 -13
  13. package/src/app/api/{sessions → chats}/[id]/restore/route.ts +1 -1
  14. package/src/app/api/{sessions → chats}/[id]/route.ts +22 -52
  15. package/src/app/api/{sessions → chats}/[id]/stop/route.ts +6 -1
  16. package/src/app/api/{sessions → chats}/route.ts +21 -7
  17. package/src/app/api/connectors/[id]/doctor/route.ts +26 -0
  18. package/src/app/api/connectors/doctor/route.ts +13 -0
  19. package/src/app/api/files/open/route.ts +16 -14
  20. package/src/app/api/memory/maintenance/route.ts +11 -1
  21. package/src/app/api/openclaw/agent-files/route.ts +27 -4
  22. package/src/app/api/openclaw/skills/route.ts +11 -3
  23. package/src/app/api/plugins/dependencies/route.ts +24 -0
  24. package/src/app/api/plugins/install/route.ts +15 -92
  25. package/src/app/api/plugins/route.ts +6 -26
  26. package/src/app/api/plugins/settings/route.ts +40 -0
  27. package/src/app/api/plugins/ui/route.ts +1 -0
  28. package/src/app/api/settings/route.ts +49 -7
  29. package/src/app/api/tasks/[id]/route.ts +15 -6
  30. package/src/app/api/tasks/bulk/route.ts +2 -2
  31. package/src/app/api/tasks/route.ts +9 -4
  32. package/src/app/api/usage/route.ts +30 -0
  33. package/src/app/api/webhooks/[id]/route.ts +8 -1
  34. package/src/app/page.tsx +9 -2
  35. package/src/cli/index.js +39 -33
  36. package/src/cli/index.ts +43 -49
  37. package/src/cli/spec.js +29 -27
  38. package/src/components/agents/agent-card.tsx +16 -13
  39. package/src/components/agents/agent-chat-list.tsx +104 -4
  40. package/src/components/agents/agent-list.tsx +54 -22
  41. package/src/components/agents/agent-sheet.tsx +209 -18
  42. package/src/components/agents/cron-job-form.tsx +3 -3
  43. package/src/components/agents/inspector-panel.tsx +110 -50
  44. package/src/components/auth/access-key-gate.tsx +36 -97
  45. package/src/components/auth/setup-wizard.tsx +5 -38
  46. package/src/components/chat/chat-area.tsx +39 -27
  47. package/src/components/{sessions/session-card.tsx → chat/chat-card.tsx} +7 -23
  48. package/src/components/chat/chat-header.tsx +299 -314
  49. package/src/components/{sessions/session-list.tsx → chat/chat-list.tsx} +11 -14
  50. package/src/components/chat/chat-tool-toggles.tsx +26 -17
  51. package/src/components/chat/checkpoint-timeline.tsx +4 -4
  52. package/src/components/chat/message-bubble.tsx +4 -1
  53. package/src/components/chat/message-list.tsx +5 -3
  54. package/src/components/chat/session-debug-panel.tsx +1 -1
  55. package/src/components/chat/tool-request-banner.tsx +3 -3
  56. package/src/components/chatrooms/agent-hover-card.tsx +3 -3
  57. package/src/components/chatrooms/chatroom-tool-request-banner.tsx +2 -2
  58. package/src/components/chatrooms/chatroom-view.tsx +347 -205
  59. package/src/components/connectors/connector-list.tsx +265 -127
  60. package/src/components/connectors/connector-sheet.tsx +218 -1
  61. package/src/components/home/home-view.tsx +129 -5
  62. package/src/components/layout/app-layout.tsx +392 -182
  63. package/src/components/layout/mobile-header.tsx +26 -8
  64. package/src/components/plugins/plugin-list.tsx +487 -254
  65. package/src/components/plugins/plugin-sheet.tsx +236 -13
  66. package/src/components/projects/project-detail.tsx +183 -0
  67. package/src/components/settings/gateway-connection-panel.tsx +1 -1
  68. package/src/components/shared/agent-picker-list.tsx +2 -2
  69. package/src/components/shared/command-palette.tsx +111 -25
  70. package/src/components/shared/settings/plugin-manager.tsx +20 -4
  71. package/src/components/shared/settings/section-capability-policy.tsx +105 -0
  72. package/src/components/shared/settings/section-heartbeat.tsx +78 -1
  73. package/src/components/shared/settings/section-orchestrator.tsx +3 -3
  74. package/src/components/shared/settings/section-providers.tsx +1 -1
  75. package/src/components/shared/settings/section-runtime-loop.tsx +5 -5
  76. package/src/components/shared/settings/section-secrets.tsx +6 -6
  77. package/src/components/shared/settings/section-user-preferences.tsx +1 -1
  78. package/src/components/shared/settings/section-voice.tsx +5 -1
  79. package/src/components/shared/settings/section-web-search.tsx +10 -2
  80. package/src/components/shared/settings/settings-page.tsx +244 -56
  81. package/src/components/tasks/approvals-panel.tsx +205 -18
  82. package/src/components/tasks/task-board.tsx +242 -46
  83. package/src/components/usage/metrics-dashboard.tsx +147 -1
  84. package/src/components/wallets/wallet-panel.tsx +17 -5
  85. package/src/components/webhooks/webhook-sheet.tsx +8 -8
  86. package/src/lib/auth.ts +17 -0
  87. package/src/lib/chat-streaming-state.test.ts +108 -0
  88. package/src/lib/chat-streaming-state.ts +108 -0
  89. package/src/lib/chat.ts +1 -1
  90. package/src/lib/{sessions.ts → chats.ts} +28 -18
  91. package/src/lib/openclaw-agent-id.test.ts +14 -0
  92. package/src/lib/openclaw-agent-id.ts +31 -0
  93. package/src/lib/providers/claude-cli.ts +1 -1
  94. package/src/lib/server/agent-assignment.test.ts +112 -0
  95. package/src/lib/server/agent-assignment.ts +169 -0
  96. package/src/lib/server/approval-connector-notify.test.ts +253 -0
  97. package/src/lib/server/approvals-auto-approve.test.ts +205 -0
  98. package/src/lib/server/approvals.ts +483 -75
  99. package/src/lib/server/autonomy-runtime.test.ts +341 -0
  100. package/src/lib/server/browser-state.test.ts +118 -0
  101. package/src/lib/server/browser-state.ts +123 -0
  102. package/src/lib/server/build-llm.test.ts +36 -0
  103. package/src/lib/server/build-llm.ts +11 -4
  104. package/src/lib/server/builtin-plugins.ts +34 -0
  105. package/src/lib/server/capability-router.ts +10 -8
  106. package/src/lib/server/chat-execution-heartbeat.test.ts +40 -0
  107. package/src/lib/server/chat-execution-tool-events.test.ts +134 -0
  108. package/src/lib/server/chat-execution.ts +285 -165
  109. package/src/lib/server/chatroom-health.test.ts +26 -0
  110. package/src/lib/server/chatroom-health.ts +2 -3
  111. package/src/lib/server/chatroom-helpers.test.ts +67 -2
  112. package/src/lib/server/chatroom-helpers.ts +48 -8
  113. package/src/lib/server/connectors/discord.ts +175 -11
  114. package/src/lib/server/connectors/doctor.test.ts +80 -0
  115. package/src/lib/server/connectors/doctor.ts +116 -0
  116. package/src/lib/server/connectors/manager.ts +948 -112
  117. package/src/lib/server/connectors/policy.test.ts +222 -0
  118. package/src/lib/server/connectors/policy.ts +452 -0
  119. package/src/lib/server/connectors/slack.ts +188 -9
  120. package/src/lib/server/connectors/telegram.ts +65 -15
  121. package/src/lib/server/connectors/thread-context.test.ts +44 -0
  122. package/src/lib/server/connectors/thread-context.ts +72 -0
  123. package/src/lib/server/connectors/types.ts +41 -11
  124. package/src/lib/server/cost.ts +34 -1
  125. package/src/lib/server/daemon-state.ts +61 -3
  126. package/src/lib/server/data-dir.ts +13 -0
  127. package/src/lib/server/delegation-jobs.test.ts +140 -0
  128. package/src/lib/server/delegation-jobs.ts +248 -0
  129. package/src/lib/server/document-utils.test.ts +47 -0
  130. package/src/lib/server/document-utils.ts +397 -0
  131. package/src/lib/server/heartbeat-service.ts +14 -40
  132. package/src/lib/server/heartbeat-source.test.ts +22 -0
  133. package/src/lib/server/heartbeat-source.ts +7 -0
  134. package/src/lib/server/identity-continuity.test.ts +77 -0
  135. package/src/lib/server/identity-continuity.ts +127 -0
  136. package/src/lib/server/mailbox-utils.ts +347 -0
  137. package/src/lib/server/main-agent-loop.ts +28 -1103
  138. package/src/lib/server/memory-db.ts +4 -6
  139. package/src/lib/server/memory-tiers.ts +40 -0
  140. package/src/lib/server/openclaw-agent-resolver.test.ts +70 -0
  141. package/src/lib/server/openclaw-agent-resolver.ts +128 -0
  142. package/src/lib/server/openclaw-exec-config.ts +5 -6
  143. package/src/lib/server/openclaw-skills-normalize.test.ts +56 -0
  144. package/src/lib/server/openclaw-skills-normalize.ts +136 -0
  145. package/src/lib/server/openclaw-sync.ts +3 -2
  146. package/src/lib/server/orchestrator-lg.ts +20 -9
  147. package/src/lib/server/orchestrator.ts +7 -7
  148. package/src/lib/server/playwright-proxy.mjs +27 -3
  149. package/src/lib/server/plugins.test.ts +207 -0
  150. package/src/lib/server/plugins.ts +927 -66
  151. package/src/lib/server/provider-health.ts +38 -6
  152. package/src/lib/server/queue.ts +13 -28
  153. package/src/lib/server/scheduler.ts +2 -0
  154. package/src/lib/server/session-archive-memory.test.ts +85 -0
  155. package/src/lib/server/session-archive-memory.ts +230 -0
  156. package/src/lib/server/session-mailbox.ts +8 -18
  157. package/src/lib/server/session-reset-policy.test.ts +99 -0
  158. package/src/lib/server/session-reset-policy.ts +311 -0
  159. package/src/lib/server/session-run-manager.ts +33 -82
  160. package/src/lib/server/session-tools/autonomy-tools.test.ts +105 -0
  161. package/src/lib/server/session-tools/calendar.ts +366 -0
  162. package/src/lib/server/session-tools/canvas.ts +1 -1
  163. package/src/lib/server/session-tools/chatroom.ts +4 -2
  164. package/src/lib/server/session-tools/connector.ts +114 -10
  165. package/src/lib/server/session-tools/context.ts +21 -5
  166. package/src/lib/server/session-tools/crawl.ts +447 -0
  167. package/src/lib/server/session-tools/crud.ts +74 -28
  168. package/src/lib/server/session-tools/delegate-fallback.test.ts +219 -0
  169. package/src/lib/server/session-tools/delegate.ts +497 -24
  170. package/src/lib/server/session-tools/discovery.ts +24 -6
  171. package/src/lib/server/session-tools/document.ts +283 -0
  172. package/src/lib/server/session-tools/edit_file.ts +4 -2
  173. package/src/lib/server/session-tools/email.ts +320 -0
  174. package/src/lib/server/session-tools/extract.ts +137 -0
  175. package/src/lib/server/session-tools/file-normalize.test.ts +93 -0
  176. package/src/lib/server/session-tools/file-send.test.ts +84 -1
  177. package/src/lib/server/session-tools/file.ts +241 -25
  178. package/src/lib/server/session-tools/git.ts +1 -1
  179. package/src/lib/server/session-tools/http.ts +1 -1
  180. package/src/lib/server/session-tools/human-loop.ts +227 -0
  181. package/src/lib/server/session-tools/image-gen.ts +380 -0
  182. package/src/lib/server/session-tools/index.ts +130 -50
  183. package/src/lib/server/session-tools/mailbox.ts +276 -0
  184. package/src/lib/server/session-tools/memory.ts +172 -3
  185. package/src/lib/server/session-tools/monitor.ts +151 -8
  186. package/src/lib/server/session-tools/normalize-tool-args.ts +17 -14
  187. package/src/lib/server/session-tools/openclaw-nodes.ts +1 -1
  188. package/src/lib/server/session-tools/openclaw-workspace.ts +1 -1
  189. package/src/lib/server/session-tools/platform-normalize.test.ts +142 -0
  190. package/src/lib/server/session-tools/platform.ts +148 -7
  191. package/src/lib/server/session-tools/plugin-creator.ts +89 -26
  192. package/src/lib/server/session-tools/primitive-tools.test.ts +257 -0
  193. package/src/lib/server/session-tools/replicate.ts +301 -0
  194. package/src/lib/server/session-tools/sample-ui.ts +1 -1
  195. package/src/lib/server/session-tools/sandbox.ts +4 -2
  196. package/src/lib/server/session-tools/schedule.ts +24 -12
  197. package/src/lib/server/session-tools/session-info.ts +43 -7
  198. package/src/lib/server/session-tools/session-tools-wiring.test.ts +31 -17
  199. package/src/lib/server/session-tools/shell.ts +5 -2
  200. package/src/lib/server/session-tools/subagent.ts +194 -28
  201. package/src/lib/server/session-tools/table.ts +587 -0
  202. package/src/lib/server/session-tools/wallet.ts +42 -12
  203. package/src/lib/server/session-tools/web-browser-config.test.ts +39 -0
  204. package/src/lib/server/session-tools/web.ts +926 -91
  205. package/src/lib/server/storage.ts +255 -16
  206. package/src/lib/server/stream-agent-chat.ts +116 -268
  207. package/src/lib/server/structured-extract.test.ts +72 -0
  208. package/src/lib/server/structured-extract.ts +373 -0
  209. package/src/lib/server/task-mention.test.ts +16 -2
  210. package/src/lib/server/task-mention.ts +61 -10
  211. package/src/lib/server/tool-aliases.ts +66 -18
  212. package/src/lib/server/tool-capability-policy.test.ts +9 -9
  213. package/src/lib/server/tool-capability-policy.ts +38 -27
  214. package/src/lib/server/tool-retry.ts +2 -0
  215. package/src/lib/server/watch-jobs.test.ts +173 -0
  216. package/src/lib/server/watch-jobs.ts +532 -0
  217. package/src/lib/server/ws-hub.ts +5 -3
  218. package/src/lib/tool-definitions.ts +4 -0
  219. package/src/lib/validation/schemas.test.ts +26 -0
  220. package/src/lib/validation/schemas.ts +10 -1
  221. package/src/lib/ws-client.ts +14 -12
  222. package/src/proxy.ts +5 -5
  223. package/src/stores/use-app-store.ts +5 -11
  224. package/src/stores/use-chat-store.ts +38 -9
  225. package/src/types/index.ts +352 -47
  226. package/src/app/api/sessions/[id]/main-loop/route.ts +0 -94
  227. package/src/components/sessions/new-session-sheet.tsx +0 -253
  228. package/src/lib/server/main-session.ts +0 -24
  229. package/src/lib/server/session-run-manager.test.ts +0 -23
  230. /package/src/app/api/{sessions → chats}/[id]/clear/route.ts +0 -0
  231. /package/src/app/api/{sessions → chats}/[id]/deploy/route.ts +0 -0
  232. /package/src/app/api/{sessions → chats}/[id]/devserver/route.ts +0 -0
  233. /package/src/app/api/{sessions → chats}/[id]/edit-resend/route.ts +0 -0
  234. /package/src/app/api/{sessions → chats}/[id]/fork/route.ts +0 -0
  235. /package/src/app/api/{sessions → chats}/[id]/mailbox/route.ts +0 -0
  236. /package/src/app/api/{sessions → chats}/[id]/retry/route.ts +0 -0
  237. /package/src/app/api/{sessions → chats}/heartbeat/route.ts +0 -0
@@ -1,253 +0,0 @@
1
- 'use client'
2
-
3
- import { useState, useMemo } from 'react'
4
- import { BottomSheet } from '@/components/shared/bottom-sheet'
5
- import { SectionLabel } from '@/components/shared/section-label'
6
- import { useAppStore } from '@/stores/use-app-store'
7
- import { api } from '@/lib/api-client'
8
- import { PROVIDERS } from '@/lib/providers'
9
- import { TOOL_LABELS, TOOL_DESCRIPTIONS } from '@/components/chat/tool-call-bubble'
10
- import { toast } from 'sonner'
11
- import { useRouter } from 'next/navigation'
12
- import { genId } from '@/lib/id'
13
- import type { ProviderType, SessionTool } from '@/types'
14
-
15
- interface Props {
16
- open: boolean
17
- onClose: () => void
18
- }
19
-
20
- export function NewSessionSheet({ open, onClose }: Props) {
21
- const router = useRouter()
22
- const agents = useAppStore((s) => s.agents)
23
- const loadSessions = useAppStore((s) => s.loadSessions)
24
-
25
- const [selectedAgentId, setSelectedAgentId] = useState<string>('')
26
- const [provider, setProvider] = useState<ProviderType>('openai')
27
- const [model, setModel] = useState<string>('')
28
- const [endpoint, setEndpoint] = useState('')
29
- const [selectedTools, setSelectedTools] = useState<SessionTool[]>([])
30
- const [loading, setLoading] = useState(false)
31
-
32
- const agentList = useMemo(() => Object.values(agents).sort((a, b) => b.updatedAt - a.updatedAt), [agents])
33
- const currentProvider = PROVIDERS[provider]
34
-
35
- const reset = () => {
36
- setSelectedAgentId('')
37
- setProvider('openai')
38
- setModel('')
39
- setEndpoint('')
40
- setSelectedTools([])
41
- }
42
-
43
- const handleCreate = async () => {
44
- setLoading(true)
45
- try {
46
- const agent = selectedAgentId ? agents[selectedAgentId] : null
47
- const id = genId(8)
48
- const now = Date.now()
49
-
50
- const agentTools = agent?.tools || (selectedTools.length ? selectedTools : undefined)
51
-
52
- const session = {
53
- id,
54
- name: agent ? `Chat with ${agent.name}` : `New Session (${model || provider})`,
55
- provider: agent ? agent.provider : provider,
56
- model: agent ? agent.model : model,
57
- apiEndpoint: agent ? agent.apiEndpoint : (endpoint || undefined),
58
- credentialId: agent ? agent.credentialId : undefined,
59
- tools: agentTools || undefined,
60
- messages: [],
61
- createdAt: now,
62
- updatedAt: now,
63
- active: true,
64
- agentId: selectedAgentId || undefined,
65
- }
66
-
67
- await api('POST', '/sessions', session)
68
- await loadSessions()
69
- router.push(`/chat?session=${id}`)
70
- onClose()
71
- reset()
72
- } catch (err: unknown) {
73
- toast.error(err instanceof Error ? err.message : 'Failed to create session')
74
- } finally {
75
- setLoading(false)
76
- }
77
- }
78
-
79
- const inputClass = "w-full py-3 px-4 rounded-[14px] bg-surface border border-white/[0.06] text-text placeholder:text-text-3/50 outline-none focus:border-accent-bright/30 transition-all"
80
-
81
- return (
82
- <BottomSheet open={open} onClose={onClose}>
83
- <div className="mb-10">
84
- <h2 className="font-display text-[28px] font-700 tracking-[-0.03em] mb-2">New Session</h2>
85
- <p className="text-[14px] text-text-3">Start a new conversation with an agent or a direct model.</p>
86
- </div>
87
-
88
- <div className="mb-8">
89
- <SectionLabel>Select Agent</SectionLabel>
90
- <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
91
- <button
92
- onClick={() => setSelectedAgentId('')}
93
- className={`flex flex-col items-center justify-center gap-2 p-4 rounded-[18px] border transition-all duration-200 cursor-pointer
94
- ${!selectedAgentId
95
- ? 'bg-accent-soft border-accent-bright/25 text-accent-bright shadow-[0_0_25px_rgba(99,102,241,0.12)]'
96
- : 'bg-surface border-white/[0.06] text-text-3 hover:bg-surface-2 hover:border-white/[0.08]'}`}
97
- >
98
- <div className={`w-10 h-10 rounded-full flex items-center justify-center ${!selectedAgentId ? 'bg-accent-bright/20' : 'bg-white/[0.04]'}`}>
99
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
100
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" />
101
- </svg>
102
- </div>
103
- <span className="text-[13px] font-600">Direct Model</span>
104
- </button>
105
-
106
- {agentList.map((a) => (
107
- <button
108
- key={a.id}
109
- onClick={() => setSelectedAgentId(a.id)}
110
- className={`flex flex-col items-center justify-center gap-2 p-4 rounded-[18px] border transition-all duration-200 cursor-pointer
111
- ${selectedAgentId === a.id
112
- ? 'bg-accent-soft border-accent-bright/25 text-accent-bright shadow-[0_0_25px_rgba(99,102,241,0.12)]'
113
- : 'bg-surface border-white/[0.06] text-text-3 hover:bg-surface-2 hover:border-white/[0.08]'}`}
114
- >
115
- <div className="w-10 h-10 rounded-full bg-accent-bright/10 overflow-hidden">
116
- {/* eslint-disable-next-line @next/next/no-img-element */}
117
- <img src={`https://api.dicebear.com/7.x/bottts-neutral/svg?seed=${a.avatarSeed || a.id}`} alt="" />
118
- </div>
119
- <span className="text-[13px] font-600 truncate w-full text-center px-1">{a.name}</span>
120
- </button>
121
- ))}
122
- </div>
123
- </div>
124
-
125
- {!selectedAgentId && (
126
- <>
127
- <div className="grid grid-cols-2 gap-4 mb-6">
128
- <div>
129
- <SectionLabel>Provider</SectionLabel>
130
- <select
131
- value={provider}
132
- onChange={(e) => {
133
- const p = e.target.value as ProviderType
134
- setProvider(p)
135
- setModel(PROVIDERS[p].models[0])
136
- }}
137
- className={`${inputClass} appearance-none cursor-pointer`}
138
- style={{ fontFamily: 'inherit' }}
139
- >
140
- {Object.values(PROVIDERS).map((p) => (
141
- <option key={p.id} value={p.id}>{p.name}</option>
142
- ))}
143
- </select>
144
- </div>
145
- <div>
146
- <SectionLabel>Model</SectionLabel>
147
- <select
148
- value={model}
149
- onChange={(e) => setModel(e.target.value)}
150
- className={`${inputClass} appearance-none cursor-pointer`}
151
- style={{ fontFamily: 'inherit' }}
152
- >
153
- {currentProvider.models.map((m) => (
154
- <option key={m} value={m}>{m}</option>
155
- ))}
156
- </select>
157
- </div>
158
- </div>
159
-
160
- {currentProvider.requiresEndpoint && (
161
- <div className="mb-8">
162
- <SectionLabel>{provider === 'openclaw' ? 'OpenClaw Endpoint' : 'Endpoint'}</SectionLabel>
163
- <input
164
- type="text"
165
- value={endpoint}
166
- onChange={(e) => setEndpoint(e.target.value)}
167
- placeholder={currentProvider.defaultEndpoint || 'http://localhost:11434'}
168
- className={`${inputClass} font-mono text-[14px]`}
169
- />
170
- {provider === 'openclaw' && (
171
- <p className="text-[11px] text-text-3/60 mt-2">
172
- The /v1 endpoint of your remote OpenClaw instance
173
- </p>
174
- )}
175
- </div>
176
- )}
177
-
178
- {/* Plugins (Capability enablement) */}
179
- <div className="mb-8">
180
- <label className="block font-display text-[12px] font-600 text-text-2 uppercase tracking-[0.08em] mb-3">
181
- Plugins <span className="normal-case tracking-normal font-normal text-text-3">(optional)</span>
182
- </label>
183
- <p className="text-[12px] text-text-3/60 mb-3">Allow this model to execute commands and access files.</p>
184
- <div className="flex flex-wrap gap-2.5">
185
- {([
186
- { id: 'shell' as SessionTool, label: 'Shell' },
187
- { id: 'files' as SessionTool, label: 'Files' },
188
- { id: 'edit_file' as SessionTool, label: 'Edit File' },
189
- { id: 'web_search' as SessionTool, label: 'Web Search' },
190
- { id: 'web_fetch' as SessionTool, label: 'Web Fetch' },
191
- { id: 'claude_code' as SessionTool, label: 'Claude Code' },
192
- { id: 'codex_cli' as SessionTool, label: 'Codex CLI' },
193
- { id: 'opencode_cli' as SessionTool, label: 'OpenCode CLI' },
194
- ]).map(({ id, label }) => {
195
- const active = selectedTools.includes(id)
196
- return (
197
- <button
198
- key={id}
199
- onClick={() => {
200
- setSelectedTools((prev) =>
201
- active ? prev.filter((t) => t !== id) : [...prev, id],
202
- )
203
- }}
204
- className={`px-4 py-2.5 rounded-[12px] text-[13px] font-600 border cursor-pointer transition-all duration-200 active:scale-[0.97]
205
- ${active
206
- ? 'bg-accent-soft border-accent-bright/25 text-accent-bright shadow-[0_0_20px_rgba(99,102,241,0.1)]'
207
- : 'bg-surface border-white/[0.06] text-text-3 hover:bg-surface-2 hover:border-white/[0.08]'}`}
208
- style={{ fontFamily: 'inherit' }}
209
- >
210
- {label}
211
- </button>
212
- )
213
- })}
214
- </div>
215
- </div>
216
- </>
217
- )}
218
-
219
- {/* Summary when agent selected */}
220
- {selectedAgentId && agents[selectedAgentId] && (
221
- <div className="mb-8 px-4 py-3 rounded-[14px] bg-surface border border-white/[0.06]">
222
- <span className="text-[13px] text-text-3">
223
- Using <span className="text-text-2 font-600">{agents[selectedAgentId].provider}</span>
224
- {' / '}
225
- <span className="text-text-2 font-600">{agents[selectedAgentId].model}</span>
226
- {agents[selectedAgentId].tools?.length ? (
227
- <>
228
- {' + '}
229
- {agents[selectedAgentId].tools!.map((tool, i) => (
230
- <span key={tool}>
231
- {i > 0 && ', '}
232
- <span className="text-sky-400/70 font-600 cursor-help" title={TOOL_DESCRIPTIONS[tool] || tool}>
233
- {TOOL_LABELS[tool] || tool.replace(/_/g, ' ')}
234
- </span>
235
- </span>
236
- ))}
237
- </>
238
- ) : null}
239
- </span>
240
- </div>
241
- )}
242
-
243
- <button
244
- onClick={handleCreate}
245
- disabled={loading || (!selectedAgentId && !model)}
246
- className="w-full py-4 rounded-[18px] bg-accent-bright text-white font-display text-[15px] font-700 shadow-[0_0_30px_rgba(56,189,248,0.3)] hover:shadow-[0_0_40px_rgba(56,189,248,0.45)] hover:scale-[1.01] active:scale-[0.99] transition-all disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:shadow-none"
247
- style={{ fontFamily: 'inherit' }}
248
- >
249
- {loading ? 'Creating...' : 'Start Session'}
250
- </button>
251
- </BottomSheet>
252
- )
253
- }
@@ -1,24 +0,0 @@
1
- const MAIN_SESSION_NAME = '__main__'
2
-
3
- export function isProtectedMainSession(session: any): boolean {
4
- if (!session || typeof session !== 'object') return false
5
- if (session.mainSession === true) return true
6
- if (session.sessionType === 'orchestrated') return true
7
-
8
- const id = typeof session.id === 'string' ? session.id.trim() : ''
9
- if (id.startsWith('main-')) return true
10
- if (id.startsWith('agent-thread-')) return true
11
-
12
- const name = typeof session.name === 'string' ? session.name.trim() : ''
13
- if (name === MAIN_SESSION_NAME) return true
14
- if (name.startsWith('agent-thread:')) return true
15
-
16
- return false
17
- }
18
-
19
- export function ensureMainSessionFlag(session: any): void {
20
- if (!session || typeof session !== 'object') return
21
- if (isProtectedMainSession(session)) {
22
- session.mainSession = true
23
- }
24
- }
@@ -1,23 +0,0 @@
1
- import { describe, it } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { isMainMissionSession } from './session-run-manager'
4
-
5
- describe('isMainMissionSession', () => {
6
- it('accepts explicit main sessions', () => {
7
- assert.equal(isMainMissionSession({ id: 'main-user', name: '__main__' }), true)
8
- })
9
-
10
- it('rejects human agent-thread sessions', () => {
11
- assert.equal(
12
- isMainMissionSession({ id: 'agent-thread-agent_coder-123', name: 'agent-thread:agent_coder', sessionType: 'human' }),
13
- false,
14
- )
15
- })
16
-
17
- it('accepts orchestrated sessions', () => {
18
- assert.equal(
19
- isMainMissionSession({ id: 'agent-thread-worker-1', name: 'agent-thread:worker', sessionType: 'orchestrated' }),
20
- true,
21
- )
22
- })
23
- })