@downcity/agent 1.1.200 → 1.1.202

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/bin/agent/local/Agent.d.ts +3 -7
  2. package/bin/agent/local/Agent.d.ts.map +1 -1
  3. package/bin/agent/local/Agent.js +14 -19
  4. package/bin/agent/local/Agent.js.map +1 -1
  5. package/bin/agent/local/services/{AgentSessionManager.d.ts → AgentSessions.d.ts} +12 -17
  6. package/bin/agent/local/services/AgentSessions.d.ts.map +1 -0
  7. package/bin/agent/local/services/{AgentSessionManager.js → AgentSessions.js} +11 -26
  8. package/bin/agent/local/services/AgentSessions.js.map +1 -0
  9. package/bin/agent/remote/RemoteAgent.d.ts +2 -9
  10. package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
  11. package/bin/agent/remote/RemoteAgent.js +40 -22
  12. package/bin/agent/remote/RemoteAgent.js.map +1 -1
  13. package/bin/agent/remote/RemoteSession.d.ts +5 -5
  14. package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
  15. package/bin/agent/remote/RemoteSession.js +5 -3
  16. package/bin/agent/remote/RemoteSession.js.map +1 -1
  17. package/bin/agent/remote/RemoteTransport.d.ts +2 -2
  18. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +2 -2
  19. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +5 -5
  20. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +2 -2
  21. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +2 -2
  22. package/bin/executor/Executor.d.ts +5 -5
  23. package/bin/executor/Executor.d.ts.map +1 -1
  24. package/bin/executor/Executor.js +22 -13
  25. package/bin/executor/Executor.js.map +1 -1
  26. package/bin/executor/SessionRunScope.d.ts +1 -1
  27. package/bin/executor/SessionRunScope.d.ts.map +1 -1
  28. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +3 -3
  29. package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
  30. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +4 -5
  31. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
  32. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +56 -16
  33. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
  34. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts +27 -0
  35. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts.map +1 -0
  36. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js +181 -0
  37. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js.map +1 -0
  38. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts +45 -0
  39. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts.map +1 -0
  40. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js +144 -0
  41. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js.map +1 -0
  42. package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +3 -3
  43. package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +1 -1
  44. package/bin/executor/composer/context/SessionContextComposer.d.ts +3 -3
  45. package/bin/executor/composer/context/SessionContextComposer.d.ts.map +1 -1
  46. package/bin/executor/composer/history/SessionHistoryComposer.d.ts +2 -2
  47. package/bin/executor/composer/history/SessionHistoryComposer.d.ts.map +1 -1
  48. package/bin/executor/composer/history/SessionHistoryWriter.d.ts +5 -5
  49. package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +1 -1
  50. package/bin/executor/composer/history/SessionHistoryWriter.js +6 -6
  51. package/bin/executor/composer/history/SessionHistoryWriter.js.map +1 -1
  52. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts +2 -2
  53. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +1 -1
  54. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +5 -5
  55. package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +1 -1
  56. package/bin/executor/core-engine/CoreEngineMessageState.d.ts +5 -5
  57. package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +1 -1
  58. package/bin/executor/core-engine/CoreEngineMessageState.js.map +1 -1
  59. package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
  60. package/bin/executor/core-engine/CoreEngineSignals.d.ts +4 -4
  61. package/bin/executor/core-engine/CoreEngineSignals.d.ts.map +1 -1
  62. package/bin/executor/core-engine/CoreEngineSignals.js.map +1 -1
  63. package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts +3 -3
  64. package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts.map +1 -1
  65. package/bin/executor/core-engine/CoreEngineUiStreamCollector.js.map +1 -1
  66. package/bin/executor/messages/AssistantResultPersistence.d.ts +5 -5
  67. package/bin/executor/messages/AssistantResultPersistence.d.ts.map +1 -1
  68. package/bin/executor/messages/AssistantResultPersistence.js +1 -1
  69. package/bin/executor/messages/AssistantResultPersistence.js.map +1 -1
  70. package/bin/executor/messages/SessionAttachmentMapper.d.ts +3 -3
  71. package/bin/executor/messages/SessionAttachmentMapper.d.ts.map +1 -1
  72. package/bin/executor/messages/SessionAttachmentMapper.js.map +1 -1
  73. package/bin/executor/messages/SessionMessageCodec.d.ts +4 -4
  74. package/bin/executor/messages/SessionMessageCodec.d.ts.map +1 -1
  75. package/bin/executor/messages/SessionMessageCodec.js +5 -5
  76. package/bin/executor/messages/SessionMessageCodec.js.map +1 -1
  77. package/bin/executor/messages/SessionMessageLog.d.ts +3 -3
  78. package/bin/executor/messages/SessionMessageLog.d.ts.map +1 -1
  79. package/bin/executor/messages/SessionMessageLog.js.map +1 -1
  80. package/bin/executor/messages/SessionStepEventMapper.d.ts +2 -2
  81. package/bin/executor/messages/SessionStepEventMapper.d.ts.map +1 -1
  82. package/bin/executor/messages/SessionStepEventMapper.js.map +1 -1
  83. package/bin/executor/messages/UserVisibleText.d.ts +3 -3
  84. package/bin/executor/messages/UserVisibleText.d.ts.map +1 -1
  85. package/bin/executor/messages/UserVisibleText.js +3 -3
  86. package/bin/executor/messages/UserVisibleText.js.map +1 -1
  87. package/bin/executor/services/ExecutorInflightService.d.ts +2 -2
  88. package/bin/executor/services/ExecutorInflightService.d.ts.map +1 -1
  89. package/bin/executor/services/ExecutorInflightService.js +4 -4
  90. package/bin/executor/services/ExecutorInflightService.js.map +1 -1
  91. package/bin/executor/store/history/SessionHistoryStore.d.ts +24 -21
  92. package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
  93. package/bin/executor/store/history/SessionHistoryStore.js +3 -3
  94. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +18 -19
  95. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
  96. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +33 -36
  97. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  98. package/bin/executor/tools/plugin/PluginToolDefinition.d.ts +1 -7
  99. package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -1
  100. package/bin/executor/tools/plugin/PluginToolSchemas.d.ts +4 -6
  101. package/bin/executor/tools/plugin/PluginToolSchemas.d.ts.map +1 -1
  102. package/bin/executor/tools/plugin/PluginToolSchemas.js +24 -10
  103. package/bin/executor/tools/plugin/PluginToolSchemas.js.map +1 -1
  104. package/bin/executor/types/{SessionMessages.d.ts → SessionRecords.d.ts} +53 -28
  105. package/bin/executor/types/SessionRecords.d.ts.map +1 -0
  106. package/bin/executor/types/SessionRecords.js +52 -0
  107. package/bin/executor/types/SessionRecords.js.map +1 -0
  108. package/bin/executor/types/SessionRun.d.ts +3 -3
  109. package/bin/executor/types/SessionRun.d.ts.map +1 -1
  110. package/bin/index.d.ts +1 -1
  111. package/bin/index.d.ts.map +1 -1
  112. package/bin/rpc/Client.d.ts +5 -5
  113. package/bin/rpc/Client.js +4 -4
  114. package/bin/session/Session.d.ts +6 -6
  115. package/bin/session/Session.d.ts.map +1 -1
  116. package/bin/session/Session.js +8 -8
  117. package/bin/session/Session.js.map +1 -1
  118. package/bin/session/SessionTitle.d.ts +2 -2
  119. package/bin/session/SessionTitle.d.ts.map +1 -1
  120. package/bin/session/SessionTitle.js +3 -3
  121. package/bin/session/SessionTitle.js.map +1 -1
  122. package/bin/session/browse/Browse.d.ts +12 -12
  123. package/bin/session/browse/Browse.d.ts.map +1 -1
  124. package/bin/session/browse/Browse.js +9 -9
  125. package/bin/session/browse/Browse.js.map +1 -1
  126. package/bin/session/index.d.ts +1 -1
  127. package/bin/session/index.js +1 -1
  128. package/bin/session/runtime/SessionPromptRuntime.d.ts +3 -3
  129. package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
  130. package/bin/session/services/SessionStateService.d.ts +7 -8
  131. package/bin/session/services/SessionStateService.d.ts.map +1 -1
  132. package/bin/session/services/SessionStateService.js +15 -31
  133. package/bin/session/services/SessionStateService.js.map +1 -1
  134. package/bin/session/services/SessionViewService.d.ts +4 -4
  135. package/bin/session/services/SessionViewService.js +12 -12
  136. package/bin/session/services/SessionViewService.js.map +1 -1
  137. package/bin/session/storage/Persistence.d.ts +4 -4
  138. package/bin/session/storage/Persistence.d.ts.map +1 -1
  139. package/bin/session/storage/RuntimeSessionPort.d.ts +2 -2
  140. package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
  141. package/bin/session/storage/RuntimeSessionPort.js +4 -4
  142. package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
  143. package/bin/types/agent/AgentTypes.d.ts +2 -2
  144. package/bin/types/agent/AgentTypes.d.ts.map +1 -1
  145. package/bin/types/agent/SessionActor.d.ts +11 -11
  146. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  147. package/bin/types/agent/SessionTypes.d.ts +12 -12
  148. package/bin/types/agent/SessionTypes.d.ts.map +1 -1
  149. package/bin/types/executor/SessionRunContext.d.ts +2 -2
  150. package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
  151. package/bin/types/rpc/RpcProtocol.d.ts +6 -6
  152. package/bin/types/runtime/agent/AgentContext.d.ts +7 -7
  153. package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
  154. package/bin/types/sdk/AgentSessionAction.d.ts +8 -49
  155. package/bin/types/sdk/AgentSessionAction.d.ts.map +1 -1
  156. package/bin/types/sdk/AgentSessionAction.js +4 -4
  157. package/bin/types/sdk/AgentSessionTurn.d.ts +2 -2
  158. package/bin/types/sdk/AgentSessionTurn.d.ts.map +1 -1
  159. package/package.json +3 -3
  160. package/scripts/agent-ready.test.mjs +1 -1
  161. package/scripts/city-model-tool-loop.test.mjs +36 -4
  162. package/scripts/plugin-tool-bridge.test.mjs +13 -0
  163. package/scripts/session-action-message.test.mjs +25 -25
  164. package/scripts/session-compaction-prompts.test.mjs +97 -0
  165. package/scripts/session-history-archive.test.mjs +8 -8
  166. package/scripts/session-history-inflight.test.mjs +10 -10
  167. package/scripts/session-list-title.test.mjs +9 -9
  168. package/scripts/session-title-event.test.mjs +12 -10
  169. package/src/agent/local/Agent.ts +16 -22
  170. package/src/agent/local/services/{AgentSessionManager.ts → AgentSessions.ts} +16 -32
  171. package/src/agent/remote/RemoteAgent.ts +58 -23
  172. package/src/agent/remote/RemoteSession.ts +10 -8
  173. package/src/agent/remote/RemoteTransport.ts +5 -5
  174. package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +10 -10
  175. package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +6 -6
  176. package/src/executor/Executor.ts +30 -19
  177. package/src/executor/SessionRunScope.ts +1 -1
  178. package/src/executor/composer/compaction/SessionCompactionComposer.ts +3 -3
  179. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +73 -29
  180. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.ts +197 -0
  181. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.ts +162 -0
  182. package/src/executor/composer/context/LocalSessionContextComposer.ts +5 -5
  183. package/src/executor/composer/context/SessionContextComposer.ts +5 -5
  184. package/src/executor/composer/history/SessionHistoryComposer.ts +2 -2
  185. package/src/executor/composer/history/SessionHistoryWriter.ts +10 -10
  186. package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +13 -13
  187. package/src/executor/core-engine/CoreEngineMessageState.ts +8 -8
  188. package/src/executor/core-engine/CoreEngineRunner.ts +7 -7
  189. package/src/executor/core-engine/CoreEngineSignals.ts +7 -7
  190. package/src/executor/core-engine/CoreEngineUiStreamCollector.ts +5 -5
  191. package/src/executor/messages/AssistantResultPersistence.ts +8 -8
  192. package/src/executor/messages/SessionAttachmentMapper.ts +11 -11
  193. package/src/executor/messages/SessionMessageCodec.ts +10 -10
  194. package/src/executor/messages/SessionMessageLog.ts +3 -3
  195. package/src/executor/messages/SessionStepEventMapper.ts +5 -5
  196. package/src/executor/messages/UserVisibleText.ts +9 -9
  197. package/src/executor/services/ExecutorInflightService.ts +7 -7
  198. package/src/executor/store/history/SessionHistoryStore.ts +26 -23
  199. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +58 -62
  200. package/src/executor/tools/plugin/PluginToolSchemas.ts +24 -10
  201. package/src/executor/types/{SessionMessages.ts → SessionRecords.ts} +71 -40
  202. package/src/executor/types/SessionRun.ts +5 -5
  203. package/src/index.ts +4 -4
  204. package/src/rpc/Client.ts +9 -9
  205. package/src/session/Session.ts +10 -10
  206. package/src/session/SessionTitle.ts +7 -7
  207. package/src/session/browse/Browse.ts +38 -38
  208. package/src/session/index.ts +1 -1
  209. package/src/session/runtime/SessionPromptRuntime.ts +6 -6
  210. package/src/session/services/SessionStateService.ts +29 -44
  211. package/src/session/services/SessionTurnService.ts +4 -4
  212. package/src/session/services/SessionViewService.ts +21 -21
  213. package/src/session/storage/Persistence.ts +6 -6
  214. package/src/session/storage/RuntimeSessionPort.ts +6 -6
  215. package/src/types/agent/AgentTypes.ts +4 -4
  216. package/src/types/agent/SessionActor.ts +12 -12
  217. package/src/types/agent/SessionTypes.ts +12 -12
  218. package/src/types/executor/SessionRunContext.ts +2 -2
  219. package/src/types/rpc/RpcProtocol.ts +6 -6
  220. package/src/types/runtime/agent/AgentContext.ts +8 -8
  221. package/src/types/sdk/AgentSessionAction.ts +12 -56
  222. package/src/types/sdk/AgentSessionTurn.ts +2 -2
  223. package/tsconfig.tsbuildinfo +1 -1
  224. package/bin/agent/local/services/AgentSessionManager.d.ts.map +0 -1
  225. package/bin/agent/local/services/AgentSessionManager.js.map +0 -1
  226. package/bin/executor/types/SessionMessages.d.ts.map +0 -1
  227. package/bin/executor/types/SessionMessages.js +0 -46
  228. package/bin/executor/types/SessionMessages.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * JsonlSessionHistoryStore:基于 JSONL 的 session history 事实源。
