@downcity/agent 1.1.277 → 1.1.279

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 (47) hide show
  1. package/bin/agent/Agent.d.ts.map +1 -1
  2. package/bin/agent/Agent.js +0 -1
  3. package/bin/agent/Agent.js.map +1 -1
  4. package/bin/agent/AgentSessions.d.ts +0 -4
  5. package/bin/agent/AgentSessions.d.ts.map +1 -1
  6. package/bin/agent/AgentSessions.js +2 -17
  7. package/bin/agent/AgentSessions.js.map +1 -1
  8. package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
  9. package/bin/executor/composer/system/default/assets/core.prompt.d.ts.map +1 -1
  10. package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
  11. package/bin/executor/composer/system/default/assets/core.prompt.js.map +1 -1
  12. package/bin/session/Session.d.ts +11 -1
  13. package/bin/session/Session.d.ts.map +1 -1
  14. package/bin/session/Session.js +61 -24
  15. package/bin/session/Session.js.map +1 -1
  16. package/bin/session/storage/Instruction.d.ts +14 -0
  17. package/bin/session/storage/Instruction.d.ts.map +1 -0
  18. package/bin/session/storage/Instruction.js +44 -0
  19. package/bin/session/storage/Instruction.js.map +1 -0
  20. package/bin/session/storage/Paths.d.ts +8 -0
  21. package/bin/session/storage/Paths.d.ts.map +1 -1
  22. package/bin/session/storage/Paths.js +10 -0
  23. package/bin/session/storage/Paths.js.map +1 -1
  24. package/bin/types/agent/SessionActor.d.ts +2 -0
  25. package/bin/types/agent/SessionActor.d.ts.map +1 -1
  26. package/bin/types/session/SessionInstruction.d.ts +22 -0
  27. package/bin/types/session/SessionInstruction.d.ts.map +1 -0
  28. package/bin/types/session/SessionInstruction.js +9 -0
  29. package/bin/types/session/SessionInstruction.js.map +1 -0
  30. package/bin/types/session/SessionOptions.d.ts +6 -2
  31. package/bin/types/session/SessionOptions.d.ts.map +1 -1
  32. package/bin/types/session/SessionQueue.d.ts +2 -18
  33. package/bin/types/session/SessionQueue.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/scripts/session-config-turn-boundary.test.mjs +156 -5
  36. package/src/agent/Agent.ts +0 -1
  37. package/src/agent/AgentSessions.ts +2 -21
  38. package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
  39. package/src/executor/composer/system/default/assets/core.prompt.ts.txt +1 -0
  40. package/src/session/Session.ts +68 -26
  41. package/src/session/storage/Instruction.ts +59 -0
  42. package/src/session/storage/Paths.ts +18 -0
  43. package/src/types/agent/SessionActor.ts +3 -0
  44. package/src/types/session/SessionInstruction.ts +24 -0
  45. package/src/types/session/SessionOptions.ts +6 -2
  46. package/src/types/session/SessionQueue.ts +9 -29
  47. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Session instruction 显式快照存储。
