@supen-ai/cli 1.4.0 → 1.4.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 (205) hide show
  1. package/README.md +1 -1
  2. package/daemon/dist/agent-sdk/app-server-stream.js +5 -5
  3. package/daemon/dist/agent-sdk/app-server-stream.js.map +1 -1
  4. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.d.ts +3 -2
  5. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.d.ts.map +1 -1
  6. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js +72 -49
  7. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js.map +1 -1
  8. package/daemon/dist/agent-sdk/drivers/driver.d.ts +8 -8
  9. package/daemon/dist/agent-sdk/drivers/driver.d.ts.map +1 -1
  10. package/daemon/dist/agent-sdk/index.d.ts +4 -4
  11. package/daemon/dist/agent-sdk/index.d.ts.map +1 -1
  12. package/daemon/dist/agent-sdk/index.js +2 -2
  13. package/daemon/dist/agent-sdk/index.js.map +1 -1
  14. package/daemon/dist/agent-sdk/intelligence/contracts.d.ts +2 -2
  15. package/daemon/dist/agent-sdk/intelligence/contracts.d.ts.map +1 -1
  16. package/daemon/dist/agent-sdk/memory/subsystem.d.ts +1 -1
  17. package/daemon/dist/agent-sdk/memory/subsystem.d.ts.map +1 -1
  18. package/daemon/dist/agent-sdk/{session-events.d.ts → thread-events.d.ts} +18 -18
  19. package/daemon/dist/agent-sdk/thread-events.d.ts.map +1 -0
  20. package/daemon/dist/agent-sdk/{session-events.js → thread-events.js} +15 -15
  21. package/daemon/dist/agent-sdk/thread-events.js.map +1 -0
  22. package/daemon/dist/agent-sdk/{session-manager.d.ts → thread-manager.d.ts} +9 -9
  23. package/daemon/dist/agent-sdk/thread-manager.d.ts.map +1 -0
  24. package/daemon/dist/agent-sdk/{session-manager.js → thread-manager.js} +7 -7
  25. package/daemon/dist/agent-sdk/thread-manager.js.map +1 -0
  26. package/daemon/dist/agent-sdk/types.d.ts +18 -18
  27. package/daemon/dist/agent-sdk/types.d.ts.map +1 -1
  28. package/daemon/dist/automation-event-listener.js +6 -6
  29. package/daemon/dist/automation-event-listener.js.map +1 -1
  30. package/daemon/dist/automation-runner.d.ts +1 -1
  31. package/daemon/dist/automation-runner.d.ts.map +1 -1
  32. package/daemon/dist/automation-runner.js +24 -24
  33. package/daemon/dist/automation-runner.js.map +1 -1
  34. package/daemon/dist/autonomy/memory-rules.d.ts +2 -2
  35. package/daemon/dist/autonomy/memory-rules.d.ts.map +1 -1
  36. package/daemon/dist/autonomy/memory-rules.js +1 -1
  37. package/daemon/dist/autonomy/memory-rules.js.map +1 -1
  38. package/daemon/dist/autonomy/session-autonomy.d.ts +4 -4
  39. package/daemon/dist/autonomy/session-autonomy.d.ts.map +1 -1
  40. package/daemon/dist/autonomy/session-autonomy.js +5 -5
  41. package/daemon/dist/autonomy/session-autonomy.js.map +1 -1
  42. package/daemon/dist/bin/mcp-os.js +1 -1
  43. package/daemon/dist/bin/mcp-os.js.map +1 -1
  44. package/daemon/dist/bin/mcp-scheduler.js +1 -1
  45. package/daemon/dist/bin/mcp-scheduler.js.map +1 -1
  46. package/daemon/dist/bin/supen-sys.js +1 -1
  47. package/daemon/dist/bin/supen-sys.js.map +1 -1
  48. package/daemon/dist/bootstrap/hub-bootstrap.js +1 -1
  49. package/daemon/dist/bootstrap/hub-bootstrap.js.map +1 -1
  50. package/daemon/dist/channels/http-routes.d.ts.map +1 -1
  51. package/daemon/dist/channels/http-routes.js +54 -60
  52. package/daemon/dist/channels/http-routes.js.map +1 -1
  53. package/daemon/dist/channels/http.js +2 -2
  54. package/daemon/dist/channels/http.js.map +1 -1
  55. package/daemon/dist/channels/index.d.ts +0 -1
  56. package/daemon/dist/channels/index.d.ts.map +1 -1
  57. package/daemon/dist/channels/index.js +0 -2
  58. package/daemon/dist/channels/index.js.map +1 -1
  59. package/daemon/dist/channels/registry.d.ts +1 -1
  60. package/daemon/dist/channels/registry.d.ts.map +1 -1
  61. package/daemon/dist/commands/builtin.d.ts +1 -1
  62. package/daemon/dist/commands/builtin.d.ts.map +1 -1
  63. package/daemon/dist/commands/builtin.js +2 -2
  64. package/daemon/dist/commands/builtin.js.map +1 -1
  65. package/daemon/dist/commands/catalog.js +3 -3
  66. package/daemon/dist/commands/catalog.js.map +1 -1
  67. package/daemon/dist/core/config.d.ts +0 -2
  68. package/daemon/dist/core/config.d.ts.map +1 -1
  69. package/daemon/dist/core/config.js +0 -5
  70. package/daemon/dist/core/config.js.map +1 -1
  71. package/daemon/dist/core/control-commands.d.ts +3 -3
  72. package/daemon/dist/core/control-commands.d.ts.map +1 -1
  73. package/daemon/dist/core/control-commands.js +6 -6
  74. package/daemon/dist/core/control-commands.js.map +1 -1
  75. package/daemon/dist/core/control-log.d.ts +4 -4
  76. package/daemon/dist/core/control-log.d.ts.map +1 -1
  77. package/daemon/dist/core/control-log.js +12 -12
  78. package/daemon/dist/core/control-log.js.map +1 -1
  79. package/daemon/dist/core/cortex.d.ts +4 -4
  80. package/daemon/dist/core/cortex.d.ts.map +1 -1
  81. package/daemon/dist/core/cortex.js +98 -117
  82. package/daemon/dist/core/cortex.js.map +1 -1
  83. package/daemon/dist/core/dispatcher.d.ts +3 -3
  84. package/daemon/dist/core/dispatcher.js +18 -18
  85. package/daemon/dist/core/dispatcher.js.map +1 -1
  86. package/daemon/dist/core/gateway-protocol.d.ts +0 -1
  87. package/daemon/dist/core/gateway-protocol.d.ts.map +1 -1
  88. package/daemon/dist/core/gateway.d.ts +3 -3
  89. package/daemon/dist/core/gateway.d.ts.map +1 -1
  90. package/daemon/dist/core/gateway.js +26 -26
  91. package/daemon/dist/core/gateway.js.map +1 -1
  92. package/daemon/dist/core/hub-snapshot.d.ts +1 -1
  93. package/daemon/dist/core/hub-snapshot.d.ts.map +1 -1
  94. package/daemon/dist/core/hub-snapshot.js +1 -1
  95. package/daemon/dist/core/hub-snapshot.js.map +1 -1
  96. package/daemon/dist/core/pairing.d.ts +2 -2
  97. package/daemon/dist/core/pairing.js +3 -3
  98. package/daemon/dist/core/pairing.js.map +1 -1
  99. package/daemon/dist/core/store.d.ts +38 -38
  100. package/daemon/dist/core/store.d.ts.map +1 -1
  101. package/daemon/dist/core/store.js +285 -289
  102. package/daemon/dist/core/store.js.map +1 -1
  103. package/daemon/dist/core/task-artifacts.d.ts +4 -4
  104. package/daemon/dist/core/task-artifacts.d.ts.map +1 -1
  105. package/daemon/dist/core/task-artifacts.js +10 -10
  106. package/daemon/dist/core/task-artifacts.js.map +1 -1
  107. package/daemon/dist/core/thread-context.d.ts +76 -0
  108. package/daemon/dist/core/thread-context.d.ts.map +1 -0
  109. package/daemon/dist/core/thread-context.js +308 -0
  110. package/daemon/dist/core/thread-context.js.map +1 -0
  111. package/daemon/dist/core/types.d.ts +28 -28
  112. package/daemon/dist/core/types.d.ts.map +1 -1
  113. package/daemon/dist/core/utils.js +1 -1
  114. package/daemon/dist/core/utils.js.map +1 -1
  115. package/daemon/dist/http/router.d.ts +2 -2
  116. package/daemon/dist/http/router.d.ts.map +1 -1
  117. package/daemon/dist/http/router.js +5 -5
  118. package/daemon/dist/http/router.js.map +1 -1
  119. package/daemon/dist/http/routes/agents.js +3 -3
  120. package/daemon/dist/http/routes/agents.js.map +1 -1
  121. package/daemon/dist/http/routes/automations.d.ts +2 -2
  122. package/daemon/dist/http/routes/automations.d.ts.map +1 -1
  123. package/daemon/dist/http/routes/automations.js +23 -23
  124. package/daemon/dist/http/routes/automations.js.map +1 -1
  125. package/daemon/dist/http/routes/chat-input.d.ts +1 -1
  126. package/daemon/dist/http/routes/chat-input.d.ts.map +1 -1
  127. package/daemon/dist/http/routes/chat-input.js +2 -2
  128. package/daemon/dist/http/routes/chat-input.js.map +1 -1
  129. package/daemon/dist/http/routes/plugins.d.ts.map +1 -1
  130. package/daemon/dist/http/routes/plugins.js +6 -74
  131. package/daemon/dist/http/routes/plugins.js.map +1 -1
  132. package/daemon/dist/http/routes/rpc.d.ts +3 -3
  133. package/daemon/dist/http/routes/rpc.d.ts.map +1 -1
  134. package/daemon/dist/http/routes/rpc.js +93 -92
  135. package/daemon/dist/http/routes/rpc.js.map +1 -1
  136. package/daemon/dist/http/routes/system.d.ts +8 -7
  137. package/daemon/dist/http/routes/system.d.ts.map +1 -1
  138. package/daemon/dist/http/routes/system.js +225 -111
  139. package/daemon/dist/http/routes/system.js.map +1 -1
  140. package/daemon/dist/http/routes/threads.d.ts +11 -0
  141. package/daemon/dist/http/routes/threads.d.ts.map +1 -0
  142. package/daemon/dist/http/routes/{sessions.js → threads.js} +158 -158
  143. package/daemon/dist/http/routes/threads.js.map +1 -0
  144. package/daemon/dist/http/stream.d.ts +2 -2
  145. package/daemon/dist/http/stream.d.ts.map +1 -1
  146. package/daemon/dist/http/stream.js +3 -3
  147. package/daemon/dist/http/stream.js.map +1 -1
  148. package/daemon/dist/http/thread-title.d.ts +1 -1
  149. package/daemon/dist/http/thread-title.d.ts.map +1 -1
  150. package/daemon/dist/http/thread-title.js +6 -6
  151. package/daemon/dist/http/thread-title.js.map +1 -1
  152. package/daemon/dist/http/websocket.d.ts +2 -2
  153. package/daemon/dist/http/websocket.d.ts.map +1 -1
  154. package/daemon/dist/http/websocket.js +11 -11
  155. package/daemon/dist/http/websocket.js.map +1 -1
  156. package/daemon/dist/index.d.ts +3 -3
  157. package/daemon/dist/index.d.ts.map +1 -1
  158. package/daemon/dist/index.js +65 -81
  159. package/daemon/dist/index.js.map +1 -1
  160. package/daemon/dist/mcp/aggregate-config.d.ts +1 -1
  161. package/daemon/dist/mcp/index.js +1 -1
  162. package/daemon/dist/mcp/index.js.map +1 -1
  163. package/daemon/dist/mcp/tools.d.ts +1 -1
  164. package/daemon/dist/mcp/tools.js +1 -1
  165. package/daemon/dist/plugins/hub.d.ts +2 -8
  166. package/daemon/dist/plugins/hub.d.ts.map +1 -1
  167. package/daemon/dist/plugins/hub.js +63 -214
  168. package/daemon/dist/plugins/hub.js.map +1 -1
  169. package/daemon/dist/plugins/types.d.ts +10 -0
  170. package/daemon/dist/plugins/types.d.ts.map +1 -1
  171. package/daemon/dist/sub-agent.d.ts +3 -3
  172. package/daemon/dist/sub-agent.d.ts.map +1 -1
  173. package/daemon/dist/sub-agent.js +8 -8
  174. package/daemon/dist/sub-agent.js.map +1 -1
  175. package/daemon/dist/sync/supabase-sync.js +18 -18
  176. package/daemon/dist/sync/supabase-sync.js.map +1 -1
  177. package/daemon/dist/task-executor.js +1 -1
  178. package/daemon/dist/task-executor.js.map +1 -1
  179. package/daemon/dist/tools/shell.js +1 -1
  180. package/daemon/dist/tools/shell.js.map +1 -1
  181. package/daemon/dist/tools/types.d.ts +1 -1
  182. package/daemon/dist/tools/types.d.ts.map +1 -1
  183. package/daemon/package.json +1 -1
  184. package/dist/computer.js +1 -1
  185. package/dist/index.js +1 -1
  186. package/package.json +1 -1
  187. package/daemon/dist/acp-client.d.ts +0 -42
  188. package/daemon/dist/acp-client.d.ts.map +0 -1
  189. package/daemon/dist/acp-client.js +0 -149
  190. package/daemon/dist/acp-client.js.map +0 -1
  191. package/daemon/dist/acp-types.d.ts +0 -98
  192. package/daemon/dist/acp-types.d.ts.map +0 -1
  193. package/daemon/dist/acp-types.js +0 -2
  194. package/daemon/dist/acp-types.js.map +0 -1
  195. package/daemon/dist/agent-sdk/session-events.d.ts.map +0 -1
  196. package/daemon/dist/agent-sdk/session-events.js.map +0 -1
  197. package/daemon/dist/agent-sdk/session-manager.d.ts.map +0 -1
  198. package/daemon/dist/agent-sdk/session-manager.js.map +0 -1
  199. package/daemon/dist/channels/acp.d.ts +0 -23
  200. package/daemon/dist/channels/acp.d.ts.map +0 -1
  201. package/daemon/dist/channels/acp.js +0 -915
  202. package/daemon/dist/channels/acp.js.map +0 -1
  203. package/daemon/dist/http/routes/sessions.d.ts +0 -11
  204. package/daemon/dist/http/routes/sessions.d.ts.map +0 -1
  205. package/daemon/dist/http/routes/sessions.js.map +0 -1
