@downcity/agent 1.1.200 → 1.1.202

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 (228) hide show
  1. package/bin/agent/local/Agent.d.ts +3 -7
  2. package/bin/agent/local/Agent.d.ts.map +1 -1
  3. package/bin/agent/local/Agent.js +14 -19
  4. package/bin/agent/local/Agent.js.map +1 -1
  5. package/bin/agent/local/services/{AgentSessionManager.d.ts → AgentSessions.d.ts} +12 -17
  6. package/bin/agent/local/services/AgentSessions.d.ts.map +1 -0
  7. package/bin/agent/local/services/{AgentSessionManager.js → AgentSessions.js} +11 -26
  8. package/bin/agent/local/services/AgentSessions.js.map +1 -0
  9. package/bin/agent/remote/RemoteAgent.d.ts +2 -9
  10. package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
  11. package/bin/agent/remote/RemoteAgent.js +40 -22
  12. package/bin/agent/remote/RemoteAgent.js.map +1 -1
  13. package/bin/agent/remote/RemoteSession.d.ts +5 -5
  14. package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
  15. package/bin/agent/remote/RemoteSession.js +5 -3
  16. package/bin/agent/remote/RemoteSession.js.map +1 -1
  17. package/bin/agent/remote/RemoteTransport.d.ts +2 -2
  18. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +2 -2
  19. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +5 -5
  20. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +2 -2
  21. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +2 -2
  22. package/bin/executor/Executor.d.ts +5 -5
  23. package/bin/executor/Executor.d.ts.map +1 -1
  24. package/bin/executor/Executor.js +22 -13
  25. package/bin/executor/Executor.js.map +1 -1
  26. package/bin/executor/SessionRunScope.d.ts +1 -1
  27. package/bin/executor/SessionRunScope.d.ts.map +1 -1
  28. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +3 -3
  29. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
  30. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +4 -5
  31. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
  32. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +56 -16
  33. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
  34. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts +27 -0
  35. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts.map +1 -0
  36. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js +181 -0
  37. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js.map +1 -0
  38. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts +45 -0
  39. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts.map +1 -0
  40. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js +144 -0
  41. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js.map +1 -0
  42. package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +3 -3
  43. package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +1 -1
  44. package/bin/executor/composer/context/SessionContextComposer.d.ts +3 -3
  45. package/bin/executor/composer/context/SessionContextComposer.d.ts.map +1 -1
  46. package/bin/executor/composer/history/SessionHistoryComposer.d.ts +2 -2
  47. package/bin/executor/composer/history/SessionHistoryComposer.d.ts.map +1 -1
  48. package/bin/executor/composer/history/SessionHistoryWriter.d.ts +5 -5
  49. package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +1 -1
  50. package/bin/executor/composer/history/SessionHistoryWriter.js +6 -6
  51. package/bin/executor/composer/history/SessionHistoryWriter.js.map +1 -1
  52. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts +2 -2
  53. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +1 -1
  54. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +5 -5
  55. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +1 -1
  56. package/bin/executor/core-engine/CoreEngineMessageState.d.ts +5 -5
  57. package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +1 -1
  58. package/bin/executor/core-engine/CoreEngineMessageState.js.map +1 -1
  59. package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
  60. package/bin/executor/core-engine/CoreEngineSignals.d.ts +4 -4
  61. package/bin/executor/core-engine/CoreEngineSignals.d.ts.map +1 -1
  62. package/bin/executor/core-engine/CoreEngineSignals.js.map +1 -1
  63. package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts +3 -3
  64. package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts.map +1 -1
  65. package/bin/executor/core-engine/CoreEngineUiStreamCollector.js.map +1 -1
  66. package/bin/executor/messages/AssistantResultPersistence.d.ts +5 -5
  67. package/bin/executor/messages/AssistantResultPersistence.d.ts.map +1 -1
  68. package/bin/executor/messages/AssistantResultPersistence.js +1 -1
  69. package/bin/executor/messages/AssistantResultPersistence.js.map +1 -1
  70. package/bin/executor/messages/SessionAttachmentMapper.d.ts +3 -3
  71. package/bin/executor/messages/SessionAttachmentMapper.d.ts.map +1 -1
  72. package/bin/executor/messages/SessionAttachmentMapper.js.map +1 -1
  73. package/bin/executor/messages/SessionMessageCodec.d.ts +4 -4
  74. package/bin/executor/messages/SessionMessageCodec.d.ts.map +1 -1
  75. package/bin/executor/messages/SessionMessageCodec.js +5 -5
  76. package/bin/executor/messages/SessionMessageCodec.js.map +1 -1
  77. package/bin/executor/messages/SessionMessageLog.d.ts +3 -3
  78. package/bin/executor/messages/SessionMessageLog.d.ts.map +1 -1
  79. package/bin/executor/messages/SessionMessageLog.js.map +1 -1
  80. package/bin/executor/messages/SessionStepEventMapper.d.ts +2 -2
  81. package/bin/executor/messages/SessionStepEventMapper.d.ts.map +1 -1
  82. package/bin/executor/messages/SessionStepEventMapper.js.map +1 -1
  83. package/bin/executor/messages/UserVisibleText.d.ts +3 -3
  84. package/bin/executor/messages/UserVisibleText.d.ts.map +1 -1
  85. package/bin/executor/messages/UserVisibleText.js +3 -3
  86. package/bin/executor/messages/UserVisibleText.js.map +1 -1
  87. package/bin/executor/services/ExecutorInflightService.d.ts +2 -2
  88. package/bin/executor/services/ExecutorInflightService.d.ts.map +1 -1
  89. package/bin/executor/services/ExecutorInflightService.js +4 -4
  90. package/bin/executor/services/ExecutorInflightService.js.map +1 -1
  91. package/bin/executor/store/history/SessionHistoryStore.d.ts +24 -21
  92. package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
  93. package/bin/executor/store/history/SessionHistoryStore.js +3 -3
  94. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +18 -19
  95. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
  96. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +33 -36
  97. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  98. package/bin/executor/tools/plugin/PluginToolDefinition.d.ts +1 -7
  99. package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -1
  100. package/bin/executor/tools/plugin/PluginToolSchemas.d.ts +4 -6
  101. package/bin/executor/tools/plugin/PluginToolSchemas.d.ts.map +1 -1
  102. package/bin/executor/tools/plugin/PluginToolSchemas.js +24 -10
  103. package/bin/executor/tools/plugin/PluginToolSchemas.js.map +1 -1
  104. package/bin/executor/types/{SessionMessages.d.ts → SessionRecords.d.ts} +53 -28
  105. package/bin/executor/types/SessionRecords.d.ts.map +1 -0
  106. package/bin/executor/types/SessionRecords.js +52 -0
  107. package/bin/executor/types/SessionRecords.js.map +1 -0
  108. package/bin/executor/types/SessionRun.d.ts +3 -3
  109. package/bin/executor/types/SessionRun.d.ts.map +1 -1
  110. package/bin/index.d.ts +1 -1
  111. package/bin/index.d.ts.map +1 -1
  112. package/bin/rpc/Client.d.ts +5 -5
  113. package/bin/rpc/Client.js +4 -4
  114. package/bin/session/Session.d.ts +6 -6
  115. package/bin/session/Session.d.ts.map +1 -1
  116. package/bin/session/Session.js +8 -8
  117. package/bin/session/Session.js.map +1 -1
  118. package/bin/session/SessionTitle.d.ts +2 -2
  119. package/bin/session/SessionTitle.d.ts.map +1 -1
  120. package/bin/session/SessionTitle.js +3 -3
  121. package/bin/session/SessionTitle.js.map +1 -1
  122. package/bin/session/browse/Browse.d.ts +12 -12
  123. package/bin/session/browse/Browse.d.ts.map +1 -1
  124. package/bin/session/browse/Browse.js +9 -9
  125. package/bin/session/browse/Browse.js.map +1 -1
  126. package/bin/session/index.d.ts +1 -1
  127. package/bin/session/index.js +1 -1
  128. package/bin/session/runtime/SessionPromptRuntime.d.ts +3 -3
  129. package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
  130. package/bin/session/services/SessionStateService.d.ts +7 -8
  131. package/bin/session/services/SessionStateService.d.ts.map +1 -1
  132. package/bin/session/services/SessionStateService.js +15 -31
  133. package/bin/session/services/SessionStateService.js.map +1 -1
  134. package/bin/session/services/SessionViewService.d.ts +4 -4
  135. package/bin/session/services/SessionViewService.js +12 -12
  136. package/bin/session/services/SessionViewService.js.map +1 -1
  137. package/bin/session/storage/Persistence.d.ts +4 -4
  138. package/bin/session/storage/Persistence.d.ts.map +1 -1
  139. package/bin/session/storage/RuntimeSessionPort.d.ts +2 -2
  140. package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
  141. package/bin/session/storage/RuntimeSessionPort.js +4 -4
  142. package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
  143. package/bin/types/agent/AgentTypes.d.ts +2 -2
  144. package/bin/types/agent/AgentTypes.d.ts.map +1 -1
  145. package/bin/types/agent/SessionActor.d.ts +11 -11
  146. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  147. package/bin/types/agent/SessionTypes.d.ts +12 -12
  148. package/bin/types/agent/SessionTypes.d.ts.map +1 -1
  149. package/bin/types/executor/SessionRunContext.d.ts +2 -2
  150. package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
  151. package/bin/types/rpc/RpcProtocol.d.ts +6 -6
  152. package/bin/types/runtime/agent/AgentContext.d.ts +7 -7
  153. package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
  154. package/bin/types/sdk/AgentSessionAction.d.ts +8 -49
  155. package/bin/types/sdk/AgentSessionAction.d.ts.map +1 -1
  156. package/bin/types/sdk/AgentSessionAction.js +4 -4
  157. package/bin/types/sdk/AgentSessionTurn.d.ts +2 -2
  158. package/bin/types/sdk/AgentSessionTurn.d.ts.map +1 -1
  159. package/package.json +3 -3
  160. package/scripts/agent-ready.test.mjs +1 -1
  161. package/scripts/city-model-tool-loop.test.mjs +36 -4
  162. package/scripts/plugin-tool-bridge.test.mjs +13 -0
  163. package/scripts/session-action-message.test.mjs +25 -25
  164. package/scripts/session-compaction-prompts.test.mjs +97 -0
  165. package/scripts/session-history-archive.test.mjs +8 -8
  166. package/scripts/session-history-inflight.test.mjs +10 -10
  167. package/scripts/session-list-title.test.mjs +9 -9
  168. package/scripts/session-title-event.test.mjs +12 -10
  169. package/src/agent/local/Agent.ts +16 -22
  170. package/src/agent/local/services/{AgentSessionManager.ts → AgentSessions.ts} +16 -32
  171. package/src/agent/remote/RemoteAgent.ts +58 -23
  172. package/src/agent/remote/RemoteSession.ts +10 -8
  173. package/src/agent/remote/RemoteTransport.ts +5 -5
  174. package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +10 -10
  175. package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +6 -6
  176. package/src/executor/Executor.ts +30 -19
  177. package/src/executor/SessionRunScope.ts +1 -1
  178. package/src/executor/composer/compaction/SessionCompactionComposer.ts +3 -3
  179. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +73 -29
  180. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.ts +197 -0
  181. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.ts +162 -0
  182. package/src/executor/composer/context/LocalSessionContextComposer.ts +5 -5
  183. package/src/executor/composer/context/SessionContextComposer.ts +5 -5
  184. package/src/executor/composer/history/SessionHistoryComposer.ts +2 -2
  185. package/src/executor/composer/history/SessionHistoryWriter.ts +10 -10
  186. package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +13 -13
  187. package/src/executor/core-engine/CoreEngineMessageState.ts +8 -8
  188. package/src/executor/core-engine/CoreEngineRunner.ts +7 -7
  189. package/src/executor/core-engine/CoreEngineSignals.ts +7 -7
  190. package/src/executor/core-engine/CoreEngineUiStreamCollector.ts +5 -5
  191. package/src/executor/messages/AssistantResultPersistence.ts +8 -8
  192. package/src/executor/messages/SessionAttachmentMapper.ts +11 -11
  193. package/src/executor/messages/SessionMessageCodec.ts +10 -10
  194. package/src/executor/messages/SessionMessageLog.ts +3 -3
  195. package/src/executor/messages/SessionStepEventMapper.ts +5 -5
  196. package/src/executor/messages/UserVisibleText.ts +9 -9
  197. package/src/executor/services/ExecutorInflightService.ts +7 -7
  198. package/src/executor/store/history/SessionHistoryStore.ts +26 -23
  199. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +58 -62
  200. package/src/executor/tools/plugin/PluginToolSchemas.ts +24 -10
  201. package/src/executor/types/{SessionMessages.ts → SessionRecords.ts} +71 -40
  202. package/src/executor/types/SessionRun.ts +5 -5
  203. package/src/index.ts +4 -4
  204. package/src/rpc/Client.ts +9 -9
  205. package/src/session/Session.ts +10 -10
  206. package/src/session/SessionTitle.ts +7 -7
  207. package/src/session/browse/Browse.ts +38 -38
  208. package/src/session/index.ts +1 -1
  209. package/src/session/runtime/SessionPromptRuntime.ts +6 -6
  210. package/src/session/services/SessionStateService.ts +29 -44
  211. package/src/session/services/SessionTurnService.ts +4 -4
  212. package/src/session/services/SessionViewService.ts +21 -21
  213. package/src/session/storage/Persistence.ts +6 -6
  214. package/src/session/storage/RuntimeSessionPort.ts +6 -6
  215. package/src/types/agent/AgentTypes.ts +4 -4
  216. package/src/types/agent/SessionActor.ts +12 -12
  217. package/src/types/agent/SessionTypes.ts +12 -12
  218. package/src/types/executor/SessionRunContext.ts +2 -2
  219. package/src/types/rpc/RpcProtocol.ts +6 -6
  220. package/src/types/runtime/agent/AgentContext.ts +8 -8
  221. package/src/types/sdk/AgentSessionAction.ts +12 -56
  222. package/src/types/sdk/AgentSessionTurn.ts +2 -2
  223. package/tsconfig.tsbuildinfo +1 -1
  224. package/bin/agent/local/services/AgentSessionManager.d.ts.map +0 -1
  225. package/bin/agent/local/services/AgentSessionManager.js.map +0 -1
  226. package/bin/executor/types/SessionMessages.d.ts.map +0 -1
  227. package/bin/executor/types/SessionMessages.js +0 -46
  228. package/bin/executor/types/SessionMessages.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @file 验证 session.history 的 compact archive 分层读取语义。
