@downcity/agent 1.1.11 → 1.1.13

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 (131) hide show
  1. package/bin/index.d.ts +3 -3
  2. package/bin/index.d.ts.map +1 -1
  3. package/bin/index.js +2 -2
  4. package/bin/index.js.map +1 -1
  5. package/bin/runtime/AgentRuntime.d.ts +2 -2
  6. package/bin/runtime/AgentRuntime.d.ts.map +1 -1
  7. package/bin/runtime/AgentRuntime.js +7 -12
  8. package/bin/runtime/AgentRuntime.js.map +1 -1
  9. package/bin/runtime/AgentRuntimeTypes.d.ts +3 -3
  10. package/bin/runtime/AgentRuntimeTypes.d.ts.map +1 -1
  11. package/bin/sdk/Agent.d.ts +13 -8
  12. package/bin/sdk/Agent.d.ts.map +1 -1
  13. package/bin/sdk/Agent.js +62 -18
  14. package/bin/sdk/Agent.js.map +1 -1
  15. package/bin/sdk/AgentSdkTypes.d.ts +95 -0
  16. package/bin/sdk/AgentSdkTypes.d.ts.map +1 -1
  17. package/bin/sdk/RemoteAgent.d.ts +3 -3
  18. package/bin/sdk/RemoteAgent.d.ts.map +1 -1
  19. package/bin/sdk/RemoteAgent.js +5 -2
  20. package/bin/sdk/RemoteAgent.js.map +1 -1
  21. package/bin/sdk/Session.d.ts +21 -19
  22. package/bin/sdk/Session.d.ts.map +1 -1
  23. package/bin/sdk/Session.js +79 -69
  24. package/bin/sdk/Session.js.map +1 -1
  25. package/bin/sdk/SessionMetadata.d.ts +7 -3
  26. package/bin/sdk/SessionMetadata.d.ts.map +1 -1
  27. package/bin/sdk/SessionMetadata.js +21 -5
  28. package/bin/sdk/SessionMetadata.js.map +1 -1
  29. package/bin/sdk/SessionPersistence.d.ts +6 -6
  30. package/bin/sdk/SessionPersistence.d.ts.map +1 -1
  31. package/bin/sdk/SessionPersistence.js +7 -7
  32. package/bin/sdk/SessionPersistence.js.map +1 -1
  33. package/bin/sdk/SessionServicePort.d.ts +5 -5
  34. package/bin/sdk/SessionServicePort.d.ts.map +1 -1
  35. package/bin/sdk/SessionServicePort.js +9 -9
  36. package/bin/sdk/SessionServicePort.js.map +1 -1
  37. package/bin/sdk/SessionSystemBuilder.d.ts +106 -0
  38. package/bin/sdk/SessionSystemBuilder.d.ts.map +1 -0
  39. package/bin/sdk/SessionSystemBuilder.js +150 -0
  40. package/bin/sdk/SessionSystemBuilder.js.map +1 -0
  41. package/bin/service/builtins/chat/runtime/ChatSession.d.ts +27 -8
  42. package/bin/service/builtins/chat/runtime/ChatSession.d.ts.map +1 -1
  43. package/bin/service/builtins/chat/runtime/ChatSession.js +9 -4
  44. package/bin/service/builtins/chat/runtime/ChatSession.js.map +1 -1
  45. package/bin/service/builtins/task/runtime/Runner.d.ts +1 -1
  46. package/bin/service/builtins/task/runtime/Runner.js +1 -1
  47. package/bin/service/builtins/task/runtime/TaskRunnerSession.d.ts +2 -2
  48. package/bin/service/builtins/task/runtime/TaskRunnerSession.js +4 -4
  49. package/bin/service/builtins/task/runtime/TaskRunnerSession.js.map +1 -1
  50. package/bin/service/builtins/task/runtime/TaskRunnerTypes.d.ts +1 -1
  51. package/bin/session/{Session.d.ts → Executor.d.ts} +54 -17
  52. package/bin/session/Executor.d.ts.map +1 -0
  53. package/bin/session/{Session.js → Executor.js} +60 -23
  54. package/bin/session/Executor.js.map +1 -0
  55. package/bin/session/composer/SessionComposer.d.ts +1 -1
  56. package/bin/session/composer/SessionComposer.js +1 -1
  57. package/bin/session/composer/compaction/SessionCompactionComposer.d.ts +2 -2
  58. package/bin/session/composer/execution/LocalSessionExecutionComposer.d.ts +1 -1
  59. package/bin/session/composer/execution/LocalSessionExecutionComposer.js +1 -1
  60. package/bin/session/composer/execution/SessionExecutionComposer.d.ts +1 -1
  61. package/bin/session/composer/history/SessionHistoryComposer.d.ts +1 -1
  62. package/bin/session/composer/system/SessionSystemComposer.d.ts +1 -1
  63. package/bin/session/composer/system/SessionSystemComposer.js +1 -1
  64. package/bin/session/executors/local/{LocalSessionCore.d.ts → Runner.d.ts} +10 -10
  65. package/bin/session/executors/local/Runner.d.ts.map +1 -0
  66. package/bin/session/executors/local/{LocalSessionCore.js → Runner.js} +11 -11
  67. package/bin/session/executors/local/Runner.js.map +1 -0
  68. package/bin/session/executors/local/SessionExecutionError.d.ts +1 -1
  69. package/bin/session/executors/local/SessionExecutionError.js +1 -1
  70. package/bin/session/executors/local/SessionLoopDecision.d.ts +3 -3
  71. package/bin/session/executors/local/SessionLoopDecision.js +3 -3
  72. package/bin/session/executors/local/SessionModelMessageState.d.ts +2 -2
  73. package/bin/session/executors/local/SessionModelMessageState.js +2 -2
  74. package/bin/session/executors/local/SessionSignals.d.ts +3 -3
  75. package/bin/session/executors/local/SessionSignals.js +3 -3
  76. package/bin/session/executors/local/SessionToolLoopRunner.d.ts +1 -1
  77. package/bin/session/executors/local/SessionToolLoopRunner.js +2 -2
  78. package/bin/session/executors/local/SessionToolLoopRunner.js.map +1 -1
  79. package/bin/session/types/SessionHistoryMeta.d.ts +2 -0
  80. package/bin/session/types/SessionHistoryMeta.d.ts.map +1 -1
  81. package/bin/session/types/SessionLoop.d.ts +1 -1
  82. package/bin/session/types/SessionLoop.js +1 -1
  83. package/bin/session/types/SessionRun.d.ts +2 -2
  84. package/bin/session/types/SessionRun.js +1 -1
  85. package/package.json +1 -1
  86. package/src/index.ts +6 -2
  87. package/src/runtime/AgentRuntime.ts +7 -17
  88. package/src/runtime/AgentRuntimeTypes.ts +3 -3
  89. package/src/sdk/Agent.ts +75 -23
  90. package/src/sdk/AgentSdkTypes.ts +113 -0
  91. package/src/sdk/RemoteAgent.ts +10 -4
  92. package/src/sdk/Session.ts +100 -85
  93. package/src/sdk/SessionMetadata.ts +23 -5
  94. package/src/sdk/SessionPersistence.ts +13 -13
  95. package/src/sdk/SessionServicePort.ts +13 -13
  96. package/src/sdk/SessionSystemBuilder.ts +261 -0
  97. package/src/service/builtins/chat/runtime/ChatSession.ts +37 -13
  98. package/src/service/builtins/task/runtime/Runner.ts +1 -1
  99. package/src/service/builtins/task/runtime/TaskRunnerSession.ts +4 -4
  100. package/src/service/builtins/task/runtime/TaskRunnerTypes.ts +1 -1
  101. package/src/session/{Session.ts → Executor.ts} +96 -26
  102. package/src/session/composer/SessionComposer.ts +1 -1
  103. package/src/session/composer/compaction/SessionCompactionComposer.ts +2 -2
  104. package/src/session/composer/execution/LocalSessionExecutionComposer.ts +1 -1
  105. package/src/session/composer/execution/SessionExecutionComposer.ts +1 -1
  106. package/src/session/composer/history/SessionHistoryComposer.ts +1 -1
  107. package/src/session/composer/system/SessionSystemComposer.ts +1 -1
  108. package/src/session/executors/local/{LocalSessionCore.ts → Runner.ts} +13 -13
  109. package/src/session/executors/local/SessionExecutionError.ts +1 -1
  110. package/src/session/executors/local/SessionLoopDecision.ts +3 -3
  111. package/src/session/executors/local/SessionModelMessageState.ts +2 -2
  112. package/src/session/executors/local/SessionSignals.ts +3 -3
  113. package/src/session/executors/local/SessionToolLoopRunner.ts +2 -2
  114. package/src/session/types/SessionHistoryMeta.ts +2 -0
  115. package/src/session/types/SessionLoop.ts +1 -1
  116. package/src/session/types/SessionRun.ts +2 -2
  117. package/tsconfig.tsbuildinfo +1 -1
  118. package/bin/sdk/SdkSessionSystemComposer.d.ts +0 -73
  119. package/bin/sdk/SdkSessionSystemComposer.d.ts.map +0 -1
  120. package/bin/sdk/SdkSessionSystemComposer.js +0 -96
  121. package/bin/sdk/SdkSessionSystemComposer.js.map +0 -1
  122. package/bin/session/Session.d.ts.map +0 -1
  123. package/bin/session/Session.js.map +0 -1
  124. package/bin/session/executors/local/LocalSessionCore.d.ts.map +0 -1
  125. package/bin/session/executors/local/LocalSessionCore.js.map +0 -1
  126. package/bin/session/executors/local/LocalSessionExecutor.d.ts +0 -61
  127. package/bin/session/executors/local/LocalSessionExecutor.d.ts.map +0 -1
  128. package/bin/session/executors/local/LocalSessionExecutor.js +0 -36
  129. package/bin/session/executors/local/LocalSessionExecutor.js.map +0 -1
  130. package/src/sdk/SdkSessionSystemComposer.ts +0 -173
  131. package/src/session/executors/local/LocalSessionExecutor.ts +0 -89