2
+ * JsonlSessionHistoryStore:基于 JSONL 的 session records 事实源。
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 负责 `.downcity/.../messages/messages.jsonl`、`meta.json`、archive 与文件锁。
@@ -18,16 +18,15 @@ import { generateId } from "@/utils/Id.js";
18
18
  import { getLogger } from "@/utils/logger/Logger.js";
19
19
  import { compactSessionMessagesIfNeeded } from "@executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js";
20
20
  import type {
21
- SessionActionMessageV1,
22
- SessionMessageV1,
21
+ SessionActionRecordV1,
22
+ SessionRecordV1,
23
23
  SessionMetadataV1,
24
- } from "@/executor/types/SessionMessages.js";
24
+ } from "@/executor/types/SessionRecords.js";
25
25
  import {
26
- isSessionActionMessage,
27
- isSessionModelMessage,
28
- toSessionActionMessage,
29
- } from "@/executor/types/SessionMessages.js";
30
- import type { AgentSessionActionRecord } from "@/types/sdk/AgentSessionAction.js";
26
+ is_session_action_record,
27
+ is_session_message_record,
28
+ to_session_action_record,
29
+ } from "@/executor/types/SessionRecords.js";
31
30
  import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
32
31
  import type { SessionHistoryMetaV1 } from "@/executor/types/SessionHistoryMeta.js";
