@downcity/agent 1.1.43 → 1.1.62

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 (256) hide show
  1. package/README.md +11 -12
  2. package/bin/agent/Agent.d.ts +31 -16
  3. package/bin/agent/Agent.d.ts.map +1 -1
  4. package/bin/agent/Agent.js +47 -63
  5. package/bin/agent/Agent.js.map +1 -1
  6. package/bin/agent/RemoteAgent.d.ts +6 -6
  7. package/bin/agent/RemoteAgent.d.ts.map +1 -1
  8. package/bin/agent/RemoteAgent.js +377 -267
  9. package/bin/agent/RemoteAgent.js.map +1 -1
  10. package/bin/config/AgentInitializer.d.ts +5 -5
  11. package/bin/config/AgentInitializer.d.ts.map +1 -1
  12. package/bin/config/AgentInitializer.js +15 -13
  13. package/bin/config/AgentInitializer.js.map +1 -1
  14. package/bin/config/Config.d.ts +9 -30
  15. package/bin/config/Config.d.ts.map +1 -1
  16. package/bin/config/Config.js +23 -70
  17. package/bin/config/Config.js.map +1 -1
  18. package/bin/config/Defaults.d.ts.map +1 -1
  19. package/bin/config/Defaults.js +1 -9
  20. package/bin/config/Defaults.js.map +1 -1
  21. package/bin/config/DowncitySchema.d.ts.map +1 -1
  22. package/bin/config/DowncitySchema.js +4 -112
  23. package/bin/config/DowncitySchema.js.map +1 -1
  24. package/bin/config/ExecutionBinding.d.ts +1 -16
  25. package/bin/config/ExecutionBinding.d.ts.map +1 -1
  26. package/bin/config/ExecutionBinding.js +2 -22
  27. package/bin/config/ExecutionBinding.js.map +1 -1
  28. package/bin/config/Paths.d.ts +4 -43
  29. package/bin/config/Paths.d.ts.map +1 -1
  30. package/bin/config/Paths.js +10 -30
  31. package/bin/config/Paths.js.map +1 -1
  32. package/bin/config/PlatformPaths.d.ts +0 -4
  33. package/bin/config/PlatformPaths.d.ts.map +1 -1
  34. package/bin/config/PlatformPaths.js +5 -1
  35. package/bin/config/PlatformPaths.js.map +1 -1
  36. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
  37. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +0 -4
  38. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
  39. package/bin/executor/composer/system/default/InitPrompts.d.ts +1 -1
  40. package/bin/executor/composer/system/default/InitPrompts.js +1 -1
  41. package/bin/executor/composer/system/default/SystemDomain.js +1 -1
  42. package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
  43. package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
  44. package/bin/executor/composer/system/default/assets/init/PROFILE.md.d.ts +1 -1
  45. package/bin/executor/composer/system/default/assets/init/PROFILE.md.d.ts.map +1 -1
  46. package/bin/executor/composer/system/default/assets/init/PROFILE.md.js +1 -1
  47. package/bin/executor/composer/system/default/assets/init/PROFILE.md.js.map +1 -1
  48. package/bin/executor/composer/system/default/assets/plugin.prompt.d.ts +1 -1
  49. package/bin/executor/composer/system/default/assets/plugin.prompt.js +1 -1
  50. package/bin/executor/composer/system/default/assets/task.prompt.d.ts +1 -1
  51. package/bin/executor/composer/system/default/assets/task.prompt.js +1 -1
  52. package/bin/executor/messages/ChatMessageMarkupTypes.d.ts +1 -1
  53. package/bin/executor/messages/ChatMessageMarkupTypes.js +1 -1
  54. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +1 -2
  55. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
  56. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +17 -56
  57. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  58. package/bin/executor/tools/shell/ShellToolBridge.js +1 -1
  59. package/bin/executor/tools/shell/ShellToolBridge.js.map +1 -1
  60. package/bin/executor/tools/shell/ShellToolDefinition.d.ts +2 -2
  61. package/bin/executor/tools/shell/ShellToolFormatting.d.ts +1 -1
  62. package/bin/executor/tools/shell/ShellToolFormatting.js +9 -9
  63. package/bin/executor/tools/shell/ShellToolFormatting.js.map +1 -1
  64. package/bin/executor/tools/shell/ShellToolSchemas.d.ts +7 -75
  65. package/bin/executor/tools/shell/ShellToolSchemas.d.ts.map +1 -1
  66. package/bin/executor/types/SessionHistoryMeta.d.ts +5 -24
  67. package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
  68. package/bin/executor/types/SessionHistoryMeta.js +1 -1
  69. package/bin/executor/types/SessionRun.d.ts +1 -1
  70. package/bin/index.d.ts +5 -6
  71. package/bin/index.d.ts.map +1 -1
  72. package/bin/index.js +6 -5
  73. package/bin/index.js.map +1 -1
  74. package/bin/model/CityModelAdapter.d.ts +23 -0
  75. package/bin/model/CityModelAdapter.d.ts.map +1 -0
  76. package/bin/model/CityModelAdapter.js +338 -0
  77. package/bin/model/CityModelAdapter.js.map +1 -0
  78. package/bin/plugin/core/PluginCommandRequest.d.ts +1 -1
  79. package/bin/plugin/core/PluginCommandRequest.js +1 -1
  80. package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
  81. package/bin/plugin/core/PluginLocalExecution.js +4 -8
  82. package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
  83. package/bin/plugin/types/PluginApi.d.ts +1 -1
  84. package/bin/rpc/Client.d.ts +104 -0
  85. package/bin/rpc/Client.d.ts.map +1 -0
  86. package/bin/rpc/Client.js +300 -0
  87. package/bin/rpc/Client.js.map +1 -0
  88. package/bin/rpc/Server.d.ts +41 -0
  89. package/bin/rpc/Server.d.ts.map +1 -0
  90. package/bin/rpc/Server.js +164 -0
  91. package/bin/rpc/Server.js.map +1 -0
  92. package/bin/runtime/host/daemon/Api.d.ts +1 -1
  93. package/bin/runtime/host/daemon/Client.d.ts +1 -1
  94. package/bin/runtime/host/daemon/Client.d.ts.map +1 -1
  95. package/bin/runtime/host/daemon/Client.js +30 -20
  96. package/bin/runtime/host/daemon/Client.js.map +1 -1
  97. package/bin/runtime/host/daemon/Paths.d.ts +1 -1
  98. package/bin/runtime/host/daemon/Paths.js +1 -1
  99. package/bin/runtime/host/daemon/ProjectSetup.js +2 -2
  100. package/bin/runtime/server/http/control/OverviewRoutes.js +1 -1
  101. package/bin/runtime/server/http/control/OverviewRoutes.js.map +1 -1
  102. package/bin/session/Session.d.ts +1 -0
  103. package/bin/session/Session.d.ts.map +1 -1
  104. package/bin/session/Session.js +32 -6
  105. package/bin/session/Session.js.map +1 -1
  106. package/bin/session/SessionTitle.d.ts +49 -0
  107. package/bin/session/SessionTitle.d.ts.map +1 -0
  108. package/bin/session/SessionTitle.js +130 -0
  109. package/bin/session/SessionTitle.js.map +1 -0
  110. package/bin/session/browse/Browse.d.ts +2 -1
  111. package/bin/session/browse/Browse.d.ts.map +1 -1
  112. package/bin/session/browse/Browse.js +18 -15
  113. package/bin/session/browse/Browse.js.map +1 -1
  114. package/bin/session/index.d.ts +3 -2
  115. package/bin/session/index.d.ts.map +1 -1
  116. package/bin/session/index.js +3 -2
  117. package/bin/session/index.js.map +1 -1
  118. package/bin/session/storage/Metadata.d.ts +4 -0
  119. package/bin/session/storage/Metadata.d.ts.map +1 -1
  120. package/bin/session/storage/Metadata.js +12 -25
  121. package/bin/session/storage/Metadata.js.map +1 -1
  122. package/bin/session/storage/Paths.d.ts +0 -4
  123. package/bin/session/storage/Paths.d.ts.map +1 -1
  124. package/bin/session/storage/Paths.js +0 -6
  125. package/bin/session/storage/Paths.js.map +1 -1
  126. package/bin/session/storage/Persistence.d.ts.map +1 -1
  127. package/bin/session/storage/Persistence.js +1 -4
  128. package/bin/session/storage/Persistence.js.map +1 -1
  129. package/bin/types/agent/AgentTypes.d.ts +32 -57
  130. package/bin/types/agent/AgentTypes.d.ts.map +1 -1
  131. package/bin/types/config/AgentProject.d.ts +7 -6
  132. package/bin/types/config/AgentProject.d.ts.map +1 -1
  133. package/bin/types/config/DowncityConfig.d.ts +11 -69
  134. package/bin/types/config/DowncityConfig.d.ts.map +1 -1
  135. package/bin/types/config/ExecutionBinding.d.ts +4 -4
  136. package/bin/types/config/ExecutionBinding.js +1 -1
  137. package/bin/types/config/LlmConfig.d.ts +1 -1
  138. package/bin/types/config/Start.d.ts +3 -0
  139. package/bin/types/config/Start.d.ts.map +1 -1
  140. package/bin/types/config/Start.js +2 -0
  141. package/bin/types/config/Start.js.map +1 -1
  142. package/bin/types/runtime/auth/AuthPermission.js +2 -2
  143. package/bin/types/runtime/auth/AuthPermission.js.map +1 -1
  144. package/bin/types/runtime/host/Store.d.ts +10 -227
  145. package/bin/types/runtime/host/Store.d.ts.map +1 -1
  146. package/bin/types/runtime/host/Store.js +7 -0
  147. package/bin/types/runtime/host/Store.js.map +1 -1
  148. package/bin/types/runtime/http/InlineInstant.d.ts +1 -1
  149. package/bin/types/runtime/platform/Platform.d.ts +7 -7
  150. package/bin/types/runtime/platform/Platform.d.ts.map +1 -1
  151. package/bin/types/runtime/platform/PlatformGateway.d.ts +2 -2
  152. package/bin/types/runtime/platform/PlatformGateway.d.ts.map +1 -1
  153. package/bin/utils/Time.d.ts +0 -1
  154. package/bin/utils/Time.d.ts.map +1 -1
  155. package/bin/utils/Time.js +0 -7
  156. package/bin/utils/Time.js.map +1 -1
  157. package/bin/utils/storage/index.d.ts +0 -1
  158. package/bin/utils/storage/index.d.ts.map +1 -1
  159. package/bin/utils/storage/index.js +0 -6
  160. package/bin/utils/storage/index.js.map +1 -1
  161. package/package.json +22 -23
  162. package/src/agent/Agent.ts +57 -73
  163. package/src/agent/RemoteAgent.ts +515 -345
  164. package/src/config/AgentInitializer.ts +15 -13
  165. package/src/config/Config.ts +28 -85
  166. package/src/config/Defaults.ts +1 -9
  167. package/src/config/DowncitySchema.ts +4 -114
  168. package/src/config/ExecutionBinding.ts +2 -24
  169. package/src/config/Paths.ts +10 -43
  170. package/src/config/PlatformPaths.ts +5 -1
  171. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +0 -4
  172. package/src/executor/composer/system/default/InitPrompts.ts +1 -1
  173. package/src/executor/composer/system/default/SystemDomain.ts +1 -1
  174. package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
  175. package/src/executor/composer/system/default/assets/core.prompt.ts.txt +1 -1
  176. package/src/executor/composer/system/default/assets/init/PROFILE.md.ts +1 -1
  177. package/src/executor/composer/system/default/assets/init/PROFILE.md.ts.txt +1 -2
  178. package/src/executor/composer/system/default/assets/plugin.prompt.ts +1 -1
  179. package/src/executor/composer/system/default/assets/plugin.prompt.ts.txt +18 -18
  180. package/src/executor/composer/system/default/assets/task.prompt.ts +1 -1
  181. package/src/executor/composer/system/default/assets/task.prompt.ts.txt +1 -1
  182. package/src/executor/messages/ChatMessageMarkupTypes.ts +1 -1
  183. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +17 -57
  184. package/src/executor/tools/shell/ShellToolBridge.ts +1 -1
  185. package/src/executor/tools/shell/ShellToolFormatting.ts +9 -9
  186. package/src/executor/types/SessionHistoryMeta.ts +5 -25
  187. package/src/executor/types/SessionRun.ts +1 -1
  188. package/src/index.ts +12 -19
  189. package/src/model/CityModelAdapter.ts +384 -0
  190. package/src/plugin/core/PluginCommandRequest.ts +1 -1
  191. package/src/plugin/core/PluginLocalExecution.ts +4 -8
  192. package/src/plugin/types/PluginApi.ts +1 -1
  193. package/src/rpc/Client.ts +467 -0
  194. package/src/rpc/Server.ts +302 -0
  195. package/src/runtime/host/daemon/Api.ts +1 -1
  196. package/src/runtime/host/daemon/Client.ts +44 -22
  197. package/src/runtime/host/daemon/Paths.ts +1 -1
  198. package/src/runtime/host/daemon/ProjectSetup.ts +2 -2
  199. package/src/runtime/server/http/control/OverviewRoutes.ts +1 -1
  200. package/src/session/Session.ts +40 -6
  201. package/src/session/SessionTitle.ts +192 -0
  202. package/src/session/browse/Browse.ts +22 -13
  203. package/src/session/index.ts +5 -1
  204. package/src/session/storage/Metadata.ts +14 -29
  205. package/src/session/storage/Paths.ts +0 -10
  206. package/src/session/storage/Persistence.ts +1 -4
  207. package/src/types/agent/AgentTypes.ts +33 -62
  208. package/src/types/config/AgentProject.ts +7 -6
  209. package/src/types/config/DowncityConfig.ts +11 -70
  210. package/src/types/config/ExecutionBinding.ts +4 -4
  211. package/src/types/config/LlmConfig.ts +1 -1
  212. package/src/types/config/Start.ts +3 -0
  213. package/src/types/runtime/auth/AuthPermission.ts +2 -2
  214. package/src/types/runtime/host/Store.ts +10 -235
  215. package/src/types/runtime/http/InlineInstant.ts +1 -1
  216. package/src/types/runtime/platform/Platform.ts +7 -7
  217. package/src/types/runtime/platform/PlatformGateway.ts +2 -2
  218. package/src/utils/Time.ts +0 -6
  219. package/src/utils/storage/index.ts +0 -7
  220. package/tsconfig.json +1 -0
  221. package/tsconfig.tsbuildinfo +1 -1
  222. package/bin/config/ConfigEnvResolver.d.ts +0 -22
  223. package/bin/config/ConfigEnvResolver.d.ts.map +0 -1
  224. package/bin/config/ConfigEnvResolver.js +0 -41
  225. package/bin/config/ConfigEnvResolver.js.map +0 -1
  226. package/bin/runtime/server/rpc/Server.d.ts +0 -18
  227. package/bin/runtime/server/rpc/Server.d.ts.map +0 -1
  228. package/bin/runtime/server/rpc/Server.js +0 -315
  229. package/bin/runtime/server/rpc/Server.js.map +0 -1
  230. package/bin/runtime/transport/rpc/Client.d.ts +0 -13
  231. package/bin/runtime/transport/rpc/Client.d.ts.map +0 -1
  232. package/bin/runtime/transport/rpc/Client.js +0 -98
  233. package/bin/runtime/transport/rpc/Client.js.map +0 -1
  234. package/bin/runtime/transport/rpc/Paths.d.ts +0 -14
  235. package/bin/runtime/transport/rpc/Paths.d.ts.map +0 -1
  236. package/bin/runtime/transport/rpc/Paths.js +0 -42
  237. package/bin/runtime/transport/rpc/Paths.js.map +0 -1
  238. package/bin/runtime/transport/rpc/Transport.d.ts +0 -21
  239. package/bin/runtime/transport/rpc/Transport.d.ts.map +0 -1
  240. package/bin/runtime/transport/rpc/Transport.js +0 -30
  241. package/bin/runtime/transport/rpc/Transport.js.map +0 -1
  242. package/bin/types/common/ResolvedConfigValue.d.ts +0 -12
  243. package/bin/types/common/ResolvedConfigValue.d.ts.map +0 -1
  244. package/bin/types/common/ResolvedConfigValue.js +0 -2
  245. package/bin/types/common/ResolvedConfigValue.js.map +0 -1
  246. package/bin/types/runtime/rpc/LocalRpc.d.ts +0 -69
  247. package/bin/types/runtime/rpc/LocalRpc.d.ts.map +0 -1
  248. package/bin/types/runtime/rpc/LocalRpc.js +0 -9
  249. package/bin/types/runtime/rpc/LocalRpc.js.map +0 -1
  250. package/src/config/ConfigEnvResolver.ts +0 -52
  251. package/src/runtime/server/rpc/Server.ts +0 -408
  252. package/src/runtime/transport/rpc/Client.ts +0 -113
  253. package/src/runtime/transport/rpc/Paths.ts +0 -50
  254. package/src/runtime/transport/rpc/Transport.ts +0 -43
  255. package/src/types/common/ResolvedConfigValue.ts +0 -16
  256. package/src/types/runtime/rpc/LocalRpc.ts +0 -72
