@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.
- package/bin/index.d.ts +3 -3
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +2 -2
- package/bin/index.js.map +1 -1
- package/bin/runtime/AgentRuntime.d.ts +2 -2
- package/bin/runtime/AgentRuntime.d.ts.map +1 -1
- package/bin/runtime/AgentRuntime.js +7 -12
- package/bin/runtime/AgentRuntime.js.map +1 -1
- package/bin/runtime/AgentRuntimeTypes.d.ts +3 -3
- package/bin/runtime/AgentRuntimeTypes.d.ts.map +1 -1
- package/bin/sdk/Agent.d.ts +13 -8
- package/bin/sdk/Agent.d.ts.map +1 -1
- package/bin/sdk/Agent.js +62 -18
- package/bin/sdk/Agent.js.map +1 -1
- package/bin/sdk/AgentSdkTypes.d.ts +95 -0
- package/bin/sdk/AgentSdkTypes.d.ts.map +1 -1
- package/bin/sdk/RemoteAgent.d.ts +3 -3
- package/bin/sdk/RemoteAgent.d.ts.map +1 -1
- package/bin/sdk/RemoteAgent.js +5 -2
- package/bin/sdk/RemoteAgent.js.map +1 -1
- package/bin/sdk/Session.d.ts +21 -19
- package/bin/sdk/Session.d.ts.map +1 -1
- package/bin/sdk/Session.js +79 -69
- package/bin/sdk/Session.js.map +1 -1
- package/bin/sdk/SessionMetadata.d.ts +7 -3
- package/bin/sdk/SessionMetadata.d.ts.map +1 -1
- package/bin/sdk/SessionMetadata.js +21 -5
- package/bin/sdk/SessionMetadata.js.map +1 -1
- package/bin/sdk/SessionPersistence.d.ts +6 -6
- package/bin/sdk/SessionPersistence.d.ts.map +1 -1
- package/bin/sdk/SessionPersistence.js +7 -7
- package/bin/sdk/SessionPersistence.js.map +1 -1
- package/bin/sdk/SessionServicePort.d.ts +5 -5
- package/bin/sdk/SessionServicePort.d.ts.map +1 -1
- package/bin/sdk/SessionServicePort.js +9 -9
- package/bin/sdk/SessionServicePort.js.map +1 -1
- package/bin/sdk/SessionSystemBuilder.d.ts +106 -0
- package/bin/sdk/SessionSystemBuilder.d.ts.map +1 -0
- package/bin/sdk/SessionSystemBuilder.js +150 -0
- package/bin/sdk/SessionSystemBuilder.js.map +1 -0
- package/bin/service/builtins/chat/runtime/ChatSession.d.ts +27 -8
- package/bin/service/builtins/chat/runtime/ChatSession.d.ts.map +1 -1
- package/bin/service/builtins/chat/runtime/ChatSession.js +9 -4
- package/bin/service/builtins/chat/runtime/ChatSession.js.map +1 -1
- package/bin/service/builtins/task/runtime/Runner.d.ts +1 -1
- package/bin/service/builtins/task/runtime/Runner.js +1 -1
- package/bin/service/builtins/task/runtime/TaskRunnerSession.d.ts +2 -2
- package/bin/service/builtins/task/runtime/TaskRunnerSession.js +4 -4
- package/bin/service/builtins/task/runtime/TaskRunnerSession.js.map +1 -1
- package/bin/service/builtins/task/runtime/TaskRunnerTypes.d.ts +1 -1
- package/bin/session/{Session.d.ts → Executor.d.ts} +54 -17
- package/bin/session/Executor.d.ts.map +1 -0
- package/bin/session/{Session.js → Executor.js} +60 -23
- package/bin/session/Executor.js.map +1 -0
- package/bin/session/composer/SessionComposer.d.ts +1 -1
- package/bin/session/composer/SessionComposer.js +1 -1
- package/bin/session/composer/compaction/SessionCompactionComposer.d.ts +2 -2
- package/bin/session/composer/execution/LocalSessionExecutionComposer.d.ts +1 -1
- package/bin/session/composer/execution/LocalSessionExecutionComposer.js +1 -1
- package/bin/session/composer/execution/SessionExecutionComposer.d.ts +1 -1
- package/bin/session/composer/history/SessionHistoryComposer.d.ts +1 -1
- package/bin/session/composer/system/SessionSystemComposer.d.ts +1 -1
- package/bin/session/composer/system/SessionSystemComposer.js +1 -1
- package/bin/session/executors/local/{LocalSessionCore.d.ts → Runner.d.ts} +10 -10
- package/bin/session/executors/local/Runner.d.ts.map +1 -0
- package/bin/session/executors/local/{LocalSessionCore.js → Runner.js} +11 -11
- package/bin/session/executors/local/Runner.js.map +1 -0
- package/bin/session/executors/local/SessionExecutionError.d.ts +1 -1
- package/bin/session/executors/local/SessionExecutionError.js +1 -1
- package/bin/session/executors/local/SessionLoopDecision.d.ts +3 -3
- package/bin/session/executors/local/SessionLoopDecision.js +3 -3
- package/bin/session/executors/local/SessionModelMessageState.d.ts +2 -2
- package/bin/session/executors/local/SessionModelMessageState.js +2 -2
- package/bin/session/executors/local/SessionSignals.d.ts +3 -3
- package/bin/session/executors/local/SessionSignals.js +3 -3
- package/bin/session/executors/local/SessionToolLoopRunner.d.ts +1 -1
- package/bin/session/executors/local/SessionToolLoopRunner.js +2 -2
- package/bin/session/executors/local/SessionToolLoopRunner.js.map +1 -1
- package/bin/session/types/SessionHistoryMeta.d.ts +2 -0
- package/bin/session/types/SessionHistoryMeta.d.ts.map +1 -1
- package/bin/session/types/SessionLoop.d.ts +1 -1
- package/bin/session/types/SessionLoop.js +1 -1
- package/bin/session/types/SessionRun.d.ts +2 -2
- package/bin/session/types/SessionRun.js +1 -1
- package/package.json +1 -1
- package/src/index.ts +6 -2
- package/src/runtime/AgentRuntime.ts +7 -17
- package/src/runtime/AgentRuntimeTypes.ts +3 -3
- package/src/sdk/Agent.ts +75 -23
- package/src/sdk/AgentSdkTypes.ts +113 -0
- package/src/sdk/RemoteAgent.ts +10 -4
- package/src/sdk/Session.ts +100 -85
- package/src/sdk/SessionMetadata.ts +23 -5
- package/src/sdk/SessionPersistence.ts +13 -13
- package/src/sdk/SessionServicePort.ts +13 -13
- package/src/sdk/SessionSystemBuilder.ts +261 -0
- package/src/service/builtins/chat/runtime/ChatSession.ts +37 -13
- package/src/service/builtins/task/runtime/Runner.ts +1 -1
- package/src/service/builtins/task/runtime/TaskRunnerSession.ts +4 -4
- package/src/service/builtins/task/runtime/TaskRunnerTypes.ts +1 -1
- package/src/session/{Session.ts → Executor.ts} +96 -26
- package/src/session/composer/SessionComposer.ts +1 -1
- package/src/session/composer/compaction/SessionCompactionComposer.ts +2 -2
- package/src/session/composer/execution/LocalSessionExecutionComposer.ts +1 -1
- package/src/session/composer/execution/SessionExecutionComposer.ts +1 -1
- package/src/session/composer/history/SessionHistoryComposer.ts +1 -1
- package/src/session/composer/system/SessionSystemComposer.ts +1 -1
- package/src/session/executors/local/{LocalSessionCore.ts → Runner.ts} +13 -13
- package/src/session/executors/local/SessionExecutionError.ts +1 -1
- package/src/session/executors/local/SessionLoopDecision.ts +3 -3
- package/src/session/executors/local/SessionModelMessageState.ts +2 -2
- package/src/session/executors/local/SessionSignals.ts +3 -3
- package/src/session/executors/local/SessionToolLoopRunner.ts +2 -2
- package/src/session/types/SessionHistoryMeta.ts +2 -0
- package/src/session/types/SessionLoop.ts +1 -1
- package/src/session/types/SessionRun.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/sdk/SdkSessionSystemComposer.d.ts +0 -73
- package/bin/sdk/SdkSessionSystemComposer.d.ts.map +0 -1
- package/bin/sdk/SdkSessionSystemComposer.js +0 -96
- package/bin/sdk/SdkSessionSystemComposer.js.map +0 -1
- package/bin/session/Session.d.ts.map +0 -1
- package/bin/session/Session.js.map +0 -1
- package/bin/session/executors/local/LocalSessionCore.d.ts.map +0 -1
- package/bin/session/executors/local/LocalSessionCore.js.map +0 -1
- package/bin/session/executors/local/LocalSessionExecutor.d.ts +0 -61
- package/bin/session/executors/local/LocalSessionExecutor.d.ts.map +0 -1
- package/bin/session/executors/local/LocalSessionExecutor.js +0 -36
- package/bin/session/executors/local/LocalSessionExecutor.js.map +0 -1
- package/src/sdk/SdkSessionSystemComposer.ts +0 -173
- package/src/session/executors/local/LocalSessionExecutor.ts +0 -89
package/src/sdk/Session.ts
CHANGED
|
@@ -4,15 +4,13 @@
|
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 面向 `new Agent(...)` 的本地会话使用场景。
|
|
6
6
|
* - 统一收口消息落盘、默认模型配置、run/stream/fork 等高层 API。
|
|
7
|
-
* -
|
|
7
|
+
* - 内部继续复用 `Executor` / `JsonlSessionHistoryComposer` / `Runner`。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { nanoid } from "nanoid";
|
|
11
11
|
import type { LanguageModel, Tool } from "ai";
|
|
12
|
-
import {
|
|
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 {
|
|
28
|
-
|
|
27
|
+
import {
|
|
28
|
+
buildSessionSystemBlocks,
|
|
29
|
+
SessionSystemBuilder,
|
|
30
|
+
} from "@/sdk/SessionSystemBuilder.js";
|
|
29
31
|
import {
|
|
30
32
|
inferModelLabel,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
47
|
+
touchSessionMetadata,
|
|
45
48
|
} from "@/sdk/SessionPersistence.js";
|
|
46
|
-
import {
|
|
49
|
+
import { createSessionServicePort } from "@/sdk/SessionServicePort.js";
|
|
47
50
|
|
|
48
|
-
type
|
|
51
|
+
type SessionOptions = {
|
|
49
52
|
/**
|
|
50
53
|
* 当前 agent 稳定标识。
|
|
51
54
|
*/
|
|
@@ -75,57 +78,59 @@ type SdkSessionOptions = {
|
|
|
75
78
|
};
|
|
76
79
|
|
|
77
80
|
/**
|
|
78
|
-
*
|
|
81
|
+
* 读取当前 SDK 调用方传入的 instruction system blocks。
|
|
79
82
|
*/
|
|
80
|
-
|
|
83
|
+
getInstructionSystemBlocks: () => AgentSessionSystemBlock[];
|
|
81
84
|
|
|
82
85
|
/**
|
|
83
|
-
* 读取当前 agent 显式注入 service 的 system
|
|
86
|
+
* 读取当前 agent 显式注入 service 的 system blocks。
|
|
84
87
|
*/
|
|
85
|
-
|
|
88
|
+
getServiceSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
86
89
|
|
|
87
90
|
/**
|
|
88
|
-
* 读取当前 agent 显式注册 plugin 的 system
|
|
91
|
+
* 读取当前 agent 显式注册 plugin 的 system blocks。
|
|
89
92
|
*/
|
|
90
|
-
|
|
93
|
+
getPluginSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
91
94
|
};
|
|
92
95
|
|
|
93
96
|
/**
|
|
94
97
|
* SDK 本地 Session。
|
|
95
98
|
*/
|
|
96
|
-
export class
|
|
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:
|
|
103
|
-
private readonly
|
|
104
|
-
private readonly
|
|
105
|
-
private readonly
|
|
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
|
|
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:
|
|
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.
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
123
|
+
this.getInstructionSystemBlocks = options.getInstructionSystemBlocks;
|
|
124
|
+
this.getServiceSystemBlocks = options.getServiceSystemBlocks;
|
|
125
|
+
this.getPluginSystemBlocks = options.getPluginSystemBlocks;
|
|
121
126
|
if (!this.id) {
|
|
122
|
-
throw new Error("
|
|
127
|
+
throw new Error("Session requires a non-empty sessionId");
|
|
123
128
|
}
|
|
124
129
|
if (!this.agentId) {
|
|
125
|
-
throw new Error("
|
|
130
|
+
throw new Error("Session requires a non-empty agentId");
|
|
126
131
|
}
|
|
127
132
|
if (!this.projectRoot) {
|
|
128
|
-
throw new Error("
|
|
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.
|
|
158
|
+
this.executor = new Executor({
|
|
154
159
|
sessionId: this.id,
|
|
155
160
|
historyComposer: this.historyComposer,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
|
184
|
+
const metadata = await readSessionMetadata({
|
|
189
185
|
projectRoot: this.projectRoot,
|
|
190
186
|
agentId: this.agentId,
|
|
191
187
|
sessionId: this.id,
|
|
192
188
|
});
|
|
193
|
-
|
|
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
|
-
|
|
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.
|
|
234
|
+
this.executor.clearExecutor();
|
|
231
235
|
}
|
|
232
|
-
await
|
|
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.
|
|
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.
|
|
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
|
-
* -
|
|
283
|
-
* -
|
|
286
|
+
* - 包含 instruction/core、显式注入 service system、显式注册 plugin system 与 session 上下文。
|
|
287
|
+
* - 返回结构化快照,不把 system prompt 写入会话历史。
|
|
284
288
|
*/
|
|
285
|
-
async system(): Promise<
|
|
286
|
-
const
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
|
|
294
|
+
createdAt: this.createdAt,
|
|
295
|
+
timezone: this.timezone,
|
|
296
|
+
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
297
|
+
getServiceSystemBlocks: this.getServiceSystemBlocks,
|
|
298
|
+
getPluginSystemBlocks: this.getPluginSystemBlocks,
|
|
292
299
|
});
|
|
293
|
-
return
|
|
294
|
-
|
|
295
|
-
|
|
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.
|
|
317
|
+
return this.executor.isExecuting();
|
|
303
318
|
}
|
|
304
319
|
|
|
305
320
|
/**
|
|
306
321
|
* 清理当前 session 的执行器缓存。
|
|
307
322
|
*/
|
|
308
323
|
clearExecutor(): void {
|
|
309
|
-
this.
|
|
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.
|
|
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.
|
|
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<
|
|
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
|
|
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
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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
|
|
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 =
|
|
461
|
+
this.servicePort = createSessionServicePort({
|
|
447
462
|
sessionId: this.id,
|
|
448
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
* - `
|
|
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
|
-
|
|
16
|
-
|
|
15
|
+
readSessionMetadata,
|
|
16
|
+
writeSessionMetadata,
|
|
17
17
|
} from "@/sdk/SessionMetadata.js";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* SDK Session 元数据写入参数。
|
|
21
21
|
*/
|
|
22
|
-
export interface
|
|
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
|
|
45
|
+
extends TouchSessionMetadataParams {
|
|
46
46
|
/**
|
|
47
|
-
* 追加 assistant
|
|
47
|
+
* 追加 assistant 消息的底层执行编排器。
|
|
48
48
|
*/
|
|
49
|
-
|
|
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
|
|
71
|
-
params:
|
|
70
|
+
export async function touchSessionMetadata(
|
|
71
|
+
params: TouchSessionMetadataParams,
|
|
72
72
|
): Promise<void> {
|
|
73
|
-
const current = await
|
|
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
|
|
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.
|
|
108
|
+
await params.executor.appendAssistantMessage({
|
|
109
109
|
...(persisted ? { message: persisted } : {}),
|
|
110
110
|
fallbackText: extractTextFromUiMessage(params.assistantMessage),
|
|
111
111
|
});
|
|
112
|
-
await
|
|
112
|
+
await touchSessionMetadata(params);
|
|
113
113
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 把 SDK 本地 session 适配成 chat service 依赖的 `SessionPort`。
|
|
6
|
-
* - service 侧直接复用底层 `
|
|
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
|
|
14
|
+
export interface CreateSessionServicePortParams {
|
|
15
15
|
/**
|
|
16
16
|
* 当前 sessionId。
|
|
17
17
|
*/
|
|
18
18
|
sessionId: string;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* 底层执行编排器。
|
|
21
21
|
*/
|
|
22
|
-
|
|
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
|
|
37
|
-
params:
|
|
36
|
+
export function createSessionServicePort(
|
|
37
|
+
params: CreateSessionServicePortParams,
|
|
38
38
|
): SessionPort {
|
|
39
39
|
return {
|
|
40
40
|
sessionId: params.sessionId,
|
|
41
|
-
getExecutor: () => params.
|
|
41
|
+
getExecutor: () => params.executor.getExecutor(),
|
|
42
42
|
getHistoryComposer: () => params.historyComposer,
|
|
43
43
|
run: async (runParams) => {
|
|
44
|
-
return await params.
|
|
44
|
+
return await params.executor.run(runParams);
|
|
45
45
|
},
|
|
46
46
|
clearExecutor: () => {
|
|
47
|
-
params.
|
|
47
|
+
params.executor.clearExecutor();
|
|
48
48
|
},
|
|
49
49
|
afterSessionUpdatedAsync: async () => {
|
|
50
|
-
await params.
|
|
50
|
+
await params.executor.afterSessionUpdatedAsync();
|
|
51
51
|
},
|
|
52
52
|
appendUserMessage: async (messageParams) => {
|
|
53
|
-
await params.
|
|
53
|
+
await params.executor.appendUserMessage(messageParams);
|
|
54
54
|
await params.touchMetadata();
|
|
55
55
|
},
|
|
56
56
|
appendAssistantMessage: async (messageParams) => {
|
|
57
|
-
await params.
|
|
57
|
+
await params.executor.appendAssistantMessage(messageParams);
|
|
58
58
|
await params.touchMetadata();
|
|
59
59
|
},
|
|
60
|
-
isExecuting: () => params.
|
|
60
|
+
isExecuting: () => params.executor.isExecuting(),
|
|
61
61
|
};
|
|
62
62
|
}
|