33
32
  import type { SessionHistoryPathOverrides } from "@/executor/types/SessionHistoryPaths.js";
@@ -220,10 +219,10 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
220
219
 
221
220
  private normalizePersistedMessage(
222
221
  input: unknown,
223
- ): SessionMessageV1 | null {
222
+ ): SessionRecordV1 | null {
224
223
  if (!input || typeof input !== "object") return null;
225
224
  if ((input as { type?: unknown }).type === "action") {
226
- return this.normalizeActionMessage(input);
225
+ return this.normalize_action_record(input);
227
226
  }
228
227
  const candidate = input as { role?: unknown; parts?: unknown };
229
228
  const role = String(candidate.role || "");
@@ -231,12 +230,12 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
231
230
  return null;
232
231
  }
233
232
  if (!Array.isArray(candidate.parts)) return null;
234
- return input as SessionMessageV1;
233
+ return input as SessionRecordV1;
235
234
  }
236
235
 
237
- private normalizeActionMessage(input: unknown): SessionActionMessageV1 | null {
236
+ private normalize_action_record(input: unknown): SessionActionRecordV1 | null {
238
237
  if (!input || typeof input !== "object") return null;
239
- const candidate = input as Partial<SessionActionMessageV1>;
238
+ const candidate = input as Partial<SessionActionRecordV1>;
240
239
  const id = String(candidate.id || "").trim();
241
240
  const title = String(candidate.title || "").trim();
242
241
  const state = String(candidate.state || "").trim();
@@ -248,7 +247,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
248
247
  candidate.metadata && typeof candidate.metadata === "object"
249
248
  ? candidate.metadata
250
249
  : {};
251
- const metadata_candidate = metadata_input as Partial<SessionActionMessageV1["metadata"]>;
250
+ const metadata_candidate = metadata_input as Partial<SessionActionRecordV1["metadata"]>;
252
251
  const session_id =
253
252
  String(metadata_candidate.sessionId || "").trim() || this.sessionId;
254
253
  const description = String(candidate.description || "").trim();
@@ -270,9 +269,9 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
270
269
  };
271
270
  }