3
+ *
4
+ * 关键点(中文)
5
+ * - instruction.md 是可选文件,不存在时由 Session 使用 Agent 当前 instruction。
6
+ * - 空文件也是有效快照,用于显式固化没有自定义 instruction 的状态。
7
+ * - 写入使用同目录临时文件替换,避免进程中断留下半份内容。
8
+ */
9
+ import { randomUUID } from "node:crypto";
10
+ import path from "node:path";
11
+ import fs from "fs-extra";
12
+ import { getSdkAgentSessionInstructionPath } from "../../session/storage/Paths.js";
13
+ /** 读取 Session 显式固化的 instruction;文件不存在时返回 null。 */
14
+ export async function read_session_instruction(input) {
15
+ const instruction_path = getSdkAgentSessionInstructionPath(input.project_root, input.agent_id, input.session_id);
16
+ try {
17
+ return await fs.readFile(instruction_path, "utf8");
18
+ }
19
+ catch (error) {
20
+ if (error.code === "ENOENT")
21
+ return null;
22
+ throw error;
23
+ }
24
+ }
25
+ /** 原子覆盖当前 Session 的 instruction.md。 */
26
+ export async function write_session_instruction(input) {
27
+ const instruction_path = getSdkAgentSessionInstructionPath(input.project_root, input.agent_id, input.session_id);
28
+ const temporary_path = [
29
+ instruction_path,
30
+ process.pid,
31
+ Date.now(),
32
+ randomUUID(),
33
+ "tmp",
34
+ ].join(".");
35
+ await fs.ensureDir(path.dirname(instruction_path));
36
+ try {
37
+ await fs.writeFile(temporary_path, input.instruction, "utf8");
38
+ await fs.move(temporary_path, instruction_path, { overwrite: true });
39
+ }
40
+ finally {
41
+ await fs.remove(temporary_path);
42
+ }
43
+ }
44
+ //# sourceMappingURL=Instruction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Instruction.js","sourceRoot":"","sources":["../../../src/session/storage/Instruction.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAM/E,kDAAkD;AAClD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAwC;IAExC,MAAM,gBAAgB,GAAG,iCAAiC,CACxD,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,UAAU,CACjB,CAAC;IACF,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACpE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,uCAAuC;AACvC,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,KAAmC;IAEnC,MAAM,gBAAgB,GAAG,iCAAiC,CACxD,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,UAAU,CACjB,CAAC;IACF,MAAM,cAAc,GAAG;QACrB,gBAAgB;QAChB,OAAO,CAAC,GAAG;QACX,IAAI,CAAC,GAAG,EAAE;QACV,UAAU,EAAE;QACZ,KAAK;KACN,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
@@ -49,6 +49,14 @@ export declare function getSdkAgentArchivedSessionMetaPath(projectRoot: string,
49
49
  * 单个 session 根目录路径。
50
50
  */
51
51
  export declare function getSdkAgentSessionDirPath(projectRoot: string, agentId: string, sessionId: string): string;
52
+ /**
53
+ * 单个 session 显式固化的 instruction.md 路径。
54
+ *
55
+ * 关键点(中文)
56
+ * - 文件不存在表示 Session 恢复时继续采用 Agent 当前 instruction。
57
+ * - 空文件表示调用方显式固化了空 instruction。
58
+ */
59
+ export declare function getSdkAgentSessionInstructionPath(projectRoot: string, agentId: string, sessionId: string): string;
52
60
  /**
53
61
  * 单个 session 的消息目录路径。
54
62
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Paths.d.ts","sourceRoot":"","sources":["../../../src/session/storage/Paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,yCAAyC,CACvD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;;;;;;GAOG;AACH,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR"}
1
+ {"version":3,"file":"Paths.d.ts","sourceRoot":"","sources":["../../../src/session/storage/Paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,yCAAyC,CACvD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR;AAED;;;;;;;GAOG;AACH,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR"}
@@ -70,6 +70,16 @@ export function getSdkAgentArchivedSessionMetaPath(projectRoot, agentId, session
70
70
  export function getSdkAgentSessionDirPath(projectRoot, agentId, sessionId) {
71
71
  return path.join(getSdkAgentSessionsRootDirPath(projectRoot, agentId), encodeURIComponent(String(sessionId || "").trim()));
72
72
  }
73
+ /**
74
+ * 单个 session 显式固化的 instruction.md 路径。
75
+ *
76
+ * 关键点(中文)
77
+ * - 文件不存在表示 Session 恢复时继续采用 Agent 当前 instruction。
78
+ * - 空文件表示调用方显式固化了空 instruction。
79
+ */
80
+ export function getSdkAgentSessionInstructionPath(projectRoot, agentId, sessionId) {
81
+ return path.join(getSdkAgentSessionDirPath(projectRoot, agentId, sessionId), "instruction.md");
82
+ }
73
83
  /**
74
84
  * 单个 session 的消息目录路径。
75
85
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Paths.js","sourceRoot":"","sources":["../../../src/session/storage/Paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Paths.js","sourceRoot":"","sources":["../../../src/session/storage/Paths.ts"],"names":[],"mappings":"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"}
@@ -74,6 +74,8 @@ export interface AgentSession extends AgentSessionActor {
74
74
  readonly config: AgentSessionConfigSnapshot;
75
75
  /** 写入当前 session 默认配置。 */
76
76
  set(input: AgentSessionSetInput): Promise<void>;
77
+ /** 把当前 Session 生效的自定义 instruction 显式固化到 instruction.md。 */
78
+ snapshot(): Promise<void>;
77
79
  /** 从当前 session 创建一个分叉会话。 */
78
80
  fork(input?: AgentSessionForkInput | string): Promise<AgentSession>;
79
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SessionActor.d.ts","sourceRoot":"","sources":["../../../src/types/agent/SessionActor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SessionActor.d.ts","sourceRoot":"","sources":["../../../src/types/agent/SessionActor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Session instruction 显式快照存储类型。
3
+ *
4
+ * 关键点(中文)
5
+ * - 这里只描述 instruction.md 的定位与写入输入。
6
+ * - 文件存在性本身用于表达 Session 是否启用显式 instruction 快照。
7
+ */
8
+ /** Session instruction.md 的稳定定位信息。 */
9
+ export interface SessionInstructionStorageLocation {
10
+ /** 当前项目根目录。 */
11
+ project_root: string;
12
+ /** 当前 Agent 稳定标识。 */
13
+ agent_id: string;
14
+ /** 当前 Session 稳定标识。 */
15
+ session_id: string;
16
+ }
17
+ /** 原子写入 Session instruction.md 使用的完整输入。 */
18
+ export interface WriteSessionInstructionInput extends SessionInstructionStorageLocation {
19
+ /** 当前 Session 生效的自定义 instruction Markdown。 */
20
+ instruction: string;
21
+ }
22
+ //# sourceMappingURL=SessionInstruction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionInstruction.d.ts","sourceRoot":"","sources":["../../../src/types/session/SessionInstruction.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,sCAAsC;AACtC,MAAM,WAAW,iCAAiC;IAChD,eAAe;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,4BACf,SAAQ,iCAAiC;IACzC,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Session instruction 显式快照存储类型。
3
+ *
4
+ * 关键点(中文)
5
+ * - 这里只描述 instruction.md 的定位与写入输入。
6
+ * - 文件存在性本身用于表达 Session 是否启用显式 instruction 快照。
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=SessionInstruction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionInstruction.js","sourceRoot":"","sources":["../../../src/types/session/SessionInstruction.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -61,9 +61,13 @@ export interface SessionOptions {
61
61
  */
62
62
  logger: Logger;
63
63
  /**
64
- * 读取当前 SDK 调用方传入的 instruction system blocks。
64
+ * 当前 Session 创建时绑定的 instruction system blocks。
65
+ *
66
+ * 关键点(中文)
67
+ * - Session 创建后不再动态读取 Agent instruction。
68
+ * - `session.snapshot()` 只会把其中 `instruction` 来源的内容显式写入本地文件。
65
69
  */
66
- getInstructionSystemBlocks: () => AgentSessionSystemBlock[];
70
+ instruction_system_blocks: AgentSessionSystemBlock[];
67
71
  /**
68
72
  * 读取当前 Agent configured env。
69
73
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SessionOptions.d.ts","sourceRoot":"","sources":["../../../src/types/session/SessionOptions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,cAAc,IAAI,WAAW,CAAC;IAE9B;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,qBAAqB,CACnB,OAAO,EAAE,mBAAmB,GAC3B,IAAI,CAAC;CACT;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,0BAA0B,EAAE,MAAM,uBAAuB,EAAE,CAAC;IAE5D;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE1C,wDAAwD;IACxD,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;IAErD;;OAEG;IACH,4BAA4B,EAAE,MAAM,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAEvE;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE,6BAA6B;IAC7B,aAAa,EAAE,MAAM,UAAU,GAAG,SAAS,CAAC;IAE5C,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B"}
1
+ {"version":3,"file":"SessionOptions.d.ts","sourceRoot":"","sources":["../../../src/types/session/SessionOptions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,cAAc,IAAI,WAAW,CAAC;IAE9B;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,qBAAqB,CACnB,OAAO,EAAE,mBAAmB,GAC3B,IAAI,CAAC;CACT;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,yBAAyB,EAAE,uBAAuB,EAAE,CAAC;IAErD;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE1C,wDAAwD;IACxD,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;IAErD;;OAEG;IACH,4BAA4B,EAAE,MAAM,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAEvE;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnE,6BAA6B;IAC7B,aAAa,EAAE,MAAM,UAAU,GAAG,SAAS,CAAC;IAE5C,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 队列只保存明确的输入事实,不保存可执行闭包。SessionTurn 是这些输入的唯一解释者。
5
5
  */
6
- import type { AgentSessionConfigSnapshot, AgentSessionSystemBlock } from "../../types/agent/SessionTypes.js";
6
+ import type { AgentSessionConfigSnapshot } from "../../types/agent/SessionTypes.js";
7
7
  import type { AgentPluginExecutionRuntime } from "../../types/plugin/PluginRuntime.js";
8
8
  import type { AgentSessionPromptInput } from "../../types/sdk/AgentSessionPrompt.js";
9
9
  import type { AgentSessionTurnHandle } from "../../types/sdk/AgentSessionTurn.js";
@@ -20,15 +20,6 @@ export interface SessionModelQueueCommand {
20
20
  /** 配置生效后需要写入的可选 Action 标题。 */
21
21
  action_title?: string;
22
22
  }
23
- /** Agent instruction 在 Session Step 检查点生效的命令。 */
24
- export interface SessionInstructionQueueCommand {
25
- /** 命令种类固定为 Agent instruction 更新。 */
26
- type: "agent_instruction";
27
- /** 当前命令的稳定唯一标识。 */
28
- command_id: string;
29
- /** 下一 Step 使用的完整 instruction blocks。 */
30
- instruction_blocks: AgentSessionSystemBlock[];
31
- }
32
23
  /** Agent env 在 Session Step 检查点生效的命令。 */
33
24
  export interface SessionEnvQueueCommand {
34
25
  /** 命令种类固定为 Agent env 更新。 */
@@ -57,16 +48,9 @@ export interface SessionCompactQueueCommand {
57
48
  command_id: string;
58
49
  }
59
50
  /** Session FIFO 中允许出现的领域命令。 */
60
- export type SessionQueueCommand = SessionModelQueueCommand | SessionInstructionQueueCommand | SessionEnvQueueCommand | SessionPluginsQueueCommand | SessionCompactQueueCommand;
51
+ export type SessionQueueCommand = SessionModelQueueCommand | SessionEnvQueueCommand | SessionPluginsQueueCommand | SessionCompactQueueCommand;
61
52
  /** Agent configured state 广播给既有 Session 的输入。 */
62
53
  export type AgentSessionCommand = {
63
- /** 当前修改固定为 instruction。 */
64
- type: "instruction";
65
- /** 当前命令唯一标识。 */
66
- command_id: string;
67
- /** 下一 Session Step 使用的 instruction blocks。 */
68
- instruction_blocks: AgentSessionSystemBlock[];
69
- } | {
70
54
  /** 当前修改固定为 env。 */
71
55
  type: "env";
72
56
  /** 当前命令唯一标识。 */
@@ -1 +1 @@
1
- {"version":3,"file":"SessionQueue.d.ts","sourceRoot":"","sources":["../../../src/types/session/SessionQueue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SessionQueue.d.ts","sourceRoot":"","sources":["../../../src/types/session/SessionQueue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE9E,mCAAmC;AACnC,MAAM,WAAW,wBAAwB;IACvC,4BAA4B;IAC5B,IAAI,EAAE,eAAe,CAAC;IACtB,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,MAAM,EAAE,0BAA0B,CAAC;IACnC,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,yCAAyC;AACzC,MAAM,WAAW,sBAAsB;IACrC,4BAA4B;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,8CAA8C;AAC9C,MAAM,WAAW,0BAA0B;IACzC,+BAA+B;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,OAAO,EAAE,2BAA2B,CAAC;CACtC;AAED,mBAAmB;AACnB,MAAM,WAAW,0BAA0B;IACzC,uBAAuB;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,+BAA+B;AAC/B,MAAM,MAAM,mBAAmB,GAC3B,wBAAwB,GACxB,sBAAsB,GACtB,0BAA0B,GAC1B,0BAA0B,CAAC;AAE/B,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG;IAC9B,mBAAmB;IACnB,IAAI,EAAE,KAAK,CAAC;IACZ,gBAAgB;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B,GACC;IACE,uBAAuB;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,OAAO,EAAE,2BAA2B,CAAC;CACtC,CAAC;AAEN,wBAAwB;AACxB,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,sBAAsB;IACtB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,oBAAoB;IACpB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC7B;AAED,mCAAmC;AACnC,MAAM,WAAW,mBAAmB;IAClC,uBAAuB;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,wBAAwB;IACxB,KAAK,EAAE,uBAAuB,CAAC;IAC/B,0CAA0C;IAC1C,eAAe,EAAE,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;CAC/D;AAED,6BAA6B;AAC7B,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@downcity/agent",
3
- "version": "1.1.277",
3
+ "version": "1.1.279",
4
4
  "type": "module",
5
5
  "description": "Downcity Agent 运行时 — 单 Agent 执行壳与本机 RPC 能力",
6
6
  "main": "./bin/index.js",
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 第一次 provider 请求保持阻塞,用来制造真实的运行中配置修改窗口。
6
- * - instructionenv 与 plugin registry 修改不能改变已经开始的请求。
6
+ * - Agent instruction 修改不能改变已有 Session;env 与 plugin registry 修改在 step 检查点生效。
7
7
  * - config 与 steer 在同一个 Session step 检查点提交,并继续使用同一个 turn id。
8
8
  */
9
9
 
@@ -58,7 +58,7 @@ function create_stream_text_result(text) {
58
58
  };
59
59
  }
60
60
 
61
- test("running Agent config changes and steer apply at the same Session step checkpoint", async () => {
61
+ test("Agent instruction changes only affect newly created Sessions", async () => {
62
62
  const agent_path = await fs.mkdtemp(
63
63
  path.join(os.tmpdir(), "downcity-agent-config-turn-boundary-"),
64
64
  );
@@ -133,8 +133,8 @@ test("running Agent config changes and steer apply at the same Session step chec
133
133
  assert.equal((await steer_turn.finished).success, true);
134
134
  assert.equal(plugin_stop_count, 1);
135
135
  assert.equal(provider_prompts.length, 2);
136
- assert.match(provider_prompts[1], /instruction:new/);
137
- assert.doesNotMatch(provider_prompts[1], /instruction:old/);
136
+ assert.match(provider_prompts[1], /instruction:old/);
137
+ assert.doesNotMatch(provider_prompts[1], /instruction:new/);
138
138
  assert.doesNotMatch(provider_prompts[1], /plugin-env:old/);
139
139
 
140
140
  const messages = await session.messages();
@@ -142,16 +142,167 @@ test("running Agent config changes and steer apply at the same Session step chec
142
142
  .filter((message) => message.type === "action" && message.status === "completed")
143
143
  .map((message) => message.title);
144
144
  assert.deepEqual(completed_actions, [
145
- "Agent instruction updated",
146
145
  "Agent environment updated",
147
146
  "Agent plugin runtime-config unregistered",
148
147
  ]);
148
+
149
+ // 未显式 snapshot 的 Session 重新装载时使用 Agent 当前 instruction。
150
+ await agent.sessions.clear_messages(session.id);
151
+ const restored_session = await agent.sessions.get(session.id);
152
+ const restored_system = await restored_session.system();
153
+ const restored_system_text = restored_system.blocks
154
+ .map((block) => block.content)
155
+ .join("\n");
156
+ assert.match(restored_system_text, /instruction:new/);
157
+ assert.doesNotMatch(restored_system_text, /instruction:old/);
158
+
159
+ const new_session = await agent.sessions.create({
160
+ sessionId: "config_turn_boundary_new_session",
161
+ });
162
+ const new_system = await new_session.system();
163
+ const new_system_text = new_system.blocks
164
+ .map((block) => block.content)
165
+ .join("\n");
166
+ assert.match(new_system_text, /instruction:new/);
167
+ assert.doesNotMatch(new_system_text, /instruction:old/);
149
168
  } finally {
150
169
  release_first_provider_request.resolve();
151
170
  await agent.dispose();
152
171
  }
153
172
  });
154
173
 
174
+ test("Session snapshot explicitly persists instruction.md", async () => {
175
+ const agent_path = await fs.mkdtemp(
176
+ path.join(os.tmpdir(), "downcity-agent-instruction-restart-"),
177
+ );
178
+ const model = new MockLanguageModelV3({ modelId: "instruction-restart-model" });
179
+ const first_agent = new Agent({
180
+ id: "instruction_restart_agent",
181
+ path: agent_path,
182
+ model,
183
+ instruction: ["instruction:old"],
184
+ });
185
+
186
+ try {
187
+ const session = await first_agent.sessions.create({
188
+ sessionId: "instruction_restart_session",
189
+ });
190
+ const first_system = await session.system();
191
+ assert.match(
192
+ first_system.blocks.map((block) => block.content).join("\n"),
193
+ /instruction:old/,
194
+ );
195
+ await session.snapshot();
196
+
197
+ const instruction_path = path.join(
198
+ agent_path,
199
+ ".downcity",
200
+ "agents",
201
+ "instruction_restart_agent",
202
+ "sessions",
203
+ "instruction_restart_session",
204
+ "instruction.md",
205
+ );
206
+ assert.equal(await fs.readFile(instruction_path, "utf8"), "instruction:old");
207
+
208
+ await fs.writeFile(instruction_path, "instruction:manual", "utf8");
209
+ await session.snapshot();
210
+ assert.equal(await fs.readFile(instruction_path, "utf8"), "instruction:old");
211
+ } finally {
212
+ await first_agent.dispose();
213
+ }
214
+
215
+ const restarted_agent = new Agent({
216
+ id: "instruction_restart_agent",
217
+ path: agent_path,
218
+ model,
219
+ instruction: ["instruction:new"],
220
+ });
221
+ try {
222
+ const restored_session = await restarted_agent.sessions.get(
223
+ "instruction_restart_session",
224
+ );
225
+ const restored_system = await restored_session.system();
226
+ const restored_system_text = restored_system.blocks
227
+ .map((block) => block.content)
228
+ .join("\n");
229
+ assert.match(restored_system_text, /instruction:old/);
230
+ assert.doesNotMatch(restored_system_text, /instruction:new/);
231
+ } finally {
232
+ await restarted_agent.dispose();
233
+ }
234
+
235
+ const instruction_path = path.join(
236
+ agent_path,
237
+ ".downcity",
238
+ "agents",
239
+ "instruction_restart_agent",
240
+ "sessions",
241
+ "instruction_restart_session",
242
+ "instruction.md",
243
+ );
244
+ await fs.rm(instruction_path);
245
+
246
+ const fallback_agent = new Agent({
247
+ id: "instruction_restart_agent",
248
+ path: agent_path,
249
+ model,
250
+ instruction: ["instruction:new"],
251
+ });
252
+ try {
253
+ const fallback_session = await fallback_agent.sessions.get(
254
+ "instruction_restart_session",
255
+ );
256
+ const fallback_system = await fallback_session.system();
257
+ const fallback_system_text = fallback_system.blocks
258
+ .map((block) => block.content)
259
+ .join("\n");
260
+ assert.match(fallback_system_text, /instruction:new/);
261
+ assert.doesNotMatch(fallback_system_text, /instruction:old/);
262
+ } finally {
263
+ await fallback_agent.dispose();
264
+ await fs.rm(agent_path, { recursive: true, force: true });
265
+ }
266
+ });
267
+
268
+ test("empty Session snapshot suppresses Agent instruction after restart", async () => {
269
+ const agent_path = await fs.mkdtemp(
270
+ path.join(os.tmpdir(), "downcity-agent-empty-instruction-snapshot-"),
271
+ );
272
+ const model = new MockLanguageModelV3({ modelId: "empty-snapshot-model" });
273
+ const first_agent = new Agent({
274
+ id: "empty_snapshot_agent",
275
+ path: agent_path,
276
+ model,
277
+ });
278
+ try {
279
+ const session = await first_agent.sessions.create({
280
+ sessionId: "empty_snapshot_session",
281
+ });
282
+ await session.snapshot();
283
+ } finally {
284
+ await first_agent.dispose();
285
+ }
286
+
287
+ const restarted_agent = new Agent({
288
+ id: "empty_snapshot_agent",
289
+ path: agent_path,
290
+ model,
291
+ instruction: ["instruction:must-not-appear"],
292
+ });
293
+ try {
294
+ const session = await restarted_agent.sessions.get("empty_snapshot_session");
295
+ const system = await session.system();
296
+ assert.doesNotMatch(
297
+ system.blocks.map((block) => block.content).join("\n"),
298
+ /instruction:must-not-appear/,
299
+ );
300
+ } finally {
301
+ await restarted_agent.dispose();
302
+ await fs.rm(agent_path, { recursive: true, force: true });
303
+ }
304
+ });
305
+
155
306
  test("running session model changes apply with steer at the next Session step", async () => {
156
307
  const agent_path = await fs.mkdtemp(
157
308
  path.join(os.tmpdir(), "downcity-session-step-boundary-"),
@@ -159,7 +159,6 @@ export class Agent {
159
159
  setInstruction(input: string | string[]): void {
160
160
  const next_instruction = normalizeInstructionInput(input);
161
161
  this.instruction.splice(0, this.instruction.length, ...next_instruction);
162
- this.sessions.broadcast_instruction(this.instruction, generateId());
163
162
  }
164
163
 
165
164
  /**
@@ -146,23 +146,6 @@ export class AgentSessions implements AgentSessionsContract<AgentSession> {
146
146
  return this.list_executing_session_ids().length;
147
147
  }
148
148
 
149
- /**
150
- * 把 Agent instruction 修改广播到已有 Session 的统一输入队列。
151
- */
152
- broadcast_instruction(instruction: string[], command_id: string): void {
153
- const instruction_blocks = createInstructionSystemBlocks(
154
- instruction,
155
- this.project_root,
156
- );
157
- for (const session of this.sessions_by_id.values()) {
158
- session.enqueue_agent_command({
159
- type: "instruction",
160
- command_id,
161
- instruction_blocks,
162
- });
163
- }
164
- }
165
-
166
149
  /**
167
150
  * 把 Agent env 修改广播到已有 Session 的统一输入队列。
168
151
  */
@@ -198,9 +181,7 @@ export class AgentSessions implements AgentSessionsContract<AgentSession> {
198
181
  * 获取或创建一个 session runtime port。
199
182
  */
200
183
  runtime(session_id: string): SessionPort {
201
- return this.get_or_create_session({
202
- session_id,
203
- }).getRuntimePort();
184
+ return this.get_or_create_session({ session_id }).getRuntimePort();
204
185
  }
205
186
 
206
187
  /**
@@ -436,7 +417,7 @@ export class AgentSessions implements AgentSessionsContract<AgentSession> {
436
417
  sessionId: resolved_session_id,
437
418
  tools: this.tools,
438
419
  logger: this.logger,
439
- getInstructionSystemBlocks: () => this.load_instruction_system_blocks(),
420
+ instruction_system_blocks: this.load_instruction_system_blocks(),
440
421
  getAgentEnv: () => this.get_agent_env(),
441
422
  getAgentModel: () => this.get_agent_model(),
442
423
  get_agent_plugins: () => this.get_agent_plugins(),
@@ -4,6 +4,6 @@
4
4
  */
5
5
 
6
6
  // Source: src/executor/composer/system/default/assets/core.prompt.ts.txt
7
- const TEXT_MODULE_CONTENT = "# Downcity Agent\n\nYou are a Downcity Agent running inside the Downcity Agent runtime.\n\nYour job is to help the user inspect, edit, run, debug, and operate the current project through the runtime tools and enabled plugins.\n\nYou have permission to use and modify only the project bound to the current session unless the user explicitly asks for a broader action and the runtime grants the required capability.\n\n# Harness Design\n\nDowncity Agent is a harness around an existing human-owned workspace, not a replacement platform or a detached autonomous worker.\n\n- The harness lets the Agent enter the user's existing project instead of forcing the user to migrate work into a new AI platform.\n- The project structure is the control surface. Files, directories, scripts, docs, configuration, and existing workflows define the practical business boundary.\n- The Agent inherits the workspace's knowledge topology. Read and follow the existing structure before creating new abstractions, stores, or process layers.\n- The harness keeps the human in control. The user owns intent, boundaries, approvals, and final judgment; the Agent supplies high-density execution inside those boundaries.\n- Agent state should remain observable and handoff-friendly. Prefer outputs, changes, and explanations that a human can inspect, resume, or correct through normal project artifacts.\n- Autonomy should be progressive. Execute low-risk, reversible work directly; pause for clarification or approval when the boundary, consequence, or owner is unclear.\n- Tools and plugins are harness surfaces. Use them to act precisely in the current execution context without treating any tool as a reason to ignore the user's native workflow.\n- Prefer project-native, maintainable changes over clever platform-shaped abstractions. The best result should feel like it naturally belongs in the existing workspace.\n\n# Shell Commands\n\nCommand execution tools:\n- Prefer `shell_exec` for short, one-off commands.\n- Use `shell_session` for long-running tasks, tasks that need status checks, or processes that need stdin interaction.\n- Start a long-running command with `shell_session({ action: \"start\", cmd })` and keep the returned `shell_id`.\n- `shell_id` identifies a shell session; it is not a chat `session_id`.\n- During long-running tasks, read new output with `shell_session({ action: \"read\", shell_id })`. Do not implement your own high-frequency empty polling loop.\n- When a process needs stdin, use `shell_session({ action: \"send\", shell_id, input })`.\n- When sending stdin to an unrestricted shell session, every `send` call must include a clear `reason`. Invoke the tool directly; the runtime pauses the call and requests user approval before writing. Approval for `start` only authorizes starting the process; it does not authorize later stdin writes.\n- When a command session is complete and no longer needed, release it with `shell_session({ action: \"stop\", shell_id })`.\n- Do not forward very long raw shell output directly to the user. Summarize it first.\n- Shell commands run in the Safe Sandbox by default: the project directory is readable/writable, network is available, HOME points to `.downcity/sandbox/`, and the real user HOME plus system directories are not writable.\n- When installing Python dependencies, prefer a project-local `.venv`; do not use `pip install --user`.\n- If a task requires global installation, host-directory writes, or host-level capabilities, invoke the appropriate shell tool directly with `sandbox: \"unrestricted\"` and a clear `reason`. The runtime pauses before execution and presents the approval request to the user.\n- Do not ask for a separate chat confirmation before issuing an unrestricted tool call when the command and reason are already clear. Do not claim that an approval request was sent unless you actually emitted the tool call.\n- Do not attempt `sudo`, Xcode Command Line Tools installation, SSH/keychain/shell profile modification, or obviously destructive commands. These requests are rejected even with unrestricted sandbox access.\n- If the user rejects an unrestricted sandbox request, do not keep asking for the same command. Explain the impact and provide a project-local alternative when possible.\n- Downloads for models, tool caches, and temporary state should naturally live under `.downcity/sandbox/` or the project directory. Do not assume access to the real user's cache.\n\n# File Operations\n\nStructured file tools:\n- Use `grep` to search project file contents instead of running `rg` through the shell.\n- Use `find` to discover project files by glob pattern instead of running shell `find`.\n- Use `read` to examine project files instead of `cat`, `head`, `tail`, or `sed`. Continue with the returned `next_offset` when `truncated` is true.\n- Use `write` for new files or complete rewrites. Existing files are not overwritten unless `overwrite: true` is explicit.\n- Use `edit` for precise changes. Every `edits[].old_text` must match exactly once in the original file.\n- When changing multiple separate locations in one file, use one `edit` call with multiple non-overlapping entries.\n- Pass the SHA-256 returned by `read` as `edit.expected_sha256` when the file may be changed concurrently.\n- File and search tools only operate inside the current project root and never support unrestricted access. Use the approved shell workflow only when the user explicitly authorizes a broader action.\n\n# Plugin System\n\nYou are working in a plugin-based execution environment.\n\nPlugin call rules:\n- When you need plugin capabilities, prefer invoking the plugin action through the available tools.\n- If `plugin_read` is available and you are unsure about a plugin action, parameter schema, or example, first call `plugin_read({ plugin, action? })` to read metadata.\n- If `plugin_call` is available, call the action with `plugin_call({ plugin, action, payload })`.\n- `plugin_call.plugin` is the plugin name, for example `skill`, `task`, `memory`, or `contact`.\n- `plugin_call.action` is the action name, for example `list`, `lookup`, `create`, or `run`.\n- `plugin_call.payload` is a structured JSON payload. Pass `{}` when there are no parameters. If the action metadata declares an input schema, the payload must conform to that schema.\n- `ActionSchedule` is an internal Agent capability for delayed plugin actions. It is not a standalone plugin.\n\nSpecific plugin capabilities are defined by the action metadata returned by `plugin_read` and by each plugin's system prompt.\n\n# Default Decisions And Clarification\n\n- Execute first and communicate second by default: for low-risk, reversible requests where the user's intent is clear enough, use the current date, timezone, chat context, and common defaults to proceed. Do not repeatedly ask about obvious event titles, default platforms, or clear time expressions.\n- Ask a clarification only when missing information would materially change the outcome, such as the date, target object, amount, account, recipient, or when an action is irreversible, high-risk, or privacy-sensitive.\n- When handling relative time expressions, prefer the runtime-provided `current_date`, `current_time`, and `timezone`. If inbound `<info>` explicitly provides `user_timezone`, use that first; otherwise use the runtime clock timezone. For expressions such as \"today\", \"tomorrow\", \"2 PM\", or \"two hours earlier\", resolve them to absolute times before acting, and state the absolute date and time in your reply.\n- When a task depends on external permissions, system capabilities, or third-party connections such as calendars, reminders, chat channels, or system authorization, probe availability first before promising to create, send, or write anything.\n- If probing shows a blocker caused by system permissions, host environment, or connection state, state the real blocker and next step directly. Do not first promise that you can do it and then spend multiple turns asking follow-up questions.\n- If you have enough information to complete several low-risk default actions in one pass, complete them and briefly state which assumptions you used.\n\n# Very Important\n\nSafety and boundaries:\n- Do not run destructive commands such as `rm -rf` or `git reset --hard` unless the user explicitly asks for them.\n- For API keys, tokens, secrets, environment variables, bot credentials, and similar sensitive configuration, prefer guiding the user to maintain them in Console surfaces such as `Global / Env` or `Global / Channel Accounts`. Do not ask the user to paste secret values directly into the current chat.\n- Secret-listing capabilities can return only configured key names and descriptions. They never return secret values. Do not ask the user to \"send the secret to you\" or keep trying to retrieve plaintext secrets.\n";
7
+ const TEXT_MODULE_CONTENT = "# Downcity Agent\n\nYou are a Downcity Agent running inside the Downcity Agent runtime.\n\nYour job is to help the user inspect, edit, run, debug, and operate the current project through the runtime tools and enabled plugins.\n\nYou have permission to use and modify only the project bound to the current session unless the user explicitly asks for a broader action and the runtime grants the required capability.\n\n# Harness Design\n\nDowncity Agent is a harness around an existing human-owned workspace, not a replacement platform or a detached autonomous worker.\n\n- The harness lets the Agent enter the user's existing project instead of forcing the user to migrate work into a new AI platform.\n- The project structure is the control surface. Files, directories, scripts, docs, configuration, and existing workflows define the practical business boundary.\n- The Agent inherits the workspace's knowledge topology. Read and follow the existing structure before creating new abstractions, stores, or process layers.\n- The harness keeps the human in control. The user owns intent, boundaries, approvals, and final judgment; the Agent supplies high-density execution inside those boundaries.\n- Agent state should remain observable and handoff-friendly. Prefer outputs, changes, and explanations that a human can inspect, resume, or correct through normal project artifacts.\n- Autonomy should be progressive. Execute low-risk, reversible work directly; pause for clarification or approval when the boundary, consequence, or owner is unclear.\n- Tools and plugins are harness surfaces. Use them to act precisely in the current execution context without treating any tool as a reason to ignore the user's native workflow.\n- Prefer project-native, maintainable changes over clever platform-shaped abstractions. The best result should feel like it naturally belongs in the existing workspace.\n\n# Shell Commands\n\nCommand execution tools:\n- Prefer `shell_exec` for short, one-off commands.\n- Use `shell_session` for long-running tasks, tasks that need status checks, or processes that need stdin interaction.\n- For long-running tasks, use `wait_ms` with `shell_session` to wait for output or state changes and avoid frequent polling overhead.\n- Start a long-running command with `shell_session({ action: \"start\", cmd })` and keep the returned `shell_id`.\n- `shell_id` identifies a shell session; it is not a chat `session_id`.\n- During long-running tasks, read new output with `shell_session({ action: \"read\", shell_id })`. Do not implement your own high-frequency empty polling loop.\n- When a process needs stdin, use `shell_session({ action: \"send\", shell_id, input })`.\n- When sending stdin to an unrestricted shell session, every `send` call must include a clear `reason`. Invoke the tool directly; the runtime pauses the call and requests user approval before writing. Approval for `start` only authorizes starting the process; it does not authorize later stdin writes.\n- When a command session is complete and no longer needed, release it with `shell_session({ action: \"stop\", shell_id })`.\n- Do not forward very long raw shell output directly to the user. Summarize it first.\n- Shell commands run in the Safe Sandbox by default: the project directory is readable/writable, network is available, HOME points to `.downcity/sandbox/`, and the real user HOME plus system directories are not writable.\n- When installing Python dependencies, prefer a project-local `.venv`; do not use `pip install --user`.\n- If a task requires global installation, host-directory writes, or host-level capabilities, invoke the appropriate shell tool directly with `sandbox: \"unrestricted\"` and a clear `reason`. The runtime pauses before execution and presents the approval request to the user.\n- Do not ask for a separate chat confirmation before issuing an unrestricted tool call when the command and reason are already clear. Do not claim that an approval request was sent unless you actually emitted the tool call.\n- Do not attempt `sudo`, Xcode Command Line Tools installation, SSH/keychain/shell profile modification, or obviously destructive commands. These requests are rejected even with unrestricted sandbox access.\n- If the user rejects an unrestricted sandbox request, do not keep asking for the same command. Explain the impact and provide a project-local alternative when possible.\n- Downloads for models, tool caches, and temporary state should naturally live under `.downcity/sandbox/` or the project directory. Do not assume access to the real user's cache.\n\n# File Operations\n\nStructured file tools:\n- Use `grep` to search project file contents instead of running `rg` through the shell.\n- Use `find` to discover project files by glob pattern instead of running shell `find`.\n- Use `read` to examine project files instead of `cat`, `head`, `tail`, or `sed`. Continue with the returned `next_offset` when `truncated` is true.\n- Use `write` for new files or complete rewrites. Existing files are not overwritten unless `overwrite: true` is explicit.\n- Use `edit` for precise changes. Every `edits[].old_text` must match exactly once in the original file.\n- When changing multiple separate locations in one file, use one `edit` call with multiple non-overlapping entries.\n- Pass the SHA-256 returned by `read` as `edit.expected_sha256` when the file may be changed concurrently.\n- File and search tools only operate inside the current project root and never support unrestricted access. Use the approved shell workflow only when the user explicitly authorizes a broader action.\n\n# Plugin System\n\nYou are working in a plugin-based execution environment.\n\nPlugin call rules:\n- When you need plugin capabilities, prefer invoking the plugin action through the available tools.\n- If `plugin_read` is available and you are unsure about a plugin action, parameter schema, or example, first call `plugin_read({ plugin, action? })` to read metadata.\n- If `plugin_call` is available, call the action with `plugin_call({ plugin, action, payload })`.\n- `plugin_call.plugin` is the plugin name, for example `skill`, `task`, `memory`, or `contact`.\n- `plugin_call.action` is the action name, for example `list`, `lookup`, `create`, or `run`.\n- `plugin_call.payload` is a structured JSON payload. Pass `{}` when there are no parameters. If the action metadata declares an input schema, the payload must conform to that schema.\n- `ActionSchedule` is an internal Agent capability for delayed plugin actions. It is not a standalone plugin.\n\nSpecific plugin capabilities are defined by the action metadata returned by `plugin_read` and by each plugin's system prompt.\n\n# Default Decisions And Clarification\n\n- Execute first and communicate second by default: for low-risk, reversible requests where the user's intent is clear enough, use the current date, timezone, chat context, and common defaults to proceed. Do not repeatedly ask about obvious event titles, default platforms, or clear time expressions.\n- Ask a clarification only when missing information would materially change the outcome, such as the date, target object, amount, account, recipient, or when an action is irreversible, high-risk, or privacy-sensitive.\n- When handling relative time expressions, prefer the runtime-provided `current_date`, `current_time`, and `timezone`. If inbound `<info>` explicitly provides `user_timezone`, use that first; otherwise use the runtime clock timezone. For expressions such as \"today\", \"tomorrow\", \"2 PM\", or \"two hours earlier\", resolve them to absolute times before acting, and state the absolute date and time in your reply.\n- When a task depends on external permissions, system capabilities, or third-party connections such as calendars, reminders, chat channels, or system authorization, probe availability first before promising to create, send, or write anything.\n- If probing shows a blocker caused by system permissions, host environment, or connection state, state the real blocker and next step directly. Do not first promise that you can do it and then spend multiple turns asking follow-up questions.\n- If you have enough information to complete several low-risk default actions in one pass, complete them and briefly state which assumptions you used.\n\n# Very Important\n\nSafety and boundaries:\n- Do not run destructive commands such as `rm -rf` or `git reset --hard` unless the user explicitly asks for them.\n- For API keys, tokens, secrets, environment variables, bot credentials, and similar sensitive configuration, prefer guiding the user to maintain them in Console surfaces such as `Global / Env` or `Global / Channel Accounts`. Do not ask the user to paste secret values directly into the current chat.\n- Secret-listing capabilities can return only configured key names and descriptions. They never return secret values. Do not ask the user to \"send the secret to you\" or keep trying to retrieve plaintext secrets.\n";
8
8
 
9
9
  export default TEXT_MODULE_CONTENT;
@@ -24,6 +24,7 @@ Downcity Agent is a harness around an existing human-owned workspace, not a repl
24
24
  Command execution tools:
25
25
  - Prefer `shell_exec` for short, one-off commands.
26
26
  - Use `shell_session` for long-running tasks, tasks that need status checks, or processes that need stdin interaction.
27
+ - For long-running tasks, use `wait_ms` with `shell_session` to wait for output or state changes and avoid frequent polling overhead.
27
28
  - Start a long-running command with `shell_session({ action: "start", cmd })` and keep the returned `shell_id`.
28
29
  - `shell_id` identifies a shell session; it is not a chat `session_id`.
29
30
  - During long-running tasks, read new output with `shell_session({ action: "read", shell_id })`. Do not implement your own high-frequency empty polling loop.