@@ -0,0 +1,11 @@
1
+ import http from 'http';
2
+ import { URL } from 'url';
3
+ import { type HttpAdminContext } from '../context.js';
4
+ import type { OnThreadStop } from '../../core/types.js';
5
+ export declare function captureWebUserMessage(input: {
6
+ threadId: string;
7
+ runtimeThreadId?: string | null;
8
+ userMessage: unknown;
9
+ }): void;
10
+ export declare function handleThreadsRoutes(req: http.IncomingMessage, res: http.ServerResponse, url: URL, pathname: string, method: string, adminContext: HttpAdminContext | null, onMessage: (chatJid: string, msg: any) => void, onThreadStop?: OnThreadStop): Promise<boolean>;
11
+ //# sourceMappingURL=threads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../../src/http/routes/threads.ts"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AA6B1B,OAAO,EAA4B,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAMhF,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,qBAAqB,CAAC;AAUtE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,OAAO,CAAC;CACtB,GAAG,IAAI,CAmBP;AA4SD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,gBAAgB,GAAG,IAAI,EACrC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,EAC9C,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,OAAO,CAAC,CAuhBlB"}
@@ -2,15 +2,15 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { randomUUID } from 'crypto';
4
4
  import { logger } from '../../core/logger.js';
5
- import { ensureSession, getSessionForAgent, getSessionInteractionEvents, getSessionsForAgent, getArchivedSessionsForAgent, getAutomationRunById, getAutomationById, getAutomationState, listAutomationRuns, finalizeRunningAutomationRunForSession, finalizeAutomationRun, clearSessionSdkId, deleteSessionForAgent, archiveSessionForAgent, restoreSessionForAgent, updateAutomationState, updateSessionMetadata, updateSessionStatus, storeMessage, } from '../../core/store.js';
5
+ import { ensureThread, getThreadForAgent, getThreadInteractionEvents, getThreadsForAgent, getArchivedThreadsForAgent, getAutomationRunById, getAutomationById, getAutomationState, listAutomationRuns, finalizeRunningAutomationRunForThread, finalizeAutomationRun, clearThreadSdkSessionId, deleteThreadForAgent, archiveThreadForAgent, restoreThreadForAgent, updateAutomationState, updateThreadMetadata, updateThreadStatus, storeMessage, } from '../../core/store.js';
6
6
  import { ASSISTANT_NAME, SUPEN_HOME } from '../../core/config.js';