272
271
 
273
- private hasStructuredAssistantParts(message: SessionMessageV1 | null): boolean {
272
+ private hasStructuredAssistantParts(message: SessionRecordV1 | null): boolean {
274
273
  if (
275
- !isSessionModelMessage(message) ||
274
+ !is_session_message_record(message) ||
276
275
  message.role !== "assistant" ||
277
276
  !Array.isArray(message.parts)
278
277
  ) {
@@ -286,11 +285,11 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
286
285
  }
287
286
 
288
287
  private mergeInflightWithFinal(
289
- inflight: SessionMessageV1,
290
- finalMessage: SessionMessageV1,
291
- ): SessionMessageV1 {
292
- if (!isSessionModelMessage(finalMessage)) return inflight;
293
- if (!isSessionModelMessage(inflight)) return finalMessage;
288
+ inflight: SessionRecordV1,
289
+ finalMessage: SessionRecordV1,
290
+ ): SessionRecordV1 {
291
+ if (!is_session_message_record(finalMessage)) return inflight;
292
+ if (!is_session_message_record(inflight)) return finalMessage;
294
293
  const final_parts = Array.isArray(finalMessage.parts)
295
294
  ? finalMessage.parts.filter((part) => part && typeof part === "object")
296
295
  : [];
@@ -396,7 +395,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
396
395
  await fs.writeJson(this.getMetaFilePath(), normalized, { spaces: 2 });
397
396
  }
398
397
 
399
- private async readInflightUnsafe(): Promise<SessionMessageV1 | null> {
398
+ private async read_inflight_unsafe(): Promise<SessionRecordV1 | null> {
400
399
  const file = this.getInflightFilePath();
401
400
  try {
402
401
  const raw = await fs.readJson(file);
@@ -406,10 +405,10 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
406
405
  }
407
406
  }
408
407
 
409
- private async writeInflightUnsafe(message: SessionMessageV1): Promise<void> {
408
+ private async write_inflight_unsafe(message: SessionRecordV1): Promise<void> {
410
409
  const normalized = this.normalizePersistedMessage(message);
411
410
  if (
412
- !isSessionModelMessage(normalized) ||
411
+ !is_session_message_record(normalized) ||
413
412
  normalized.role !== "assistant"
414
413
  ) {
415
414
  throw new Error("inflight assistant must be an assistant UIMessage");
@@ -425,7 +424,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
425
424
  await fs.remove(this.getInflightFilePath());
426
425
  }
427
426
 
428
- private async appendMessageUnsafe(message: SessionMessageV1): Promise<void> {
427
+ private async appendMessageUnsafe(message: SessionRecordV1): Promise<void> {
429
428
  await fs.appendFile(
430
429
  this.getMessagesFilePath(),
431
430
  JSON.stringify(message) + "\n",
@@ -433,7 +432,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
433
432
  );
434
433
  }
435
434
 
436
- private async rewriteMessagesUnsafe(messages: SessionMessageV1[]): Promise<void> {
435
+ private async rewriteMessagesUnsafe(messages: SessionRecordV1[]): Promise<void> {
437
436
  const file = this.getMessagesFilePath();
438
437
  const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
439
438
  const payload =
@@ -444,19 +443,19 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
444
443
  await fs.move(temp, file, { overwrite: true });
445
444
  }
446
445
 
447
- private async upsertActionMessageUnsafe(
448
- message: SessionActionMessageV1,
446
+ private async upsert_action_record_unsafe(
447
+ message: SessionActionRecordV1,
449
448
  ): Promise<void> {
450
449
  const file = this.getMessagesFilePath();
451
450
  const raw = await fs.readFile(file, "utf8").catch(() => "");
452
- const messages: SessionMessageV1[] = [];
451
+ const messages: SessionRecordV1[] = [];
453
452
  let replaced = false;
454
453
 
455
454
  for (const line of raw.split("\n").filter(Boolean)) {
456
455
  try {
457
456
  const current = this.normalizePersistedMessage(JSON.parse(line));
458
457
  if (!current) continue;
459
- if (isSessionActionMessage(current) && current.id === message.id) {
458
+ if (is_session_action_record(current) && current.id === message.id) {
460
459
  messages.push(message);
461
460
  replaced = true;
462
461
  continue;
@@ -539,7 +538,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
539
538
  rootPath: this.rootPath,
540
539
  sessionId: this.sessionId,
541
540
  withWriteLock: (fn) => this.withWriteLock(fn),
542
- loadAll: () => this.list(),
541
+ loadAll: () => this.list_records(),
543
542
  createSummaryMessage: ({ text, archiveId, sourceRange }) => ({
544
543
  id: `a:${this.sessionId}:${generateId()}`,
545
544
  role: "assistant",
@@ -571,19 +570,19 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
571
570
  );
572
571
  }
573
572
 
574
- async append(message: SessionMessageV1): Promise<void> {
573
+ async write_record(message: SessionRecordV1): Promise<void> {
575
574
  await this.withWriteLock(async () => {
576
575
  const normalized = this.normalizePersistedMessage(message);
577
576
  if (!normalized) return;
578
- if (isSessionActionMessage(normalized)) {
579
- await this.upsertActionMessageUnsafe(normalized);
577
+ if (is_session_action_record(normalized)) {
578
+ await this.upsert_action_record_unsafe(normalized);
580
579
  return;
581
580
  }
582
581
 
583
582
  // 关键点(中文):若上一次 assistant 在运行中中断,新的 user 到来前先把残留快照收口到正式历史,
584
- // 避免 `list()` 时旧 inflight 跑到新 user 后面,打乱时序。
585
- if (isSessionModelMessage(normalized) && normalized.role === "user") {
586
- const current_inflight = await this.readInflightUnsafe();
583
+ // 避免 `list_records()` 时旧 inflight 跑到新 user 后面,打乱时序。
584
+ if (is_session_message_record(normalized) && normalized.role === "user") {
585
+ const current_inflight = await this.read_inflight_unsafe();
587
586
  if (current_inflight) {
588
587
  await this.appendMessageUnsafe(current_inflight);
589
588
  await this.removeInflightUnsafe();
@@ -601,11 +600,11 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
601
600
  * - 一次锁、一次 IO,适合 fork 等需要拷贝整段历史的场景。
602
601
  * - 不处理 inflight,调用方需自行确保历史已经收口。
603
602
  */
604
- async appendMany(messages: SessionMessageV1[]): Promise<void> {
603
+ async write_records(messages: SessionRecordV1[]): Promise<void> {
605
604
  if (!Array.isArray(messages) || messages.length === 0) return;
606
605
  const normalized_list = messages
607
606
  .map((message) => this.normalizePersistedMessage(message))
608
- .filter((message): message is SessionMessageV1 => message !== null);
607
+ .filter((message): message is SessionRecordV1 => message !== null);
609
608
  if (normalized_list.length === 0) return;
610
609
 
611
610
  const payload = normalized_list
@@ -616,20 +615,20 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
616
615
  });
617
616
  }
618
617
 
619
- async readInflight(): Promise<SessionMessageV1 | null> {
618
+ async read_inflight(): Promise<SessionRecordV1 | null> {
620
619
  await this.ensureLayout();
621
- return this.readInflightUnsafe();
620
+ return this.read_inflight_unsafe();
622
621
  }
623
622
 
624
- async writeInflight(message: SessionMessageV1): Promise<void> {
623
+ async write_inflight(message: SessionRecordV1): Promise<void> {
625
624
  await this.withWriteLock(async () => {
626
- await this.writeInflightUnsafe(message);
625
+ await this.write_inflight_unsafe(message);
627
626
  });
628
627
  }
629
628
 
630
- async finalizeInflight(message?: SessionMessageV1 | null): Promise<void> {
629
+ async finalize_inflight(message?: SessionRecordV1 | null): Promise<void> {
631
630
  await this.withWriteLock(async () => {
632
- const current_inflight = await this.readInflightUnsafe();
631
+ const current_inflight = await this.read_inflight_unsafe();
633
632
  const normalized_message = this.normalizePersistedMessage(message);
634
633
  const final_message =
635
634
  current_inflight && normalized_message
@@ -644,12 +643,12 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
644
643
  });
645
644
  }
646
645
 
647
- async list(): Promise<SessionMessageV1[]> {
646
+ async list_records(): Promise<SessionRecordV1[]> {
648
647
  await this.ensureLayout();
649
648
  const file = this.getMessagesFilePath();
650
649
  const raw = await fs.readFile(file, "utf8");
651
650
  const lines = raw.split("\n").filter(Boolean);
652
- const out: SessionMessageV1[] = [];
651
+ const out: SessionRecordV1[] = [];
653
652
  for (const line of lines) {
654
653
  try {
655
654
  const obj = this.normalizePersistedMessage(JSON.parse(line));
@@ -659,22 +658,22 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
659
658
  // ignore invalid lines
660
659
  }
661
660
  }
662
- const current_inflight = await this.readInflightUnsafe();
661
+ const current_inflight = await this.read_inflight_unsafe();
663
662
  if (current_inflight) {
664
663
  out.push(current_inflight);
665
664
  }
666
665
  return out;
667
666
  }
668
667
 
669
- async slice(start: number, end: number): Promise<SessionMessageV1[]> {
670
- const msgs = await this.list();
668
+ async slice_records(start: number, end: number): Promise<SessionRecordV1[]> {
669
+ const msgs = await this.list_records();
671
670
  const startIndex = Math.max(0, Math.floor(start));
672
671
  const endIndex = Math.max(startIndex, Math.floor(end));
673
672
  return msgs.slice(startIndex, endIndex);
674
673
  }
675
674
 
676
- async size(): Promise<number> {
677
- const msgs = await this.list();
675
+ async record_count(): Promise<number> {
676
+ const msgs = await this.list_records();
678
677
  return msgs.length;
679
678
  }
680
679
 
@@ -691,7 +690,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
691
690
  metadata: Omit<SessionMetadataV1, "v" | "ts"> &
692
691
  Partial<Pick<SessionMetadataV1, "ts">>;
693
692
  id?: string;
694
- }): SessionMessageV1 {
693
+ }): SessionRecordV1 {
695
694
  const { ts, ...metadata } = input.metadata;
696
695
  const md: SessionMetadataV1 = {
697
696
  v: 1,
@@ -716,7 +715,7 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
716
715
  id?: string;
717
716
  kind?: "normal" | "summary";
718
717
  source?: "egress" | "compact";
719
- }): SessionMessageV1 {
718
+ }): SessionRecordV1 {
720
719
  const { ts, ...metadata } = input.metadata;
721
720
  const md: SessionMetadataV1 = {
722
721
  v: 1,
@@ -735,17 +734,14 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
735
734
  }
736
735
 
737
736
  action(input: {
738
- action: AgentSessionActionRecord;
737
+ action: SessionActionRecordV1;
739
738
  metadata: Pick<SessionMetadataV1, "sessionId"> &
740
739
  Partial<Pick<SessionMetadataV1, "ts">>;
741
740
  id?: string;
742
- }): SessionActionMessageV1 {
741
+ }): SessionActionRecordV1 {
743
742
  const { ts, ...metadata } = input.metadata;
744
- const message = toSessionActionMessage(
745
- {
746
- ...input.action,
747
- ...(input.id ? { id: input.id } : {}),
748
- },
743
+ const message = to_session_action_record(
744
+ input.id ? { ...input.action, id: input.id } : input.action,
749
745
  metadata.sessionId || this.sessionId,
750
746
  );
751
747
  return {
@@ -3,20 +3,34 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - plugin_call 是 agent 内置的最低层 plugin action 桥。
6
- * - schema 只描述模型需要提交的目标 pluginaction JSON payload
6
+ * - plugin_call.payload 是透传给具体 plugin action JSON object
7
+ * - 这里不用 Zod 表达 payload 的开放对象语义,避免 AI SDK zodSchema
8
+ * 转换后把 additionalProperties 收窄为 false。
7
9
  */
8
10
 
11
+ import { jsonSchema } from "ai";
9
12
  import { z } from "zod";
10
13
 
11
- export const plugin_call_input_schema = z.object({
12
- plugin: z.string().describe("Registered plugin name to call, for example image."),
13
- action: z.string().describe("Plugin action name to execute, for example image_create."),
14
- payload: z
15
- .object({})
16
- .passthrough()
17
- .optional()
18
- .default({})
19
- .describe("JSON payload passed to the plugin action."),
14
+ export const plugin_call_input_schema = jsonSchema({
15
+ type: "object",
16
+ required: ["plugin", "action"],
17
+ additionalProperties: false,
18
+ properties: {
19
+ plugin: {
20
+ type: "string",
21
+ description: "Registered plugin name to call, for example image.",
22
+ },
23
+ action: {
24
+ type: "string",
25
+ description: "Plugin action name to execute, for example image_create.",
26
+ },
27
+ payload: {
28
+ type: "object",
29
+ additionalProperties: true,
30
+ default: {},
31
+ description: "JSON payload passed to the plugin action.",
32
+ },
33
+ },
20
34
  });
21
35
 
22
36
  export const plugin_read_input_schema = z.object({
@@ -1,26 +1,23 @@
1
1
  /**
2
- * SessionMessage 类型定义。
2
+ * SessionRecord 类型定义。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 这里统一描述 session 消息落盘格式与元信息结构。
6
- * - session 的唯一事实源是消息 JSONL,模型消息继续使用 AI SDK `UIMessage`。
7
- * - 这些类型会被 history Store、history Composer、compact、control UI、task runtime 共同复用。
5
+ * - 这里统一描述 session JSONL 中的持久化 record 结构。
6
+ * - record 是 session 内部事实源;其中 message record 继续使用 AI SDK `UIMessage`。
7
+ * - action record UI record,不属于 LLM 输入。
8
+ * - 这些类型会被 Store、Composer、compact、control UI、task runtime 共同复用。
8
9
  */
9
10
 
10
11
  import type { UIMessage } from "ai";
11
12
  import type { JsonObject } from "@/types/common/Json.js";
12
- import type {
13
- AgentSessionActionRecord,
14
- AgentSessionActionState,
15
- } from "@/types/sdk/AgentSessionAction.js";
16
13
 
17
14
  /**
18
- * Session 消息:以 UIMessage[] 作为唯一事实源。
15
+ * Session message record 类别。
19
16
  *
20
17
  * 关键点(中文)
21
18
  * - 持久化存储在 `.downcity/agents/<encodedAgentId>/sessions/<encodedSessionId>/messages/messages.jsonl`
22
- * - 默认只存模型消息,或 `type=action` 的 UI 状态消息。
23
- * - compact 会把更早消息压缩为一条 `assistant` 摘要消息
19
+ * - record 文件默认包含 message record,或 `type=action` 的 UI 状态记录。
20
+ * - compact 会把更早 message record 压缩为一条 `assistant` 摘要 record。
24
21
  * - action 只用于 UI timeline,不进入 LLM 输入
25
22
  */
26
23
  export type SessionMessageKind = "normal" | "summary";
@@ -87,12 +84,17 @@ export type SessionMetadataV1 = {
87
84
  };
88
85
 
89
86
  /**
90
- * 模型可消费的 Session UI 消息结构。
87
+ * 大模型可消费的 Session message record。
91
88
  */
92
- export type SessionModelMessageV1 = UIMessage<SessionMetadataV1>;
89
+ export type SessionMessageRecordV1 = UIMessage<SessionMetadataV1>;
93
90
 
94
91
  /**
95
- * action 消息元信息。
92
+ * Session action 当前状态。
93
+ */
94
+ export type SessionActionStateV1 = "running" | "completed" | "failed";
95
+
96
+ /**
97
+ * action record 元信息。
96
98
  */
97
99
  export type SessionActionMetadataV1 = {
98
100
  /** 元信息 schema 版本号。 */
@@ -106,14 +108,14 @@ export type SessionActionMetadataV1 = {
106
108
  };
107
109
 
108
110
  /**
109
- * action 类型的 Session 消息结构。
111
+ * action 类型的 Session record 结构。
110
112
  *
111
113
  * 关键点(中文)
112
- * - `action` 不是 AI SDK 原生模型消息。
113
- * - 它只存在于 JSONL history 与前端 timeline,进入 LLM 前必须过滤。
114
+ * - `action` 不是 AI SDK 原生 message record。
115
+ * - 它只存在于 session records 与前端 timeline,进入 LLM 前必须过滤。
114
116
  */
115
- export type SessionActionMessageV1 = {
116
- /** item 类型固定为 `action`。 */
117
+ export type SessionActionRecordV1 = {
118
+ /** record 类型固定为 `action`。 */
117
119
  type: "action";
118
120
  /** 同一个 action 生命周期内稳定复用的 ID。 */
119
121
  id: string;
@@ -122,44 +124,73 @@ export type SessionActionMessageV1 = {
122
124
  /** 当前 action 描述。 */
123
125
  description?: string;
124
126
  /** 当前 action 状态。 */
125
- state: AgentSessionActionState;
127
+ state: SessionActionStateV1;
126
128
  /** action 元信息。 */
127
129
  metadata: SessionActionMetadataV1;
128
130
  };
129
131
 
130
132
  /**
131
- * Session 持久化消息结构。
133
+ * 构造 action record 的输入结构。
134
+ */
135
+ export type SessionActionRecordInputV1 = {
136
+ /** 同一个 action 生命周期内稳定复用的 ID。 */
137
+ id?: string;
138
+ /** 当前 action 标题。 */
139
+ title: string;
140
+ /** 当前 action 描述。 */
141
+ description?: string;
142
+ /** 当前 action 状态。 */
143
+ state: SessionActionStateV1;
144
+ /** 当前 action 关联的 turn 标识。 */
145
+ turnId?: string;
146
+ /** 可选 action 元信息覆盖。 */
147
+ metadata?: Partial<SessionActionMetadataV1>;
148
+ };
149
+
150
+ /**
151
+ * Session 持久化 record 结构。
152
+ *
153
+ * 说明(中文)
154
+ * - message record 是可进入 LLM 的 record。
155
+ * - action record 是只给前端展示的 record,组装模型输入前必须过滤。
132
156
  */
133
- export type SessionMessageV1 = SessionModelMessageV1 | SessionActionMessageV1;
157
+ export type SessionRecordV1 = SessionMessageRecordV1 | SessionActionRecordV1;
134
158
 
135
159
  /**
136
- * user 角色的 Session 消息结构。
160
+ * user 角色的 Session message record。
137
161
  */
138
- export type SessionUserMessageV1 = SessionModelMessageV1 & {
162
+ export type SessionUserMessageV1 = SessionMessageRecordV1 & {
139
163
  /** 消息角色固定为 `user`。 */
140
164
  role: "user";
141
165
  };
142
166
 
143
167
  /**
144
- * 判断一条消息是否为 action message
168
+ * 判断一条 record 是否为 action record
145
169
  */
146
- export function isSessionActionMessage(
147
- message: SessionMessageV1 | null | undefined,
148
- ): message is SessionActionMessageV1 {
170
+ export function is_session_action_record(
171
+ message: SessionRecordV1 | null | undefined,
172
+ ): message is SessionActionRecordV1 {
149
173
  if (!message || typeof message !== "object") return false;
150
174
  return (message as { type?: unknown }).type === "action";
151
175
  }
152
176
 
153
177
  /**
154
- * 从订阅事件构造 action message
178
+ * 从订阅事件构造 action record
155
179
  */
156
- export function toSessionActionMessage(
157
- action: AgentSessionActionRecord,
180
+ export function to_session_action_record(
181
+ action: SessionActionRecordInputV1 | SessionActionRecordV1,
158
182
  session_id: string,
159
- ): SessionActionMessageV1 {
183
+ ): SessionActionRecordV1 {
160
184
  const title = String(action.title || "").trim() || "Action";
161
185
  const description = String(action.description || "").trim();
162
186
  const id = String(action.id || "").trim() || `action:${session_id}:${Date.now()}`;
187
+ const metadata =
188
+ "metadata" in action && action.metadata && typeof action.metadata === "object"
189
+ ? action.metadata
190
+ : {};
191
+ const turn_id =
192
+ String(metadata.turnId || "").trim() ||
193
+ ("turnId" in action ? String(action.turnId || "").trim() : "");
163
194
  return {
164
195
  type: "action",
165
196
  id,
@@ -168,19 +199,19 @@ export function toSessionActionMessage(
168
199
  state: action.state,
169
200
  metadata: {
170
201
  v: 1,
171
- ts: Date.now(),
172
- sessionId: session_id,
173
- ...(action.turnId ? { turnId: action.turnId } : {}),
202
+ ts: typeof metadata.ts === "number" ? metadata.ts : Date.now(),
203
+ sessionId: String(metadata.sessionId || "").trim() || session_id,
204
+ ...(turn_id ? { turnId: turn_id } : {}),
174
205
  },
175
206
  };
176
207
  }
177
208
 
178
209
  /**
179
- * 判断一条消息是否为模型可消费的 UIMessage
210
+ * 判断一条 record 是否为大模型可消费的 message record
180
211
  */
181
- export function isSessionModelMessage(
182
- message: SessionMessageV1 | null | undefined,
183
- ): message is SessionModelMessageV1 {
212
+ export function is_session_message_record(
213
+ message: SessionRecordV1 | null | undefined,
214
+ ): message is SessionMessageRecordV1 {
184
215
  if (!message || typeof message !== "object") return false;
185
- return !isSessionActionMessage(message);
216
+ return !is_session_action_record(message);
186
217
  }
@@ -9,10 +9,10 @@
9
9
 
10
10
  import type { Tool, UIMessageChunk } from "ai";
11
11
  import type {
12
- SessionMessageV1,
13
- SessionModelMessageV1,
12
+ SessionRecordV1,
13
+ SessionMessageRecordV1,
14
14
  SessionUserMessageV1,
15
- } from "@/executor/types/SessionMessages.js";
15
+ } from "@/executor/types/SessionRecords.js";
16
16
  import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
17
17
  import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
18
18
 
@@ -102,7 +102,7 @@ export interface SessionRunResult {
102
102
  * - stop/abort 且没有任何 assistant 内容时可以为空。
103
103
  * - turn 状态通过 `success` / `error` 表达,不应伪造成 assistant 正文。
104
104
  */
105
- assistantMessage?: SessionModelMessageV1 | null;
105
+ assistantMessage?: SessionMessageRecordV1 | null;
106
106
 
107
107
  /**
108
108
  * 本轮执行结束后待写入长期历史的 user 消息。
@@ -150,7 +150,7 @@ export interface SessionExecuteInput {
150
150
  /**
151
151
  * 当前轮 context 语义消息历史。
152
152
  */
153
- messages: SessionMessageV1[];
153
+ messages: SessionRecordV1[];
154
154
 
155
155
  /**
156
156
  * 当前轮可用工具集合。
package/src/index.ts CHANGED
@@ -22,7 +22,7 @@ export type {
22
22
  AgentArchiveSessionResult,
23
23
  AgentArchiveSessionsResult,
24
24
  AgentCleanArchiveResult,
25
- AgentSessionCollection,
25
+ AgentSessions,
26
26
  AgentModel,
27
27
  AgentManagedSession,
28
28
  AgentSessionActor,
@@ -34,9 +34,9 @@ export type {
34
34
  RemoteAgentOptions,
35
35
  AgentSessionConfigSnapshot,
36
36
  AgentSessionForkInput,
37
- AgentSessionHistoryInput,
38
- AgentSessionHistoryPage,
39
- AgentSessionHistoryView,
37
+ AgentSessionRecordsInput,
38
+ AgentSessionRecordsPage,
39
+ AgentSessionRecordsView,
40
40
  AgentSessionInfo,
41
41
  AgentSessionSetInput,
42
42
  AgentSessionSummary,
package/src/rpc/Client.ts CHANGED
@@ -16,8 +16,8 @@ import type {
16
16
  AgentArchiveSessionResult,
17
17
  AgentArchiveSessionsResult,
18
18
  AgentCleanArchiveResult,
19
- AgentSessionHistoryInput,
20
- AgentSessionHistoryPage,
19
+ AgentSessionRecordsInput,
20
+ AgentSessionRecordsPage,
21
21
  AgentSessionInfo,
22
22
  AgentSessionStopResult,
23
23
  AgentSessionSummaryPage,
@@ -196,20 +196,20 @@ export class RpcClient {
196
196
  }
197
197
 
198
198
  /**
199
- * 读取 history
199
+ * 读取 session records
200
200
  */
201
- async get_session_history(params: {
201
+ async get_session_records(params: {
202
202
  session_id: string;
203
- input?: AgentSessionHistoryInput;
204
- }): Promise<AgentSessionHistoryPage> {
205
- const data = await this.request<{ history: AgentSessionHistoryPage }>({
206
- method: "sdk.sessions.history",
203
+ input?: AgentSessionRecordsInput;
204
+ }): Promise<AgentSessionRecordsPage> {
205
+ const data = await this.request<{ records: AgentSessionRecordsPage }>({
206
+ method: "sdk.sessions.records",
207
207
  params: {
208
208
  sessionId: params.session_id,
209
209
  input: params.input,
210
210
  },
211
211
  });
212
- return data.history;
212
+ return data.records;
213
213
  }
214
214
 
215
215
  /**