@@ -0,0 +1,467 @@
1
+ /**
2
+ * Agent 本机 RPC Client。
3
+ *
4
+ * 职责说明(中文)
5
+ * - 为 `RemoteAgent(rpc://...)` 提供最小客户端实现。
6
+ * - 复用逐行 JSON(NDJSON)协议,与本机 RPC Server 对接。
7
+ * - 当前只承载 Session actor 所需方法。
8
+ */
9
+
10
+ import net from "node:net";
11
+ import type {
12
+ AgentCreateSessionInput,
13
+ AgentListSessionsInput,
14
+ AgentSessionHistoryInput,
15
+ AgentSessionHistoryPage,
16
+ AgentSessionInfo,
17
+ AgentSessionSummaryPage,
18
+ AgentSessionSystemSnapshot,
19
+ } from "@/types/agent/AgentTypes.js";
20
+ import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
21
+ import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
22
+
23
+ type RpcClientRequest =
24
+ | {
25
+ id: string;
26
+ method: "sdk.sessions.list";
27
+ params?: AgentListSessionsInput;
28
+ }
29
+ | {
30
+ id: string;
31
+ method: "sdk.sessions.create";
32
+ params?: AgentCreateSessionInput;
33
+ }
34
+ | {
35
+ id: string;
36
+ method: "sdk.sessions.get";
37
+ params: {
38
+ sessionId: string;
39
+ };
40
+ }
41
+ | {
42
+ id: string;
43
+ method: "sdk.sessions.prompt";
44
+ params: {
45
+ sessionId: string;
46
+ input: AgentSessionPromptInput;
47
+ };
48
+ }
49
+ | {
50
+ id: string;
51
+ method: "sdk.sessions.history";
52
+ params: {
53
+ sessionId: string;
54
+ input?: AgentSessionHistoryInput;
55
+ };
56
+ }
57
+ | {
58
+ id: string;
59
+ method: "sdk.sessions.system";
60
+ params: {
61
+ sessionId: string;
62
+ };
63
+ }
64
+ | {
65
+ id: string;
66
+ method: "sdk.sessions.fork";
67
+ params: {
68
+ sessionId: string;
69
+ messageId?: string;
70
+ };
71
+ }
72
+ | {
73
+ id: string;
74
+ method: "sdk.sessions.subscribe";
75
+ params: {
76
+ sessionId: string;
77
+ };
78
+ }
79
+ | {
80
+ id: string;
81
+ method: "sdk.sessions.unsubscribe";
82
+ params: {
83
+ subscriptionId: string;
84
+ };
85
+ };
86
+
87
+ type RpcResponseFrame = {
88
+ id: string;
89
+ success: boolean;
90
+ data?: unknown;
91
+ error?: string;
92
+ };
93
+
94
+ type RpcReadyFrame = {
95
+ type: "ready";
96
+ subscriptionId: string;
97
+ };
98
+
99
+ type RpcEventFrame = {
100
+ type: "event";
101
+ subscriptionId: string;
102
+ event: AgentSessionEvent;
103
+ };
104
+
105
+ type PendingRequest = {
106
+ resolve: (value: any) => void;
107
+ reject: (error: unknown) => void;
108
+ };
109
+
110
+ type RpcSubscription = {
111
+ on_ready: () => void;
112
+ on_event: (event: AgentSessionEvent) => void;
113
+ };
114
+
115
+ /**
116
+ * RPC endpoint。
117
+ */
118
+ export interface RpcClientEndpoint {
119
+ /** RPC host。 */
120
+ host: string;
121
+ /** RPC port。 */
122
+ port: number;
123
+ }
124
+
125
+ /**
126
+ * RPC Session 订阅句柄。
127
+ */
128
+ export interface RpcSessionSubscription {
129
+ /** 当前订阅 id。 */
130
+ subscription_id: string;
131
+ /** 取消订阅。 */
132
+ unsubscribe(): Promise<void>;
133
+ }
134
+
135
+ /**
136
+ * RPC Client。
137
+ */
138
+ export class RpcClient {
139
+ private readonly endpoint: RpcClientEndpoint;
140
+ private socket: net.Socket | null = null;
141
+ private connect_promise: Promise<void> | null = null;
142
+ private buffered = "";
143
+ private readonly pending_requests = new Map<string, PendingRequest>();
144
+ private readonly subscriptions = new Map<string, RpcSubscription>();
145
+ private request_sequence = 0;
146
+
147
+ constructor(endpoint: RpcClientEndpoint) {
148
+ this.endpoint = endpoint;
149
+ }
150
+
151
+ /**
152
+ * 列出远程 session。
153
+ */
154
+ async list_sessions(
155
+ input?: AgentListSessionsInput,
156
+ ): Promise<AgentSessionSummaryPage> {
157
+ const data = await this.request<{ page: AgentSessionSummaryPage }>({
158
+ method: "sdk.sessions.list",
159
+ params: input,
160
+ });
161
+ return data.page;
162
+ }
163
+
164
+ /**
165
+ * 创建远程 session。
166
+ */
167
+ async create_session(
168
+ input?: AgentCreateSessionInput,
169
+ ): Promise<AgentSessionInfo> {
170
+ const data = await this.request<{ session: AgentSessionInfo }>({
171
+ method: "sdk.sessions.create",
172
+ params: input,
173
+ });
174
+ return data.session;
175
+ }
176
+
177
+ /**
178
+ * 获取远程 session 信息。
179
+ */
180
+ async get_session(session_id: string): Promise<AgentSessionInfo> {
181
+ const data = await this.request<{ session: AgentSessionInfo }>({
182
+ method: "sdk.sessions.get",
183
+ params: {
184
+ sessionId: session_id,
185
+ },
186
+ });
187
+ return data.session;
188
+ }
189
+
190
+ /**
191
+ * 发送 prompt。
192
+ */
193
+ async prompt_session(params: {
194
+ session_id: string;
195
+ input: AgentSessionPromptInput;
196
+ }): Promise<{ id: string }> {
197
+ const data = await this.request<{ turn: { id: string } }>({
198
+ method: "sdk.sessions.prompt",
199
+ params: {
200
+ sessionId: params.session_id,
201
+ input: params.input,
202
+ },
203
+ });
204
+ return data.turn;
205
+ }
206
+
207
+ /**
208
+ * 读取 history。
209
+ */
210
+ async get_session_history(params: {
211
+ session_id: string;
212
+ input?: AgentSessionHistoryInput;
213
+ }): Promise<AgentSessionHistoryPage> {
214
+ const data = await this.request<{ history: AgentSessionHistoryPage }>({
215
+ method: "sdk.sessions.history",
216
+ params: {
217
+ sessionId: params.session_id,
218
+ input: params.input,
219
+ },
220
+ });
221
+ return data.history;
222
+ }
223
+
224
+ /**
225
+ * 读取 system snapshot。
226
+ */
227
+ async get_session_system(session_id: string): Promise<AgentSessionSystemSnapshot> {
228
+ const data = await this.request<{ system: AgentSessionSystemSnapshot }>({
229
+ method: "sdk.sessions.system",
230
+ params: {
231
+ sessionId: session_id,
232
+ },
233
+ });
234
+ return data.system;
235
+ }
236
+
237
+ /**
238
+ * 分叉 session。
239
+ */
240
+ async fork_session(params: {
241
+ session_id: string;
242
+ message_id?: string;
243
+ }): Promise<AgentSessionInfo> {
244
+ const data = await this.request<{ session: AgentSessionInfo }>({
245
+ method: "sdk.sessions.fork",
246
+ params: {
247
+ sessionId: params.session_id,
248
+ ...(params.message_id ? { messageId: params.message_id } : {}),
249
+ },
250
+ });
251
+ return data.session;
252
+ }
253
+
254
+ /**
255
+ * 订阅 session 事件。
256
+ */
257
+ async subscribe_session(params: {
258
+ session_id: string;
259
+ on_ready: () => void;
260
+ on_event: (event: AgentSessionEvent) => void;
261
+ }): Promise<RpcSessionSubscription> {
262
+ const data = await this.request<{ subscriptionId: string }>({
263
+ method: "sdk.sessions.subscribe",
264
+ params: {
265
+ sessionId: params.session_id,
266
+ },
267
+ });
268
+ const subscription_id = String(data.subscriptionId || "").trim();
269
+ if (!subscription_id) {
270
+ throw new Error("RPC subscription did not return subscriptionId");
271
+ }
272
+ this.subscriptions.set(subscription_id, {
273
+ on_ready: params.on_ready,
274
+ on_event: params.on_event,
275
+ });
276
+ params.on_ready();
277
+ return {
278
+ subscription_id,
279
+ unsubscribe: async () => {
280
+ this.subscriptions.delete(subscription_id);
281
+ await this.request({
282
+ method: "sdk.sessions.unsubscribe",
283
+ params: {
284
+ subscriptionId: subscription_id,
285
+ },
286
+ });
287
+ },
288
+ };
289
+ }
290
+
291
+ /**
292
+ * 关闭底层连接。
293
+ */
294
+ async close(): Promise<void> {
295
+ const socket = this.socket;
296
+ this.socket = null;
297
+ this.connect_promise = null;
298
+ this.buffered = "";
299
+ for (const pending of this.pending_requests.values()) {
300
+ pending.reject(new Error("RPC client closed"));
301
+ }
302
+ this.pending_requests.clear();
303
+ this.fail_all_subscriptions("RPC client closed");
304
+ if (!socket) return;
305
+ await new Promise<void>((resolve) => {
306
+ socket.end(() => resolve());
307
+ });
308
+ }
309
+
310
+ private async request<TData = unknown>(input: {
311
+ method: RpcClientRequest["method"];
312
+ params?: unknown;
313
+ }): Promise<TData> {
314
+ await this.ensure_connected();
315
+ const socket = this.socket;
316
+ if (!socket) {
317
+ throw new Error("RPC socket is not connected");
318
+ }
319
+ const id = `rpc_${Date.now()}_${this.request_sequence += 1}`;
320
+ const request = (
321
+ input.params === undefined
322
+ ? {
323
+ id,
324
+ method: input.method,
325
+ }
326
+ : {
327
+ id,
328
+ method: input.method,
329
+ params: input.params as never,
330
+ }
331
+ ) as RpcClientRequest;
332
+ const result = await new Promise<TData>((resolve, reject) => {
333
+ this.pending_requests.set(id, { resolve, reject });
334
+ socket.write(`${JSON.stringify(request)}\n`, (error) => {
335
+ if (!error) return;
336
+ this.pending_requests.delete(id);
337
+ reject(error);
338
+ });
339
+ });
340
+ return result;
341
+ }
342
+
343
+ private async ensure_connected(): Promise<void> {
344
+ if (this.socket && !this.socket.destroyed) return;
345
+ if (this.connect_promise) {
346
+ await this.connect_promise;
347
+ return;
348
+ }
349
+
350
+ this.connect_promise = new Promise<void>((resolve, reject) => {
351
+ const socket = net.createConnection({
352
+ host: this.endpoint.host,
353
+ port: this.endpoint.port,
354
+ });
355
+
356
+ socket.setEncoding("utf8");
357
+
358
+ socket.on("connect", () => {
359
+ this.socket = socket;
360
+ resolve();
361
+ });
362
+
363
+ socket.on("data", (chunk: string) => {
364
+ this.consume_data(chunk);
365
+ });
366
+
367
+ socket.on("error", (error) => {
368
+ if (!this.socket) {
369
+ reject(error);
370
+ return;
371
+ }
372
+ this.fail_all_pending(error);
373
+ this.fail_all_subscriptions(
374
+ error instanceof Error ? error.message : String(error),
375
+ );
376
+ });
377
+
378
+ socket.on("close", () => {
379
+ this.socket = null;
380
+ this.connect_promise = null;
381
+ this.fail_all_pending(new Error("RPC socket closed"));
382
+ this.fail_all_subscriptions("RPC socket closed");
383
+ });
384
+ });
385
+
386
+ try {
387
+ await this.connect_promise;
388
+ } catch (error) {
389
+ this.connect_promise = null;
390
+ throw error;
391
+ }
392
+ }
393
+
394
+ private consume_data(chunk: string): void {
395
+ this.buffered += chunk;
396
+ let newline_index = this.buffered.indexOf("\n");
397
+ while (newline_index >= 0) {
398
+ const line = this.buffered.slice(0, newline_index).trim();
399
+ this.buffered = this.buffered.slice(newline_index + 1);
400
+ if (line) {
401
+ this.consume_line(line);
402
+ }
403
+ newline_index = this.buffered.indexOf("\n");
404
+ }
405
+ }
406
+
407
+ private consume_line(line: string): void {
408
+ const payload = JSON.parse(line) as RpcResponseFrame | RpcReadyFrame | RpcEventFrame;
409
+ if ("type" in payload && payload.type === "ready") {
410
+ const subscription = this.subscriptions.get(payload.subscriptionId);
411
+ subscription?.on_ready();
412
+ return;
413
+ }
414
+ if ("type" in payload && payload.type === "event") {
415
+ const subscription = this.subscriptions.get(payload.subscriptionId);
416
+ subscription?.on_event(payload.event);
417
+ return;
418
+ }
419
+ const pending = this.pending_requests.get(payload.id);
420
+ if (!pending) return;
421
+ this.pending_requests.delete(payload.id);
422
+ if (payload.success) {
423
+ pending.resolve(payload.data);
424
+ return;
425
+ }
426
+ pending.reject(new Error(String(payload.error || "RPC request failed")));
427
+ }
428
+
429
+ private fail_all_pending(error: unknown): void {
430
+ for (const pending of this.pending_requests.values()) {
431
+ pending.reject(error);
432
+ }
433
+ this.pending_requests.clear();
434
+ }
435
+
436
+ private fail_all_subscriptions(message: string): void {
437
+ for (const subscription of this.subscriptions.values()) {
438
+ subscription.on_event({
439
+ type: "error",
440
+ message,
441
+ });
442
+ }
443
+ this.subscriptions.clear();
444
+ }
445
+ }
446
+
447
+ /**
448
+ * 解析 rpc url。
449
+ */
450
+ export function parse_rpc_url(url_input: string): RpcClientEndpoint {
451
+ const url = new URL(url_input);
452
+ if (url.protocol !== "rpc:") {
453
+ throw new Error(`Unsupported RPC protocol: ${url.protocol}`);
454
+ }
455
+ const host = String(url.hostname || "").trim();
456
+ const port = Number.parseInt(String(url.port || ""), 10);
457
+ if (!host) {
458
+ throw new Error("RPC url requires a host");
459
+ }
460
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
461
+ throw new Error("RPC url requires a valid port");
462
+ }
463
+ return {
464
+ host,
465
+ port,
466
+ };
467
+ }