@downcity/agent 1.1.11 → 1.1.12
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 +1 -1
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js.map +1 -1
- package/bin/sdk/Agent.d.ts +11 -6
- package/bin/sdk/Agent.d.ts.map +1 -1
- package/bin/sdk/Agent.js +60 -16
- 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/SdkSessionSystemComposer.d.ts +52 -19
- package/bin/sdk/SdkSessionSystemComposer.d.ts.map +1 -1
- package/bin/sdk/SdkSessionSystemComposer.js +102 -48
- package/bin/sdk/SdkSessionSystemComposer.js.map +1 -1
- package/bin/sdk/Session.d.ts +15 -13
- package/bin/sdk/Session.d.ts.map +1 -1
- package/bin/sdk/Session.js +47 -25
- package/bin/sdk/Session.js.map +1 -1
- package/bin/sdk/SessionMetadata.d.ts +4 -0
- package/bin/sdk/SessionMetadata.d.ts.map +1 -1
- package/bin/sdk/SessionMetadata.js +16 -0
- package/bin/sdk/SessionMetadata.js.map +1 -1
- package/bin/session/types/SessionHistoryMeta.d.ts +2 -0
- package/bin/session/types/SessionHistoryMeta.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/sdk/Agent.ts +70 -18
- package/src/sdk/AgentSdkTypes.ts +113 -0
- package/src/sdk/RemoteAgent.ts +10 -4
- package/src/sdk/SdkSessionSystemComposer.ts +165 -77
- package/src/sdk/Session.ts +61 -32
- package/src/sdk/SessionMetadata.ts +18 -0
- package/src/session/types/SessionHistoryMeta.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -3,19 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 面向 `Agent` SDK 的本地会话执行场景。
|
|
6
|
-
* -
|
|
6
|
+
* - 注入调用方显式传入的静态 instruction、显式注入 service system 与显式注册 plugin system。
|
|
7
|
+
* - SDK 不在 system 中注入动态变量;动态上下文应由调用方放入 user message。
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
import { SessionSystemComposer } from "@session/composer/system/SessionSystemComposer.js";
|
|
10
11
|
import { getSessionRunScope } from "@session/SessionRunScope.js";
|
|
11
|
-
import { transformPromptsIntoSystemMessages } from "@session/composer/system/default/PromptRenderer.js";
|
|
12
|
-
import { buildRuntimeClockSystemPrompt } from "@session/composer/system/default/variables/VariableReplacer.js";
|
|
13
12
|
import type { SessionSystemMessage } from "@/session/types/SessionPrompts.js";
|
|
13
|
+
import type {
|
|
14
|
+
AgentSessionSystemBlock,
|
|
15
|
+
AgentSessionSystemSessionInfo,
|
|
16
|
+
} from "@/sdk/AgentSdkTypes.js";
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
|
-
* 解析 SDK session system
|
|
19
|
+
* 解析 SDK session system blocks 的输入。
|
|
17
20
|
*/
|
|
18
|
-
export interface
|
|
21
|
+
export interface ResolveSdkSessionSystemBlocksParams {
|
|
22
|
+
/**
|
|
23
|
+
* 当前 agent 的稳定标识。
|
|
24
|
+
*/
|
|
25
|
+
agentId: string;
|
|
26
|
+
|
|
19
27
|
/**
|
|
20
28
|
* 当前 agent 绑定的项目根目录。
|
|
21
29
|
*/
|
|
@@ -27,128 +35,205 @@ export interface ResolveSdkSessionSystemMessagesParams {
|
|
|
27
35
|
sessionId: string;
|
|
28
36
|
|
|
29
37
|
/**
|
|
30
|
-
*
|
|
38
|
+
* 当前 session 首次创建时间(ms)。
|
|
39
|
+
*/
|
|
40
|
+
createdAt: number;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 当前 session 初始化时解析到的系统时区。
|
|
31
44
|
*/
|
|
32
|
-
|
|
45
|
+
timezone: string;
|
|
33
46
|
|
|
34
47
|
/**
|
|
35
|
-
*
|
|
48
|
+
* 读取当前 SDK 调用方传入的 instruction system blocks。
|
|
36
49
|
*/
|
|
37
|
-
|
|
50
|
+
getInstructionSystemBlocks: () => AgentSessionSystemBlock[];
|
|
38
51
|
|
|
39
52
|
/**
|
|
40
|
-
*
|
|
53
|
+
* 读取当前显式注入 service 的 system blocks。
|
|
41
54
|
*/
|
|
42
|
-
|
|
55
|
+
getServiceSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 读取当前显式注册 plugin 的 system blocks。
|
|
59
|
+
*/
|
|
60
|
+
getPluginSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
43
61
|
}
|
|
44
62
|
|
|
45
63
|
type SdkSessionSystemComposerOptions = {
|
|
46
64
|
/**
|
|
47
|
-
* 当前 agent
|
|
65
|
+
* 当前 agent 的稳定标识。
|
|
48
66
|
*/
|
|
49
|
-
|
|
67
|
+
agentId: string;
|
|
50
68
|
|
|
51
69
|
/**
|
|
52
|
-
*
|
|
70
|
+
* 当前 agent 绑定的项目根目录。
|
|
53
71
|
*/
|
|
54
|
-
|
|
72
|
+
projectRoot: string;
|
|
55
73
|
|
|
56
74
|
/**
|
|
57
|
-
*
|
|
75
|
+
* 读取当前 session 首次创建时间(ms)。
|
|
58
76
|
*/
|
|
59
|
-
|
|
77
|
+
getSessionCreatedAt: () => number;
|
|
60
78
|
|
|
61
79
|
/**
|
|
62
|
-
*
|
|
80
|
+
* 读取当前 session 初始化时解析到的系统时区。
|
|
63
81
|
*/
|
|
64
|
-
|
|
65
|
-
};
|
|
82
|
+
getSessionTimezone: () => string;
|
|
66
83
|
|
|
67
|
-
async function resolvePromptMessages(params: {
|
|
68
84
|
/**
|
|
69
|
-
*
|
|
85
|
+
* 读取当前 SDK 调用方传入的 instruction system blocks。
|
|
70
86
|
*/
|
|
71
|
-
|
|
87
|
+
getInstructionSystemBlocks: () => AgentSessionSystemBlock[];
|
|
88
|
+
|
|
72
89
|
/**
|
|
73
|
-
*
|
|
90
|
+
* 读取当前显式注册 plugin 的 system blocks。
|
|
74
91
|
*/
|
|
75
|
-
|
|
92
|
+
getPluginSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
93
|
+
|
|
76
94
|
/**
|
|
77
|
-
*
|
|
95
|
+
* 读取当前显式注入 service 的 system blocks。
|
|
78
96
|
*/
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
97
|
+
getServiceSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
function normalizeSystemBlocks(
|
|
101
|
+
blocks: AgentSessionSystemBlock[],
|
|
102
|
+
): AgentSessionSystemBlock[] {
|
|
103
|
+
if (!Array.isArray(blocks)) return [];
|
|
104
|
+
return blocks
|
|
105
|
+
.map((block) => {
|
|
106
|
+
const content = String(block?.content || "").trim();
|
|
107
|
+
if (!content) return null;
|
|
108
|
+
const source = block.source;
|
|
109
|
+
if (
|
|
110
|
+
source !== "core" &&
|
|
111
|
+
source !== "instruction" &&
|
|
112
|
+
source !== "service" &&
|
|
113
|
+
source !== "plugin" &&
|
|
114
|
+
source !== "session"
|
|
115
|
+
) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
source,
|
|
120
|
+
name: String(block.name || source).trim() || source,
|
|
121
|
+
content,
|
|
122
|
+
} satisfies AgentSessionSystemBlock;
|
|
123
|
+
})
|
|
124
|
+
.filter((block): block is AgentSessionSystemBlock => Boolean(block));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function createSessionInfo(
|
|
128
|
+
params: Pick<
|
|
129
|
+
ResolveSdkSessionSystemBlocksParams,
|
|
130
|
+
"agentId" | "sessionId" | "projectRoot" | "createdAt" | "timezone"
|
|
131
|
+
>,
|
|
132
|
+
): AgentSessionSystemSessionInfo {
|
|
133
|
+
const createdAt = Number.isFinite(params.createdAt) ? params.createdAt : 0;
|
|
134
|
+
return {
|
|
135
|
+
agentId: String(params.agentId || "").trim(),
|
|
136
|
+
sessionId: String(params.sessionId || "").trim(),
|
|
137
|
+
projectRoot: String(params.projectRoot || "").trim(),
|
|
138
|
+
createdAt: new Date(createdAt).toISOString(),
|
|
139
|
+
timezone: String(params.timezone || "").trim() || "UTC",
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function createSessionSystemBlock(
|
|
144
|
+
session: AgentSessionSystemSessionInfo,
|
|
145
|
+
): AgentSessionSystemBlock {
|
|
146
|
+
const content = [
|
|
147
|
+
"当前会话上下文:",
|
|
148
|
+
`你正在服务 agent "${session.agentId}" 的 session "${session.sessionId}"。`,
|
|
149
|
+
`当前项目根目录是 "${session.projectRoot}"。`,
|
|
150
|
+
`本会话创建于 ${session.createdAt},参考时区是 ${session.timezone}。`,
|
|
151
|
+
"这个创建时间是当前会话的稳定参考时间,不代表每轮运行时的当前时间。",
|
|
152
|
+
"如果用户消息中提供了新的当前时间、相对时间或其他动态上下文,应优先使用用户消息中的动态信息。",
|
|
153
|
+
].join("\n");
|
|
154
|
+
return {
|
|
155
|
+
source: "session",
|
|
156
|
+
name: "context",
|
|
157
|
+
content,
|
|
158
|
+
};
|
|
89
159
|
}
|
|
90
160
|
|
|
91
161
|
/**
|
|
92
|
-
* 解析 SDK session 当前生效的 system
|
|
162
|
+
* 解析 SDK session 当前生效的 system blocks。
|
|
93
163
|
*/
|
|
94
|
-
export async function
|
|
95
|
-
params:
|
|
96
|
-
): Promise<
|
|
164
|
+
export async function resolveSdkSessionSystemBlocks(
|
|
165
|
+
params: ResolveSdkSessionSystemBlocksParams,
|
|
166
|
+
): Promise<AgentSessionSystemBlock[]> {
|
|
167
|
+
const agentId = String(params.agentId || "").trim();
|
|
97
168
|
const projectRoot = String(params.projectRoot || "").trim();
|
|
98
169
|
const sessionId = String(params.sessionId || "").trim();
|
|
170
|
+
const createdAt = Number(params.createdAt || 0);
|
|
171
|
+
const timezone = String(params.timezone || "").trim();
|
|
172
|
+
if (!agentId) {
|
|
173
|
+
throw new Error("resolveSdkSessionSystemBlocks requires a non-empty agentId");
|
|
174
|
+
}
|
|
99
175
|
if (!projectRoot) {
|
|
100
|
-
throw new Error("
|
|
176
|
+
throw new Error("resolveSdkSessionSystemBlocks requires a non-empty projectRoot");
|
|
101
177
|
}
|
|
102
178
|
if (!sessionId) {
|
|
103
|
-
throw new Error("
|
|
179
|
+
throw new Error("resolveSdkSessionSystemBlocks requires a non-empty sessionId");
|
|
180
|
+
}
|
|
181
|
+
if (!Number.isFinite(createdAt) || createdAt <= 0) {
|
|
182
|
+
throw new Error("resolveSdkSessionSystemBlocks requires a valid createdAt");
|
|
183
|
+
}
|
|
184
|
+
if (!timezone) {
|
|
185
|
+
throw new Error("resolveSdkSessionSystemBlocks requires a non-empty timezone");
|
|
104
186
|
}
|
|
105
|
-
const staticMessages = await resolvePromptMessages({
|
|
106
|
-
prompts: params.getStaticSystemPrompts(),
|
|
107
|
-
projectRoot,
|
|
108
|
-
sessionId,
|
|
109
|
-
});
|
|
110
|
-
const serviceMessages = await resolvePromptMessages({
|
|
111
|
-
prompts: await params.getServiceSystemPrompts(),
|
|
112
|
-
projectRoot,
|
|
113
|
-
sessionId,
|
|
114
|
-
});
|
|
115
|
-
const pluginMessages = await resolvePromptMessages({
|
|
116
|
-
prompts: await params.getPluginSystemPrompts(),
|
|
117
|
-
projectRoot,
|
|
118
|
-
sessionId,
|
|
119
|
-
});
|
|
120
|
-
|
|
121
187
|
return [
|
|
122
|
-
...
|
|
123
|
-
...
|
|
124
|
-
...
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
sessionId,
|
|
130
|
-
}),
|
|
131
|
-
},
|
|
188
|
+
...normalizeSystemBlocks(params.getInstructionSystemBlocks()),
|
|
189
|
+
...normalizeSystemBlocks(await params.getServiceSystemBlocks()),
|
|
190
|
+
...normalizeSystemBlocks(await params.getPluginSystemBlocks()),
|
|
191
|
+
// session block 放在最后,尽量保留前缀 system blocks 的跨 session 缓存命中。
|
|
192
|
+
createSessionSystemBlock(
|
|
193
|
+
createSessionInfo({ agentId, projectRoot, sessionId, createdAt, timezone }),
|
|
194
|
+
),
|
|
132
195
|
];
|
|
133
196
|
}
|
|
134
197
|
|
|
198
|
+
/**
|
|
199
|
+
* 解析 SDK session 当前生效的 system messages。
|
|
200
|
+
*/
|
|
201
|
+
export async function resolveSdkSessionSystemMessages(
|
|
202
|
+
params: ResolveSdkSessionSystemBlocksParams,
|
|
203
|
+
): Promise<SessionSystemMessage[]> {
|
|
204
|
+
const blocks = await resolveSdkSessionSystemBlocks(params);
|
|
205
|
+
return blocks.map((block) => ({
|
|
206
|
+
role: "system" as const,
|
|
207
|
+
content: block.content,
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
|
|
135
211
|
/**
|
|
136
212
|
* SDK Session system composer 实现。
|
|
137
213
|
*/
|
|
138
214
|
export class SdkSessionSystemComposer extends SessionSystemComposer {
|
|
139
215
|
readonly name = "sdk_prompt_system";
|
|
140
216
|
|
|
217
|
+
private readonly agentId: string;
|
|
141
218
|
private readonly projectRoot: string;
|
|
142
|
-
private readonly
|
|
143
|
-
private readonly
|
|
144
|
-
private readonly
|
|
219
|
+
private readonly getSessionCreatedAt: SdkSessionSystemComposerOptions["getSessionCreatedAt"];
|
|
220
|
+
private readonly getSessionTimezone: SdkSessionSystemComposerOptions["getSessionTimezone"];
|
|
221
|
+
private readonly getInstructionSystemBlocks: SdkSessionSystemComposerOptions["getInstructionSystemBlocks"];
|
|
222
|
+
private readonly getServiceSystemBlocks: SdkSessionSystemComposerOptions["getServiceSystemBlocks"];
|
|
223
|
+
private readonly getPluginSystemBlocks: SdkSessionSystemComposerOptions["getPluginSystemBlocks"];
|
|
145
224
|
|
|
146
225
|
constructor(options: SdkSessionSystemComposerOptions) {
|
|
147
226
|
super();
|
|
227
|
+
this.agentId = String(options.agentId || "").trim();
|
|
148
228
|
this.projectRoot = String(options.projectRoot || "").trim();
|
|
149
|
-
this.
|
|
150
|
-
this.
|
|
151
|
-
this.
|
|
229
|
+
this.getSessionCreatedAt = options.getSessionCreatedAt;
|
|
230
|
+
this.getSessionTimezone = options.getSessionTimezone;
|
|
231
|
+
this.getInstructionSystemBlocks = options.getInstructionSystemBlocks;
|
|
232
|
+
this.getServiceSystemBlocks = options.getServiceSystemBlocks;
|
|
233
|
+
this.getPluginSystemBlocks = options.getPluginSystemBlocks;
|
|
234
|
+
if (!this.agentId) {
|
|
235
|
+
throw new Error("SdkSessionSystemComposer requires a non-empty agentId");
|
|
236
|
+
}
|
|
152
237
|
if (!this.projectRoot) {
|
|
153
238
|
throw new Error("SdkSessionSystemComposer requires a non-empty projectRoot");
|
|
154
239
|
}
|
|
@@ -163,11 +248,14 @@ export class SdkSessionSystemComposer extends SessionSystemComposer {
|
|
|
163
248
|
throw new Error("SdkSessionSystemComposer.resolve requires a non-empty sessionId");
|
|
164
249
|
}
|
|
165
250
|
return await resolveSdkSessionSystemMessages({
|
|
251
|
+
agentId: this.agentId,
|
|
166
252
|
projectRoot: this.projectRoot,
|
|
167
253
|
sessionId,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
254
|
+
createdAt: this.getSessionCreatedAt(),
|
|
255
|
+
timezone: this.getSessionTimezone(),
|
|
256
|
+
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
257
|
+
getServiceSystemBlocks: this.getServiceSystemBlocks,
|
|
258
|
+
getPluginSystemBlocks: this.getPluginSystemBlocks,
|
|
171
259
|
});
|
|
172
260
|
}
|
|
173
261
|
}
|
package/src/sdk/Session.ts
CHANGED
|
@@ -22,14 +22,19 @@ import type {
|
|
|
22
22
|
AgentSessionRunResult,
|
|
23
23
|
AgentSessionSetInput,
|
|
24
24
|
AgentSessionStreamEvent,
|
|
25
|
+
AgentSessionSystemBlock,
|
|
26
|
+
AgentSessionSystemSnapshot,
|
|
25
27
|
} from "@/sdk/AgentSdkTypes.js";
|
|
26
28
|
import type { SessionMessageV1 } from "@/session/types/SessionMessages.js";
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
+
import {
|
|
30
|
+
resolveSdkSessionSystemBlocks,
|
|
31
|
+
SdkSessionSystemComposer,
|
|
32
|
+
} from "@/sdk/SdkSessionSystemComposer.js";
|
|
29
33
|
import {
|
|
30
34
|
inferModelLabel,
|
|
31
35
|
patchSdkSessionModelLabel,
|
|
32
36
|
readSdkSessionMetadata,
|
|
37
|
+
resolveSystemTimezone,
|
|
33
38
|
writeSdkSessionMetadata,
|
|
34
39
|
} from "@/sdk/SessionMetadata.js";
|
|
35
40
|
import {
|
|
@@ -75,19 +80,19 @@ type SdkSessionOptions = {
|
|
|
75
80
|
};
|
|
76
81
|
|
|
77
82
|
/**
|
|
78
|
-
*
|
|
83
|
+
* 读取当前 SDK 调用方传入的 instruction system blocks。
|
|
79
84
|
*/
|
|
80
|
-
|
|
85
|
+
getInstructionSystemBlocks: () => AgentSessionSystemBlock[];
|
|
81
86
|
|
|
82
87
|
/**
|
|
83
|
-
* 读取当前 agent 显式注入 service 的 system
|
|
88
|
+
* 读取当前 agent 显式注入 service 的 system blocks。
|
|
84
89
|
*/
|
|
85
|
-
|
|
90
|
+
getServiceSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
86
91
|
|
|
87
92
|
/**
|
|
88
|
-
* 读取当前 agent 显式注册 plugin 的 system
|
|
93
|
+
* 读取当前 agent 显式注册 plugin 的 system blocks。
|
|
89
94
|
*/
|
|
90
|
-
|
|
95
|
+
getPluginSystemBlocks: () => Promise<AgentSessionSystemBlock[]>;
|
|
91
96
|
};
|
|
92
97
|
|
|
93
98
|
/**
|
|
@@ -100,12 +105,14 @@ export class SdkSession {
|
|
|
100
105
|
private readonly projectRoot: string;
|
|
101
106
|
private readonly tools: Record<string, Tool>;
|
|
102
107
|
private readonly logger: SdkSessionOptions["logger"];
|
|
103
|
-
private readonly
|
|
104
|
-
private readonly
|
|
105
|
-
private readonly
|
|
108
|
+
private readonly getInstructionSystemBlocks: SdkSessionOptions["getInstructionSystemBlocks"];
|
|
109
|
+
private readonly getServiceSystemBlocks: SdkSessionOptions["getServiceSystemBlocks"];
|
|
110
|
+
private readonly getPluginSystemBlocks: SdkSessionOptions["getPluginSystemBlocks"];
|
|
106
111
|
private readonly historyComposer: JsonlSessionHistoryComposer;
|
|
107
112
|
private readonly coreSession: CoreSession;
|
|
108
113
|
private sessionConfig: AgentSessionConfigSnapshot = {};
|
|
114
|
+
private createdAt = Date.now();
|
|
115
|
+
private timezone = resolveSystemTimezone();
|
|
109
116
|
private initializePromise: Promise<this> | null = null;
|
|
110
117
|
private servicePort: SessionPort | null = null;
|
|
111
118
|
|
|
@@ -115,9 +122,9 @@ export class SdkSession {
|
|
|
115
122
|
this.projectRoot = String(options.projectRoot || "").trim();
|
|
116
123
|
this.tools = options.tools;
|
|
117
124
|
this.logger = options.logger;
|
|
118
|
-
this.
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
125
|
+
this.getInstructionSystemBlocks = options.getInstructionSystemBlocks;
|
|
126
|
+
this.getServiceSystemBlocks = options.getServiceSystemBlocks;
|
|
127
|
+
this.getPluginSystemBlocks = options.getPluginSystemBlocks;
|
|
121
128
|
if (!this.id) {
|
|
122
129
|
throw new Error("SdkSession requires a non-empty sessionId");
|
|
123
130
|
}
|
|
@@ -166,10 +173,13 @@ export class SdkSession {
|
|
|
166
173
|
historyComposer,
|
|
167
174
|
compactionComposer: new JsonlSessionCompactionComposer(),
|
|
168
175
|
systemComposer: new SdkSessionSystemComposer({
|
|
176
|
+
agentId: this.agentId,
|
|
169
177
|
projectRoot: this.projectRoot,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
178
|
+
getSessionCreatedAt: () => this.createdAt,
|
|
179
|
+
getSessionTimezone: () => this.timezone,
|
|
180
|
+
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
181
|
+
getServiceSystemBlocks: this.getServiceSystemBlocks,
|
|
182
|
+
getPluginSystemBlocks: this.getPluginSystemBlocks,
|
|
173
183
|
}),
|
|
174
184
|
getTools: () => this.tools,
|
|
175
185
|
});
|
|
@@ -190,6 +200,12 @@ export class SdkSession {
|
|
|
190
200
|
agentId: this.agentId,
|
|
191
201
|
sessionId: this.id,
|
|
192
202
|
});
|
|
203
|
+
const createdAt =
|
|
204
|
+
typeof metadata.createdAt === "number" ? metadata.createdAt : Date.now();
|
|
205
|
+
const timezone =
|
|
206
|
+
typeof metadata.timezone === "string" && metadata.timezone.trim()
|
|
207
|
+
? metadata.timezone.trim()
|
|
208
|
+
: resolveSystemTimezone();
|
|
193
209
|
await writeSdkSessionMetadata({
|
|
194
210
|
projectRoot: this.projectRoot,
|
|
195
211
|
agentId: this.agentId,
|
|
@@ -197,10 +213,12 @@ export class SdkSession {
|
|
|
197
213
|
meta: {
|
|
198
214
|
...metadata,
|
|
199
215
|
agentId: this.agentId,
|
|
200
|
-
createdAt
|
|
201
|
-
|
|
216
|
+
createdAt,
|
|
217
|
+
timezone,
|
|
202
218
|
},
|
|
203
219
|
});
|
|
220
|
+
this.createdAt = createdAt;
|
|
221
|
+
this.timezone = timezone;
|
|
204
222
|
this.sessionConfig = {
|
|
205
223
|
...(metadata.sdkConfig?.modelLabel
|
|
206
224
|
? { modelLabel: metadata.sdkConfig.modelLabel }
|
|
@@ -279,20 +297,31 @@ export class SdkSession {
|
|
|
279
297
|
*
|
|
280
298
|
* 关键点(中文)
|
|
281
299
|
* - 返回内容与实际 run 时使用的 SDK system composer 同源。
|
|
282
|
-
* -
|
|
283
|
-
* -
|
|
300
|
+
* - 包含 instruction/core、显式注入 service system、显式注册 plugin system 与 session 上下文。
|
|
301
|
+
* - 返回结构化快照,不把 system prompt 写入会话历史。
|
|
284
302
|
*/
|
|
285
|
-
async system(): Promise<
|
|
286
|
-
const
|
|
303
|
+
async system(): Promise<AgentSessionSystemSnapshot> {
|
|
304
|
+
const blocks = await resolveSdkSessionSystemBlocks({
|
|
305
|
+
agentId: this.agentId,
|
|
287
306
|
projectRoot: this.projectRoot,
|
|
288
307
|
sessionId: this.id,
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
308
|
+
createdAt: this.createdAt,
|
|
309
|
+
timezone: this.timezone,
|
|
310
|
+
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
311
|
+
getServiceSystemBlocks: this.getServiceSystemBlocks,
|
|
312
|
+
getPluginSystemBlocks: this.getPluginSystemBlocks,
|
|
292
313
|
});
|
|
293
|
-
return
|
|
294
|
-
|
|
295
|
-
|
|
314
|
+
return {
|
|
315
|
+
sessionId: this.id,
|
|
316
|
+
session: {
|
|
317
|
+
agentId: this.agentId,
|
|
318
|
+
sessionId: this.id,
|
|
319
|
+
projectRoot: this.projectRoot,
|
|
320
|
+
createdAt: new Date(this.createdAt).toISOString(),
|
|
321
|
+
timezone: this.timezone,
|
|
322
|
+
},
|
|
323
|
+
blocks,
|
|
324
|
+
};
|
|
296
325
|
}
|
|
297
326
|
|
|
298
327
|
/**
|
|
@@ -401,9 +430,9 @@ export class SdkSession {
|
|
|
401
430
|
sessionId: `fork-${Date.now()}-${nanoid(8)}`,
|
|
402
431
|
tools: this.tools,
|
|
403
432
|
logger: this.logger,
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
433
|
+
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
434
|
+
getServiceSystemBlocks: this.getServiceSystemBlocks,
|
|
435
|
+
getPluginSystemBlocks: this.getPluginSystemBlocks,
|
|
407
436
|
});
|
|
408
437
|
await forked.initialize();
|
|
409
438
|
if (this.sessionConfig.model) {
|
|
@@ -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
|
*/
|
|
@@ -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
|
};
|
|
@@ -160,6 +177,7 @@ export async function patchSdkSessionModelLabel(
|
|
|
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
|
? {
|
|
@@ -27,6 +27,8 @@ export type SessionHistoryMetaV1 = {
|
|
|
27
27
|
agentId?: string;
|
|
28
28
|
/** 当前 session 首次创建时间戳(ms)。 */
|
|
29
29
|
createdAt?: number;
|
|
30
|
+
/** 当前 session 初始化时解析到的系统时区。 */
|
|
31
|
+
timezone?: string;
|
|
30
32
|
/** 最近一次更新元信息的时间戳(ms)。 */
|
|
31
33
|
updatedAt: number;
|
|
32
34
|
/** 固定注入到 Session 上下文的 skill id 列表。 */
|