@downcity/agent 1.1.222 → 1.1.224

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 (166) hide show
  1. package/bin/agent/local/Agent.d.ts +1 -34
  2. package/bin/agent/local/Agent.d.ts.map +1 -1
  3. package/bin/agent/local/Agent.js +1 -44
  4. package/bin/agent/local/Agent.js.map +1 -1
  5. package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
  6. package/bin/agent/local/services/AgentAssemblyService.js +35 -2
  7. package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
  8. package/bin/agent/local/services/AgentSessions.d.ts +6 -0
  9. package/bin/agent/local/services/AgentSessions.d.ts.map +1 -1
  10. package/bin/agent/local/services/AgentSessions.js +42 -0
  11. package/bin/agent/local/services/AgentSessions.js.map +1 -1
  12. package/bin/agent/remote/RemoteAgent.d.ts +1 -35
  13. package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
  14. package/bin/agent/remote/RemoteAgent.js +1 -37
  15. package/bin/agent/remote/RemoteAgent.js.map +1 -1
  16. package/bin/agent/remote/RemoteSession.d.ts +24 -45
  17. package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
  18. package/bin/agent/remote/RemoteSession.js +74 -121
  19. package/bin/agent/remote/RemoteSession.js.map +1 -1
  20. package/bin/agent/remote/RemoteTransport.d.ts +11 -27
  21. package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
  22. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +7 -21
  23. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
  24. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +11 -47
  25. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
  26. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +7 -20
  27. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
  28. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +8 -17
  29. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
  30. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +2 -2
  31. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  32. package/bin/executor/types/SessionHistoryPaths.d.ts +1 -1
  33. package/bin/index.d.ts +3 -3
  34. package/bin/index.d.ts.map +1 -1
  35. package/bin/index.js +1 -1
  36. package/bin/index.js.map +1 -1
  37. package/bin/rpc/Client.d.ts +7 -36
  38. package/bin/rpc/Client.d.ts.map +1 -1
  39. package/bin/rpc/Client.js +28 -78
  40. package/bin/rpc/Client.js.map +1 -1
  41. package/bin/session/Session.d.ts +16 -8
  42. package/bin/session/Session.d.ts.map +1 -1
  43. package/bin/session/Session.js +66 -21
  44. package/bin/session/Session.js.map +1 -1
  45. package/bin/session/browse/Browse.d.ts.map +1 -1
  46. package/bin/session/browse/Browse.js +49 -18
  47. package/bin/session/browse/Browse.js.map +1 -1
  48. package/bin/session/recorder/JsonlSessionMessageStore.d.ts +30 -24
  49. package/bin/session/recorder/JsonlSessionMessageStore.d.ts.map +1 -1
  50. package/bin/session/recorder/JsonlSessionMessageStore.js +163 -59
  51. package/bin/session/recorder/JsonlSessionMessageStore.js.map +1 -1
  52. package/bin/session/recorder/SessionMessageCodec.d.ts.map +1 -1
  53. package/bin/session/recorder/SessionMessageCodec.js +6 -1
  54. package/bin/session/recorder/SessionMessageCodec.js.map +1 -1
  55. package/bin/session/recorder/SessionRecorder.d.ts +20 -11
  56. package/bin/session/recorder/SessionRecorder.d.ts.map +1 -1
  57. package/bin/session/recorder/SessionRecorder.js +148 -103
  58. package/bin/session/recorder/SessionRecorder.js.map +1 -1
  59. package/bin/session/recorder/SessionRecorderCompaction.d.ts.map +1 -1
  60. package/bin/session/recorder/SessionRecorderCompaction.js +1 -0
  61. package/bin/session/recorder/SessionRecorderCompaction.js.map +1 -1
  62. package/bin/session/recorder/SessionRecorderHistoryStore.d.ts +5 -5
  63. package/bin/session/recorder/SessionRecorderHistoryStore.d.ts.map +1 -1
  64. package/bin/session/recorder/SessionRecorderHistoryStore.js +5 -5
  65. package/bin/session/recorder/SessionRecorderHistoryStore.js.map +1 -1
  66. package/bin/session/runtime/SessionEventHub.d.ts +12 -5
  67. package/bin/session/runtime/SessionEventHub.d.ts.map +1 -1
  68. package/bin/session/runtime/SessionEventHub.js +11 -6
  69. package/bin/session/runtime/SessionEventHub.js.map +1 -1
  70. package/bin/session/runtime/SessionPromptRuntime.d.ts +2 -2
  71. package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
  72. package/bin/session/runtime/SessionPromptRuntime.js +35 -17
  73. package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
  74. package/bin/session/services/SessionStateService.d.ts +2 -2
  75. package/bin/session/services/SessionStateService.d.ts.map +1 -1
  76. package/bin/session/services/SessionStateService.js +6 -2
  77. package/bin/session/services/SessionStateService.js.map +1 -1
  78. package/bin/session/services/SessionTurnService.d.ts +2 -7
  79. package/bin/session/services/SessionTurnService.d.ts.map +1 -1
  80. package/bin/session/services/SessionTurnService.js +2 -8
  81. package/bin/session/services/SessionTurnService.js.map +1 -1
  82. package/bin/session/storage/Paths.d.ts +1 -1
  83. package/bin/session/storage/Paths.d.ts.map +1 -1
  84. package/bin/session/storage/Paths.js +2 -2
  85. package/bin/session/storage/Paths.js.map +1 -1
  86. package/bin/session/storage/RuntimeSessionPort.d.ts +3 -4
  87. package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
  88. package/bin/session/storage/RuntimeSessionPort.js +2 -2
  89. package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
  90. package/bin/types/agent/SessionActor.d.ts +11 -7
  91. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  92. package/bin/types/rpc/RpcProtocol.d.ts +35 -62
  93. package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
  94. package/bin/types/runtime/agent/AgentContext.d.ts +4 -4
  95. package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
  96. package/bin/types/runtime/agent/AgentContext.js.map +1 -1
  97. package/bin/types/session/SessionApproval.d.ts +97 -0
  98. package/bin/types/session/SessionApproval.d.ts.map +1 -0
  99. package/bin/types/session/SessionApproval.js +7 -0
  100. package/bin/types/session/SessionApproval.js.map +1 -0
  101. package/bin/types/session/SessionMessage.d.ts +10 -4
  102. package/bin/types/session/SessionMessage.d.ts.map +1 -1
  103. package/bin/types/session/SessionMutation.d.ts +116 -0
  104. package/bin/types/session/SessionMutation.d.ts.map +1 -0
  105. package/bin/types/session/SessionMutation.js +19 -0
  106. package/bin/types/session/SessionMutation.js.map +1 -0
  107. package/bin/types/session/SessionOptions.d.ts +9 -0
  108. package/bin/types/session/SessionOptions.d.ts.map +1 -1
  109. package/package.json +3 -3
  110. package/scripts/remote-session-reconnect.test.mjs +7 -3
  111. package/scripts/session-history-inflight.test.mjs +2 -2
  112. package/scripts/session-prompt-runtime.test.mjs +3 -3
  113. package/scripts/session-recorder.test.mjs +100 -146
  114. package/src/agent/local/Agent.ts +1 -55
  115. package/src/agent/local/services/AgentAssemblyService.ts +39 -3
  116. package/src/agent/local/services/AgentSessions.ts +47 -0
  117. package/src/agent/remote/RemoteAgent.ts +1 -54
  118. package/src/agent/remote/RemoteSession.ts +105 -163
  119. package/src/agent/remote/RemoteTransport.ts +23 -34
  120. package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +33 -90
  121. package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +22 -39
  122. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +2 -2
  123. package/src/executor/types/SessionHistoryPaths.ts +1 -1
  124. package/src/index.ts +20 -12
  125. package/src/rpc/Client.ts +48 -106
  126. package/src/session/Session.ts +91 -34
  127. package/src/session/browse/Browse.ts +51 -22
  128. package/src/session/recorder/JsonlSessionMessageStore.ts +170 -86
  129. package/src/session/recorder/SessionMessageCodec.ts +6 -1
  130. package/src/session/recorder/SessionRecorder.ts +183 -124
  131. package/src/session/recorder/SessionRecorderCompaction.ts +1 -0
  132. package/src/session/recorder/SessionRecorderHistoryStore.ts +5 -5
  133. package/src/session/runtime/SessionEventHub.ts +25 -12
  134. package/src/session/runtime/SessionPromptRuntime.ts +37 -19
  135. package/src/session/services/SessionStateService.ts +8 -6
  136. package/src/session/services/SessionTurnService.ts +3 -14
  137. package/src/session/storage/Paths.ts +2 -2
  138. package/src/session/storage/RuntimeSessionPort.ts +8 -11
  139. package/src/types/agent/SessionActor.ts +23 -20
  140. package/src/types/rpc/RpcProtocol.ts +34 -71
  141. package/src/types/runtime/agent/AgentContext.ts +7 -11
  142. package/src/types/session/SessionApproval.ts +108 -0
  143. package/src/types/session/SessionMessage.ts +10 -4
  144. package/src/types/session/SessionMutation.ts +141 -0
  145. package/src/types/session/SessionOptions.ts +25 -0
  146. package/tsconfig.tsbuildinfo +1 -1
  147. package/bin/session/recorder/SessionMessageReducer.d.ts +0 -12
  148. package/bin/session/recorder/SessionMessageReducer.d.ts.map +0 -1
  149. package/bin/session/recorder/SessionMessageReducer.js +0 -109
  150. package/bin/session/recorder/SessionMessageReducer.js.map +0 -1
  151. package/bin/session/runtime/SessionMessageEventHub.d.ts +0 -15
  152. package/bin/session/runtime/SessionMessageEventHub.d.ts.map +0 -1
  153. package/bin/session/runtime/SessionMessageEventHub.js +0 -28
  154. package/bin/session/runtime/SessionMessageEventHub.js.map +0 -1
  155. package/bin/types/sdk/AgentSessionEvent.d.ts +0 -303
  156. package/bin/types/sdk/AgentSessionEvent.d.ts.map +0 -1
  157. package/bin/types/sdk/AgentSessionEvent.js +0 -9
  158. package/bin/types/sdk/AgentSessionEvent.js.map +0 -1
  159. package/bin/types/session/SessionMessageMutation.d.ts +0 -92
  160. package/bin/types/session/SessionMessageMutation.d.ts.map +0 -1
  161. package/bin/types/session/SessionMessageMutation.js +0 -21
  162. package/bin/types/session/SessionMessageMutation.js.map +0 -1
  163. package/src/session/recorder/SessionMessageReducer.ts +0 -155
  164. package/src/session/runtime/SessionMessageEventHub.ts +0 -35
  165. package/src/types/sdk/AgentSessionEvent.ts +0 -372
  166. package/src/types/session/SessionMessageMutation.ts +0 -121