2
+ * @file 验证 session.records 的 compact archive 分层读取语义。
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - compact summary 是模型上下文消息,但不应作为用户可见 history item 返回。
@@ -91,7 +91,7 @@ async function write_archive(file_path, session_id, messages) {
91
91
  );
92
92
  }
93
93
 
94
- test("session.history hides compact summary and reads archive layers by archive_id", async () => {
94
+ test("session.records hides compact summary and reads archive layers by archive_id", async () => {
95
95
  const agent_path = await fs.mkdtemp(
96
96
  path.join(os.tmpdir(), "downcity-agent-history-archive-"),
97
97
  );
@@ -99,7 +99,7 @@ test("session.history hides compact summary and reads archive layers by archive_
99
99
  id: "history_archive_agent",
100
100
  path: agent_path,
101
101
  });
102
- const session = await agent.session_collection().create_session({
102
+ const session = await agent.sessions.create({
103
103
  sessionId: "history_archive_session",
104
104
  });
105
105
 
@@ -131,7 +131,7 @@ test("session.history hides compact summary and reads archive layers by archive_
131
131
  assistant_message(session.id, 2),
132
132
  ]);
133
133
 
134
- const current_page = await session.history({
134
+ const current_page = await session.records({
135
135
  limit: 1,
136
136
  });
137
137
  assert.equal(current_page.total, 2);
@@ -144,7 +144,7 @@ test("session.history hides compact summary and reads archive layers by archive_
144
144
  ["u:31"],
145
145
  );
146
146
 
147
- const next_current_page = await session.history({
147
+ const next_current_page = await session.records({
148
148
  cursor: current_page.next_cursor,
149
149
  });
150
150
  assert.equal(next_current_page.has_more, false);
@@ -153,7 +153,7 @@ test("session.history hides compact summary and reads archive layers by archive_
153
153
  ["a:32"],
154
154
  );
155
155
 
156
- const previous_page = await session.history({
156
+ const previous_page = await session.records({
157
157
  archive_id: current_page.previous_archive_id,
158
158
  });
159
159
  assert.equal(previous_page.archive_id, "compact-B");
@@ -164,7 +164,7 @@ test("session.history hides compact summary and reads archive layers by archive_
164
164
  ["u:16", "a:17"],
165
165
  );
166
166
 
167
- const oldest_page = await session.history({
167
+ const oldest_page = await session.records({
168
168
  archive_id: previous_page.previous_archive_id,
169
169
  });
170
170
  assert.equal(oldest_page.archive_id, "compact-A");
@@ -174,7 +174,7 @@ test("session.history hides compact summary and reads archive layers by archive_
174
174
  ["u:1", "a:2"],
175
175
  );
176
176
 
177
- const timeline_page = await session.history({
177
+ const timeline_page = await session.records({
178
178
  view: "timeline",
179
179
  archive_id: "compact-B",
180
180
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @file 验证 session history 会把运行中的 assistant 收敛到 inflight 快照,并在完成后写回正式历史。
2
+ * @file 验证 session records 会把运行中的 assistant 收敛到 inflight 快照,并在完成后写回正式历史。
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 直接覆盖 JSONL history store 的落盘语义,确保运行中不中断丢失过程。
@@ -41,7 +41,7 @@ test("JsonlSessionHistoryStore exposes inflight assistant during execution and f
41
41
  sessionId: "session_test",
42
42
  });
43
43
 
44
- await store.append(
44
+ await store.write_record(
45
45
  store.userText({
46
46
  text: "write to document",
47
47
  metadata: {
@@ -50,7 +50,7 @@ test("JsonlSessionHistoryStore exposes inflight assistant during execution and f
50
50
  }),
51
51
  );
52
52
 
53
- await store.writeInflight(
53
+ await store.write_inflight(
54
54
  create_assistant_message([
55
55
  { type: "step-start" },
56
56
  { type: "text", text: "Let me inspect the document.", state: "done" },
@@ -64,7 +64,7 @@ test("JsonlSessionHistoryStore exposes inflight assistant during execution and f
64
64
  ]),
65
65
  );
66
66
 
67
- const during_run = await store.list();
67
+ const during_run = await store.list_records();
68
68
  assert.equal(during_run.length, 2);
69
69
  assert.equal(during_run[1]?.role, "assistant");
70
70
  assert.deepEqual(
@@ -72,13 +72,13 @@ test("JsonlSessionHistoryStore exposes inflight assistant during execution and f
72
72
  ["step-start", "text", "tool-exec_command"],
73
73
  );
74
74
 
75
- await store.finalizeInflight(
75
+ await store.finalize_inflight(
76
76
  create_assistant_message([
77
77
  { type: "text", text: "Done writing.", state: "done" },
78
78
  ]),
79
79
  );
80
80
 
81
- const after_finish = await store.list();
81
+ const after_finish = await store.list_records();
82
82
  assert.equal(after_finish.length, 2);
83
83
  assert.deepEqual(
84
84
  after_finish[1]?.parts.map((part) => part.type),
@@ -113,7 +113,7 @@ test("Appending a new user message flushes stale inflight assistant before the n
113
113
  sessionId: "session_flush_test",
114
114
  });
115
115
 
116
- await store.append(
116
+ await store.write_record(
117
117
  store.userText({
118
118
  text: "first",
119
119
  metadata: {
@@ -122,14 +122,14 @@ test("Appending a new user message flushes stale inflight assistant before the n
122
122
  }),
123
123
  );
124
124
 
125
- await store.writeInflight(
125
+ await store.write_inflight(
126
126
  create_assistant_message([
127
127
  { type: "step-start" },
128
128
  { type: "text", text: "partial assistant", state: "done" },
129
129
  ]),
130
130
  );
131
131
 
132
- await store.append(
132
+ await store.write_record(
133
133
  store.userText({
134
134
  text: "second",
135
135
  metadata: {
@@ -138,7 +138,7 @@ test("Appending a new user message flushes stale inflight assistant before the n
138
138
  }),
139
139
  );
140
140
 
141
- const messages = await store.list();
141
+ const messages = await store.list_records();
142
142
  assert.equal(messages.length, 3);
143
143
  assert.equal(messages[0]?.role, "user");
144
144
  assert.equal(messages[1]?.role, "assistant");
@@ -54,12 +54,12 @@ async function create_agent_with_titled_session(input) {
54
54
  path: agent_path,
55
55
  model: create_mock_title_model(input.title),
56
56
  });
57
- const collection = agent.session_collection();
58
- const session = await collection.create_session({
57
+ const collection = agent.sessions;
58
+ const session = await collection.create({
59
59
  sessionId: input.session_id,
60
60
  });
61
61
 
62
- await session.appendUserMessage({
62
+ await session.append_user_message({
63
63
  text: input.first_user_text,
64
64
  });
65
65
 
@@ -80,7 +80,7 @@ test("list_sessions returns persisted title from active session metadata", async
80
80
  });
81
81
 
82
82
  try {
83
- const page = await collection.list_sessions();
83
+ const page = await collection.list();
84
84
 
85
85
  assert.equal(page.total, 1);
86
86
  assert.deepEqual(
@@ -93,7 +93,7 @@ test("list_sessions returns persisted title from active session metadata", async
93
93
  {
94
94
  sessionId: session.id,
95
95
  title: "列表标题",
96
- messageCount: 1,
96
+ messageCount: 2,
97
97
  },
98
98
  ],
99
99
  );
@@ -112,12 +112,12 @@ test("archive_sessions returns title from archived session metadata", async () =
112
112
  });
113
113
 
114
114
  try {
115
- await collection.archive_session({
115
+ await collection.archive({
116
116
  id: session.id,
117
117
  });
118
118
 
119
- const active_page = await collection.list_sessions();
120
- const archived_page = await collection.archive_sessions();
119
+ const active_page = await collection.list();
120
+ const archived_page = await collection.archived();
121
121
 
122
122
  assert.equal(active_page.total, 0);
123
123
  assert.equal(archived_page.total, 1);
@@ -131,7 +131,7 @@ test("archive_sessions returns title from archived session metadata", async () =
131
131
  {
132
132
  sessionId: session.id,
133
133
  title: "归档标题",
134
- messageCount: 1,
134
+ messageCount: 2,
135
135
  },
136
136
  ],
137
137
  );
@@ -53,24 +53,25 @@ test("Session keeps title empty when no model is available", async () => {
53
53
  id: "title_agent",
54
54
  path: agent_path,
55
55
  });
56
- const session = await agent.createSession();
56
+ const session = await agent.sessions.create();
57
57
  const events = [];
58
58
  const unsubscribe = session.subscribe((event) => {
59
59
  events.push(event);
60
60
  });
61
61
 
62
62
  try {
63
- await session.appendUserMessage({
63
+ await session.append_user_message({
64
64
  text: "Use shell tools to inspect the current workspace",
65
65
  });
66
66
 
67
67
  const title_event = events.find((event) => event.type === "session-title");
68
68
  assert.equal(title_event, undefined);
69
69
 
70
- const history = await session.history();
71
- assert.equal(history.session.title, undefined);
70
+ const records = await session.records();
71
+ assert.equal(records.session.title, undefined);
72
72
  } finally {
73
73
  unsubscribe();
74
+ await agent.dispose();
74
75
  }
75
76
  });
76
77
 
@@ -82,24 +83,24 @@ test("Session retries title generation after model becomes available", async ()
82
83
  id: "title_retry_agent",
83
84
  path: agent_path,
84
85
  });
85
- const session = await agent.createSession();
86
+ const session = await agent.sessions.create();
86
87
  const events = [];
87
88
  const unsubscribe = session.subscribe((event) => {
88
89
  events.push(event);
89
90
  });
90
91
 
91
92
  try {
92
- await session.appendUserMessage({
93
+ await session.append_user_message({
93
94
  text: "Investigate flaky session title generation in the SDK",
94
95
  });
95
96
 
96
- const history_before_model = await session.history();
97
+ const history_before_model = await session.records();
97
98
  assert.equal(history_before_model.session.title, undefined);
98
99
 
99
100
  await session.set({
100
101
  model: create_mock_title_model("排查 session 标题"),
101
102
  });
102
- await session.appendUserMessage({
103
+ await session.append_user_message({
103
104
  text: "Need another prompt to trigger the retry path",
104
105
  });
105
106
 
@@ -110,9 +111,10 @@ test("Session retries title generation after model becomes available", async ()
110
111
  title: "排查 session 标题",
111
112
  });
112
113
 
113
- const history = await session.history();
114
- assert.equal(history.session.title, "排查 session 标题");
114
+ const records = await session.records();
115
+ assert.equal(records.session.title, "排查 session 标题");
115
116
  } finally {
116
117
  unsubscribe();
118
+ await agent.dispose();
117
119
  }
118
120
  });
@@ -14,7 +14,7 @@ import type { AgentPlugins } from "@/plugin/types/Plugin.js";
14
14
  import type {
15
15
  AgentModel,
16
16
  AgentOptions,
17
- AgentSessionCollection,
17
+ AgentSessions as AgentSessionsApi,
18
18
  } from "@/types/agent/AgentTypes.js";
19
19
  import type {
20
20
  ShellApprovalMode,
@@ -32,7 +32,7 @@ import {
32
32
  AgentAssemblyService,
33
33
  type AgentAssemblyResult,
34
34
  } from "@/agent/local/services/AgentAssemblyService.js";
35
- import { AgentSessionManager } from "@/agent/local/services/AgentSessionManager.js";
35
+ import { AgentSessions as LocalAgentSessions } from "@/agent/local/services/AgentSessions.js";
36
36
  import { AgentBackgroundService } from "@/agent/local/services/AgentBackgroundService.js";
37
37
 
38
38
  /**
@@ -43,6 +43,7 @@ export class Agent {
43
43
  readonly path: string;
44
44
  readonly tools: Record<string, Tool>;
45
45
  readonly plugins: AgentPlugins;
46
+ readonly sessions: AgentSessionsApi;
46
47
 
47
48
  private readonly logger: Logger;
48
49
  private readonly agentContext: AgentContext;
@@ -51,7 +52,6 @@ export class Agent {
51
52
  private readonly env: Record<string, string>;
52
53
  private readonly defaultModel?: AgentModel;
53
54
  private readonly SessionClass: AgentOptions["Session"];
54
- private readonly sessionManager: AgentSessionManager;
55
55
  private readonly backgroundService: AgentBackgroundService;
56
56
  private readonly shell?: AgentOptions["shell"];
57
57
 
@@ -60,19 +60,19 @@ export class Agent {
60
60
  constructor(options: AgentOptions) {
61
61
  this.defaultModel = options.model;
62
62
  this.SessionClass = options.Session;
63
- let session_manager_ref: AgentSessionManager | null = null;
63
+ let sessions_ref: LocalAgentSessions | null = null;
64
64
  const assembly_service = new AgentAssemblyService({
65
65
  options,
66
- list_cached_sessions: () => session_manager_ref?.list_cached_sessions() || [],
66
+ list_cached_sessions: () => sessions_ref?.list_cached_sessions() || [],
67
67
  get_session_port: (session_id) => {
68
- if (!session_manager_ref) {
69
- throw new Error("Agent session manager is not initialized");
68
+ if (!sessions_ref) {
69
+ throw new Error("Agent sessions are not initialized");
70
70
  }
71
- return session_manager_ref.get_session_port(session_id);
71
+ return sessions_ref.get_session_port(session_id);
72
72
  },
73
73
  resolve_session_model: async (session_id) => {
74
- if (!session_manager_ref) return undefined;
75
- const session = await session_manager_ref.get_session(session_id);
74
+ if (!sessions_ref) return undefined;
75
+ const session = await sessions_ref.get(session_id);
76
76
  return session.config.model;
77
77
  },
78
78
  });
@@ -96,8 +96,9 @@ export class Agent {
96
96
  agent_context: this.agentContext,
97
97
  get_shell: () => this.shell,
98
98
  });
99
- this.sessionManager = this.create_session_manager(assembly);
100
- session_manager_ref = this.sessionManager;
99
+ const sessions = this.create_sessions(assembly);
100
+ this.sessions = sessions;
101
+ sessions_ref = sessions;
101
102
  }
102
103
 
103
104
  /**
@@ -244,13 +245,6 @@ export class Agent {
244
245
  return this.agentContext;
245
246
  }
246
247
 
247
- /**
248
- * 返回当前 session collection 入口。
249
- */
250
- session_collection(): AgentSessionCollection {
251
- return this.sessionManager.get_session_collection();
252
- }
253
-
254
248
  /**
255
249
  * 返回当前 agent 挂载的 Shell。
256
250
  */
@@ -258,10 +252,10 @@ export class Agent {
258
252
  return this.shell;
259
253
  }
260
254
 
261
- private create_session_manager(
255
+ private create_sessions(
262
256
  assembly: AgentAssemblyResult,
263
- ): AgentSessionManager {
264
- return new AgentSessionManager({
257
+ ): LocalAgentSessions {
258
+ return new LocalAgentSessions({
265
259
  agent_id: this.id || assembly.id,
266
260
  project_root: this.path || assembly.path,
267
261
  tools: this.tools || assembly.tools,
@@ -1,8 +1,8 @@
1
1
  /**
2
- * AgentSessionManager:本地 Agent session 管理服务。
2
+ * AgentSessions:本地 Agent session 集合入口。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 统一管理 session 缓存、创建、恢复、默认配置注入与 session collection。
5
+ * - 统一管理 session 缓存、创建、恢复、默认配置注入与列表查询。
6
6
  * - 该服务只负责 session 生命周期与查询,不负责 plugin / RPC 启停。
7
7
  * - Session 对象创建细节集中在这里,避免 facade 和 lifecycle 重复依赖 Session 构造逻辑。
8
8
  */
@@ -22,7 +22,7 @@ import type {
22
22
  AgentManagedSession,
23
23
  AgentModel,
24
24
  AgentSession,
25
- AgentSessionCollection,
25
+ AgentSessions as AgentSessionsApi,
26
26
  AgentSessionConstructor,
27
27
  AgentSessionSummaryPage,
28
28
  AgentSessionSystemBlock,
@@ -48,7 +48,7 @@ function decodeMaybe(input: string): string {
48
48
  }
49
49
  }
50
50
 
51
- type AgentSessionManagerOptions = {
51
+ type AgentSessionsOptions = {
52
52
  /**
53
53
  * 当前 agent 稳定标识。
54
54
  */
@@ -106,22 +106,21 @@ type AgentSessionManagerOptions = {
106
106
  /**
107
107
  * 本地 Agent session 管理服务。
108
108
  */
109
- export class AgentSessionManager {
109
+ export class AgentSessions implements AgentSessionsApi<AgentSession> {
110
110
  private readonly agent_id: string;
111
111
  private readonly project_root: string;
112
112
  private readonly tools: Record<string, Tool>;
113
113
  private readonly logger: Logger;
114
- private readonly get_agent_context: AgentSessionManagerOptions["get_agent_context"];
115
- private readonly get_instruction: AgentSessionManagerOptions["get_instruction"];
114
+ private readonly get_agent_context: AgentSessionsOptions["get_agent_context"];
115
+ private readonly get_instruction: AgentSessionsOptions["get_instruction"];
116
116
  private readonly plugin_instances: Map<string, Plugin>;
117
- private readonly ensure_agent_ready: AgentSessionManagerOptions["ensure_agent_ready"];
117
+ private readonly ensure_agent_ready: AgentSessionsOptions["ensure_agent_ready"];
118
118
  private readonly default_model?: AgentModel;
119
119
  private readonly SessionClass: AgentSessionConstructor;
120
120
  private readonly sessions_by_id = new Map<string, AgentManagedSession>();
121
121
  private readonly configured_session_ids = new Set<string>();
122
- private readonly session_collection: AgentSessionCollection;
123
122
 
124
- constructor(options: AgentSessionManagerOptions) {
123
+ constructor(options: AgentSessionsOptions) {
125
124
  this.agent_id = options.agent_id;
126
125
  this.project_root = options.project_root;
127
126
  this.tools = options.tools;
@@ -132,14 +131,6 @@ export class AgentSessionManager {
132
131
  this.ensure_agent_ready = options.ensure_agent_ready;
133
132
  this.default_model = options.default_model;
134
133
  this.SessionClass = options.SessionClass || Session;
135
- this.session_collection = {
136
- create_session: async (input) => await this.create_session(input),
137
- get_session: async (session_id) => await this.get_session(session_id),
138
- list_sessions: async (input) => await this.list_sessions(input),
139
- archive_session: async (input) => await this.archive_session(input),
140
- archive_sessions: async (input) => await this.archive_sessions(input),
141
- clean_archive: async () => await this.clean_archive(),
142
- };
143
134
  }
144
135
 
145
136
  /**
@@ -149,13 +140,6 @@ export class AgentSessionManager {
149
140
  return [...this.sessions_by_id.values()];
150
141
  }
151
142
 
152
- /**
153
- * 返回对外暴露的 session collection。
154
- */
155
- get_session_collection(): AgentSessionCollection {
156
- return this.session_collection;
157
- }
158
-
159
143
  /**
160
144
  * 获取或创建一个 session runtime port。
161
145
  */
@@ -168,7 +152,7 @@ export class AgentSessionManager {
168
152
  /**
169
153
  * 新建一个 session。
170
154
  */
171
- async create_session(
155
+ async create(
172
156
  input?: AgentCreateSessionInput,
173
157
  ): Promise<AgentSession> {
174
158
  const explicit_session_id =
@@ -197,10 +181,10 @@ export class AgentSessionManager {
197
181
  /**
198
182
  * 获取一个已存在的 session。
199
183
  */
200
- async get_session(session_id: string): Promise<AgentSession> {
184
+ async get(session_id: string): Promise<AgentSession> {
201
185
  const resolved_session_id = String(session_id || "").trim();
202
186
  if (!resolved_session_id) {
203
- throw new Error("get_session requires a non-empty sessionId");
187
+ throw new Error("sessions.get requires a non-empty sessionId");
204
188
  }
205
189
  const session_dir_path = getSdkAgentSessionDirPath(
206
190
  this.project_root,
@@ -224,7 +208,7 @@ export class AgentSessionManager {
224
208
  /**
225
209
  * 列出当前 agent 的 session 摘要页。
226
210
  */
227
- async list_sessions(
211
+ async list(
228
212
  input?: AgentListSessionsInput,
229
213
  ): Promise<AgentSessionSummaryPage> {
230
214
  return await listAgentSessionSummaryPage({
@@ -238,12 +222,12 @@ export class AgentSessionManager {
238
222
  /**
239
223
  * 归档单个 session。
240
224
  */
241
- async archive_session(
225
+ async archive(
242
226
  input: AgentArchiveSessionInput,
243
227
  ): Promise<AgentArchiveSessionResult> {
244
228
  const session_id = String(input?.id || "").trim();
245
229
  if (!session_id) {
246
- throw new Error("archive_session requires a non-empty id");
230
+ throw new Error("sessions.archive requires a non-empty id");
247
231
  }
248
232
 
249
233
  const executing_session_ids = new Set(
@@ -290,7 +274,7 @@ export class AgentSessionManager {
290
274
  /**
291
275
  * 列出当前 agent 的已归档 session 摘要页。
292
276
  */
293
- async archive_sessions(
277
+ async archived(
294
278
  input?: AgentArchiveSessionsInput,
295
279
  ): Promise<AgentArchiveSessionsResult> {
296
280
  return await listArchivedAgentSessionSummaryPage({
@@ -8,7 +8,15 @@
8
8
  */
9
9
 
10
10
  import type {
11
- AgentSessionCollection,
11
+ AgentArchiveSessionInput,
12
+ AgentArchiveSessionsInput,
13
+ AgentArchiveSessionResult,
14
+ AgentArchiveSessionsResult,
15
+ AgentCleanArchiveResult,
16
+ AgentCreateSessionInput,
17
+ AgentListSessionsInput,
18
+ AgentSessionSummaryPage,
19
+ AgentSessions,
12
20
  RemoteAgentPluginActionInput,
13
21
  RemoteAgentPluginActionResult,
14
22
  RemoteAgentOptions,
@@ -30,6 +38,8 @@ import { create_remote_agent_transport } from "@/agent/remote/TransportFactory.j
30
38
  * RemoteAgent:远程 Agent 客户端。
31
39
  */
32
40
  export class RemoteAgent {
41
+ readonly sessions: AgentSessions<RemoteAgentSession>;
42
+
33
43
  private readonly transport: RemoteAgentTransport;
34
44
 
35
45
  constructor(options: RemoteAgentOptions) {
@@ -38,6 +48,7 @@ export class RemoteAgent {
38
48
  throw new Error("RemoteAgent requires a non-empty url");
39
49
  }
40
50
  this.transport = create_remote_agent_transport(url, options.token);
51
+ this.sessions = new RemoteAgentSessions(this.transport);
41
52
  }
42
53
 
43
54
  /**
@@ -121,27 +132,51 @@ export class RemoteAgent {
121
132
  await this.transport.close?.();
122
133
  }
123
134
 
124
- /**
125
- * 返回当前远程 session collection 入口。
126
- *
127
- * 关键点(中文)
128
- * - `RemoteAgentTransport` 只负责协议传输,不直接等价于 `AgentSessionCollection`。
129
- * - 这里把 transport 包装为 `AgentSessionCollection`,`create_session` / `get_session` 返回 `RemoteSession` 实例。
130
- */
131
- session_collection(): AgentSessionCollection {
132
- return {
133
- create_session: async (input) => {
134
- const info = await this.transport.create_session(input);
135
- return new RemoteSession(this.transport, info);
136
- },
137
- get_session: async (session_id) => {
138
- const info = await this.transport.get_info(session_id);
139
- return new RemoteSession(this.transport, info);
140
- },
141
- list_sessions: async (input) => await this.transport.list_sessions(input),
142
- archive_session: async (input) => await this.transport.archive_session(input),
143
- archive_sessions: async (input) => await this.transport.archive_sessions(input),
144
- clean_archive: async () => await this.transport.clean_archive(),
145
- };
135
+ }
136
+
137
+ /**
138
+ * 远程 Agent session 集合入口。
139
+ *
140
+ * 关键点(中文)
141
+ * - `RemoteAgentTransport` 只负责协议传输,不直接暴露为用户 SDK API。
142
+ * - 这里把远程传输包装成和本地 `agent.sessions` 一致的方法命名。
143
+ */
144
+ class RemoteAgentSessions implements AgentSessions<RemoteAgentSession> {
145
+ private readonly transport: RemoteAgentTransport;
146
+
147
+ constructor(transport: RemoteAgentTransport) {
148
+ this.transport = transport;
149
+ }
150
+
151
+ /** 新建一个远程 session。 */
152
+ async create(input?: AgentCreateSessionInput): Promise<RemoteAgentSession> {
153
+ const info = await this.transport.create_session(input);
154
+ return new RemoteSession(this.transport, info);
155
+ }
156
+
157
+ /** 获取一个远程 session。 */
158
+ async get(session_id: string): Promise<RemoteAgentSession> {
159
+ const info = await this.transport.get_info(session_id);
160
+ return new RemoteSession(this.transport, info);
161
+ }
162
+
163
+ /** 列出远程 session 摘要页。 */
164
+ async list(input?: AgentListSessionsInput): Promise<AgentSessionSummaryPage> {
165
+ return await this.transport.list_sessions(input);
166
+ }
167
+
168
+ /** 归档一个远程 session。 */
169
+ async archive(input: AgentArchiveSessionInput): Promise<AgentArchiveSessionResult> {
170
+ return await this.transport.archive_session(input);
171
+ }
172
+
173
+ /** 列出远程已归档 session。 */
174
+ async archived(input?: AgentArchiveSessionsInput): Promise<AgentArchiveSessionsResult> {
175
+ return await this.transport.archive_sessions(input);
176
+ }
177
+
178
+ /** 永久清空远程已归档 session。 */
179
+ async clean_archive(): Promise<AgentCleanArchiveResult> {
180
+ return await this.transport.clean_archive();
146
181
  }
147
182
  }