7
7
  import { writeJson, writeProtocolError, readJsonBody } from '../response.js';
8
- import { broadcastToChat, buildHttpSessionId } from '../stream.js';
8
+ import { broadcastToChat, buildHttpThreadId } from '../stream.js';
9
9
  import { deriveHttpSenderIdentity } from '../context.js';
10
- import { readCodexThreadTitleFromStateDb, readCodexThreadTitleFromSessionIndex, } from '../thread-title.js';
10
+ import { readCodexThreadTitleFromStateDb, readCodexThreadTitleFromThreadIndex, } from '../thread-title.js';
11
11
  import { listWebCommands, resolveWebCommandInput } from '../command-catalog.js';
12
12
  import { AgentCortex } from '../../core/cortex.js';
13
- import { recordSessionControlCommand } from '../../core/control-commands.js';
13
+ import { recordThreadControlCommand } from '../../core/control-commands.js';
14
14
  import { listControlLogEntries } from '../../core/control-log.js';
15
15
  import { appendThreadEvent } from '../../core/thread-event-log.js';
16
16
  import { projectThreadRuntimeState } from '../../core/thread-runtime-state.js';
@@ -34,11 +34,11 @@ export function captureWebUserMessage(input) {
34
34
  }, 'Failed to capture web user message');
35
35
  }