@@ -13,7 +13,7 @@ import type {
13
13
  SessionRecordV1,
14
14
  SessionMessageRecordV1,
15
15
  } from "@/executor/types/SessionRecords.js";
16
- import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
16
+ import type { SessionMutation } from "@/types/session/SessionMutation.js";
17
17
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
18
18
  import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
19
19
  import type {
@@ -89,7 +89,7 @@ export interface SessionPromptRuntimeOptions {
89
89
  /**
90
90
  * 广播 session 事件。
91
91
  */
92
- publish: (event: AgentSessionEvent) => void;
92
+ publish: (mutation: SessionMutation) => void;
93
93
 
94
94
  /**
95
95
  * 构造并持久化一条 user 消息。
@@ -226,8 +226,13 @@ export class SessionPromptRuntime {
226
226
  const activeTurn = createActiveTurnState(turnId);
227
227
  this.activeTurn = activeTurn;
228
228
  this.publish({
229
- type: "turn-start",
230
- turnId,
229
+ mutation_id: nanoid(),
230
+ variant: "turn",
231
+ type: "start",
232
+ session_id: this.sessionId,
233
+ turn_id: turnId,
234
+ status: "running",
235
+ created_at: Date.now(),
231
236
  });
232
237
  current.deferredHandle.resolve(createTurnHandle(activeTurn));
233
238
 
@@ -255,10 +260,14 @@ export class SessionPromptRuntime {
255
260
  };
256
261
  activeTurn.result = finalResult;
257
262
  this.publish({
258
- type: "turn-finish",
259
- turnId,
263
+ mutation_id: nanoid(),
264
+ variant: "turn",
265
+ type: "finish",
266
+ session_id: this.sessionId,
267
+ turn_id: turnId,
268
+ status: stopped ? "stopped" : finalResult.success ? "completed" : "failed",
269
+ created_at: Date.now(),
260
270
  text: finalResult.text,
261
- success: finalResult.success,
262
271
  ...(finalResult.error ? { error: finalResult.error } : {}),
263
272
  });
264
273
  activeTurn.deferredFinished.resolve(finalResult);
@@ -286,16 +295,16 @@ export class SessionPromptRuntime {
286
295
  } catch {
287
296
  // Error Message 写入失败不能阻止 turn handle 收口。
288
297
  }
289
- this.publish({
290
- type: "error",
291
- message,
292
- });
293
298
  }
294
299
  this.publish({
295
- type: "turn-finish",
296
- turnId,
300
+ mutation_id: nanoid(),
301
+ variant: "turn",
302
+ type: "finish",
303
+ session_id: this.sessionId,
304
+ turn_id: turnId,
305
+ status: activeTurn.abortController.signal.aborted ? "stopped" : "failed",
306
+ created_at: Date.now(),
297
307
  text: "",
298
- success: false,
299
308
  error: message,
300
309
  });
301
310
  activeTurn.deferredFinished.resolve(finalResult);
@@ -326,14 +335,23 @@ export class SessionPromptRuntime {
326
335
  cancelledTurn.result = finalResult;
327
336
  cancelledTurn.deferredFinished.resolve(finalResult);
328
337
  this.publish({
329
- type: "turn-start",
330
- turnId,
338
+ mutation_id: nanoid(),
339
+ variant: "turn",
340
+ type: "start",
341
+ session_id: this.sessionId,
342
+ turn_id: turnId,
343
+ status: "running",
344
+ created_at: Date.now(),
331
345
  });
332
346
  this.publish({
333
- type: "turn-finish",
334
- turnId,
347
+ mutation_id: nanoid(),
348
+ variant: "turn",
349
+ type: "finish",
350
+ session_id: this.sessionId,
351
+ turn_id: turnId,
352
+ status: "failed",
353
+ created_at: Date.now(),
335
354
  text: "",
336
- success: false,
337
355
  error: QUEUED_PROMPT_CANCELLED_MESSAGE,
338
356
  });
339
357
  item.deferredHandle.resolve(createTurnHandle(cancelledTurn));
@@ -26,9 +26,7 @@ import type {
26
26
  AgentSessionConfigSnapshot,
27
27
  AgentSessionSetInput,
28
28
  } from "@/types/agent/SessionTypes.js";
29
- import type {
30
- AgentSessionEvent,
31
- } from "@/types/sdk/AgentSessionEvent.js";
29
+ import type { SessionMutation } from "@/types/session/SessionMutation.js";
32
30
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
33
31
  import type {
34
32
  SessionActionRecordInputV1,
@@ -102,7 +100,7 @@ type SessionStateServiceOptions = {
102
100
  /**
103
101
  * 发布 session 事件。
104
102
  */
105
- publish_event: (event: AgentSessionEvent) => void;
103
+ publish_event: (mutation: SessionMutation) => void;
106
104
  };
107
105
 
108
106
  type SessionSetOptions = {
@@ -372,6 +370,7 @@ export class SessionStateService {
372
370
  ? from_ui_assistant_parts(params.message.parts)
373
371
  : [{
374
372
  part_id: `external-assistant-text:${Date.now()}`,
373
+ sequence: 1,
375
374
  type: "text" as const,
376
375
  text: String(params.fallbackText || "").trim(),
377
376
  state: "done" as const,
@@ -442,8 +441,11 @@ export class SessionStateService {
442
441
  const next_title = String(next_metadata.title || "").trim();
443
442
  if (!next_title || next_title === before_title) return;
444
443
  this.publish_event({
445
- type: "session-title",
446
- sessionId: this.session_id,
444
+ mutation_id: generateId(),
445
+ variant: "session",
446
+ type: "title",
447
+ session_id: this.session_id,
448
+ created_at: Date.now(),
447
449
  title: next_title,
448
450
  });
449
451
  }
@@ -9,11 +9,7 @@
9
9
 
10
10
  import { extractTextFromParts, extractTextFromUiMessage } from "@/executor/messages/UIMessageTransformer.js";
11
11
  import type { Executor } from "@executor/Executor.js";
12
- import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
13
- import type {
14
- AgentSessionSubscriber,
15
- AgentSessionUnsubscribe,
16
- } from "@/types/sdk/AgentSessionEvent.js";
12
+ import type { SessionMutation } from "@/types/session/SessionMutation.js";
17
13
  import { isAgentSessionPromptInputEmpty } from "@/types/sdk/AgentSessionPrompt.js";
18
14
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
19
15
  import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
@@ -118,15 +114,8 @@ export class SessionTurnService {
118
114
  /**
119
115
  * 发布一条 session 事件。
120
116
  */
121
- publish_event(event: AgentSessionEvent): void {
122
- this.event_hub.publish(event);
123
- }
124
-
125
- /**
126
- * 订阅当前 session 的未来事件。
127
- */
128
- subscribe(subscriber: AgentSessionSubscriber): AgentSessionUnsubscribe {
129
- return this.event_hub.subscribe(subscriber);
117
+ publish_event(mutation: SessionMutation): void {
118
+ this.event_hub.publish(mutation);
130
119
  }
131
120
 
132
121
  /**
@@ -212,13 +212,13 @@ export function getSdkAgentSessionArchiveFilePath(
212
212
  * - step / tool 过程会持续重写这个文件,避免中途中断后过程完全丢失。
213
213
  * - 完成后再把最终 assistant 合并进 `messages.jsonl`,并清理该文件。
214
214
  */
215
- export function getSdkAgentSessionInflightPath(
215
+ export function getSdkAgentSessionAssistantMessagePath(
216
216
  projectRoot: string,
217
217
  agentId: string,
218
218
  sessionId: string,
219
219
  ): string {
220
220
  return path.join(
221
221
  getSdkAgentSessionMessagesDirPath(projectRoot, agentId, sessionId),
222
- "inflight.json",
222
+ "assistant_message.json",
223
223
  );
224
224
  }
@@ -11,12 +11,9 @@ import type { SessionHistoryStore } from "@/executor/store/history/SessionHistor
11
11
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
12
12
  import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
13
13
  import type {
14
- AgentSessionEvent,
15
- } from "@/types/sdk/AgentSessionEvent.js";
16
- import type {
17
- SessionMessageMutationSubscriber,
18
- SessionMessageMutationUnsubscribe,
19
- } from "@/types/session/SessionMessageMutation.js";
14
+ SessionMutationSubscriber,
15
+ SessionMutationUnsubscribe,
16
+ } from "@/types/session/SessionMutation.js";
20
17
  import type { AgentSessionTurnHandle } from "@/types/sdk/AgentSessionTurn.js";
21
18
 
22
19
  /**
@@ -43,12 +40,12 @@ export interface CreateRuntimeSessionPortParams {
43
40
  * 订阅当前 session 的 future 事件。
44
41
  */
45
42
  subscribe: (
46
- subscriber: SessionMessageMutationSubscriber,
47
- ) => SessionMessageMutationUnsubscribe;
43
+ subscriber: SessionMutationSubscriber,
44
+ ) => SessionMutationUnsubscribe;
48
45
  /**
49
46
  * 发布一条 session runtime 事件。
50
47
  */
51
- publishEvent: (event: AgentSessionEvent) => void;
48
+ publishEvent: SessionPort["publishEvent"];
52
49
  /**
53
50
  * 追加 user 消息到底层历史。
54
51
  */
@@ -92,8 +89,8 @@ export function createRuntimeSessionPort(
92
89
  subscribe: (subscriber) => {
93
90
  return params.subscribe(subscriber);
94
91
  },
95
- publishEvent: (event) => {
96
- params.publishEvent(event);
92
+ publishEvent: async (event) => {
93
+ await params.publishEvent(event);
97
94
  },
98
95
  append_user_message: async (messageParams) => {
99
96
  await params.append_user_message(messageParams);
@@ -22,15 +22,16 @@ import type {
22
22
  AgentSessionSystemSnapshot,
23
23
  } from "@/types/agent/SessionTypes.js";
24
24
  import type {
25
- AgentSessionSubscriber,
26
- AgentSessionUnsubscribe,
27
- } from "@/types/sdk/AgentSessionEvent.js";
25
+ SessionMutationSubscriber,
26
+ SessionMutationUnsubscribe,
27
+ } from "@/types/session/SessionMutation.js";
28
28
  import type {
29
- ListSessionMessageChangesInput,
30
- SessionMessageMutationPage,
31
- SessionMessageMutationSubscriber,
32
- SessionMessageMutationUnsubscribe,
33
- } from "@/types/session/SessionMessageMutation.js";
29
+ ResolveSessionApprovalInput,
30
+ SessionApproval,
31
+ SessionApprovalModeSnapshot,
32
+ SessionApprovalResult,
33
+ SetSessionApprovalModeInput,
34
+ } from "@/types/session/SessionApproval.js";
34
35
  import type {
35
36
  ListSessionMessagesInput,
36
37
  SessionMessagePage,
@@ -80,24 +81,26 @@ export interface AgentSessionActor {
80
81
 
81
82
  /** 订阅当前 session 的未来事件。 */
82
83
  subscribe(
83
- subscriber: SessionMessageMutationSubscriber,
84
- ): SessionMessageMutationUnsubscribe;
85
-
86
- /** 订阅远程 transport 使用的 Message 与 turn lifecycle 事件。 */
87
- subscribe_transport(
88
- subscriber: AgentSessionSubscriber,
89
- ): AgentSessionUnsubscribe;
84
+ subscriber: SessionMutationSubscriber,
85
+ ): SessionMutationUnsubscribe;
90
86
 
91
87
  /** 读取当前 session messages 分页。 */
92
88
  messages(input?: ListSessionMessagesInput): Promise<SessionMessagePage>;
93
89
 
94
- /** 读取指定 cursor 后的 Message Mutation。 */
95
- message_changes(
96
- input: ListSessionMessageChangesInput,
97
- ): Promise<SessionMessageMutationPage>;
98
-
99
90
  /** 读取当前 session 生效的 system 快照。 */
100
91
  system(): Promise<AgentSessionSystemSnapshot>;
92
+
93
+ /** 列出当前 Session 的 pending 工具审批。 */
94
+ approvals(): Promise<SessionApproval[]>;
95
+
96
+ /** 读取当前 Session 的工具审批模式。 */
97
+ approval_mode(): Promise<SessionApprovalModeSnapshot>;
98
+
99
+ /** 更新当前 Session 的工具审批模式。 */
100
+ set_approval_mode(input: SetSessionApprovalModeInput): Promise<SessionApprovalModeSnapshot>;
101
+
102
+ /** 处理当前 Session 的 pending 工具审批。 */
103
+ resolve_approval(input: ResolveSessionApprovalInput): Promise<SessionApprovalResult>;
101
104
  }
102
105
 
103
106
  /**
@@ -18,14 +18,16 @@ import type {
18
18
  AgentSessionSystemSnapshot,
19
19
  AgentSessionSetInput,
20
20
  } from "@/types/agent/SessionTypes.js";
21
- import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
21
+ import type { SessionMutation } from "@/types/session/SessionMutation.js";
22
+ import type {
23
+ ResolveSessionApprovalInput,
24
+ SetSessionApprovalModeInput,
25
+ } from "@/types/session/SessionApproval.js";
22
26
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
23
27
  import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
24
28
  import type { ListSessionMessagesInput } from "@/types/session/SessionMessage.js";
25
- import type { ListSessionMessageChangesInput } from "@/types/session/SessionMessageMutation.js";
26
29
  import type { JsonObject, JsonValue } from "@/types/common/Json.js";
27
30
  import type { PluginControlAction } from "@/types/plugin/PluginState.js";
28
- import type { ShellApprovalMode } from "@downcity/shell";
29
31
 
30
32
  /**
31
33
  * RPC 请求。
@@ -140,15 +142,34 @@ export type RpcRequest =
140
142
  | {
141
143
  /** 请求 id,用于匹配响应。 */
142
144
  id: string;
143
- /** 读取 session message mutations。 */
144
- method: "sdk.sessions.message_changes";
145
- /** changes 查询参数。 */
146
- params: {
147
- /** 目标 session id。 */
148
- sessionId: string;
149
- /** Mutation 增量参数。 */
150
- input: ListSessionMessageChangesInput;
151
- };
145
+ /** 列出指定 Session 的 pending 工具审批。 */
146
+ method: "sdk.sessions.approvals";
147
+ /** 目标 Session 参数。 */
148
+ params: { sessionId: string };
149
+ }
150
+ | {
151
+ /** 请求 id,用于匹配响应。 */
152
+ id: string;
153
+ /** 读取指定 Session 的工具审批模式。 */
154
+ method: "sdk.sessions.approvalMode";
155
+ /** 目标 Session 参数。 */
156
+ params: { sessionId: string };
157
+ }
158
+ | {
159
+ /** 请求 id,用于匹配响应。 */
160
+ id: string;
161
+ /** 更新指定 Session 的工具审批模式。 */
162
+ method: "sdk.sessions.setApprovalMode";
163
+ /** Session 与审批模式参数。 */
164
+ params: { sessionId: string; input: SetSessionApprovalModeInput };
165
+ }
166
+ | {
167
+ /** 请求 id,用于匹配响应。 */
168
+ id: string;
169
+ /** 处理指定 Session 的 pending 工具审批。 */
170
+ method: "sdk.sessions.resolveApproval";
171
+ /** Session 与审批决策参数。 */
172
+ params: { sessionId: string; input: ResolveSessionApprovalInput };
152
173
  }
153
174
  | {
154
175
  /** 请求 id,用于匹配响应。 */
@@ -302,64 +323,6 @@ export type RpcRequest =
302
323
  /** action payload。 */
303
324
  payload?: JsonValue;
304
325
  };
305
- }
306
- | {
307
- /** 请求 id,用于匹配响应。 */
308
- id: string;
309
- /** 列出 shell approvals。 */
310
- method: "internal.shell.approvals";
311
- }
312
- | {
313
- /** 请求 id,用于匹配响应。 */
314
- id: string;
315
- /** 列出 shell approval 模式。 */
316
- method: "internal.shell.approvalModes";
317
- }
318
- | {
319
- /** 请求 id,用于匹配响应。 */
320
- id: string;
321
- /** 读取 shell approval 模式。 */
322
- method: "internal.shell.approvalMode";
323
- /** session 参数。 */
324
- params: {
325
- /** session id。 */
326
- sessionId: string;
327
- };
328
- }
329
- | {
330
- /** 请求 id,用于匹配响应。 */
331
- id: string;
332
- /** 设置 shell approval 模式。 */
333
- method: "internal.shell.setApprovalMode";
334
- /** session 模式参数。 */
335
- params: {
336
- /** session id。 */
337
- sessionId: string;
338
- /** approval 模式。 */
339
- mode: ShellApprovalMode;
340
- };
341
- }
342
- | {
343
- /** 请求 id,用于匹配响应。 */
344
- id: string;
345
- /** 批准 shell approval。 */
346
- method: "internal.shell.approve";
347
- /** approval 参数。 */
348
- params: {
349
- /** approval id。 */
350
- approvalId: string;
351
- };
352
- }
353
- | {
354
- /** 请求 id,用于匹配响应。 */
355
- id: string;
356
- /** 拒绝 shell approval。 */
357
- method: "internal.shell.deny";
358
- /** approval 参数。 */
359
- params: {
360
- /** approval id。 */
361
- approvalId: string;
362
- };
363
326
  };
364
327
 
365
328
  /**
@@ -410,7 +373,7 @@ export interface RpcEventFrame {
410
373
  /** 当前订阅 id。 */
411
374
  subscriptionId: string;
412
375
  /** session 事件。 */
413
- event: AgentSessionEvent;
376
+ event: SessionMutation;
414
377
  }
415
378
 
416
379
  /**
@@ -29,14 +29,10 @@ import type { SessionHistoryStore } from "@/executor/store/history/SessionHistor
29
29
  import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
30
30
  import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
31
31
  import type {
32
- AgentSessionEvent,
33
- AgentSessionSubscriber,
34
- AgentSessionUnsubscribe,
35
- } from "@/types/sdk/AgentSessionEvent.js";
36
- import type {
37
- SessionMessageMutationSubscriber,
38
- SessionMessageMutationUnsubscribe,
39
- } from "@/types/session/SessionMessageMutation.js";
32
+ SessionMutationSubscriber,
33
+ SessionMutationUnsubscribe,
34
+ } from "@/types/session/SessionMutation.js";
35
+ import type { SessionApprovalRuntimeEvent } from "@/types/session/SessionApproval.js";
40
36
  import type { AgentSessionTurnHandle } from "@/types/sdk/AgentSessionTurn.js";
41
37
 
42
38
  /**
@@ -140,8 +136,8 @@ export interface SessionPort {
140
136
  * - 当前 Message snapshot 通过公开 SDK `session.messages()` 读取。
141
137
  */
142
138
  subscribe(
143
- subscriber: SessionMessageMutationSubscriber,
144
- ): SessionMessageMutationUnsubscribe;
139
+ subscriber: SessionMutationSubscriber,
140
+ ): SessionMutationUnsubscribe;
145
141
  /**
146
142
  * 发布一条 session runtime 事件。
147
143
  *
@@ -149,7 +145,7 @@ export interface SessionPort {
149
145
  * - plugin runtime 用它把审批、外部进度等非模型 chunk 事件推送给订阅方。
150
146
  * - 历史消息持久化仍由 append_user_message / append_assistant_message 负责。
151
147
  */
152
- publishEvent(event: AgentSessionEvent): void;
148
+ publishEvent(event: SessionApprovalRuntimeEvent): Promise<void>;
153
149
  /**
154
150
  * 追加一条 user 消息。
155
151
  */
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Session 级工具审批类型。
3
+ *
4
+ * 审批由具体工具运行时执行,但归属、查询和决策能力统一通过 Session 暴露。
5
+ */
6
+
7
+ /** Session 工具审批的最终人工决策。 */
8
+ export type SessionApprovalDecision = "approved" | "denied";
9
+
10
+ /** Session 工具审批模式。 */
11
+ export type SessionApprovalMode = "ask" | "always-allow";
12
+
13
+ /** 当前 Session 的待审批工具请求。 */
14
+ export interface SessionApproval {
15
+ /** 当前审批请求的稳定唯一标识。 */
16
+ approval_id: string;
17
+ /** 当前审批所属 Session 标识。 */
18
+ session_id: string;
19
+ /** 当前审批所属 Turn 标识。 */
20
+ turn_id?: string;
21
+ /** 当前审批对应的工具调用标识。 */
22
+ tool_call_id?: string;
23
+ /** 当前审批对应的工具注册名称。 */
24
+ tool_name: string;
25
+ /** 请求执行的命令或输入文本。 */
26
+ command: string;
27
+ /** 当前工具执行工作目录。 */
28
+ cwd: string;
29
+ /** 工具申请 unrestricted 权限的原因。 */
30
+ reason: string;
31
+ /** 当前审批对应的工具操作类型。 */
32
+ operation: "exec" | "start" | "write";
33
+ /** 当前审批创建时间戳(ms)。 */
34
+ created_at: number;
35
+ }
36
+
37
+ /** 提交 Session 工具审批决策的参数。 */
38
+ export interface ResolveSessionApprovalInput {
39
+ /** 需要处理的审批请求标识。 */
40
+ approval_id: string;
41
+ /** 对当前审批请求作出的最终决定。 */
42
+ decision: SessionApprovalDecision;
43
+ }
44
+
45
+ /** Session 工具审批决策结果。 */
46
+ export interface SessionApprovalResult {
47
+ /** 是否成功命中并处理 pending 审批。 */
48
+ success: boolean;
49
+ /** 已尝试处理的审批请求标识。 */
50
+ approval_id: string;
51
+ /** 已提交的最终审批决定。 */
52
+ decision: SessionApprovalDecision;
53
+ }
54
+
55
+ /** 当前 Session 的审批模式快照。 */
56
+ export interface SessionApprovalModeSnapshot {
57
+ /** 当前审批模式所属 Session 标识。 */
58
+ session_id: string;
59
+ /** 当前 Session 生效的审批模式。 */
60
+ mode: SessionApprovalMode;
61
+ }
62
+
63
+ /** 更新当前 Session 审批模式的参数。 */
64
+ export interface SetSessionApprovalModeInput {
65
+ /** 需要设置的新审批模式。 */
66
+ mode: SessionApprovalMode;
67
+ }
68
+
69
+ /** Shell Runtime 发给 Session 的工具审批请求。 */
70
+ export interface SessionToolApprovalRequest {
71
+ /** Runtime 事件类型固定为工具审批请求。 */
72
+ type: "tool-approval-request";
73
+ /** 当前审批所属 Turn 标识。 */
74
+ turn_id: string;
75
+ /** 当前审批对应的工具调用标识。 */
76
+ tool_call_id: string;
77
+ /** 当前审批对应的工具注册名称。 */
78
+ tool_name: string;
79
+ /** 当前审批请求的稳定唯一标识。 */
80
+ approval_id: string;
81
+ /** 请求执行的命令或输入文本。 */
82
+ command: string;
83
+ /** 当前工具执行工作目录。 */
84
+ cwd: string;
85
+ /** 工具申请 unrestricted 权限的原因。 */
86
+ reason: string;
87
+ /** 当前审批对应的工具操作类型。 */
88
+ operation: "exec" | "start" | "write";
89
+ }
90
+
91
+ /** Shell Runtime 发给 Session 的工具审批结果。 */
92
+ export interface SessionToolApprovalResult {
93
+ /** Runtime 事件类型固定为工具审批结果。 */
94
+ type: "tool-approval-result";
95
+ /** 当前审批所属 Turn 标识。 */
96
+ turn_id: string;
97
+ /** 当前审批对应的工具调用标识。 */
98
+ tool_call_id: string;
99
+ /** 当前审批请求的稳定唯一标识。 */
100
+ approval_id: string;
101
+ /** 当前审批的最终结果,超时由 Runtime 标记为 expired。 */
102
+ decision: SessionApprovalDecision | "expired";
103
+ }
104
+
105
+ /** Session 内部接收的工具审批 Runtime 事件。 */
106
+ export type SessionApprovalRuntimeEvent =
107
+ | SessionToolApprovalRequest
108
+ | SessionToolApprovalResult;
@@ -30,7 +30,7 @@ export interface SessionMessageBase {
30
30
  turn_id?: string;
31
31
  /** Message 的线性位置;创建后永远不变。 */
32
32
  sequence: number;
33
- /** Message 版本号;每次 Mutation 后递增。 */
33
+ /** Message 版本号;每次对外发布的消息变化后递增。 */
34
34
  revision: number;
35
35
  /** 当前 Message 是否默认对用户可见。 */
36
36
  visibility: SessionMessageVisibility;
@@ -100,6 +100,8 @@ export interface SessionUserMessage extends SessionMessageBase {
100
100
  export interface SessionAssistantTextPart {
101
101
  /** Assistant Message 内稳定的 part 标识。 */
102
102
  part_id: string;
103
+ /** Assistant Part 在当前 Message 中的不可变线性顺序,从 1 开始。 */
104
+ sequence: number;
103
105
  /** part 是可见文本或推理文本。 */
104
106
  type: "text" | "reasoning";
105
107
  /** 当前已经累计的完整文本。 */
@@ -112,6 +114,8 @@ export interface SessionAssistantTextPart {
112
114
  export interface SessionAssistantToolPart {
113
115
  /** Assistant Message 内稳定的 part 标识。 */
114
116
  part_id: string;
117
+ /** Assistant Part 在当前 Message 中的不可变线性顺序,从 1 开始。 */
118
+ sequence: number;
115
119
  /** part 类型固定为 tool。 */
116
120
  type: "tool";
117
121
  /** 模型工具调用稳定标识。 */
@@ -119,7 +123,7 @@ export interface SessionAssistantToolPart {
119
123
  /** 工具注册名称。 */
120
124
  tool_name: string;
121
125
  /** 工具当前生命周期状态。 */
122
- state: "input-streaming" | "approval-required" | "running" | "completed" | "failed";
126
+ state: "input-streaming" | "ready" | "approval-required" | "running" | "completed" | "failed";
123
127
  /** 流式接收中的参数原文。 */
124
128
  input_text?: string;
125
129
  /** 收敛后的结构化输入。 */
@@ -136,6 +140,8 @@ export interface SessionAssistantToolPart {
136
140
  export interface SessionAssistantFilePart {
137
141
  /** Assistant Message 内稳定的 part 标识。 */
138
142
  part_id: string;
143
+ /** Assistant Part 在当前 Message 中的不可变线性顺序,从 1 开始。 */
144
+ sequence: number;
139
145
  /** part 类型固定为 file。 */
140
146
  type: "file";
141
147
  /** 文件 MIME 类型。 */
@@ -150,6 +156,8 @@ export interface SessionAssistantFilePart {
150
156
  export interface SessionAssistantDataPart {
151
157
  /** Assistant Message 内稳定的 part 标识。 */
152
158
  part_id: string;
159
+ /** Assistant Part 在当前 Message 中的不可变线性顺序,从 1 开始。 */
160
+ sequence: number;
153
161
  /** part 类型固定为 data。 */
154
162
  type: "data";
155
163
  /** 对应 AI SDK 的 data-* 类型名称。 */
@@ -242,6 +250,4 @@ export interface SessionMessagePage {
242
250
  next_cursor?: string;
243
251
  /** 是否仍有更多 Message。 */
244
252
  has_more: boolean;
245
- /** 当前 snapshot 已包含的最大 commit_sequence。 */
246
- latest_commit_sequence: number;
247
253
  }