@downcity/agent 1.1.208 → 1.1.210

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 (262) hide show
  1. package/bin/agent/local/Agent.d.ts +3 -3
  2. package/bin/agent/local/Agent.d.ts.map +1 -1
  3. package/bin/agent/local/Agent.js +0 -3
  4. package/bin/agent/local/Agent.js.map +1 -1
  5. package/bin/agent/local/AgentInstructions.d.ts +1 -1
  6. package/bin/agent/local/AgentInstructions.d.ts.map +1 -1
  7. package/bin/agent/local/services/AgentAssemblyService.d.ts +3 -8
  8. package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
  9. package/bin/agent/local/services/AgentAssemblyService.js +0 -1
  10. package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
  11. package/bin/agent/local/services/AgentSessions.d.ts +5 -7
  12. package/bin/agent/local/services/AgentSessions.d.ts.map +1 -1
  13. package/bin/agent/local/services/AgentSessions.js +2 -3
  14. package/bin/agent/local/services/AgentSessions.js.map +1 -1
  15. package/bin/agent/remote/RemoteAgent.d.ts +3 -1
  16. package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
  17. package/bin/agent/remote/RemoteAgent.js.map +1 -1
  18. package/bin/agent/remote/RemoteSession.d.ts +10 -1
  19. package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
  20. package/bin/agent/remote/RemoteSession.js +18 -0
  21. package/bin/agent/remote/RemoteSession.js.map +1 -1
  22. package/bin/agent/remote/RemoteTransport.d.ts +5 -1
  23. package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
  24. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +4 -1
  25. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
  26. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +7 -0
  27. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
  28. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +4 -1
  29. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
  30. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +1 -0
  31. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
  32. package/bin/executor/Executor.d.ts +0 -16
  33. package/bin/executor/Executor.d.ts.map +1 -1
  34. package/bin/executor/Executor.js +0 -16
  35. package/bin/executor/Executor.js.map +1 -1
  36. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +1 -3
  37. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
  38. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +1 -5
  39. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
  40. package/bin/executor/composer/history/SessionHistoryWriter.d.ts +0 -10
  41. package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +1 -1
  42. package/bin/executor/composer/history/SessionHistoryWriter.js +31 -61
  43. package/bin/executor/composer/history/SessionHistoryWriter.js.map +1 -1
  44. package/bin/executor/messages/AssistantFileResource.d.ts.map +1 -1
  45. package/bin/executor/messages/AssistantFileResource.js +58 -15
  46. package/bin/executor/messages/AssistantFileResource.js.map +1 -1
  47. package/bin/executor/services/ExecutorInflightService.d.ts +0 -5
  48. package/bin/executor/services/ExecutorInflightService.d.ts.map +1 -1
  49. package/bin/executor/services/ExecutorInflightService.js +0 -6
  50. package/bin/executor/services/ExecutorInflightService.js.map +1 -1
  51. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +4 -0
  52. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
  53. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +115 -3
  54. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  55. package/bin/executor/types/SessionHistoryMeta.d.ts +6 -0
  56. package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
  57. package/bin/index.d.ts +38 -6
  58. package/bin/index.d.ts.map +1 -1
  59. package/bin/index.js +14 -1
  60. package/bin/index.js.map +1 -1
  61. package/bin/plugin/core/ActionScheduleExecutor.js +1 -1
  62. package/bin/plugin/core/ActionScheduleExecutor.js.map +1 -1
  63. package/bin/plugin/core/BasePlugin.d.ts +7 -9
  64. package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
  65. package/bin/plugin/core/BasePlugin.js +1 -14
  66. package/bin/plugin/core/BasePlugin.js.map +1 -1
  67. package/bin/plugin/core/HookRegistry.d.ts +1 -1
  68. package/bin/plugin/core/HookRegistry.d.ts.map +1 -1
  69. package/bin/plugin/core/PluginActionFactory.d.ts +1 -5
  70. package/bin/plugin/core/PluginActionFactory.d.ts.map +1 -1
  71. package/bin/plugin/core/PluginActionFactory.js +0 -3
  72. package/bin/plugin/core/PluginActionFactory.js.map +1 -1
  73. package/bin/plugin/core/PluginActionRunner.d.ts +6 -4
  74. package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
  75. package/bin/plugin/core/PluginActionRunner.js +2 -2
  76. package/bin/plugin/core/PluginActionRunner.js.map +1 -1
  77. package/bin/plugin/core/PluginCatalog.d.ts +2 -1
  78. package/bin/plugin/core/PluginCatalog.d.ts.map +1 -1
  79. package/bin/plugin/core/PluginCatalog.js.map +1 -1
  80. package/bin/plugin/core/PluginCommand.d.ts +1 -1
  81. package/bin/plugin/core/PluginCommand.d.ts.map +1 -1
  82. package/bin/plugin/core/PluginCommand.js.map +1 -1
  83. package/bin/plugin/core/PluginHttpRoutes.d.ts +1 -1
  84. package/bin/plugin/core/PluginHttpRoutes.d.ts.map +1 -1
  85. package/bin/plugin/core/PluginLocalExecution.d.ts +4 -1
  86. package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
  87. package/bin/plugin/core/PluginLocalExecution.js +0 -1
  88. package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
  89. package/bin/plugin/core/PluginRegistry.d.ts +4 -2
  90. package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
  91. package/bin/plugin/core/PluginRegistry.js +7 -6
  92. package/bin/plugin/core/PluginRegistry.js.map +1 -1
  93. package/bin/plugin/core/PluginStateController.d.ts +7 -27
  94. package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
  95. package/bin/plugin/core/PluginStateController.js +5 -39
  96. package/bin/plugin/core/PluginStateController.js.map +1 -1
  97. package/bin/plugin/types/PluginApi.d.ts +3 -79
  98. package/bin/plugin/types/PluginApi.d.ts.map +1 -1
  99. package/bin/rpc/Client.d.ts +11 -6
  100. package/bin/rpc/Client.d.ts.map +1 -1
  101. package/bin/rpc/Client.js +2 -0
  102. package/bin/rpc/Client.js.map +1 -1
  103. package/bin/session/Session.d.ts +2 -5
  104. package/bin/session/Session.d.ts.map +1 -1
  105. package/bin/session/Session.js +3 -16
  106. package/bin/session/Session.js.map +1 -1
  107. package/bin/session/SessionSystemBuilder.d.ts +1 -1
  108. package/bin/session/SessionSystemBuilder.d.ts.map +1 -1
  109. package/bin/session/browse/Browse.d.ts +4 -6
  110. package/bin/session/browse/Browse.d.ts.map +1 -1
  111. package/bin/session/browse/Browse.js +71 -71
  112. package/bin/session/browse/Browse.js.map +1 -1
  113. package/bin/session/preview/SessionMessagePreview.d.ts +13 -0
  114. package/bin/session/preview/SessionMessagePreview.d.ts.map +1 -0
  115. package/bin/session/preview/SessionMessagePreview.js +61 -0
  116. package/bin/session/preview/SessionMessagePreview.js.map +1 -0
  117. package/bin/session/services/SessionStateService.d.ts +1 -1
  118. package/bin/session/services/SessionStateService.d.ts.map +1 -1
  119. package/bin/session/services/SessionStateService.js +2 -2
  120. package/bin/session/services/SessionStateService.js.map +1 -1
  121. package/bin/session/services/SessionViewService.d.ts +2 -1
  122. package/bin/session/services/SessionViewService.d.ts.map +1 -1
  123. package/bin/session/services/SessionViewService.js +4 -1
  124. package/bin/session/services/SessionViewService.js.map +1 -1
  125. package/bin/session/storage/Metadata.d.ts.map +1 -1
  126. package/bin/session/storage/Metadata.js +23 -0
  127. package/bin/session/storage/Metadata.js.map +1 -1
  128. package/bin/session/storage/Persistence.d.ts +1 -1
  129. package/bin/session/storage/Persistence.d.ts.map +1 -1
  130. package/bin/session/storage/RuntimeSessionPort.d.ts +0 -12
  131. package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
  132. package/bin/session/storage/RuntimeSessionPort.js +0 -8
  133. package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
  134. package/bin/types/plugin/PluginAction.d.ts +0 -10
  135. package/bin/types/plugin/PluginAction.d.ts.map +1 -1
  136. package/bin/types/plugin/PluginCommand.d.ts +2 -3
  137. package/bin/types/plugin/PluginCommand.d.ts.map +1 -1
  138. package/bin/types/plugin/PluginControl.d.ts +74 -0
  139. package/bin/types/plugin/PluginControl.d.ts.map +1 -0
  140. package/bin/types/plugin/PluginControl.js +9 -0
  141. package/bin/types/plugin/PluginControl.js.map +1 -0
  142. package/bin/types/plugin/PluginDefinition.d.ts +1 -1
  143. package/bin/types/plugin/PluginDefinition.d.ts.map +1 -1
  144. package/bin/types/plugin/PluginRuntime.d.ts +1 -3
  145. package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
  146. package/bin/types/plugin/PluginState.d.ts +3 -16
  147. package/bin/types/plugin/PluginState.d.ts.map +1 -1
  148. package/bin/types/rpc/RpcProtocol.d.ts +3 -3
  149. package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
  150. package/bin/types/runtime/agent/AgentContext.d.ts +1 -9
  151. package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
  152. package/bin/types/runtime/agent/AgentContext.js.map +1 -1
  153. package/bin/types/session/SessionLocalState.d.ts +1 -1
  154. package/bin/types/session/SessionLocalState.d.ts.map +1 -1
  155. package/package.json +4 -7
  156. package/scripts/agent-ready.test.mjs +38 -0
  157. package/scripts/assistant-file-resource.test.mjs +39 -0
  158. package/scripts/city-model-tool-loop.test.mjs +18 -30
  159. package/scripts/image-plugin-job.test.mjs +13 -13
  160. package/scripts/plugin-tool-bridge.test.mjs +2 -3
  161. package/scripts/remote-session-reconnect.test.mjs +67 -0
  162. package/scripts/session-history-writer-error.test.mjs +57 -0
  163. package/scripts/session-list-title.test.mjs +114 -23
  164. package/src/agent/local/Agent.ts +4 -10
  165. package/src/agent/local/AgentInstructions.ts +1 -1
  166. package/src/agent/local/services/AgentAssemblyService.ts +3 -9
  167. package/src/agent/local/services/AgentSessions.ts +8 -15
  168. package/src/agent/remote/RemoteAgent.ts +5 -4
  169. package/src/agent/remote/RemoteSession.ts +21 -2
  170. package/src/agent/remote/RemoteTransport.ts +6 -2
  171. package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +13 -3
  172. package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +6 -2
  173. package/src/executor/Executor.ts +0 -23
  174. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +2 -8
  175. package/src/executor/composer/history/SessionHistoryWriter.ts +33 -64
  176. package/src/executor/messages/AssistantFileResource.ts +61 -17
  177. package/src/executor/services/ExecutorInflightService.ts +0 -10
  178. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +130 -4
  179. package/src/executor/types/SessionHistoryMeta.ts +6 -0
  180. package/src/index.ts +100 -29
  181. package/src/plugin/core/ActionScheduleExecutor.ts +1 -1
  182. package/src/plugin/core/BasePlugin.ts +8 -22
  183. package/src/plugin/core/HookRegistry.ts +1 -1
  184. package/src/plugin/core/PluginActionFactory.ts +1 -8
  185. package/src/plugin/core/PluginActionRunner.ts +8 -11
  186. package/src/plugin/core/PluginCatalog.ts +2 -5
  187. package/src/plugin/core/PluginCommand.ts +2 -1
  188. package/src/plugin/core/PluginHttpRoutes.ts +1 -1
  189. package/src/plugin/core/PluginLocalExecution.ts +4 -7
  190. package/src/plugin/core/PluginRegistry.ts +10 -10
  191. package/src/plugin/core/PluginStateController.ts +12 -60
  192. package/src/plugin/types/PluginApi.ts +6 -81
  193. package/src/rpc/Client.ts +22 -16
  194. package/src/session/Session.ts +5 -21
  195. package/src/session/SessionSystemBuilder.ts +1 -1
  196. package/src/session/browse/Browse.ts +103 -84
  197. package/src/session/preview/SessionMessagePreview.ts +75 -0
  198. package/src/session/services/SessionStateService.ts +3 -4
  199. package/src/session/services/SessionViewService.ts +6 -6
  200. package/src/session/storage/Metadata.ts +26 -0
  201. package/src/session/storage/Persistence.ts +1 -1
  202. package/src/session/storage/RuntimeSessionPort.ts +0 -20
  203. package/src/types/plugin/PluginAction.ts +0 -10
  204. package/src/types/plugin/PluginCommand.ts +2 -3
  205. package/src/types/plugin/PluginControl.ts +80 -0
  206. package/src/types/plugin/PluginDefinition.ts +1 -1
  207. package/src/types/plugin/PluginRuntime.ts +1 -3
  208. package/src/types/plugin/PluginState.ts +3 -20
  209. package/src/types/rpc/RpcProtocol.ts +4 -4
  210. package/src/types/runtime/agent/AgentContext.ts +1 -9
  211. package/src/types/session/SessionLocalState.ts +1 -1
  212. package/tsconfig.tsbuildinfo +1 -1
  213. package/bin/config/DowncitySchema.d.ts +0 -20
  214. package/bin/config/DowncitySchema.d.ts.map +0 -1
  215. package/bin/config/DowncitySchema.js +0 -160
  216. package/bin/config/DowncitySchema.js.map +0 -1
  217. package/bin/plugin/core/Activation.d.ts +0 -18
  218. package/bin/plugin/core/Activation.d.ts.map +0 -1
  219. package/bin/plugin/core/Activation.js +0 -21
  220. package/bin/plugin/core/Activation.js.map +0 -1
  221. package/bin/plugin/core/Manager.d.ts +0 -7
  222. package/bin/plugin/core/Manager.d.ts.map +0 -1
  223. package/bin/plugin/core/Manager.js +0 -6
  224. package/bin/plugin/core/Manager.js.map +0 -1
  225. package/bin/plugin/types/Plugin.d.ts +0 -15
  226. package/bin/plugin/types/Plugin.d.ts.map +0 -1
  227. package/bin/plugin/types/Plugin.js +0 -9
  228. package/bin/plugin/types/Plugin.js.map +0 -1
  229. package/bin/plugin/types/PluginLifecycle.d.ts +0 -34
  230. package/bin/plugin/types/PluginLifecycle.d.ts.map +0 -1
  231. package/bin/plugin/types/PluginLifecycle.js +0 -9
  232. package/bin/plugin/types/PluginLifecycle.js.map +0 -1
  233. package/bin/plugin/types/PluginState.d.ts +0 -5
  234. package/bin/plugin/types/PluginState.d.ts.map +0 -1
  235. package/bin/plugin/types/PluginState.js +0 -5
  236. package/bin/plugin/types/PluginState.js.map +0 -1
  237. package/bin/plugin/types/Plugins.d.ts +0 -61
  238. package/bin/plugin/types/Plugins.d.ts.map +0 -1
  239. package/bin/plugin/types/Plugins.js +0 -5
  240. package/bin/plugin/types/Plugins.js.map +0 -1
  241. package/bin/session/index.d.ts +0 -15
  242. package/bin/session/index.d.ts.map +0 -1
  243. package/bin/session/index.js +0 -15
  244. package/bin/session/index.js.map +0 -1
  245. package/bin/types/agent/AgentTypes.d.ts +0 -18
  246. package/bin/types/agent/AgentTypes.d.ts.map +0 -1
  247. package/bin/types/agent/AgentTypes.js +0 -10
  248. package/bin/types/agent/AgentTypes.js.map +0 -1
  249. package/bin/utils/logger/Format.d.ts +0 -11
  250. package/bin/utils/logger/Format.d.ts.map +0 -1
  251. package/bin/utils/logger/Format.js +0 -10
  252. package/bin/utils/logger/Format.js.map +0 -1
  253. package/src/config/DowncitySchema.ts +0 -175
  254. package/src/plugin/core/Activation.ts +0 -26
  255. package/src/plugin/core/Manager.ts +0 -17
  256. package/src/plugin/types/Plugin.ts +0 -63
  257. package/src/plugin/types/PluginLifecycle.ts +0 -35
  258. package/src/plugin/types/PluginState.ts +0 -12
  259. package/src/plugin/types/Plugins.ts +0 -67
  260. package/src/session/index.ts +0 -57
  261. package/src/types/agent/AgentTypes.ts +0 -58
  262. package/src/utils/logger/Format.ts +0 -15