36
36
  }
37
- function serializeTask(session) {
38
- const { session_id: sessionId, ...rest } = session;
37
+ function serializeTask(thread) {
38
+ const { thread_id: threadId, ...rest } = thread;
39
39
  return {
40
40
  ...rest,
41
- task_id: sessionId,
41
+ task_id: threadId,
42
42
  };
43
43
  }
44
44
  function isNoOpAutomationRun(runId) {
@@ -125,7 +125,7 @@ function runtimeThreadIdCandidatesForThread(threadId) {
125
125
  }
126
126
  function readCodexTitleForThread(threadId) {
127
127
  for (const candidate of runtimeThreadIdCandidatesForThread(threadId)) {
128
- const title = readCodexThreadTitleFromSessionIndex(candidate) ||
128
+ const title = readCodexThreadTitleFromThreadIndex(candidate) ||
129
129
  readCodexThreadTitleFromStateDb(candidate);
130
130
  if (title)
131
131
  return title;
@@ -142,19 +142,19 @@ function shouldReplaceTitle(input) {
142
142
  return false;
143
143
  }
144
144
  function refreshThreadTitleFromCodexIndex(agentId, threadId, options = {}) {
145
- const session = getSessionForAgent(agentId, threadId);
146
- if (!session)
145
+ const thread = getThreadForAgent(agentId, threadId);
146
+ if (!thread)
147
147
  return { updated: false, title: null, previousTitle: null, reason: 'thread_not_found' };
148
148
  const title = readCodexTitleForThread(threadId);
149
149
  if (!title) {
150
150
  return {
151
151
  updated: false,
152
152
  title: null,
153
- previousTitle: session.title || null,
153
+ previousTitle: thread.title || null,
154
154
  reason: 'codex_title_not_found',
155
155
  };
156
156
  }
157
- const previousTitle = session.title?.trim() || '';
157
+ const previousTitle = thread.title?.trim() || '';
158
158
  if (!shouldReplaceTitle({
159
159
  currentTitle: previousTitle,
160
160
  nextTitle: title,
@@ -167,10 +167,10 @@ function refreshThreadTitleFromCodexIndex(agentId, threadId, options = {}) {
167
167
  reason: 'title_preserved',
168
168
  };
169
169
  }
170
- updateSessionMetadata(agentId, threadId, { title });
171
- broadcastToChat(buildHttpSessionId(agentId, threadId), {
172
- type: 'session_updated',
173
- session: { task_id: threadId, title },
170
+ updateThreadMetadata(agentId, threadId, { title });
171
+ broadcastToChat(buildHttpThreadId(agentId, threadId), {
172
+ type: 'thread_updated',
173
+ thread: { task_id: threadId, title },
174
174
  });
175
175
  return {
176
176
  updated: true,
@@ -186,10 +186,10 @@ function runtimeStateSummary(projection) {
186
186
  runtime: projection.runtime,
187
187
  };
188
188
  }
189
- function prewarmSessionInBackground(agentId, sessionId, options) {
189
+ function prewarmThreadInBackground(agentId, threadId, options) {
190
190
  const key = [
191
191
  agentId,
192
- sessionId,
192
+ threadId,
193
193
  options?.model || '',
194
194
  options?.permissionMode || '',
195
195
  options?.networkAccess ? 'network' : '',
@@ -200,8 +200,8 @@ function prewarmSessionInBackground(agentId, sessionId, options) {
200
200
  return;
201
201
  }
202
202
  recentPrewarmAttempts.set(key, now);
203
- const cortex = new AgentCortex(agentId, sessionId);
204
- void cortex.prewarmNativeSession(options);
203
+ const cortex = new AgentCortex(agentId, threadId);
204
+ void cortex.prewarmNativeThread(options);
205
205
  }
206
206
  function readRuntimeOptions(body) {
207
207
  const model = typeof body?.model === 'string' && body.model.trim()
@@ -235,8 +235,8 @@ function readRuntimeOptions(body) {
235
235
  ...(networkAccess ? { networkAccess } : {}),
236
236
  };
237
237
  }
238
- function resetAutomationRuntimeForSession(sessionId) {
239
- const automationMatch = sessionId.match(/^sched-(.+)$/);
238
+ function resetAutomationRuntimeForThread(threadId) {
239
+ const automationMatch = threadId.match(/^sched-(.+)$/);
240
240
  if (!automationMatch)
241
241
  return null;
242
242
  const automationId = automationMatch[1];
@@ -280,8 +280,8 @@ function resetAutomationRuntimeForSession(sessionId) {
280
280
  });
281
281
  return { automation_id: automationId, status: 'reset_state' };
282
282
  }
283
- export async function handleSessionsRoutes(req, res, url, pathname, method, adminContext, onMessage, onSessionStop) {
284
- const commandsV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/commands$/);
283
+ export async function handleThreadsRoutes(req, res, url, pathname, method, adminContext, onMessage, onThreadStop) {
284
+ const commandsV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/commands$/);
285
285
  if (commandsV1Match && method === 'GET') {
286
286
  const agentId = decodeURIComponent(commandsV1Match[1]);
287
287
  const commands = await listWebCommands({ channel: 'web', agentId });
@@ -295,7 +295,7 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
295
295
  writeJson(res, 200, { commands });
296
296
  return true;
297
297
  }
298
- const resolveCommandsV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/commands\/resolve$/);
298
+ const resolveCommandsV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/commands\/resolve$/);
299
299
  if (resolveCommandsV1Match && method === 'POST') {
300
300
  const agentId = decodeURIComponent(resolveCommandsV1Match[1]);
301
301
  const parsed = await readJsonBody(req);
@@ -309,31 +309,31 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
309
309
  writeJson(res, 200, resolved);
310
310
  return true;
311
311
  }
312
- const stopV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/stop$/);
312
+ const stopV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/stop$/);
313
313
  if (stopV1Match && method === 'POST') {
314
314
  const agentId = decodeURIComponent(stopV1Match[1]);
315
- const sessionId = decodeURIComponent(stopV1Match[2]);
316
- if (!onSessionStop) {
317
- writeProtocolError(res, 501, 'input_error', 'stop_not_supported', 'Session stop is not supported by this daemon.');
315
+ const threadId = decodeURIComponent(stopV1Match[2]);
316
+ if (!onThreadStop) {
317
+ writeProtocolError(res, 501, 'input_error', 'stop_not_supported', 'Thread stop is not supported by this daemon.');
318
318
  return true;
319
319
  }
320
320
  const actor = adminContext?.actor || 'http';
321
- recordSessionControlCommand({
321
+ recordThreadControlCommand({
322
322
  agentId,
323
- sessionId,
323
+ threadId,
324
324
  surface: 'web',
325
- commandType: 'session.stop',
325
+ commandType: 'thread.stop',
326
326
  method: 'turn/interrupt',
327
327
  actor,
328
328
  status: 'received',
329
329
  payload: { endpoint: 'stop' },
330
330
  });
331
- const result = onSessionStop(agentId, sessionId, actor);
332
- if (!result.ok && result.code !== 'session_not_running') {
331
+ const result = onThreadStop(agentId, threadId, actor);
332
+ if (!result.ok && result.code !== 'thread_not_running') {
333
333
  writeProtocolError(res, 404, 'input_error', result.code, result.message);
334
334
  return true;
335
335
  }
336
- const finalizedAutomationRun = finalizeRunningAutomationRunForSession(agentId, sessionId, {
336
+ const finalizedAutomationRun = finalizeRunningAutomationRunForThread(agentId, threadId, {
337
337
  actor,
338
338
  });
339
339
  const automationReset = finalizedAutomationRun
@@ -342,15 +342,15 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
342
342
  status: 'finalized_run',
343
343
  run_id: finalizedAutomationRun.run_id,
344
344
  }
345
- : resetAutomationRuntimeForSession(sessionId);
345
+ : resetAutomationRuntimeForThread(threadId);
346
346
  const automationRuntimeReleased = automationReset?.status === 'finalized_run' || automationReset?.status === 'reset_state';
347
347
  if (automationRuntimeReleased) {
348
- updateSessionStatus(agentId, sessionId, 'idle');
349
- const refreshedSession = getSessionForAgent(agentId, sessionId);
350
- if (refreshedSession) {
351
- broadcastToChat(buildHttpSessionId(agentId, sessionId), {
352
- type: 'session_updated',
353
- session: refreshedSession,
348
+ updateThreadStatus(agentId, threadId, 'idle');
349
+ const refreshedThread = getThreadForAgent(agentId, threadId);
350
+ if (refreshedThread) {
351
+ broadcastToChat(buildHttpThreadId(agentId, threadId), {
352
+ type: 'thread_updated',
353
+ thread: refreshedThread,
354
354
  });
355
355
  }
356
356
  }
@@ -361,114 +361,114 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
361
361
  });
362
362
  return true;
363
363
  }
364
- const resetRuntimeV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/reset-runtime$/);
364
+ const resetRuntimeV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/reset-runtime$/);
365
365
  if (resetRuntimeV1Match && method === 'POST') {
366
366
  const agentId = decodeURIComponent(resetRuntimeV1Match[1]);
367
- const sessionId = decodeURIComponent(resetRuntimeV1Match[2]);
368
- const session = getSessionForAgent(agentId, sessionId);
369
- if (!session) {
370
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
367
+ const threadId = decodeURIComponent(resetRuntimeV1Match[2]);
368
+ const thread = getThreadForAgent(agentId, threadId);
369
+ if (!thread) {
370
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
371
371
  return true;
372
372
  }
373
- const clearedSdkSessionId = Boolean(session.sdk_session_id);
374
- clearSessionSdkId(agentId, sessionId);
375
- updateSessionStatus(agentId, sessionId, 'idle');
376
- const automationReset = resetAutomationRuntimeForSession(sessionId);
377
- const refreshedSession = getSessionForAgent(agentId, sessionId) || {
378
- ...session,
373
+ const clearedSdkSessionId = Boolean(thread.sdk_session_id);
374
+ clearThreadSdkSessionId(agentId, threadId);
375
+ updateThreadStatus(agentId, threadId, 'idle');
376
+ const automationReset = resetAutomationRuntimeForThread(threadId);
377
+ const refreshedThread = getThreadForAgent(agentId, threadId) || {
378
+ ...thread,
379
379
  status: 'idle',
380
380
  };
381
- broadcastToChat(buildHttpSessionId(agentId, sessionId), {
382
- type: 'session_updated',
383
- session: serializeTask(refreshedSession),
381
+ broadcastToChat(buildHttpThreadId(agentId, threadId), {
382
+ type: 'thread_updated',
383
+ thread: serializeTask(refreshedThread),
384
384
  });
385
385
  writeJson(res, 200, {
386
386
  ok: true,
387
- session: serializeTask(refreshedSession),
387
+ thread: serializeTask(refreshedThread),
388
388
  cleared_sdk_session_id: clearedSdkSessionId,
389
389
  automation_reset: automationReset,
390
390
  });
391
391
  return true;
392
392
  }
393
- const prewarmV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/prewarm$/);
393
+ const prewarmV1Match = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/prewarm$/);
394
394
  if (prewarmV1Match && method === 'POST') {
395
395
  const agentId = decodeURIComponent(prewarmV1Match[1]);
396
- const sessionId = decodeURIComponent(prewarmV1Match[2]);
397
- const session = getSessionForAgent(agentId, sessionId);
398
- if (!session) {
399
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
396
+ const threadId = decodeURIComponent(prewarmV1Match[2]);
397
+ const thread = getThreadForAgent(agentId, threadId);
398
+ if (!thread) {
399
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
400
400
  return true;
401
401
  }
402
402
  const parsed = await readJsonBody(req).catch(() => ({}));
403
403
  const runtimeOptions = readRuntimeOptions(parsed);
404
- prewarmSessionInBackground(agentId, sessionId, runtimeOptions);
405
- writeJson(res, 202, { ok: true, task_id: sessionId, prewarming: true });
404
+ prewarmThreadInBackground(agentId, threadId, runtimeOptions);
405
+ writeJson(res, 202, { ok: true, task_id: threadId, prewarming: true });
406
406
  return true;
407
407
  }
408
- // ── List Sessions ──
409
- const listSessionsMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions$/);
410
- if (listSessionsMatch && method === 'POST') {
411
- const agentId = decodeURIComponent(listSessionsMatch[1]);
408
+ // ── List Threads ──
409
+ const listThreadsMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads$/);
410
+ if (listThreadsMatch && method === 'POST') {
411
+ const agentId = decodeURIComponent(listThreadsMatch[1]);
412
412
  const parsed = await readJsonBody(req);
413
- const requestedSessionId = typeof parsed?.task_id === 'string'
413
+ const requestedThreadId = typeof parsed?.task_id === 'string'
414
414
  ? parsed.task_id.trim()
415
- : typeof parsed?.session_id === 'string'
416
- ? parsed.session_id.trim()
415
+ : typeof parsed?.thread_id === 'string'
416
+ ? parsed.thread_id.trim()
417
417
  : '';
418
418
  const requestedTitle = typeof parsed?.title === 'string' ? parsed.title.trim() : '';
419
419
  const requestedKnowledgeId = typeof parsed?.knowledge_id === 'string' ? parsed.knowledge_id.trim() : '';
420
420
  const requestedKnowledgeName = typeof parsed?.knowledge_name === 'string' ? parsed.knowledge_name.trim() : '';
421
- if (requestedSessionId && getSessionForAgent(agentId, requestedSessionId)) {
422
- writeProtocolError(res, 409, 'input_error', 'session_exists', `Task "${requestedSessionId}" already exists for agent "${agentId}"`);
421
+ if (requestedThreadId && getThreadForAgent(agentId, requestedThreadId)) {
422
+ writeProtocolError(res, 409, 'input_error', 'thread_exists', `Task "${requestedThreadId}" already exists for agent "${agentId}"`);
423
423
  return true;
424
424
  }
425
- let sessionId = requestedSessionId;
426
- if (!sessionId) {
425
+ let threadId = requestedThreadId;
426
+ if (!threadId) {
427
427
  do {
428
- sessionId = `session-${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
429
- } while (getSessionForAgent(agentId, sessionId));
428
+ threadId = `thread-${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
429
+ } while (getThreadForAgent(agentId, threadId));
430
430
  }
431
- const session = ensureSession({
431
+ const thread = ensureThread({
432
432
  agent_id: agentId,
433
- session_id: sessionId,
433
+ thread_id: threadId,
434
434
  channel: 'http',
435
435
  agent_name: agentId,
436
- source_ref: buildHttpSessionId(agentId, sessionId),
436
+ source_ref: buildHttpThreadId(agentId, threadId),
437
437
  knowledge_id: requestedKnowledgeId || undefined,
438
438
  knowledge_name: requestedKnowledgeName || undefined,
439
439
  title: requestedTitle || undefined,
440
440
  });
441
- recordSessionControlCommand({
441
+ recordThreadControlCommand({
442
442
  agentId,
443
- sessionId,
443
+ threadId,
444
444
  surface: 'web',
445
- commandType: 'session.start',
445
+ commandType: 'thread.start',
446
446
  method: 'thread/start',
447
447
  actor: adminContext?.actor || 'http',
448
448
  status: 'completed',
449
449
  payload: {
450
- requested_task_id: requestedSessionId || null,
450
+ requested_task_id: requestedThreadId || null,
451
451
  title: requestedTitle || null,
452
452
  knowledge_id: requestedKnowledgeId || null,
453
453
  knowledge_name: requestedKnowledgeName || null,
454
454
  },
455
455
  });
456
- const refreshedSession = getSessionForAgent(agentId, sessionId) || session;
457
- prewarmSessionInBackground(agentId, sessionId);
458
- writeJson(res, 200, { session: serializeTask(refreshedSession) });
456
+ const refreshedThread = getThreadForAgent(agentId, threadId) || thread;
457
+ prewarmThreadInBackground(agentId, threadId);
458
+ writeJson(res, 200, { thread: serializeTask(refreshedThread) });
459
459
  return true;
460
460
  }
461
- if (listSessionsMatch && method === 'GET') {
462
- const agentId = decodeURIComponent(listSessionsMatch[1]);
463
- const sessions = getSessionsForAgent(agentId).map(serializeTask);
464
- writeJson(res, 200, { sessions });
461
+ if (listThreadsMatch && method === 'GET') {
462
+ const agentId = decodeURIComponent(listThreadsMatch[1]);
463
+ const threads = getThreadsForAgent(agentId).map(serializeTask);
464
+ writeJson(res, 200, { threads });
465
465
  return true;
466
466
  }
467
- const archivedSessionsMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/archived_sessions$/);
468
- if (archivedSessionsMatch && method === 'GET') {
469
- const agentId = decodeURIComponent(archivedSessionsMatch[1]);
470
- const sessions = getArchivedSessionsForAgent(agentId).map(serializeTask);
471
- writeJson(res, 200, { sessions });
467
+ const archivedThreadsMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/archived_threads$/);
468
+ if (archivedThreadsMatch && method === 'GET') {
469
+ const agentId = decodeURIComponent(archivedThreadsMatch[1]);
470
+ const threads = getArchivedThreadsForAgent(agentId).map(serializeTask);
471
+ writeJson(res, 200, { threads });
472
472
  return true;
473
473
  }
474
474
  const refreshTitlesMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/refresh-titles$/);
@@ -476,11 +476,11 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
476
476
  const agentId = decodeURIComponent(refreshTitlesMatch[1]);
477
477
  const parsed = await readJsonBody(req).catch(() => ({}));
478
478
  const force = parsed?.force === true;
479
- const sessions = getSessionsForAgent(agentId);
480
- const results = sessions.map((session) => {
481
- const result = refreshThreadTitleFromCodexIndex(agentId, session.session_id, { force });
479
+ const threads = getThreadsForAgent(agentId);
480
+ const results = threads.map((thread) => {
481
+ const result = refreshThreadTitleFromCodexIndex(agentId, thread.thread_id, { force });
482
482
  return {
483
- thread_id: session.session_id,
483
+ thread_id: thread.thread_id,
484
484
  updated: result.updated,
485
485
  title: result.title,
486
486
  previous_title: result.previousTitle,
@@ -518,94 +518,94 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
518
518
  });
519
519
  return true;
520
520
  }
521
- const sessionLifecycleMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)$/);
522
- if (sessionLifecycleMatch && method === 'PATCH') {
523
- const agentId = decodeURIComponent(sessionLifecycleMatch[1]);
524
- const sessionId = decodeURIComponent(sessionLifecycleMatch[2]);
521
+ const threadLifecycleMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)$/);
522
+ if (threadLifecycleMatch && method === 'PATCH') {
523
+ const agentId = decodeURIComponent(threadLifecycleMatch[1]);
524
+ const threadId = decodeURIComponent(threadLifecycleMatch[2]);
525
525
  const parsed = await readJsonBody(req);
526
526
  if (parsed?.archived === true) {
527
- const archived = archiveSessionForAgent(agentId, sessionId);
527
+ const archived = archiveThreadForAgent(agentId, threadId);
528
528
  if (!archived) {
529
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
529
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
530
530
  return true;
531
531
  }
532
532
  writeJson(res, 200, { ok: true, archived: true });
533
533
  return true;
534
534
  }
535
535
  if (parsed?.archived === false) {
536
- const restored = restoreSessionForAgent(agentId, sessionId);
536
+ const restored = restoreThreadForAgent(agentId, threadId);
537
537
  if (!restored) {
538
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Archived task "${sessionId}" was not found for agent "${agentId}"`);
538
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Archived task "${threadId}" was not found for agent "${agentId}"`);
539
539
  return true;
540
540
  }
541
541
  writeJson(res, 200, {
542
542
  ok: true,
543
543
  archived: false,
544
- session: serializeTask(getSessionForAgent(agentId, sessionId)),
544
+ thread: serializeTask(getThreadForAgent(agentId, threadId)),
545
545
  });
546
546
  return true;
547
547
  }
548
548
  if (typeof parsed?.title === 'string') {
549
- const updated = updateSessionMetadata(agentId, sessionId, {
549
+ const updated = updateThreadMetadata(agentId, threadId, {
550
550
  title: parsed.title.trim() || undefined,
551
551
  });
552
552
  if (!updated) {
553
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
553
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
554
554
  return true;
555
555
  }
556
- const session = getSessionForAgent(agentId, sessionId);
557
- writeJson(res, 200, { ok: true, session: session ? serializeTask(session) : null });
556
+ const thread = getThreadForAgent(agentId, threadId);
557
+ writeJson(res, 200, { ok: true, thread: thread ? serializeTask(thread) : null });
558
558
  return true;
559
559
  }
560
- writeProtocolError(res, 400, 'input_error', 'invalid_session_update', 'Expected archived or title in request body.');
560
+ writeProtocolError(res, 400, 'input_error', 'invalid_thread_update', 'Expected archived or title in request body.');
561
561
  return true;
562
562
  }
563
- if (sessionLifecycleMatch && method === 'DELETE') {
564
- const agentId = decodeURIComponent(sessionLifecycleMatch[1]);
565
- const sessionId = decodeURIComponent(sessionLifecycleMatch[2]);
566
- const deleted = deleteSessionForAgent(agentId, sessionId) ||
567
- deleteSessionForAgent(agentId, sessionId, true);
563
+ if (threadLifecycleMatch && method === 'DELETE') {
564
+ const agentId = decodeURIComponent(threadLifecycleMatch[1]);
565
+ const threadId = decodeURIComponent(threadLifecycleMatch[2]);
566
+ const deleted = deleteThreadForAgent(agentId, threadId) ||
567
+ deleteThreadForAgent(agentId, threadId, true);
568
568
  if (!deleted) {
569
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
569
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
570
570
  return true;
571
571
  }
572
572
  writeJson(res, 200, { ok: true });
573
573
  return true;
574
574
  }
575
- const runtimeStateMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/runtime-state$/);
575
+ const runtimeStateMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/runtime-state$/);
576
576
  if (runtimeStateMatch && method === 'GET') {
577
577
  const agentId = decodeURIComponent(runtimeStateMatch[1]);
578
- const sessionId = decodeURIComponent(runtimeStateMatch[2]);
579
- const session = getSessionForAgent(agentId, sessionId);
580
- if (!session) {
581
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Session "${sessionId}" was not found for agent "${agentId}"`);
578
+ const threadId = decodeURIComponent(runtimeStateMatch[2]);
579
+ const thread = getThreadForAgent(agentId, threadId);
580
+ if (!thread) {
581
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Thread "${threadId}" was not found for agent "${agentId}"`);
582
582
  return true;
583
583
  }
584
- const projection = projectThreadRuntimeState(sessionId);
584
+ const projection = projectThreadRuntimeState(threadId);
585
585
  writeJson(res, 200, {
586
- session,
586
+ thread,
587
587
  runtimeState: runtimeStateSummary(projection),
588
588
  projection,
589
589
  });
590
590
  return true;
591
591
  }
592
- const sessionMessagesMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/sessions\/([^/]+)\/messages$/);
593
- if (sessionMessagesMatch && method === 'GET') {
594
- const agentId = decodeURIComponent(sessionMessagesMatch[1]);
595
- const sessionId = decodeURIComponent(sessionMessagesMatch[2]);
596
- const session = getSessionForAgent(agentId, sessionId);
597
- if (!session) {
598
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
592
+ const threadMessagesMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/([^/]+)\/threads\/([^/]+)\/messages$/);
593
+ if (threadMessagesMatch && method === 'GET') {
594
+ const agentId = decodeURIComponent(threadMessagesMatch[1]);
595
+ const threadId = decodeURIComponent(threadMessagesMatch[2]);
596
+ const thread = getThreadForAgent(agentId, threadId);
597
+ if (!thread) {
598
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
599
599
  return true;
600
600
  }
601
- const limit = Math.max(1, parseInt(url.searchParams.get('limit') || '100', 10) || 100);
602
- const interactionEvents = getSessionInteractionEvents(agentId, sessionId, limit);
603
- const controlLog = listControlLogEntries(sessionId, limit);
604
- const runtimeState = runtimeStateForThread(sessionId);
601
+ const limit = Math.max(1, parseInt(url.searchParams.get('limit') || '200', 10) || 200);
602
+ const interactionEvents = getThreadInteractionEvents(agentId, threadId, limit);
603
+ const controlLog = listControlLogEntries(threadId, limit);
604
+ const runtimeState = runtimeStateForThread(threadId);
605
605
  const responseMessages = runtimeState.messages.slice(-limit);
606
606
  const responseEvents = runtimeState.events.slice(-limit);
607
607
  writeJson(res, 200, {
608
- session,
608
+ thread,
609
609
  messages: responseMessages,
610
610
  events: responseEvents,
611
611
  interaction_events: interactionEvents,
@@ -614,12 +614,12 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
614
614
  });
615
615
  return true;
616
616
  }
617
- if (sessionMessagesMatch && method === 'POST') {
618
- const agentId = decodeURIComponent(sessionMessagesMatch[1]);
619
- const sessionId = decodeURIComponent(sessionMessagesMatch[2]);
620
- const session = getSessionForAgent(agentId, sessionId);
621
- if (!session) {
622
- writeProtocolError(res, 404, 'input_error', 'session_not_found', `Task "${sessionId}" was not found for agent "${agentId}"`);
617
+ if (threadMessagesMatch && method === 'POST') {
618
+ const agentId = decodeURIComponent(threadMessagesMatch[1]);
619
+ const threadId = decodeURIComponent(threadMessagesMatch[2]);
620
+ const thread = getThreadForAgent(agentId, threadId);
621
+ if (!thread) {
622
+ writeProtocolError(res, 404, 'input_error', 'thread_not_found', `Task "${threadId}" was not found for agent "${agentId}"`);
623
623
  return true;
624
624
  }
625
625
  const parsed = await readJsonBody(req);
@@ -629,15 +629,15 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
629
629
  writeProtocolError(res, 400, 'input_error', 'content_required', 'user_text and assistant_text are required non-empty strings');
630
630
  return true;
631
631
  }
632
- const chatJid = buildHttpSessionId(agentId, sessionId);
632
+ const chatJid = buildHttpThreadId(agentId, threadId);
633
633
  const senderIdentity = deriveHttpSenderIdentity(adminContext);
634
634
  const pairId = randomUUID();
635
- recordSessionControlCommand({
635
+ recordThreadControlCommand({
636
636
  agentId,
637
- sessionId,
637
+ threadId,
638
638
  turnId: pairId,
639
639
  surface: 'web',
640
- commandType: 'session.instruct',
640
+ commandType: 'thread.instruct',
641
641
  method: 'turn/start',
642
642
  actor: senderIdentity.sender,
643
643
  status: 'completed',
@@ -653,7 +653,7 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
653
653
  id: `http-slash-${pairId}-user`,
654
654
  chat_jid: chatJid,
655
655
  agent_id: agentId,
656
- session_id: sessionId,
656
+ thread_id: threadId,
657
657
  sender: senderIdentity.sender,
658
658
  sender_name: senderIdentity.sender_name,
659
659
  content: userText,
@@ -666,7 +666,7 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
666
666
  id: `http-slash-${pairId}-assistant`,
667
667
  chat_jid: chatJid,
668
668
  agent_id: agentId,
669
- session_id: sessionId,
669
+ thread_id: threadId,
670
670
  sender: ASSISTANT_NAME,
671
671
  sender_name: ASSISTANT_NAME,
672
672
  content: assistantText,
@@ -675,14 +675,14 @@ export async function handleSessionsRoutes(req, res, url, pathname, method, admi
675
675
  is_bot_message: true,
676
676
  metadata: { source: 'http-slash-command' },
677
677
  });
678
- await ensureThreadTitleFromBackend(agentId, sessionId);
678
+ await ensureThreadTitleFromBackend(agentId, threadId);
679
679
  writeJson(res, 200, { ok: true });
680
680
  return true;
681
681
  }
682
682
  return false;
683
683
  }
684
684
  async function ensureThreadTitleFromBackend(agentId, threadId) {
685
- const existingTitle = getSessionForAgent(agentId, threadId)?.title?.trim();
685
+ const existingTitle = getThreadForAgent(agentId, threadId)?.title?.trim();
686
686
  if (existingTitle)
687
687
  return;
688
688
  let title = readCodexTitleForThread(threadId);
@@ -698,10 +698,10 @@ async function ensureThreadTitleFromBackend(agentId, threadId) {
698
698
  return;
699
699
  if (existingTitle === title)
700
700
  return;
701
- updateSessionMetadata(agentId, threadId, { title });
702
- broadcastToChat(buildHttpSessionId(agentId, threadId), {
703
- type: 'session_updated',
704
- session: { task_id: threadId, title },
701
+ updateThreadMetadata(agentId, threadId, { title });
702
+ broadcastToChat(buildHttpThreadId(agentId, threadId), {
703
+ type: 'thread_updated',
704
+ thread: { task_id: threadId, title },
705
705
  });
706
706
  }
707
- //# sourceMappingURL=sessions.js.map
707
+ //# sourceMappingURL=threads.js.map