@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,302 @@
1
+ /**
2
+ * Agent 本机 RPC Server。
3
+ *
4
+ * 职责说明(中文)
5
+ * - 为本机 `RemoteAgent(rpc://...)` 提供最小 SDK 会话访问面。
6
+ * - 当前只承载 Session actor 所需方法,不混入控制台 HTTP 语义。
7
+ * - 协议使用逐行 JSON(NDJSON),便于调试与事件流推送。
8
+ */
9
+
10
+ import net from "node:net";
11
+ import type {
12
+ AgentListSessionsInput,
13
+ AgentSessionCollection,
14
+ } from "@/types/agent/AgentTypes.js";
15
+ import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
16
+ import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
17
+
18
+ type RpcSessionRequest =
19
+ | {
20
+ id: string;
21
+ method: "sdk.sessions.list";
22
+ params?: AgentListSessionsInput;
23
+ }
24
+ | {
25
+ id: string;
26
+ method: "sdk.sessions.create";
27
+ params?: {
28
+ sessionId?: string;
29
+ };
30
+ }
31
+ | {
32
+ id: string;
33
+ method: "sdk.sessions.get";
34
+ params: {
35
+ sessionId: string;
36
+ };
37
+ }
38
+ | {
39
+ id: string;
40
+ method: "sdk.sessions.prompt";
41
+ params: {
42
+ sessionId: string;
43
+ input: AgentSessionPromptInput;
44
+ };
45
+ }
46
+ | {
47
+ id: string;
48
+ method: "sdk.sessions.history";
49
+ params: {
50
+ sessionId: string;
51
+ input?: {
52
+ limit?: number;
53
+ cursor?: string;
54
+ order?: "asc" | "desc";
55
+ view?: "message" | "timeline";
56
+ };
57
+ };
58
+ }
59
+ | {
60
+ id: string;
61
+ method: "sdk.sessions.system";
62
+ params: {
63
+ sessionId: string;
64
+ };
65
+ }
66
+ | {
67
+ id: string;
68
+ method: "sdk.sessions.fork";
69
+ params: {
70
+ sessionId: string;
71
+ messageId?: string;
72
+ };
73
+ }
74
+ | {
75
+ id: string;
76
+ method: "sdk.sessions.subscribe";
77
+ params: {
78
+ sessionId: string;
79
+ };
80
+ }
81
+ | {
82
+ id: string;
83
+ method: "sdk.sessions.unsubscribe";
84
+ params: {
85
+ subscriptionId: string;
86
+ };
87
+ };
88
+
89
+ type RpcSuccessFrame = {
90
+ id: string;
91
+ success: true;
92
+ data?: unknown;
93
+ };
94
+
95
+ type RpcErrorFrame = {
96
+ id: string;
97
+ success: false;
98
+ error: string;
99
+ };
100
+
101
+ type RpcEventFrame = {
102
+ type: "event";
103
+ subscriptionId: string;
104
+ event: AgentSessionEvent;
105
+ };
106
+
107
+ type SocketSubscription = {
108
+ sessionId: string;
109
+ unsubscribe: () => void;
110
+ };
111
+
112
+ /**
113
+ * RPC Server 启动参数。
114
+ */
115
+ export interface RpcServerStartOptions {
116
+ /** RPC 服务监听端口。 */
117
+ port: number;
118
+ /** RPC 服务监听主机。 */
119
+ host: string;
120
+ /** Session 集合访问口。 */
121
+ sessionCollection: AgentSessionCollection;
122
+ }
123
+
124
+ /**
125
+ * RPC Server 运行实例。
126
+ */
127
+ export interface RpcServerInstance {
128
+ /** 当前监听 host。 */
129
+ host: string;
130
+ /** 当前监听 port。 */
131
+ port: number;
132
+ /** 当前访问 URL。 */
133
+ url: string;
134
+ /** 原生 net server。 */
135
+ server: net.Server;
136
+ /** 停止当前服务。 */
137
+ stop(): Promise<void>;
138
+ }
139
+
140
+ /**
141
+ * 启动 Agent 本机 RPC 服务。
142
+ */
143
+ export async function startRpcServer(
144
+ options: RpcServerStartOptions,
145
+ ): Promise<RpcServerInstance> {
146
+ const server = net.createServer((socket) => {
147
+ const subscriptions = new Map<string, SocketSubscription>();
148
+ let buffered = "";
149
+
150
+ const cleanupSubscriptions = (): void => {
151
+ for (const subscription of subscriptions.values()) {
152
+ subscription.unsubscribe();
153
+ }
154
+ subscriptions.clear();
155
+ };
156
+
157
+ const writeFrame = (frame: RpcSuccessFrame | RpcErrorFrame | RpcEventFrame): void => {
158
+ socket.write(`${JSON.stringify(frame)}\n`);
159
+ };
160
+
161
+ const writeSuccess = (id: string, data?: unknown): void => {
162
+ writeFrame({
163
+ id,
164
+ success: true,
165
+ ...(data === undefined ? {} : { data }),
166
+ });
167
+ };
168
+
169
+ const writeError = (id: string, error: unknown): void => {
170
+ writeFrame({
171
+ id,
172
+ success: false,
173
+ error: error instanceof Error ? error.message : String(error),
174
+ });
175
+ };
176
+
177
+ const handleRequest = async (request: RpcSessionRequest): Promise<void> => {
178
+ try {
179
+ switch (request.method) {
180
+ case "sdk.sessions.list": {
181
+ const page = await options.sessionCollection.listSessions(request.params);
182
+ writeSuccess(request.id, { page });
183
+ return;
184
+ }
185
+ case "sdk.sessions.create": {
186
+ const session = await options.sessionCollection.createSession(request.params);
187
+ writeSuccess(request.id, { session: await session.getInfo() });
188
+ return;
189
+ }
190
+ case "sdk.sessions.get": {
191
+ const session = await options.sessionCollection.getSession(request.params.sessionId);
192
+ writeSuccess(request.id, { session: await session.getInfo() });
193
+ return;
194
+ }
195
+ case "sdk.sessions.prompt": {
196
+ const session = await options.sessionCollection.getSession(request.params.sessionId);
197
+ const turn = await session.prompt(request.params.input);
198
+ writeSuccess(request.id, { turn: { id: turn.id } });
199
+ return;
200
+ }
201
+ case "sdk.sessions.history": {
202
+ const session = await options.sessionCollection.getSession(request.params.sessionId);
203
+ const history = await session.history(request.params.input);
204
+ writeSuccess(request.id, { history });
205
+ return;
206
+ }
207
+ case "sdk.sessions.system": {
208
+ const session = await options.sessionCollection.getSession(request.params.sessionId);
209
+ writeSuccess(request.id, { system: await session.system() });
210
+ return;
211
+ }
212
+ case "sdk.sessions.fork": {
213
+ const session = await options.sessionCollection.getSession(request.params.sessionId);
214
+ const forked = await session.fork(request.params.messageId);
215
+ writeSuccess(request.id, { session: await forked.getInfo() });
216
+ return;
217
+ }
218
+ case "sdk.sessions.subscribe": {
219
+ const session = await options.sessionCollection.getSession(request.params.sessionId);
220
+ const subscriptionId = `${request.params.sessionId}:${Date.now()}:${Math.random().toString(36).slice(2, 10)}`;
221
+ const unsubscribe = session.subscribe((event) => {
222
+ writeFrame({
223
+ type: "event",
224
+ subscriptionId,
225
+ event,
226
+ });
227
+ });
228
+ subscriptions.set(subscriptionId, {
229
+ sessionId: request.params.sessionId,
230
+ unsubscribe,
231
+ });
232
+ writeSuccess(request.id, { subscriptionId });
233
+ return;
234
+ }
235
+ case "sdk.sessions.unsubscribe": {
236
+ const subscription = subscriptions.get(request.params.subscriptionId);
237
+ if (subscription) {
238
+ subscription.unsubscribe();
239
+ subscriptions.delete(request.params.subscriptionId);
240
+ }
241
+ writeSuccess(request.id, { unsubscribed: true });
242
+ return;
243
+ }
244
+ }
245
+ } catch (error) {
246
+ writeError(request.id, error);
247
+ }
248
+ };
249
+
250
+ socket.on("data", (chunk) => {
251
+ buffered += chunk.toString("utf8");
252
+ let newlineIndex = buffered.indexOf("\n");
253
+ while (newlineIndex >= 0) {
254
+ const line = buffered.slice(0, newlineIndex).trim();
255
+ buffered = buffered.slice(newlineIndex + 1);
256
+ if (line) {
257
+ try {
258
+ const parsed = JSON.parse(line) as RpcSessionRequest;
259
+ void handleRequest(parsed);
260
+ } catch (error) {
261
+ writeFrame({
262
+ id: "parse",
263
+ success: false,
264
+ error: error instanceof Error ? error.message : String(error),
265
+ });
266
+ }
267
+ }
268
+ newlineIndex = buffered.indexOf("\n");
269
+ }
270
+ });
271
+
272
+ socket.on("error", () => {
273
+ cleanupSubscriptions();
274
+ });
275
+ socket.on("close", () => {
276
+ cleanupSubscriptions();
277
+ });
278
+ socket.on("end", () => {
279
+ cleanupSubscriptions();
280
+ });
281
+ });
282
+
283
+ await new Promise<void>((resolve, reject) => {
284
+ server.once("error", reject);
285
+ server.listen(options.port, options.host, () => {
286
+ server.off("error", reject);
287
+ resolve();
288
+ });
289
+ });
290
+
291
+ return {
292
+ host: options.host,
293
+ port: options.port,
294
+ url: `rpc://${options.host}:${options.port}`,
295
+ server,
296
+ async stop(): Promise<void> {
297
+ await new Promise<void>((resolve) => {
298
+ server.close(() => resolve());
299
+ });
300
+ },
301
+ };
302
+ }
@@ -39,7 +39,7 @@ export type DaemonJsonApiCallParams = {
39
39
  * 单次调用超时(毫秒)。
40
40
  *
41
41
  * 说明(中文)
42
- * - 仅本地 IPC transport 当前会消费该参数。
42
+ * - HTTP daemon client 可消费该参数。
43
43
  * - 用于 `session execute`、`plugin command` 这类可能持续几十秒的请求,
44
44
  * 避免被默认短超时误判成“Agent server 未启动”。
45
45
  */
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 业务模块统一通过 daemon API 与运行时通信。
6
- * - 地址解析优先级:CLI 参数 > 环境变量 > daemon meta > 默认值。
6
+ * - HTTP gateway 与本机 RPC 的地址解析分开,避免端口语义混淆。
7
7
  */
8
8
 
9
9
  import fs from "fs-extra";
@@ -62,29 +62,27 @@ function pickArgValue(args: string[], key: string): string | undefined {
62
62
  return next || undefined;
63
63
  }
64
64
 
65
- /**
66
- * 解析 daemon endpoint。
67
- *
68
- * 优先级(中文)
69
- * 1) 显式入参 `host/port`
70
- * 2) 环境变量 `DC_SERVER_*` / `DC_CTX_SERVER_*`
71
- * 3) daemon meta args(`downcity.daemon.json`)
72
- * 4) 默认 `127.0.0.1:5314`
73
- */
74
- function resolveDaemonEndpoint(params: {
65
+ type ResolveDaemonEndpointParams = {
75
66
  projectRoot: string;
76
67
  host?: string;
77
68
  port?: number;
69
+ };
70
+
71
+ function resolveDaemonEndpointFromSources(params: {
72
+ projectRoot: string;
73
+ explicit_host?: string;
74
+ explicit_port?: number;
75
+ env_host_name: string;
76
+ env_port_name: string;
77
+ arg_port_name: string;
78
+ default_host: string;
79
+ default_port: number;
78
80
  }): DaemonEndpoint {
79
- const explicitHost = normalizeHost(params.host);
80
- const explicitPort = parsePortLike(params.port);
81
+ const explicitHost = normalizeHost(params.explicit_host);
82
+ const explicitPort = parsePortLike(params.explicit_port);
81
83
 
82
- const envHost =
83
- normalizeHost(process.env.DC_SERVER_HOST) ||
84
- normalizeHost(process.env.DC_CTX_SERVER_HOST);
85
- const envPort =
86
- parsePortLike(process.env.DC_SERVER_PORT) ||
87
- parsePortLike(process.env.DC_CTX_SERVER_PORT);
84
+ const envHost = normalizeHost(process.env[params.env_host_name]);
85
+ const envPort = parsePortLike(process.env[params.env_port_name]);
88
86
 
89
87
  let daemonArgHost: string | undefined;
90
88
  let daemonArgPort: number | undefined;
@@ -96,14 +94,14 @@ function resolveDaemonEndpoint(params: {
96
94
  ? raw.args.map((item) => String(item))
97
95
  : [];
98
96
  daemonArgHost = normalizeHost(pickArgValue(args, "--host"));
99
- daemonArgPort = parsePortLike(pickArgValue(args, "--port"));
97
+ daemonArgPort = parsePortLike(pickArgValue(args, params.arg_port_name));
100
98
  }
101
99
  } catch {
102
100
  // ignore daemon meta errors, fallback to other sources
103
101
  }
104
102
 
105
- const host = explicitHost || envHost || daemonArgHost || "127.0.0.1";
106
- const port = explicitPort || envPort || daemonArgPort || 5314;
103
+ const host = explicitHost || envHost || daemonArgHost || params.default_host;
104
+ const port = explicitPort || envPort || daemonArgPort || params.default_port;
107
105
 
108
106
  return {
109
107
  host,
@@ -112,6 +110,30 @@ function resolveDaemonEndpoint(params: {
112
110
  };
113
111
  }
114
112
 
113
+ /**
114
+ * 解析 daemon endpoint。
115
+ *
116
+ * 优先级(中文)
117
+ * 1) 显式入参 `host/port`
118
+ * 2) 环境变量 `DC_CITY_HOST/DC_CITY_PORT`
119
+ * 3) daemon meta args(`downcity.daemon.json`)
120
+ * 4) 默认 `127.0.0.1:5314`
121
+ */
122
+ function resolveDaemonEndpoint(
123
+ params: ResolveDaemonEndpointParams,
124
+ ): DaemonEndpoint {
125
+ return resolveDaemonEndpointFromSources({
126
+ projectRoot: params.projectRoot,
127
+ explicit_host: params.host,
128
+ explicit_port: params.port,
129
+ env_host_name: "DC_CITY_HOST",
130
+ env_port_name: "DC_CITY_PORT",
131
+ arg_port_name: "--port",
132
+ default_host: "127.0.0.1",
133
+ default_port: 5314,
134
+ });
135
+ }
136
+
115
137
  /**
116
138
  * 调用 daemon JSON API。
117
139
  *
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 这里只保留 agent 侧访问 daemon meta 所需的项目级路径。
6
- * - daemon 进程启停、pid 清理、registry 同步属于 `@downcity/city`,不放在 agent 包内。
6
+ * - daemon 进程启停、pid 清理、registry 同步属于 `downcity`,不放在 agent 包内。
7
7
  */
8
8
 
9
9
  import path from "node:path";
@@ -30,14 +30,14 @@ function ensureContextFiles(projectRoot: string): void {
30
30
  // Check if initialized(启动入口一次性确认工程根目录与关键文件)
31
31
  if (!fs.existsSync(getProfileMdPath(projectRoot))) {
32
32
  console.error(
33
- '❌ Project not initialized. Please run "city agent create" first',
33
+ '❌ Project not initialized. Please run "town agent create" first',
34
34
  );
35
35
  process.exit(1);
36
36
  }
37
37
 
38
38
  if (!fs.existsSync(getDowncityJsonPath(projectRoot))) {
39
39
  console.error(
40
- '❌ downcity.json does not exist. Please run "city agent create" first',
40
+ '❌ downcity.json does not exist. Please run "town agent create" first',
41
41
  );
42
42
  process.exit(1);
43
43
  }
@@ -82,7 +82,7 @@ export function registerControlOverviewRoutes(
82
82
  cityVersion: DC_VERSION,
83
83
  now: new Date().toISOString(),
84
84
  agent: {
85
- name: runtime.config.name,
85
+ id: runtime.config.id,
86
86
  status: "running",
87
87
  },
88
88
  sessions: {
@@ -30,7 +30,6 @@ import {
30
30
  SessionSystemBuilder,
31
31
  } from "@/session/SessionSystemBuilder.js";
32
32
  import {
33
- inferModelLabel,
34
33
  buildSessionHistoryPage,
35
34
  buildSessionInfo,
36
35
  patchSessionModelLabel,
@@ -62,6 +61,11 @@ import type { AgentSessionTurnHandle } from "@/types/sdk/AgentSessionTurn.js";
62
61
  import type { SessionUserMessageV1 } from "@/executor/types/SessionMessages.js";
63
62
  import { SessionEventHub } from "@/session/runtime/SessionEventHub.js";
64
63
  import { SessionPromptRuntime } from "@/session/runtime/SessionPromptRuntime.js";
64
+ import {
65
+ inferAgentModelLabel,
66
+ normalizeAgentModel,
67
+ } from "@/model/CityModelAdapter.js";
68
+ import { ensureSessionTitle } from "@/session/SessionTitle.js";
65
69
 
66
70
  type SessionOptions = {
67
71
  /**
@@ -257,8 +261,8 @@ export class Session implements AgentSession {
257
261
  this.createdAt = createdAt;
258
262
  this.timezone = timezone;
259
263
  this.sessionConfig = {
260
- ...(metadata.sdkConfig?.modelLabel
261
- ? { modelLabel: metadata.sdkConfig.modelLabel }
264
+ ...(metadata.modelLabel
265
+ ? { modelLabel: metadata.modelLabel }
262
266
  : {}),
263
267
  };
264
268
  return this;
@@ -280,8 +284,8 @@ export class Session implements AgentSession {
280
284
  */
281
285
  async set(input: AgentSessionSetInput): Promise<void> {
282
286
  if (input.model) {
283
- this.sessionConfig.model = input.model;
284
- this.sessionConfig.modelLabel = inferModelLabel(input.model);
287
+ this.sessionConfig.model = normalizeAgentModel(input.model);
288
+ this.sessionConfig.modelLabel = inferAgentModelLabel(input.model);
285
289
  this.executor.clearExecutor();
286
290
  }
287
291
  await patchSessionModelLabel({
@@ -333,6 +337,7 @@ export class Session implements AgentSession {
333
337
  await this.executor.appendUserMessage({
334
338
  text: String(input.text || "").trim(),
335
339
  });
340
+ await this.ensureTitleFromHistory({ generate: true });
336
341
  await this.touchMetadata();
337
342
  }
338
343
 
@@ -363,11 +368,19 @@ export class Session implements AgentSession {
363
368
  }),
364
369
  this.historyStore.list(),
365
370
  ]);
371
+ const metadataWithTitle = metadata.title
372
+ ? metadata
373
+ : await ensureSessionTitle({
374
+ projectRoot: this.projectRoot,
375
+ agentId: this.agentId,
376
+ sessionId: this.id,
377
+ messages,
378
+ });
366
379
  return buildSessionInfo({
367
380
  projectRoot: this.projectRoot,
368
381
  agentId: this.agentId,
369
382
  sessionId: this.id,
370
- metadata,
383
+ metadata: metadataWithTitle,
371
384
  messages,
372
385
  executing: this.isExecuting(),
373
386
  });
@@ -477,6 +490,7 @@ export class Session implements AgentSession {
477
490
  for (const message of forkMessages) {
478
491
  await forked.historyStore.append(message);
479
492
  }
493
+ await forked.ensureTitleFromHistory({ generate: true });
480
494
  await forked.touchMetadata();
481
495
  return forked;
482
496
  }
@@ -503,6 +517,8 @@ export class Session implements AgentSession {
503
517
  },
504
518
  appendUserMessage: async (messageParams) => {
505
519
  await this.executor.appendUserMessage(messageParams);
520
+ await this.ensureTitleFromHistory({ generate: true });
521
+ await this.touchMetadata();
506
522
  },
507
523
  appendAssistantMessage: async (messageParams) => {
508
524
  await this.executor.appendAssistantMessage(messageParams);
@@ -558,6 +574,23 @@ export class Session implements AgentSession {
558
574
  });
559
575
  }
560
576
 
577
+ private async ensureTitleFromHistory(input?: {
578
+ /**
579
+ * 是否允许调用模型生成标题。
580
+ */
581
+ generate?: boolean;
582
+ }): Promise<void> {
583
+ const messages = await this.historyStore.list();
584
+ await ensureSessionTitle({
585
+ projectRoot: this.projectRoot,
586
+ agentId: this.agentId,
587
+ sessionId: this.id,
588
+ messages,
589
+ ...(input?.generate ? { model: this.sessionConfig.model } : {}),
590
+ generate: input?.generate === true,
591
+ });
592
+ }
593
+
561
594
  private async persistAssistantResult(
562
595
  assistantMessage: SessionMessageV1,
563
596
  ): Promise<void> {
@@ -583,6 +616,7 @@ export class Session implements AgentSession {
583
616
  await this.executor.appendUserMessage({
584
617
  message,
585
618
  });
619
+ await this.ensureTitleFromHistory({ generate: true });
586
620
  await this.touchMetadata();
587
621
  return message;
588
622
  }