@@ -7,70 +7,13 @@
7
7
  */
8
8
 
9
9
  import type { JsonValue } from "@/types/common/Json.js";
10
+ import type {
11
+ PluginAvailability,
12
+ PluginView,
13
+ } from "@/types/plugin/PluginRuntime.js";
10
14
 
11
- /**
12
- * Plugin 概览视图。
13
- */
14
- export interface PluginView {
15
- /**
16
- * Plugin 稳定名称。
17
- */
18
- name: string;
19
- /**
20
- * Plugin 展示标题。
21
- */
22
- title: string;
23
- /**
24
- * Plugin 面向人类的用途说明。
25
- */
26
- description: string;
27
- /**
28
- * 已声明的 Action 名称列表。
29
- */
30
- actions: string[];
31
- /**
32
- * 已声明的 pipeline 点名称列表。
33
- */
34
- pipelines: string[];
35
- /**
36
- * 已声明的 guard 点名称列表。
37
- */
38
- guards: string[];
39
- /**
40
- * 已声明的 effect 点名称列表。
41
- */
42
- effects: string[];
43
- /**
44
- * 已声明的 resolve 点名称列表。
45
- */
46
- resolves: string[];
47
- /**
48
- * 是否声明了 system 注入。
49
- */
50
- hasSystem: boolean;
51
- /**
52
- * 是否声明了 availability 检查。
53
- */
54
- hasAvailability: boolean;
55
- }
56
-
57
- /**
58
- * Plugin 可用性响应视图。
59
- */
60
- export interface PluginAvailabilityView {
61
- /**
62
- * Plugin 是否启用。
63
- */
64
- enabled: boolean;
65
- /**
66
- * Plugin 当前是否可用。
67
- */
68
- available: boolean;
69
- /**
70
- * 不可用原因列表。
71
- */
72
- reasons: string[];
73
- }
15
+ export type { PluginView } from "@/types/plugin/PluginRuntime.js";
16
+ export type PluginAvailabilityView = PluginAvailability;
74
17
 
