@downcity/agent 1.1.281 → 1.1.283
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/agent/AgentSessions.d.ts.map +1 -1
- package/bin/agent/AgentSessions.js +1 -0
- package/bin/agent/AgentSessions.js.map +1 -1
- package/bin/executor/Executor.d.ts +4 -1
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +6 -1
- package/bin/executor/Executor.js.map +1 -1
- package/bin/session/Session.d.ts +24 -4
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +102 -23
- package/bin/session/Session.js.map +1 -1
- package/bin/session/storage/Instruction.d.ts +7 -5
- package/bin/session/storage/Instruction.d.ts.map +1 -1
- package/bin/session/storage/Instruction.js +9 -5
- package/bin/session/storage/Instruction.js.map +1 -1
- package/bin/session/storage/Paths.d.ts +2 -2
- package/bin/session/storage/Paths.js +2 -2
- package/bin/types/agent/SessionActor.d.ts +3 -1
- package/bin/types/agent/SessionActor.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +2 -2
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/session/SessionInstruction.d.ts +3 -3
- package/bin/types/session/SessionInstruction.d.ts.map +1 -1
- package/bin/types/session/SessionInstruction.js +2 -2
- package/bin/types/session/SessionOptions.d.ts +9 -1
- package/bin/types/session/SessionOptions.d.ts.map +1 -1
- package/package.json +3 -3
- package/scripts/agent-compiler.mjs +12 -5
- package/scripts/session-config-turn-boundary.test.mjs +141 -5
- package/src/agent/AgentSessions.ts +1 -0
- package/src/executor/Executor.ts +9 -1
- package/src/session/Session.ts +115 -26
- package/src/session/storage/Instruction.ts +18 -5
- package/src/session/storage/Paths.ts +2 -2
- package/src/types/agent/SessionActor.ts +4 -1
- package/src/types/agent/SessionTypes.ts +2 -2
- package/src/types/session/SessionInstruction.ts +3 -3
- package/src/types/session/SessionOptions.ts +10 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/session/Session.ts
CHANGED
|
@@ -75,6 +75,7 @@ import { buildSessionInfo } from "@/session/browse/Browse.js";
|
|
|
75
75
|
import { ensureSessionTitle } from "@/session/SessionTitle.js";
|
|
76
76
|
import { readSessionMetadata } from "@/session/storage/Metadata.js";
|
|
77
77
|
import {
|
|
78
|
+
has_session_instruction,
|
|
78
79
|
read_session_instruction,
|
|
79
80
|
write_session_instruction,
|
|
80
81
|
} from "@/session/storage/Instruction.js";
|
|
@@ -107,10 +108,16 @@ export class Session implements AgentSession {
|
|
|
107
108
|
private readonly get_agent_env: SessionOptions["getAgentEnv"];
|
|
108
109
|
private readonly get_agent_model: SessionOptions["getAgentModel"];
|
|
109
110
|
private readonly get_agent_plugins: SessionOptions["get_agent_plugins"];
|
|
111
|
+
private readonly get_instruction_system_blocks:
|
|
112
|
+
SessionOptions["get_instruction_system_blocks"];
|
|
110
113
|
private effective_instruction_system_blocks: AgentSessionSystemBlock[];
|
|
111
114
|
private instruction_initialize_promise: Promise<void> | null = null;
|
|
112
115
|
private effective_agent_env: Record<string, string>;
|
|
113
116
|
private effective_agent_plugins: AgentPluginExecutionRuntime;
|
|
117
|
+
/** 当前 Session 首次生成后固定的完整 system snapshot。 */
|
|
118
|
+
private system_snapshot_blocks: AgentSessionSystemBlock[] | null = null;
|
|
119
|
+
/** 串行化 snapshot / syncshot 对 system 与 instruction.md 的修改。 */
|
|
120
|
+
private system_mutation_chain: Promise<void> = Promise.resolve();
|
|
114
121
|
private readonly state: SessionState;
|
|
115
122
|
private readonly session_turn: SessionTurn;
|
|
116
123
|
private runtime_port: SessionPort | null = null;
|
|
@@ -124,6 +131,7 @@ export class Session implements AgentSession {
|
|
|
124
131
|
this.get_agent_env = options.getAgentEnv;
|
|
125
132
|
this.get_agent_model = options.getAgentModel;
|
|
126
133
|
this.get_agent_plugins = options.get_agent_plugins;
|
|
134
|
+
this.get_instruction_system_blocks = options.get_instruction_system_blocks;
|
|
127
135
|
this.effective_instruction_system_blocks = options
|
|
128
136
|
.instruction_system_blocks
|
|
129
137
|
.map((block) => ({ ...block }));
|
|
@@ -200,23 +208,52 @@ export class Session implements AgentSession {
|
|
|
200
208
|
}
|
|
201
209
|
|
|
202
210
|
/**
|
|
203
|
-
* 把当前 Session
|
|
211
|
+
* 把当前 Session 首次生成后固定的完整 system 显式固化到 instruction.md。
|
|
204
212
|
*
|
|
205
213
|
* 关键点(中文)
|
|
206
|
-
* -
|
|
207
|
-
* - 多个
|
|
214
|
+
* - 包含 instruction、SDK core、plugin system 与 Session context。
|
|
215
|
+
* - 多个 system block 按原顺序合并为一个 Markdown 文档。
|
|
208
216
|
*/
|
|
209
217
|
async snapshot(): Promise<void> {
|
|
210
|
-
await this.
|
|
211
|
-
|
|
212
|
-
.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
await this.run_system_mutation(async () => {
|
|
219
|
+
const system_snapshot = await this.system();
|
|
220
|
+
await this.write_system_snapshot(system_snapshot.blocks);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* 使用 Agent 当前 instruction 与 plugin 重新生成一次完整 system。
|
|
226
|
+
*
|
|
227
|
+
* 关键点(中文)
|
|
228
|
+
* - 只替换内存 snapshot,不改变 plugin execution view。
|
|
229
|
+
* - instruction.md 已存在时同步覆盖;不存在时不自动创建。
|
|
230
|
+
* - 当前已经发出的 provider 请求不受影响,后续 step 使用新 snapshot。
|
|
231
|
+
*/
|
|
232
|
+
async syncshot(): Promise<void> {
|
|
233
|
+
await this.run_system_mutation(async () => {
|
|
234
|
+
await this.initialize_instruction();
|
|
235
|
+
const should_persist = await has_session_instruction({
|
|
236
|
+
project_root: this.project_root,
|
|
237
|
+
agent_id: this.agentId,
|
|
238
|
+
session_id: this.id,
|
|
239
|
+
});
|
|
240
|
+
const run_context: SessionRunContext = {
|
|
241
|
+
sessionId: this.id,
|
|
242
|
+
injectedUserMessages: [],
|
|
243
|
+
deferredPersistedUserMessages: [],
|
|
244
|
+
pendingAssistantFileParts: [],
|
|
245
|
+
};
|
|
246
|
+
const composed = await this.composer.compose(
|
|
247
|
+
await this.create_compose_input(run_context, 0, true),
|
|
248
|
+
);
|
|
249
|
+
const next_blocks = resolve_composed_system_blocks(composed);
|
|
250
|
+
|
|
251
|
+
if (should_persist) {
|
|
252
|
+
await this.write_system_snapshot(next_blocks);
|
|
253
|
+
}
|
|
254
|
+
this.effective_instruction_system_blocks =
|
|
255
|
+
this.get_instruction_system_blocks().map((block) => ({ ...block }));
|
|
256
|
+
this.system_snapshot_blocks = next_blocks;
|
|
220
257
|
});
|
|
221
258
|
}
|
|
222
259
|
|
|
@@ -556,6 +593,7 @@ export class Session implements AgentSession {
|
|
|
556
593
|
instruction_system_blocks: this.effective_instruction_system_blocks.map(
|
|
557
594
|
(block) => ({ ...block }),
|
|
558
595
|
),
|
|
596
|
+
get_instruction_system_blocks: this.get_instruction_system_blocks,
|
|
559
597
|
getAgentEnv: this.get_agent_env,
|
|
560
598
|
get_agent_plugins: this.get_agent_plugins,
|
|
561
599
|
getManagedPluginSystemBlocks: this.get_managed_plugin_system_blocks,
|
|
@@ -579,7 +617,7 @@ export class Session implements AgentSession {
|
|
|
579
617
|
return new SessionClass(options) as this;
|
|
580
618
|
}
|
|
581
619
|
|
|
582
|
-
/**
|
|
620
|
+
/** 恢复显式固化的完整 system snapshot;文件不存在时等待首次生成。 */
|
|
583
621
|
private async initialize_instruction(): Promise<void> {
|
|
584
622
|
if (!this.instruction_initialize_promise) {
|
|
585
623
|
this.instruction_initialize_promise = (async () => {
|
|
@@ -591,6 +629,13 @@ export class Session implements AgentSession {
|
|
|
591
629
|
if (persisted_instruction === null) return;
|
|
592
630
|
|
|
593
631
|
const instruction = persisted_instruction.trim();
|
|
632
|
+
this.system_snapshot_blocks = instruction
|
|
633
|
+
? [{
|
|
634
|
+
source: "instruction" as const,
|
|
635
|
+
name: "snapshot",
|
|
636
|
+
content: instruction,
|
|
637
|
+
}]
|
|
638
|
+
: [];
|
|
594
639
|
const stable_system_blocks = this.effective_instruction_system_blocks
|
|
595
640
|
.filter((block) => block.source !== "instruction")
|
|
596
641
|
.map((block) => ({ ...block }));
|
|
@@ -650,6 +695,7 @@ export class Session implements AgentSession {
|
|
|
650
695
|
getModel: () => this.get_model(),
|
|
651
696
|
logger: this.logger,
|
|
652
697
|
get_plugins: () => this.effective_agent_plugins,
|
|
698
|
+
apply_system_snapshot: (input) => this.apply_system_snapshot(input),
|
|
653
699
|
});
|
|
654
700
|
}
|
|
655
701
|
|
|
@@ -657,10 +703,18 @@ export class Session implements AgentSession {
|
|
|
657
703
|
private async create_compose_input(
|
|
658
704
|
run_context: SessionRunContext,
|
|
659
705
|
retry_count: number,
|
|
706
|
+
refresh_system = false,
|
|
660
707
|
): Promise<SessionComposeInput> {
|
|
661
|
-
const
|
|
662
|
-
?
|
|
663
|
-
:
|
|
708
|
+
const instruction_system_blocks = refresh_system
|
|
709
|
+
? this.get_instruction_system_blocks().map((block) => ({ ...block }))
|
|
710
|
+
: this.effective_instruction_system_blocks.map((block) => ({ ...block }));
|
|
711
|
+
const plugin_system_blocks = this.system_snapshot_blocks && !refresh_system
|
|
712
|
+
? []
|
|
713
|
+
: refresh_system
|
|
714
|
+
? await this.get_agent_plugins().systemBlocks(run_context)
|
|
715
|
+
: run_context.agentPlugins
|
|
716
|
+
? await run_context.agentPlugins.systemBlocks(run_context)
|
|
717
|
+
: await this.effective_agent_plugins.systemBlocks(run_context);
|
|
664
718
|
return {
|
|
665
719
|
session: {
|
|
666
720
|
agent_id: this.agentId,
|
|
@@ -674,17 +728,14 @@ export class Session implements AgentSession {
|
|
|
674
728
|
model_context_window: this.get_model_context_window(),
|
|
675
729
|
env: Object.freeze({ ...this.effective_agent_env }),
|
|
676
730
|
systems: Object.freeze(
|
|
677
|
-
|
|
678
|
-
(block) => block.content,
|
|
679
|
-
),
|
|
731
|
+
instruction_system_blocks.map((block) => block.content),
|
|
680
732
|
),
|
|
681
733
|
tools: Object.freeze({ ...this.tools }),
|
|
682
|
-
instruction_system_blocks
|
|
683
|
-
this.effective_instruction_system_blocks.map(
|
|
684
|
-
(block) => ({ ...block }),
|
|
685
|
-
),
|
|
734
|
+
instruction_system_blocks,
|
|
686
735
|
managed_plugin_system_blocks:
|
|
687
|
-
|
|
736
|
+
this.system_snapshot_blocks && !refresh_system
|
|
737
|
+
? []
|
|
738
|
+
: await this.get_managed_plugin_system_blocks(),
|
|
688
739
|
plugin_system_blocks,
|
|
689
740
|
},
|
|
690
741
|
history: await this.session_messages.context_snapshot(),
|
|
@@ -703,9 +754,47 @@ export class Session implements AgentSession {
|
|
|
703
754
|
deferredPersistedUserMessages: [],
|
|
704
755
|
pendingAssistantFileParts: [],
|
|
705
756
|
};
|
|
706
|
-
|
|
757
|
+
const composed = await this.composer.compose(
|
|
707
758
|
await this.create_compose_input(run_context, 0),
|
|
708
759
|
);
|
|
760
|
+
return this.apply_system_snapshot(composed);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/** 固定或应用当前 Session 的 system snapshot。 */
|
|
764
|
+
private apply_system_snapshot(input: SessionStepInput): SessionStepInput {
|
|
765
|
+
if (!this.system_snapshot_blocks) {
|
|
766
|
+
this.system_snapshot_blocks = resolve_composed_system_blocks(input);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return {
|
|
770
|
+
...input,
|
|
771
|
+
system: this.system_snapshot_blocks.map((block) => ({
|
|
772
|
+
role: "system" as const,
|
|
773
|
+
content: block.content,
|
|
774
|
+
})),
|
|
775
|
+
system_blocks: this.system_snapshot_blocks.map((block) => ({ ...block })),
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/** 串行执行一次 Session system 修改。 */
|
|
780
|
+
private async run_system_mutation(
|
|
781
|
+
operation: () => Promise<void>,
|
|
782
|
+
): Promise<void> {
|
|
783
|
+
const next = this.system_mutation_chain.then(operation, operation);
|
|
784
|
+
this.system_mutation_chain = next.catch(() => undefined);
|
|
785
|
+
await next;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/** 把指定完整 system blocks 原子写入 instruction.md。 */
|
|
789
|
+
private async write_system_snapshot(
|
|
790
|
+
blocks: readonly AgentSessionSystemBlock[],
|
|
791
|
+
): Promise<void> {
|
|
792
|
+
await write_session_instruction({
|
|
793
|
+
project_root: this.project_root,
|
|
794
|
+
agent_id: this.agentId,
|
|
795
|
+
session_id: this.id,
|
|
796
|
+
instruction: blocks.map((block) => block.content).join("\n\n"),
|
|
797
|
+
});
|
|
709
798
|
}
|
|
710
799
|
|
|
711
800
|
/** 提交 Composer 生成的 Segment 压缩计划。 */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session
|
|
2
|
+
* Session system 显式快照存储。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* - instruction.md 是可选文件,不存在时由 Session
|
|
6
|
-
* -
|
|
5
|
+
* - instruction.md 是可选文件,不存在时由 Session 在内存中重新生成完整 system。
|
|
6
|
+
* - 空文件也是有效的完整 system 快照。
|
|
7
7
|
* - 写入使用同目录临时文件替换,避免进程中断留下半份内容。
|
|
8
8
|
*/
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
WriteSessionInstructionInput,
|
|
17
17
|
} from "@/types/session/SessionInstruction.js";
|
|
18
18
|
|
|
19
|
-
/** 读取 Session
|
|
19
|
+
/** 读取 Session 显式固化的完整 system;文件不存在时返回 null。 */
|
|
20
20
|
export async function read_session_instruction(
|
|
21
21
|
input: SessionInstructionStorageLocation,
|
|
22
22
|
): Promise<string | null> {
|
|
@@ -33,7 +33,20 @@ export async function read_session_instruction(
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
/**
|
|
36
|
+
/** 判断当前 Session 是否已经显式持久化 instruction.md。 */
|
|
37
|
+
export async function has_session_instruction(
|
|
38
|
+
input: SessionInstructionStorageLocation,
|
|
39
|
+
): Promise<boolean> {
|
|
40
|
+
return await fs.pathExists(
|
|
41
|
+
getSdkAgentSessionInstructionPath(
|
|
42
|
+
input.project_root,
|
|
43
|
+
input.agent_id,
|
|
44
|
+
input.session_id,
|
|
45
|
+
),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 使用完整 system Markdown 原子覆盖当前 Session 的 instruction.md。 */
|
|
37
50
|
export async function write_session_instruction(
|
|
38
51
|
input: WriteSessionInstructionInput,
|
|
39
52
|
): Promise<void> {
|
|
@@ -130,11 +130,11 @@ export function getSdkAgentSessionDirPath(
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
|
-
* 单个 session
|
|
133
|
+
* 单个 session 显式固化完整 system 的 instruction.md 路径。
|
|
134
134
|
*
|
|
135
135
|
* 关键点(中文)
|
|
136
136
|
* - 文件不存在表示 Session 恢复时继续采用 Agent 当前 instruction。
|
|
137
|
-
* - 空文件表示调用方显式固化了空
|
|
137
|
+
* - 空文件表示调用方显式固化了空 system。
|
|
138
138
|
*/
|
|
139
139
|
export function getSdkAgentSessionInstructionPath(
|
|
140
140
|
projectRoot: string,
|
|
@@ -125,9 +125,12 @@ export interface AgentSession extends AgentSessionActor {
|
|
|
125
125
|
/** 写入当前 session 默认配置。 */
|
|
126
126
|
set(input: AgentSessionSetInput): Promise<void>;
|
|
127
127
|
|
|
128
|
-
/** 把当前 Session
|
|
128
|
+
/** 把当前 Session 首次生成后固定的完整 system 显式固化到 instruction.md。 */
|
|
129
129
|
snapshot(): Promise<void>;
|
|
130
130
|
|
|
131
|
+
/** 使用 Agent 当前 instruction 与 plugin 显式重新生成 Session system。 */
|
|
132
|
+
syncshot(): Promise<void>;
|
|
133
|
+
|
|
131
134
|
/** 从当前 session 创建一个分叉会话。 */
|
|
132
135
|
fork(input?: AgentSessionForkInput | string): Promise<AgentSession>;
|
|
133
136
|
}
|
|
@@ -203,7 +203,7 @@ export interface AgentSessionSystemSessionInfo {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
|
-
* 当前 session
|
|
206
|
+
* 当前 session 首次生成后固定的完整 system prompt 快照。
|
|
207
207
|
*/
|
|
208
208
|
export interface AgentSessionSystemSnapshot {
|
|
209
209
|
/** 当前 sessionId。 */
|
|
@@ -217,7 +217,7 @@ export interface AgentSessionSystemSnapshot {
|
|
|
217
217
|
* - 每轮动态信息应由调用方放入 user message,避免破坏 instruction 缓存命中。
|
|
218
218
|
*/
|
|
219
219
|
session: AgentSessionSystemSessionInfo;
|
|
220
|
-
/**
|
|
220
|
+
/** 首次生成后固定的 system blocks,按进入模型的顺序排列。 */
|
|
221
221
|
blocks: AgentSessionSystemBlock[];
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session
|
|
2
|
+
* Session system 显式快照存储类型。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 这里只描述 instruction.md 的定位与写入输入。
|
|
6
|
-
* - 文件存在性本身用于表达 Session 是否启用显式
|
|
6
|
+
* - 文件存在性本身用于表达 Session 是否启用显式 system 快照。
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** Session instruction.md 的稳定定位信息。 */
|
|
@@ -19,6 +19,6 @@ export interface SessionInstructionStorageLocation {
|
|
|
19
19
|
/** 原子写入 Session instruction.md 使用的完整输入。 */
|
|
20
20
|
export interface WriteSessionInstructionInput
|
|
21
21
|
extends SessionInstructionStorageLocation {
|
|
22
|
-
/** 当前 Session
|
|
22
|
+
/** 当前 Session 首次生成后固定的完整 system Markdown。 */
|
|
23
23
|
instruction: string;
|
|
24
24
|
}
|
|
@@ -78,10 +78,19 @@ export interface SessionOptions {
|
|
|
78
78
|
*
|
|
79
79
|
* 关键点(中文)
|
|
80
80
|
* - Session 创建后不再动态读取 Agent instruction。
|
|
81
|
-
* - `session.snapshot()`
|
|
81
|
+
* - `session.snapshot()` 会把首次生成后固定的完整 system 显式写入本地文件。
|
|
82
82
|
*/
|
|
83
83
|
instruction_system_blocks: AgentSessionSystemBlock[];
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* 读取当前 Agent configured instruction system blocks。
|
|
87
|
+
*
|
|
88
|
+
* 关键点(中文)
|
|
89
|
+
* - 仅供 `session.syncshot()` 显式重新生成 system 使用。
|
|
90
|
+
* - 普通 Session 执行仍使用首次生成后固定的 system snapshot。
|
|
91
|
+
*/
|
|
92
|
+
get_instruction_system_blocks: () => AgentSessionSystemBlock[];
|
|
93
|
+
|
|
85
94
|
/**
|
|
86
95
|
* 读取当前 Agent configured env。
|
|
87
96
|
*
|