@@ -4,15 +4,13 @@
4
4
  * 关键点(中文)
5
5
  * - 面向 `new Agent(...)` 的本地会话使用场景。
6
6
  * - 统一收口消息落盘、默认模型配置、run/stream/fork 等高层 API。
7
- * - 内部继续复用现有 `Session` / `JsonlSessionHistoryComposer` / `LocalSessionExecutor`。
7
+ * - 内部继续复用 `Executor` / `JsonlSessionHistoryComposer` / `Runner`。
8
8
  */
9
9
 
10
10
  import { nanoid } from "nanoid";
11
11
  import type { LanguageModel, Tool } from "ai";
12
- import { Session as CoreSession } from "@session/Session.js";
12
+ import { Executor } from "@session/Executor.js";
13
13
  import { JsonlSessionHistoryComposer } from "@session/composer/history/jsonl/JsonlSessionHistoryComposer.js";
14
- import { JsonlSessionCompactionComposer } from "@session/composer/compaction/jsonl/JsonlSessionCompactionComposer.js";
15
- import { LocalSessionExecutor } from "@session/executors/local/LocalSessionExecutor.js";
16
14
  import { extractTextFromUiMessage } from "@/service/builtins/chat/runtime/UIMessageTransformer.js";
17
15
  import type {
18
16
  AgentSessionConfigSnapshot,
@@ -22,15 +20,20 @@ import type {
22
20
  AgentSessionRunResult,
23
21
  AgentSessionSetInput,
24
22
  AgentSessionStreamEvent,
23
+ AgentSessionSystemBlock,
24
+ AgentSessionSystemSnapshot,
25
25
  } from "@/sdk/AgentSdkTypes.js";
26
26
  import type { SessionMessageV1 } from "@/session/types/SessionMessages.js";
27
- import { SdkSessionSystemComposer } from "@/sdk/SdkSessionSystemComposer.js";
28
- import { resolveSdkSessionSystemMessages } from "@/sdk/SdkSessionSystemComposer.js";
27
+ import {
28
+ buildSessionSystemBlocks,
29
+ SessionSystemBuilder,
30
+ } from "@/sdk/SessionSystemBuilder.js";
29
31
  import {
30
32
  inferModelLabel,
31
- patchSdkSessionModelLabel,
32
- readSdkSessionMetadata,
33
- writeSdkSessionMetadata,
33
+ patchSessionModelLabel,
34
+ readSessionMetadata,
35
+ resolveSystemTimezone,
36
+ writeSessionMetadata,
34
37
  } from "@/sdk/SessionMetadata.js";
35
38
  import {
36
39
  getSdkAgentSessionArchiveDirPath,
@@ -41,11 +44,11 @@ import type { SessionPort } from "@/runtime/AgentContextTypes.js";
41
44
  import { pushUiMessageChunkAsSdkEvent } from "@/sdk/StreamEvents.js";
42
45
  import {
43
46
  persistSdkAssistantResult,
44
- touchSdkSessionMetadata,
47
+ touchSessionMetadata,
45
48
  } from "@/sdk/SessionPersistence.js";
46
- import { createSdkSessionServicePort } from "@/sdk/SessionServicePort.js";
49
+ import { createSessionServicePort } from "@/sdk/SessionServicePort.js";
47
50
 
48
- type SdkSessionOptions = {
51
+ type SessionOptions = {
49
52
  /**
50
53
  * 当前 agent 稳定标识。
51
54
  */
@@ -75,57 +78,59 @@ type SdkSessionOptions = {
75
78
  };
76
79
 
77
80
  /**
78
- * 读取静态 system 文本集合。
81
+ * 读取当前 SDK 调用方传入的 instruction system blocks。
79
82
  */
80
- getStaticSystemPrompts: () => string[];
83
+ getInstructionSystemBlocks: () => AgentSessionSystemBlock[];
81
84
 
82
85
  /**
83
- * 读取当前 agent 显式注入 service 的 system 文本集合。
86
+ * 读取当前 agent 显式注入 service 的 system blocks。
84
87
  */
85
- getServiceSystemPrompts: () => Promise<string[]>;
88
+ getServiceSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
86
89
 
87
90
  /**
88
- * 读取当前 agent 显式注册 plugin 的 system 文本集合。
91
+ * 读取当前 agent 显式注册 plugin 的 system blocks。
89
92
  */
90
- getPluginSystemPrompts: () => Promise<string[]>;
93
+ getPluginSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
91
94
  };
92
95
 
93
96
  /**
94
97
  * SDK 本地 Session。
95
98
  */
96
- export class SdkSession {
99
+ export class Session {
97
100
  readonly id: string;
98
101
  readonly agentId: string;
99
102
 
100
103
  private readonly projectRoot: string;
101
104
  private readonly tools: Record<string, Tool>;
102
- private readonly logger: SdkSessionOptions["logger"];
103
- private readonly getStaticSystemPrompts: SdkSessionOptions["getStaticSystemPrompts"];
104
- private readonly getServiceSystemPrompts: SdkSessionOptions["getServiceSystemPrompts"];
105
- private readonly getPluginSystemPrompts: SdkSessionOptions["getPluginSystemPrompts"];
105
+ private readonly logger: SessionOptions["logger"];
106
+ private readonly getInstructionSystemBlocks: SessionOptions["getInstructionSystemBlocks"];
107
+ private readonly getServiceSystemBlocks: SessionOptions["getServiceSystemBlocks"];
108
+ private readonly getPluginSystemBlocks: SessionOptions["getPluginSystemBlocks"];
106
109
  private readonly historyComposer: JsonlSessionHistoryComposer;
107
- private readonly coreSession: CoreSession;
110
+ private readonly executor: Executor;
108
111
  private sessionConfig: AgentSessionConfigSnapshot = {};
112
+ private createdAt = Date.now();
113
+ private timezone = resolveSystemTimezone();
109
114
  private initializePromise: Promise<this> | null = null;
110
115
  private servicePort: SessionPort | null = null;
111
116
 
112
- constructor(options: SdkSessionOptions) {
117
+ constructor(options: SessionOptions) {
113
118
  this.id = String(options.sessionId || "").trim();
114
119
  this.agentId = String(options.agentId || "").trim();
115
120
  this.projectRoot = String(options.projectRoot || "").trim();
116
121
  this.tools = options.tools;
117
122
  this.logger = options.logger;
118
- this.getStaticSystemPrompts = options.getStaticSystemPrompts;
119
- this.getServiceSystemPrompts = options.getServiceSystemPrompts;
120
- this.getPluginSystemPrompts = options.getPluginSystemPrompts;
123
+ this.getInstructionSystemBlocks = options.getInstructionSystemBlocks;
124
+ this.getServiceSystemBlocks = options.getServiceSystemBlocks;
125
+ this.getPluginSystemBlocks = options.getPluginSystemBlocks;
121
126
  if (!this.id) {
122
- throw new Error("SdkSession requires a non-empty sessionId");
127
+ throw new Error("Session requires a non-empty sessionId");
123
128
  }
124
129
  if (!this.agentId) {
125
- throw new Error("SdkSession requires a non-empty agentId");
130
+ throw new Error("Session requires a non-empty agentId");
126
131
  }
127
132
  if (!this.projectRoot) {
128
- throw new Error("SdkSession requires a non-empty projectRoot");
133
+ throw new Error("Session requires a non-empty projectRoot");
129
134
  }
130
135
 
131
136
  const sessionDirPath = getSdkAgentSessionDirPath(
@@ -150,30 +155,21 @@ export class SdkSession {
150
155
  },
151
156
  });
152
157
 
153
- this.coreSession = new CoreSession({
158
+ this.executor = new Executor({
154
159
  sessionId: this.id,
155
160
  historyComposer: this.historyComposer,
156
- createExecutor: (historyComposer) => {
157
- const model = this.sessionConfig.model;
158
- if (!model) {
159
- throw new Error(
160
- `Session "${this.id}" has no model configured. Call session.set({ model }) first.`,
161
- );
162
- }
163
- return new LocalSessionExecutor({
164
- model,
165
- logger: this.logger as never,
166
- historyComposer,
167
- compactionComposer: new JsonlSessionCompactionComposer(),
168
- systemComposer: new SdkSessionSystemComposer({
169
- projectRoot: this.projectRoot,
170
- getStaticSystemPrompts: this.getStaticSystemPrompts,
171
- getServiceSystemPrompts: this.getServiceSystemPrompts,
172
- getPluginSystemPrompts: this.getPluginSystemPrompts,
173
- }),
174
- getTools: () => this.tools,
175
- });
176
- },
161
+ getModel: () => this.sessionConfig.model,
162
+ logger: this.logger as never,
163
+ systemComposer: new SessionSystemBuilder({
164
+ agentId: this.agentId,
165
+ projectRoot: this.projectRoot,
166
+ getSessionCreatedAt: () => this.createdAt,
167
+ getSessionTimezone: () => this.timezone,
168
+ getInstructionSystemBlocks: this.getInstructionSystemBlocks,
169
+ getServiceSystemBlocks: this.getServiceSystemBlocks,
170
+ getPluginSystemBlocks: this.getPluginSystemBlocks,
171
+ }),
172
+ getTools: () => this.tools,
177
173
  });
178
174
  }
179
175
 
@@ -185,22 +181,30 @@ export class SdkSession {
185
181
  return await this.initializePromise;
186
182
  }
187
183
  this.initializePromise = (async () => {
188
- const metadata = await readSdkSessionMetadata({
184
+ const metadata = await readSessionMetadata({
189
185
  projectRoot: this.projectRoot,
190
186
  agentId: this.agentId,
191
187
  sessionId: this.id,
192
188
  });
193
- await writeSdkSessionMetadata({
189
+ const createdAt =
190
+ typeof metadata.createdAt === "number" ? metadata.createdAt : Date.now();
191
+ const timezone =
192
+ typeof metadata.timezone === "string" && metadata.timezone.trim()
193
+ ? metadata.timezone.trim()
194
+ : resolveSystemTimezone();
195
+ await writeSessionMetadata({
194
196
  projectRoot: this.projectRoot,
195
197
  agentId: this.agentId,
196
198
  sessionId: this.id,
197
199
  meta: {
198
200
  ...metadata,
199
201
  agentId: this.agentId,
200
- createdAt:
201
- typeof metadata.createdAt === "number" ? metadata.createdAt : Date.now(),
202
+ createdAt,
203
+ timezone,
202
204
  },
203
205
  });
206
+ this.createdAt = createdAt;
207
+ this.timezone = timezone;
204
208
  this.sessionConfig = {
205
209
  ...(metadata.sdkConfig?.modelLabel
206
210
  ? { modelLabel: metadata.sdkConfig.modelLabel }
@@ -227,9 +231,9 @@ export class SdkSession {
227
231
  if (input.model) {
228
232
  this.sessionConfig.model = input.model;
229
233
  this.sessionConfig.modelLabel = inferModelLabel(input.model);
230
- this.coreSession.clearExecutor();
234
+ this.executor.clearExecutor();
231
235
  }
232
- await patchSdkSessionModelLabel({
236
+ await patchSessionModelLabel({
233
237
  projectRoot: this.projectRoot,
234
238
  agentId: this.agentId,
235
239
  sessionId: this.id,
@@ -246,7 +250,7 @@ export class SdkSession {
246
250
  */
247
251
  text: string;
248
252
  }): Promise<void> {
249
- await this.coreSession.appendUserMessage({
253
+ await this.executor.appendUserMessage({
250
254
  text: String(input.text || "").trim(),
251
255
  });
252
256
  await this.touchMetadata();
@@ -261,7 +265,7 @@ export class SdkSession {
261
265
  */
262
266
  text: string;
263
267
  }): Promise<void> {
264
- await this.coreSession.appendAssistantMessage({
268
+ await this.executor.appendAssistantMessage({
265
269
  fallbackText: String(input.text || "").trim(),
266
270
  });
267
271
  await this.touchMetadata();
@@ -279,34 +283,45 @@ export class SdkSession {
279
283
  *
280
284
  * 关键点(中文)
281
285
  * - 返回内容与实际 run 时使用的 SDK system composer 同源。
282
- * - 包含静态 system、显式注入 service system、显式注册 plugin system 与 runtime clock。
283
- * - 这里只返回文本数组,不把 system prompt 写入会话历史。
286
+ * - 包含 instruction/core、显式注入 service system、显式注册 plugin system 与 session 上下文。
287
+ * - 返回结构化快照,不把 system prompt 写入会话历史。
284
288
  */
285
- async system(): Promise<string[]> {
286
- const messages = await resolveSdkSessionSystemMessages({
289
+ async system(): Promise<AgentSessionSystemSnapshot> {
290
+ const blocks = await buildSessionSystemBlocks({
291
+ agentId: this.agentId,
287
292
  projectRoot: this.projectRoot,
288
293
  sessionId: this.id,
289
- getStaticSystemPrompts: this.getStaticSystemPrompts,
290
- getServiceSystemPrompts: this.getServiceSystemPrompts,
291
- getPluginSystemPrompts: this.getPluginSystemPrompts,
294
+ createdAt: this.createdAt,
295
+ timezone: this.timezone,
296
+ getInstructionSystemBlocks: this.getInstructionSystemBlocks,
297
+ getServiceSystemBlocks: this.getServiceSystemBlocks,
298
+ getPluginSystemBlocks: this.getPluginSystemBlocks,
292
299
  });
293
- return messages
294
- .map((message) => String(message.content || ""))
295
- .filter((content) => content.trim().length > 0);
300
+ return {
301
+ sessionId: this.id,
302
+ session: {
303
+ agentId: this.agentId,
304
+ sessionId: this.id,
305
+ projectRoot: this.projectRoot,
306
+ createdAt: new Date(this.createdAt).toISOString(),
307
+ timezone: this.timezone,
308
+ },
309
+ blocks,
310
+ };
296
311
  }
297
312
 
298
313
  /**
299
314
  * 返回当前 session 是否正在执行。
300
315
  */
301
316
  isExecuting(): boolean {
302
- return this.coreSession.isExecuting();
317
+ return this.executor.isExecuting();
303
318
  }
304
319
 
305
320
  /**
306
321
  * 清理当前 session 的执行器缓存。
307
322
  */
308
323
  clearExecutor(): void {
309
- this.coreSession.clearExecutor();
324
+ this.executor.clearExecutor();
310
325
  }
311
326
 
312
327
  /**
@@ -318,7 +333,7 @@ export class SdkSession {
318
333
  throw new Error("session.run requires a non-empty query");
319
334
  }
320
335
  await this.appendUserMessage({ text: query });
321
- const result = await this.coreSession.run({
336
+ const result = await this.executor.run({
322
337
  query,
323
338
  });
324
339
  await this.persistAssistantResult(result.assistantMessage);
@@ -346,7 +361,7 @@ export class SdkSession {
346
361
 
347
362
  const runPromise = (async () => {
348
363
  try {
349
- const result = await this.coreSession.run({
364
+ const result = await this.executor.run({
350
365
  query,
351
366
  onUiMessageChunkCallback: async (chunk) => {
352
367
  pushUiMessageChunkAsSdkEvent({
@@ -377,7 +392,7 @@ export class SdkSession {
377
392
  /**
378
393
  * 从当前 session 创建一个分叉会话。
379
394
  */
380
- async fork(input?: AgentSessionForkInput["messageId"]): Promise<SdkSession> {
395
+ async fork(input?: AgentSessionForkInput["messageId"]): Promise<Session> {
381
396
  const messageId = String(input || "").trim() || undefined;
382
397
  const messages = await this.historyComposer.list();
383
398
  const forkMessages =
@@ -395,15 +410,15 @@ export class SdkSession {
395
410
  return messages.slice(0, targetIndex + 1);
396
411
  })();
397
412
 
398
- const forked = new SdkSession({
413
+ const forked = new Session({
399
414
  agentId: this.agentId,
400
415
  projectRoot: this.projectRoot,
401
416
  sessionId: `fork-${Date.now()}-${nanoid(8)}`,
402
417
  tools: this.tools,
403
418
  logger: this.logger,
404
- getStaticSystemPrompts: this.getStaticSystemPrompts,
405
- getServiceSystemPrompts: this.getServiceSystemPrompts,
406
- getPluginSystemPrompts: this.getPluginSystemPrompts,
419
+ getInstructionSystemBlocks: this.getInstructionSystemBlocks,
420
+ getServiceSystemBlocks: this.getServiceSystemBlocks,
421
+ getPluginSystemBlocks: this.getPluginSystemBlocks,
407
422
  });
408
423
  await forked.initialize();
409
424
  if (this.sessionConfig.model) {
@@ -422,7 +437,7 @@ export class SdkSession {
422
437
  * 生成当前 session 的元数据快照。
423
438
  */
424
439
  async toMetadata(): Promise<AgentSessionMetadata> {
425
- const meta = await readSdkSessionMetadata({
440
+ const meta = await readSessionMetadata({
426
441
  projectRoot: this.projectRoot,
427
442
  agentId: this.agentId,
428
443
  sessionId: this.id,
@@ -443,9 +458,9 @@ export class SdkSession {
443
458
  */
444
459
  getServicePort(): SessionPort {
445
460
  if (this.servicePort) return this.servicePort;
446
- this.servicePort = createSdkSessionServicePort({
461
+ this.servicePort = createSessionServicePort({
447
462
  sessionId: this.id,
448
- coreSession: this.coreSession,
463
+ executor: this.executor,
449
464
  historyComposer: this.historyComposer,
450
465
  touchMetadata: async () => {
451
466
  await this.touchMetadata();
@@ -455,7 +470,7 @@ export class SdkSession {
455
470
  }
456
471
 
457
472
  private async touchMetadata(): Promise<void> {
458
- await touchSdkSessionMetadata({
473
+ await touchSessionMetadata({
459
474
  projectRoot: this.projectRoot,
460
475
  agentId: this.agentId,
461
476
  sessionId: this.id,
@@ -471,7 +486,7 @@ export class SdkSession {
471
486
  agentId: this.agentId,
472
487
  sessionId: this.id,
473
488
  sessionConfig: this.sessionConfig,
474
- coreSession: this.coreSession,
489
+ executor: this.executor,
475
490
  assistantMessage,
476
491
  });
477
492
  }
@@ -36,6 +36,21 @@ function normalizeModelLabel(input: unknown): string | undefined {
36
36
  return label || undefined;
37
37
  }
38
38
 
39
+ /**
40
+ * 读取当前系统时区。
41
+ */
42
+ export function resolveSystemTimezone(): string {
43
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
44
+ return typeof timezone === "string" && timezone.trim()
45
+ ? timezone.trim()
46
+ : "UTC";
47
+ }
48
+
49
+ function normalizeTimezone(input: unknown): string | undefined {
50
+ const timezone = typeof input === "string" ? input.trim() : "";
51
+ return timezone || undefined;
52
+ }
53
+
39
54
  /**
40
55
  * 从模型实例推导轻量可读标签。
41
56
  */
@@ -65,7 +80,7 @@ export function inferModelLabel(
65
80
  /**
66
81
  * 读取当前 session 的 meta.json。
67
82
  */
68
- export async function readSdkSessionMetadata(
83
+ export async function readSessionMetadata(
69
84
  input: ReadSessionMetadataInput,
70
85
  ): Promise<SessionHistoryMetaV1> {
71
86
  const filePath = getSdkAgentSessionMetaPath(
@@ -83,6 +98,7 @@ export async function readSdkSessionMetadata(
83
98
  typeof raw.createdAt === "number" && Number.isFinite(raw.createdAt)
84
99
  ? raw.createdAt
85
100
  : Date.now(),
101
+ timezone: normalizeTimezone(raw.timezone) || resolveSystemTimezone(),
86
102
  updatedAt:
87
103
  typeof raw.updatedAt === "number" && Number.isFinite(raw.updatedAt)
88
104
  ? raw.updatedAt
@@ -116,6 +132,7 @@ export async function readSdkSessionMetadata(
116
132
  sessionId: input.sessionId,
117
133
  agentId: input.agentId,
118
134
  createdAt: Date.now(),
135
+ timezone: resolveSystemTimezone(),
119
136
  updatedAt: 0,
120
137
  pinnedSkillIds: [],
121
138
  };
@@ -125,7 +142,7 @@ export async function readSdkSessionMetadata(
125
142
  /**
126
143
  * 写回当前 session 的 meta.json。
127
144
  */
128
- export async function writeSdkSessionMetadata(
145
+ export async function writeSessionMetadata(
129
146
  input: ReadSessionMetadataInput & {
130
147
  /**
131
148
  * 下一份 meta 数据。
@@ -145,7 +162,7 @@ export async function writeSdkSessionMetadata(
145
162
  /**
146
163
  * 更新当前 session 的 SDK 配置摘要。
147
164
  */
148
- export async function patchSdkSessionModelLabel(
165
+ export async function patchSessionModelLabel(
149
166
  input: ReadSessionMetadataInput & {
150
167
  /**
151
168
  * 当前模型实例。
@@ -153,13 +170,14 @@ export async function patchSdkSessionModelLabel(
153
170
  model?: LanguageModel;
154
171
  },
155
172
  ): Promise<SessionHistoryMetaV1> {
156
- const current = await readSdkSessionMetadata(input);
173
+ const current = await readSessionMetadata(input);
157
174
  const modelLabel = inferModelLabel(input.model);
158
175
  const next: SessionHistoryMetaV1 = {
159
176
  ...current,
160
177
  agentId: input.agentId,
161
178
  createdAt:
162
179
  typeof current.createdAt === "number" ? current.createdAt : Date.now(),
180
+ timezone: normalizeTimezone(current.timezone) || resolveSystemTimezone(),
163
181
  updatedAt: Date.now(),
164
182
  ...(modelLabel
165
183
  ? {
@@ -170,7 +188,7 @@ export async function patchSdkSessionModelLabel(
170
188
  }
171
189
  : {}),
172
190
  };
173
- await writeSdkSessionMetadata({
191
+ await writeSessionMetadata({
174
192
  ...input,
175
193
  meta: next,
176
194
  });
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 集中处理 session meta 更新时间、模型展示标签与 assistant 消息落盘。
6
- * - `SdkSession` 只负责调用这些能力,不直接拼装 meta 结构。
6
+ * - `Session` 只负责调用这些能力,不直接拼装 meta 结构。
7
7
  */
8
8
 
9
9
  import { resolveAssistantMessageForPersistence } from "@/service/builtins/chat/runtime/UserVisibleText.js";
@@ -12,14 +12,14 @@ import type { SessionHistoryMetaV1 } from "@/session/types/SessionHistoryMeta.js
12
12
  import type { SessionMessageV1 } from "@/session/types/SessionMessages.js";
13
13
  import type { AgentSessionConfigSnapshot } from "@/sdk/AgentSdkTypes.js";
14
14
  import {
15
- readSdkSessionMetadata,
16
- writeSdkSessionMetadata,
15
+ readSessionMetadata,
16
+ writeSessionMetadata,
17
17
  } from "@/sdk/SessionMetadata.js";
18
18
 
19
19
  /**
20
20
  * SDK Session 元数据写入参数。
21
21
  */
22
- export interface TouchSdkSessionMetadataParams {
22
+ export interface TouchSessionMetadataParams {
23
23
  /**
24
24
  * 当前项目根目录。
25
25
  */
@@ -42,11 +42,11 @@ export interface TouchSdkSessionMetadataParams {
42
42
  * Assistant 结果落盘参数。
43
43
  */
44
44
  export interface PersistSdkAssistantResultParams
45
- extends TouchSdkSessionMetadataParams {
45
+ extends TouchSessionMetadataParams {
46
46
  /**
47
- * 追加 assistant 消息的底层 session 端口。
47
+ * 追加 assistant 消息的底层执行编排器。
48
48
  */
49
- coreSession: {
49
+ executor: {
50
50
  appendAssistantMessage(params: {
51
51
  /**
52
52
  * 已构造好的完整消息。
@@ -67,10 +67,10 @@ export interface PersistSdkAssistantResultParams
67
67
  /**
68
68
  * 刷新 SDK session 元数据。
69
69
  */
70
- export async function touchSdkSessionMetadata(
71
- params: TouchSdkSessionMetadataParams,
70
+ export async function touchSessionMetadata(
71
+ params: TouchSessionMetadataParams,
72
72
  ): Promise<void> {
73
- const current = await readSdkSessionMetadata({
73
+ const current = await readSessionMetadata({
74
74
  projectRoot: params.projectRoot,
75
75
  agentId: params.agentId,
76
76
  sessionId: params.sessionId,
@@ -90,7 +90,7 @@ export async function touchSdkSessionMetadata(
90
90
  }
91
91
  : {}),
92
92
  };
93
- await writeSdkSessionMetadata({
93
+ await writeSessionMetadata({
94
94
  projectRoot: params.projectRoot,
95
95
  agentId: params.agentId,
96
96
  sessionId: params.sessionId,
@@ -105,9 +105,9 @@ export async function persistSdkAssistantResult(
105
105
  params: PersistSdkAssistantResultParams,
106
106
  ): Promise<void> {
107
107
  const persisted = resolveAssistantMessageForPersistence(params.assistantMessage);
108
- await params.coreSession.appendAssistantMessage({
108
+ await params.executor.appendAssistantMessage({
109
109
  ...(persisted ? { message: persisted } : {}),
110
110
  fallbackText: extractTextFromUiMessage(params.assistantMessage),
111
111
  });
112
- await touchSdkSessionMetadata(params);
112
+ await touchSessionMetadata(params);
113
113
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 把 SDK 本地 session 适配成 chat service 依赖的 `SessionPort`。
6
- * - service 侧直接复用底层 `CoreSession` 协议,避免 SDK `run()` 包装层重复补写消息。
6
+ * - service 侧直接复用底层 `Executor` 协议,避免 SDK `run()` 包装层重复补写消息。
7
7
  */
8
8
 
9
9
  import type { SessionPort } from "@/runtime/AgentContextTypes.js";
@@ -11,15 +11,15 @@ import type { SessionPort } from "@/runtime/AgentContextTypes.js";
11
11
  /**
12
12
  * 构造 SDK SessionPort 的参数。
13
13
  */
14
- export interface CreateSdkSessionServicePortParams {
14
+ export interface CreateSessionServicePortParams {
15
15
  /**
16
16
  * 当前 sessionId。
17
17
  */
18
18
  sessionId: string;
19
19
  /**
20
- * 底层 session 实例。
20
+ * 底层执行编排器。
21
21
  */
22
- coreSession: Omit<SessionPort, "sessionId" | "getHistoryComposer">;
22
+ executor: Omit<SessionPort, "sessionId" | "getHistoryComposer">;
23
23
  /**
24
24
  * 当前 session 历史持久化端口。
25
25
  */
@@ -33,30 +33,30 @@ export interface CreateSdkSessionServicePortParams {
33
33
  /**
34
34
  * 创建供 service 使用的 session 端口。
35
35
  */
36
- export function createSdkSessionServicePort(
37
- params: CreateSdkSessionServicePortParams,
36
+ export function createSessionServicePort(
37
+ params: CreateSessionServicePortParams,
38
38
  ): SessionPort {
39
39
  return {
40
40
  sessionId: params.sessionId,
41
- getExecutor: () => params.coreSession.getExecutor(),
41
+ getExecutor: () => params.executor.getExecutor(),
42
42
  getHistoryComposer: () => params.historyComposer,
43
43
  run: async (runParams) => {
44
- return await params.coreSession.run(runParams);
44
+ return await params.executor.run(runParams);
45
45
  },
46
46
  clearExecutor: () => {
47
- params.coreSession.clearExecutor();
47
+ params.executor.clearExecutor();
48
48
  },
49
49
  afterSessionUpdatedAsync: async () => {
50
- await params.coreSession.afterSessionUpdatedAsync();
50
+ await params.executor.afterSessionUpdatedAsync();
51
51
  },
52
52
  appendUserMessage: async (messageParams) => {
53
- await params.coreSession.appendUserMessage(messageParams);
53
+ await params.executor.appendUserMessage(messageParams);
54
54
  await params.touchMetadata();
55
55
  },
56
56
  appendAssistantMessage: async (messageParams) => {
57
- await params.coreSession.appendAssistantMessage(messageParams);
57
+ await params.executor.appendAssistantMessage(messageParams);
58
58
  await params.touchMetadata();
59
59
  },
60
- isExecuting: () => params.coreSession.isExecuting(),
60
+ isExecuting: () => params.executor.isExecuting(),
61
61
  };
62
62
  }