75
18
  /**
76
19
  * plugin catalog 响应。
@@ -141,21 +84,3 @@ export interface PluginActionResponse {
141
84
  */
142
85
  error?: string;
143
86
  }
144
-
145
- /**
146
- * plugin CLI 通用选项。
147
- */
148
- export interface PluginCliBaseOptions {
149
- /**
150
- * agent 项目路径(默认当前目录)。
151
- */
152
- path?: string;
153
- /**
154
- * 是否输出 JSON。
155
- */
156
- json?: boolean;
157
- /**
158
- * agent id(从 managed agent registry 解析到项目路径)。
159
- */
160
- agent?: string;
161
- }
package/src/rpc/Client.ts CHANGED
@@ -19,21 +19,22 @@ import type {
19
19
  AgentSessionRecordsInput,
20
20
  AgentSessionRecordsPage,
21
21
  AgentSessionInfo,
22
- AgentSessionStopResult,
23
22
  AgentSessionSummaryPage,
24
23
  AgentSessionSystemSnapshot,
25
- } from "@/types/agent/AgentTypes.js";
24
+ } from "@/types/agent/SessionTypes.js";
26
25
  import type { JsonValue } from "@/types/common/Json.js";
27
26
  import type { JsonObject } from "@/types/common/Json.js";
27
+ import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
28
28
  import type {
29
29
  PluginActionResult,
30
- PluginAvailability,
31
- PluginCommandResult,
32
- PluginStateControlAction,
33
- PluginStateControlResult,
34
- PluginStateSnapshot,
35
- PluginView,
36
- } from "@/plugin/types/Plugin.js";
30
+ } from "@/types/plugin/PluginAction.js";
31
+ import type { PluginCommandResult } from "@/types/plugin/PluginCommand.js";
32
+ import type { PluginAvailability, PluginView } from "@/types/plugin/PluginRuntime.js";
33
+ import type {
34
+ PluginControlAction,
35
+ PluginControlResult,
36
+ PluginSnapshot,
37
+ } from "@/types/plugin/PluginState.js";
37
38
  import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
38
39
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
39
40
  import type {
@@ -66,6 +67,8 @@ type PendingRequest = {
66
67
  type RpcSubscription = {
67
68
  on_ready: () => void;
68
69
  on_event: (event: AgentSessionEvent) => void;
70
+ /** 底层 RPC 连接结束后的通知。 */
71
+ on_close: (error?: unknown) => void;
69
72
  };
70
73
 
71
74
  /**
@@ -249,6 +252,7 @@ export class RpcClient {
249
252
  session_id: string;
250
253
  on_ready: () => void;
251
254
  on_event: (event: AgentSessionEvent) => void;
255
+ on_close: (error?: unknown) => void;
252
256
  }): Promise<RpcSessionSubscription> {
253
257
  const data = await this.request<{ subscriptionId: string }>({
254
258
  method: "sdk.sessions.subscribe",
@@ -263,6 +267,7 @@ export class RpcClient {
263
267
  this.subscriptions.set(subscription_id, {
264
268
  on_ready: params.on_ready,
265
269
  on_event: params.on_event,
270
+ on_close: params.on_close,
266
271
  });
267
272
  params.on_ready();
268
273
  return {
@@ -343,8 +348,8 @@ export class RpcClient {
343
348
  /**
344
349
  * 列出 Agent runtime 内 plugin 状态。
345
350
  */
346
- async list_internal_plugin_states(): Promise<PluginStateSnapshot[]> {
347
- const data = await this.request<{ plugins: PluginStateSnapshot[] }>({
351
+ async list_internal_plugin_states(): Promise<PluginSnapshot[]> {
352
+ const data = await this.request<{ plugins: PluginSnapshot[] }>({
348
353
  method: "internal.plugins.list",
349
354
  });
350
355
  return Array.isArray(data.plugins) ? data.plugins : [];
@@ -355,9 +360,9 @@ export class RpcClient {
355
360
  */
356
361
  async control_internal_plugin(params: {
357
362
  plugin_name: string;
358
- action: PluginStateControlAction;
359
- }): Promise<PluginStateControlResult> {
360
- return await this.request<PluginStateControlResult>({
363
+ action: PluginControlAction;
364
+ }): Promise<PluginControlResult> {
365
+ return await this.request<PluginControlResult>({
361
366
  method: "internal.plugins.control",
362
367
  params: {
363
368
  pluginName: params.plugin_name,
@@ -374,8 +379,8 @@ export class RpcClient {
374
379
  command: string;
375
380
  payload?: JsonValue;
376
381
  schedule?: JsonValue;
377
- }): Promise<PluginCommandResult & { plugin?: PluginStateSnapshot }> {
378
- return await this.request<PluginCommandResult & { plugin?: PluginStateSnapshot }>({
382
+ }): Promise<PluginCommandResult & { plugin?: PluginSnapshot }> {
383
+ return await this.request<PluginCommandResult & { plugin?: PluginSnapshot }>({
379
384
  method: "internal.plugins.command",
380
385
  params: {
381
386
  pluginName: params.plugin_name,
@@ -650,6 +655,7 @@ export class RpcClient {
650
655
  type: "error",
651
656
  message,
652
657
  });
658
+ subscription.on_close(new Error(message));
653
659
  }
654
660
  this.subscriptions.clear();
655
661
  }
@@ -12,7 +12,6 @@ import type { Tool } from "ai";
12
12
  import { JsonlSessionHistoryComposer } from "@executor/composer/history/jsonl/JsonlSessionHistoryComposer.js";
13
13
  import { JsonlSessionHistoryStore } from "@/executor/store/history/jsonl/JsonlSessionHistoryStore.js";
14
14
  import type {
15
- AgentSession,
16
15
  AgentSessionConfigSnapshot,
17
16
  AgentSessionForkInput,
18
17
  AgentSessionRecordsInput,
@@ -21,14 +20,15 @@ import type {
21
20
  AgentSessionSetInput,
22
21
  AgentSessionSystemBlock,
23
22
  AgentSessionSystemSnapshot,
24
- } from "@/types/agent/AgentTypes.js";
23
+ } from "@/types/agent/SessionTypes.js";
24
+ import type { AgentSession } from "@/types/agent/SessionActor.js";
25
25
  import {
26
26
  getSdkAgentSessionArchiveDirPath,
27
27
  getSdkAgentSessionDirPath,
28
28
  getSdkAgentSessionInflightPath,
29
- resolveSystemTimezone,
30
- createRuntimeSessionPort,
31
- } from "@/session/index.js";
29
+ } from "@/session/storage/Paths.js";
30
+ import { resolveSystemTimezone } from "@/session/storage/Metadata.js";
31
+ import { createRuntimeSessionPort } from "@/session/storage/RuntimeSessionPort.js";
32
32
  import { SessionSystemBuilder } from "@/session/SessionSystemBuilder.js";
33
33
  import type { SessionPort } from "@/types/runtime/agent/AgentContext.js";
34
34
  import type {
@@ -256,13 +256,6 @@ export class Session implements AgentSession {
256
256
  return this.turnService.is_prompt_runtime_active() || this.executor.isExecuting();
257
257
  }
258
258
 
259
- /**
260
- * 清理当前 session 的执行器缓存。
261
- */
262
- clearExecutor(): void {
263
- this.executor.clearExecutor();
264
- }
265
-
266
259
  /**
267
260
  * 从当前 session 创建一个分叉会话。
268
261
  */
@@ -284,12 +277,6 @@ export class Session implements AgentSession {
284
277
  publishEvent: (event) => {
285
278
  this.eventHub.publish(event);
286
279
  },
287
- clearExecutor: () => {
288
- this.executor.clearExecutor();
289
- },
290
- afterSessionUpdatedAsync: async () => {
291
- await this.executor.afterSessionUpdatedAsync();
292
- },
293
280
  append_user_message: async (message_params) => {
294
281
  await this.stateService.append_user_message(message_params);
295
282
  },
@@ -301,9 +288,6 @@ export class Session implements AgentSession {
301
288
  ensureReadyForExecution: async () => {
302
289
  await this.ensureReadyForExecution();
303
290
  },
304
- touchMetadata: async () => {
305
- await this.stateService.touch_metadata();
306
- },
307
291
  });
308
292
  return this.runtimePort;
309
293
  }
@@ -12,7 +12,7 @@ import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
12
12
  import type {
13
13
  AgentSessionSystemBlock,
14
14
  AgentSessionSystemSessionInfo,
15
- } from "@/types/agent/AgentTypes.js";
15
+ } from "@/types/agent/SessionTypes.js";
16
16
  import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
17
17
 
18
18
  /**
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  import fs from "fs-extra";
12
+ import path from "node:path";
12
13
  import {
13
14
  getToolName,
14
15
  isTextUIPart,
@@ -24,7 +25,7 @@ import type {
24
25
  AgentSessionSummary,
25
26
  AgentSessionSummaryPage,
26
27
  AgentSessionTimelineEvent,
27
- } from "@/types/agent/AgentTypes.js";
28
+ } from "@/types/agent/SessionTypes.js";
28
29
  import type {
29
30
  SessionActionRecordV1,
30
31
  SessionRecordV1,
@@ -36,7 +37,7 @@ import {
36
37
  is_session_message_record,
37
38
  } from "@/executor/types/SessionRecords.js";
38
39
  import type { SessionHistoryMetaV1 } from "@/executor/types/SessionHistoryMeta.js";
39
- import { pickLastSuccessfulChatSendText } from "@/executor/messages/UserVisibleText.js";
40
+ import { resolve_session_message_preview } from "@/session/preview/SessionMessagePreview.js";
40
41
  import { getSdkAgentSessionMessagesPath } from "@/session/storage/Paths.js";
41
42
  import { getSdkAgentSessionMetaPath } from "@/session/storage/Paths.js";
42
43
  import { getSdkAgentSessionsRootDirPath } from "@/session/storage/Paths.js";
@@ -80,8 +81,10 @@ type SessionBrowseBaseInput = {
80
81
 
81
82
  /**
82
83
  * 当前 session 已读取到的完整消息。
84
+ *
85
+ * 说明(中文):列表查询已有 metadata 摘要时可省略,详情查询仍传完整记录。
83
86
  */
84
- messages: SessionRecordV1[];
87
+ messages?: SessionRecordV1[];
85
88
 
86
89
  /**
87
90
  * 当前 session 是否正在执行。
@@ -163,52 +166,6 @@ function stringifyForDisplay(input: unknown, maxChars = 2400): string {
163
166
  }
164
167
  }
165
168
 
166
- function extractMessageText(parts: unknown): string {
167
- if (!Array.isArray(parts)) return "";
168
- const texts: string[] = [];
169
- for (const part of parts) {
170
- if (!part || typeof part !== "object") continue;
171
- const textPart = part as { type?: unknown; text?: unknown };
172
- if (textPart.type !== "text" || typeof textPart.text !== "string") continue;
173
- const text = textPart.text.trim();
174
- if (!text) continue;
175
- texts.push(text);
176
- }
177
- return texts.join("\n").trim();
178
- }
179
-
180
- function extractAssistantToolSummary(message: SessionMessageRecordV1): string {
181
- if (!Array.isArray(message.parts)) return "";
182
- const toolNames = new Set<string>();
183
- for (const part of message.parts as AnyUiPart[]) {
184
- if (!part || typeof part !== "object") continue;
185
- if (!isToolUIPart(part)) continue;
186
- const toolName = String(getToolName(part) || "").trim();
187
- if (toolName) toolNames.add(toolName);
188
- }
189
- if (toolNames.size === 0) return "";
190
- return `[tool] ${Array.from(toolNames).join(", ")}`;
191
- }
192
-
193
- /**
194
- * 解析单条 session 消息的用户可见预览文本。
195
- */
196
- export function resolveSessionMessagePreview(message: SessionRecordV1): string {
197
- if (is_session_action_record(message)) {
198
- return message.description
199
- ? `${message.title}\n${message.description}`
200
- : message.title;
201
- }
202
- if (!is_session_message_record(message)) return "";
203
- const plainText = extractMessageText(message.parts);
204
- if (plainText) return plainText;
205
- if (message.role !== "assistant") return "";
206
-
207
- const userVisible = pickLastSuccessfulChatSendText(message).trim();
208
- if (userVisible) return userVisible;
209
- return extractAssistantToolSummary(message);
210
- }
211
-
212
169
  function resolveToolName(part: ToolPartCompatShape, aiToolName?: string): string {
213
170
  const fromAi = String(aiToolName || "").trim();
214
171
  if (fromAi) return fromAi;
@@ -263,7 +220,7 @@ function toActionTimelineEvent(
263
220
  id: `${String(message.id || "")}:0`,
264
221
  role: "action",
265
222
  ...(typeof metadata?.ts === "number" ? { ts: metadata.ts } : {}),
266
- text: resolveSessionMessagePreview(message),
223
+ text: resolve_session_message_preview(message),
267
224
  actionTitle: message.title,
268
225
  ...(message.description ? { actionDescription: message.description } : {}),
269
226
  actionState: message.state,
@@ -286,7 +243,7 @@ export function toSessionTimelineEvents(
286
243
  toTimelineEvent({
287
244
  message,
288
245
  role: message.role === "user" ? "user" : "assistant",
289
- text: resolveSessionMessagePreview(message),
246
+ text: resolve_session_message_preview(message),
290
247
  sequence: 0,
291
248
  }),
292
249
  ];
@@ -352,7 +309,7 @@ export function toSessionTimelineEvents(
352
309
  toTimelineEvent({
353
310
  message,
354
311
  role: "assistant",
355
- text: resolveSessionMessagePreview(message),
312
+ text: resolve_session_message_preview(message),
356
313
  sequence: 0,
357
314
  }),
358
315
  );
@@ -467,12 +424,16 @@ function filterUserVisibleHistoryMessages(
467
424
  export function buildSessionInfo(
468
425
  input: SessionBrowseBaseInput,
469
426
  ): AgentSessionInfo {
470
- const previewText = input.messages.length > 0
427
+ const messages = input.messages;
428
+ const previewText = messages && messages.length > 0
471
429
  ? truncateText(
472
- resolveSessionMessagePreview(input.messages[input.messages.length - 1]),
430
+ resolve_session_message_preview(messages[messages.length - 1]),
473
431
  180,
474
432
  )
475
- : undefined;
433
+ : input.metadata.previewText;
434
+ const message_count = messages
435
+ ? messages.length
436
+ : input.metadata.messageCount || 0;
476
437
  const title =
477
438
  typeof input.metadata.title === "string" && input.metadata.title.trim()
478
439
  ? input.metadata.title.trim()
@@ -482,7 +443,7 @@ export function buildSessionInfo(
482
443
  sessionId: input.sessionId,
483
444
  ...(title ? { title } : {}),
484
445
  ...(previewText ? { previewText } : {}),
485
- messageCount: input.messages.length,
446
+ messageCount: message_count,
486
447
  ...(typeof input.metadata.createdAt === "number"
487
448
  ? { createdAt: input.metadata.createdAt }
488
449
  : {}),
@@ -499,6 +460,56 @@ export function buildSessionInfo(
499
460
  };
500
461
  }
501
462
 
463
+ /**
464
+ * 读取列表所需的轻量 session 摘要。
465
+ *
466
+ * 关键点(中文)
467
+ * - 新记录直接使用 metadata 摘要,不扫描 messages.jsonl。
468
+ * - 旧记录或执行中记录回退读取一次完整历史,并把摘要补写回 metadata。
469
+ */
470
+ async function resolve_session_summary_metadata(input: {
471
+ /** 当前 session metadata。 */
472
+ metadata: SessionHistoryMetaV1;
473
+ /** 当前消息 JSONL 路径。 */
474
+ messagesPath: string;
475
+ /** 当前 metadata 路径。 */
476
+ metaPath: string;
477
+ /** 是否强制刷新摘要。 */
478
+ refresh: boolean;
479
+ }): Promise<SessionHistoryMetaV1> {
480
+ const history_bytes = await fs.stat(input.messagesPath)
481
+ .then((file_stat) => file_stat.size)
482
+ .catch(() => 0);
483
+ const inflight_path = `${input.messagesPath.slice(0, -"messages.jsonl".length)}inflight.json`;
484
+ const has_inflight = await fs.pathExists(inflight_path);
485
+ if (
486
+ !input.refresh &&
487
+ !has_inflight &&
488
+ typeof input.metadata.messageCount === "number" &&
489
+ input.metadata.historyBytes === history_bytes
490
+ ) {
491
+ return input.metadata;
492
+ }
493
+ const messages = await loadSessionMessagesFromPath(input.messagesPath);
494
+ const last_message = messages[messages.length - 1];
495
+ const preview_text = last_message
496
+ ? truncateText(resolve_session_message_preview(last_message), 180)
497
+ : "";
498
+ const { previewText: _previous_preview, ...metadata_without_preview } = input.metadata;
499
+ void _previous_preview;
500
+ const next_metadata: SessionHistoryMetaV1 = {
501
+ ...metadata_without_preview,
502
+ messageCount: messages.length,
503
+ historyBytes: history_bytes,
504
+ ...(preview_text ? { previewText: preview_text } : {}),
505
+ };
506
+ const temp_path = `${input.metaPath}.${process.pid}.${Date.now()}.tmp`;
507
+ await fs.ensureDir(path.dirname(input.metaPath));
508
+ await fs.writeJson(temp_path, next_metadata, { spaces: 2 });
509
+ await fs.move(temp_path, input.metaPath, { overwrite: true });
510
+ return next_metadata;
511
+ }
512
+
502
513
  /**
503
514
  * 基于完整消息列表构建 session records 分页结果。
504
515
  */
@@ -584,28 +595,32 @@ export async function listAgentSessionSummaryPage(params: {
584
595
  if (!entry.isDirectory()) continue;
585
596
  const sessionId = decodeMaybe(entry.name);
586
597
  if (!sessionId) continue;
587
- const metadata = await readSessionMetadataFromPath({
588
- filePath: getSdkAgentSessionMetaPath(
589
- params.projectRoot,
590
- params.agentId,
591
- sessionId,
592
- ),
598
+ const meta_path = getSdkAgentSessionMetaPath(
599
+ params.projectRoot,
600
+ params.agentId,
601
+ sessionId,
602
+ );
603
+ const messages_path = getSdkAgentSessionMessagesPath(
604
+ params.projectRoot,
605
+ params.agentId,
606
+ sessionId,
607
+ );
608
+ const persisted_metadata = await readSessionMetadataFromPath({
609
+ filePath: meta_path,
593
610
  sessionId,
594
611
  agentId: params.agentId,
595
612
  });
596
- const messages = await loadSessionMessagesFromPath(
597
- getSdkAgentSessionMessagesPath(
598
- params.projectRoot,
599
- params.agentId,
600
- sessionId,
601
- ),
602
- );
613
+ const metadata = await resolve_session_summary_metadata({
614
+ metadata: persisted_metadata,
615
+ messagesPath: messages_path,
616
+ metaPath: meta_path,
617
+ refresh: params.executingSessionIds?.has(sessionId) === true,
618
+ });
603
619
  const info = buildSessionInfo({
604
620
  projectRoot: params.projectRoot,
605
621
  agentId: params.agentId,
606
622
  sessionId,
607
623
  metadata,
608
- messages,
609
624
  executing: params.executingSessionIds?.has(sessionId),
610
625
  });
611
626
  const summary: AgentSessionSummary = {
@@ -679,29 +694,33 @@ export async function listArchivedAgentSessionSummaryPage(params: {
679
694
  if (!entry.isDirectory()) continue;
680
695
  const sessionId = decodeMaybe(entry.name);
681
696
  if (!sessionId) continue;
682
- const metadata = await readSessionMetadataFromPath({
683
- filePath: getSdkAgentArchivedSessionMetaPath(
684
- params.projectRoot,
685
- params.agentId,
686
- sessionId,
687
- ),
697
+ const meta_path = getSdkAgentArchivedSessionMetaPath(
698
+ params.projectRoot,
699
+ params.agentId,
700
+ sessionId,
701
+ );
702
+ const messages_path = getSdkAgentArchivedSessionMessagesPath(
703
+ params.projectRoot,
704
+ params.agentId,
705
+ sessionId,
706
+ );
707
+ const persisted_metadata = await readSessionMetadataFromPath({
708
+ filePath: meta_path,
688
709
  sessionId,
689
710
  agentId: params.agentId,
690
711
  });
691
- const messages = await loadSessionMessagesFromPath(
692
- getSdkAgentArchivedSessionMessagesPath(
693
- params.projectRoot,
694
- params.agentId,
695
- sessionId,
696
- ),
697
- );
712
+ const metadata = await resolve_session_summary_metadata({
713
+ metadata: persisted_metadata,
714
+ messagesPath: messages_path,
715
+ metaPath: meta_path,
716
+ refresh: false,
717
+ });
698
718
  // 关键点(中文):归档 session 不再生成新 title,仅读取归档目录内已有 meta。
699
719
  const info = buildSessionInfo({
700
720
  projectRoot: params.projectRoot,
701
721
  agentId: params.agentId,
702
722
  sessionId,
703
723
  metadata,
704
- messages,
705
724
  executing: false,
706
725
  });
707
726
  const summary: AgentSessionSummary = {
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Session 消息预览投影。
3
+ *
4
+ * 关键点(中文)
5
+ * - 只负责从单条持久化 record 提取用户可见文本。
6
+ * - history store 与浏览层共用该投影,避免摘要写入和读取采用不同规则。
7
+ */
8
+
9
+ import {
10
+ getToolName,
11
+ isToolUIPart,
12
+ type UIMessagePart,
13
+ } from "ai";
14
+ import { pickLastSuccessfulChatSendText } from "@/executor/messages/UserVisibleText.js";
15
+ import type {
16
+ SessionMessageRecordV1,
17
+ SessionRecordV1,
18
+ } from "@/executor/types/SessionRecords.js";
19
+ import {
20
+ is_session_action_record,
21
+ is_session_message_record,
22
+ } from "@/executor/types/SessionRecords.js";
23
+
24
+ type SessionPreviewPart = UIMessagePart<
25
+ Record<string, never>,
26
+ Record<string, never>
27
+ >;
28
+
29
+ function extract_message_text(parts: unknown): string {
30
+ if (!Array.isArray(parts)) return "";
31
+ const texts: string[] = [];
32
+ for (const part of parts) {
33
+ if (!part || typeof part !== "object") continue;
34
+ const text_part = part as { type?: unknown; text?: unknown };
35
+ if (text_part.type !== "text" || typeof text_part.text !== "string") continue;
36
+ const text = text_part.text.trim();
37
+ if (text) texts.push(text);
38
+ }
39
+ return texts.join("\n").trim();
40
+ }
41
+
42
+ function extract_assistant_tool_summary(
43
+ message: SessionMessageRecordV1,
44
+ ): string {
45
+ if (!Array.isArray(message.parts)) return "";
46
+ const tool_names = new Set<string>();
47
+ for (const part of message.parts as SessionPreviewPart[]) {
48
+ if (!part || typeof part !== "object" || !isToolUIPart(part)) continue;
49
+ const tool_name = String(getToolName(part) || "").trim();
50
+ if (tool_name) tool_names.add(tool_name);
51
+ }
52
+ return tool_names.size > 0
53
+ ? `[tool] ${Array.from(tool_names).join(", ")}`
54
+ : "";
55
+ }
56
+
57
+ /**
58
+ * 解析单条 session record 的用户可见预览文本。
59
+ */
60
+ export function resolve_session_message_preview(
61
+ message: SessionRecordV1,
62
+ ): string {
63
+ if (is_session_action_record(message)) {
64
+ return message.description
65
+ ? `${message.title}\n${message.description}`
66
+ : message.title;
67
+ }
68
+ if (!is_session_message_record(message)) return "";
69
+ const plain_text = extract_message_text(message.parts);
70
+ if (plain_text) return plain_text;
71
+ if (message.role !== "assistant") return "";
72
+
73
+ const user_visible = pickLastSuccessfulChatSendText(message).trim();
74
+ return user_visible || extract_assistant_tool_summary(message);
75
+ }
@@ -15,9 +15,9 @@ import {
15
15
  patchSessionModelLabel,
16
16
  readSessionMetadata,
17
17
  resolveSystemTimezone,
18
- touchSessionMetadata,
19
18
  writeSessionMetadata,
20
- } from "@/session/index.js";
19
+ } from "@/session/storage/Metadata.js";
20
+ import { touchSessionMetadata } from "@/session/storage/Persistence.js";
21
21
  import { ensureSessionTitle } from "@/session/SessionTitle.js";
22
22
  import { persistSdkAssistantResult } from "@/session/storage/Persistence.js";
23
23
  import { hydrateUserPromptFileParts } from "@executor/messages/SessionAttachmentMapper.js";
@@ -26,7 +26,7 @@ import type { JsonlSessionHistoryStore } from "@/executor/store/history/jsonl/Js
26
26
  import type {
27
27
  AgentSessionConfigSnapshot,
28
28
  AgentSessionSetInput,
29
- } from "@/types/agent/AgentTypes.js";
29
+ } from "@/types/agent/SessionTypes.js";
30
30
  import type {
31
31
  AgentSessionEvent,
32
32
  } from "@/types/sdk/AgentSessionEvent.js";
@@ -259,7 +259,6 @@ export class SessionStateService {
259
259
  if (input.model) {
260
260
  this.state.sessionConfig.model = normalizeAgentModel(input.model);
261
261
  this.state.sessionConfig.modelLabel = next_model_label;
262
- this.executor.clearExecutor();
263
262
  }
264
263
  await patchSessionModelLabel({
265
264
  projectRoot: this.project_root,