@downcity/agent 1.1.401 → 1.1.408

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 (83) hide show
  1. package/README.md +4 -3
  2. package/bin/agent/WorkspaceEntry.js +1 -1
  3. package/bin/agent/WorkspaceEntry.js.map +1 -1
  4. package/bin/city/types/PluginHostContext.d.ts +3 -0
  5. package/bin/city/types/PluginHostContext.d.ts.map +1 -1
  6. package/bin/executor/core-engine/CoreEngineError.js +8 -2
  7. package/bin/executor/core-engine/CoreEngineError.js.map +1 -1
  8. package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
  9. package/bin/executor/core-engine/CoreEngineRunner.js +36 -0
  10. package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
  11. package/bin/executor/model/ModelGenerate.d.ts.map +1 -1
  12. package/bin/executor/model/ModelGenerate.js +2 -1
  13. package/bin/executor/model/ModelGenerate.js.map +1 -1
  14. package/bin/executor/model/ModelStepRunner.d.ts +2 -0
  15. package/bin/executor/model/ModelStepRunner.d.ts.map +1 -1
  16. package/bin/executor/model/ModelStepRunner.js +33 -7
  17. package/bin/executor/model/ModelStepRunner.js.map +1 -1
  18. package/bin/executor/model/ModelStreamFailure.d.ts +22 -0
  19. package/bin/executor/model/ModelStreamFailure.d.ts.map +1 -0
  20. package/bin/executor/model/ModelStreamFailure.js +35 -0
  21. package/bin/executor/model/ModelStreamFailure.js.map +1 -0
  22. package/bin/group/GroupDispatchSession.d.ts +36 -0
  23. package/bin/group/GroupDispatchSession.d.ts.map +1 -0
  24. package/bin/group/GroupDispatchSession.js +154 -0
  25. package/bin/group/GroupDispatchSession.js.map +1 -0
  26. package/bin/group/GroupSession.d.ts +3 -1
  27. package/bin/group/GroupSession.d.ts.map +1 -1
  28. package/bin/group/GroupSession.js +65 -28
  29. package/bin/group/GroupSession.js.map +1 -1
  30. package/bin/index.d.ts +2 -0
  31. package/bin/index.d.ts.map +1 -1
  32. package/bin/index.js.map +1 -1
  33. package/bin/session/messages/SessionAssistantMessageWriter.d.ts.map +1 -1
  34. package/bin/session/messages/SessionAssistantMessageWriter.js +10 -6
  35. package/bin/session/messages/SessionAssistantMessageWriter.js.map +1 -1
  36. package/bin/types/group/DispatchStrategy.d.ts +3 -0
  37. package/bin/types/group/DispatchStrategy.d.ts.map +1 -1
  38. package/bin/types/group/DispatchStrategy.js +66 -18
  39. package/bin/types/group/DispatchStrategy.js.map +1 -1
  40. package/bin/types/group/GroupDispatchSession.d.ts +65 -0
  41. package/bin/types/group/GroupDispatchSession.d.ts.map +1 -0
  42. package/bin/types/group/GroupDispatchSession.js +8 -0
  43. package/bin/types/group/GroupDispatchSession.js.map +1 -0
  44. package/bin/types/group/GroupSession.d.ts +2 -0
  45. package/bin/types/group/GroupSession.d.ts.map +1 -1
  46. package/bin/types/group/GroupSessionStore.d.ts +6 -1
  47. package/bin/types/group/GroupSessionStore.d.ts.map +1 -1
  48. package/bin/types/plugin/PluginNotification.d.ts +31 -0
  49. package/bin/types/plugin/PluginNotification.d.ts.map +1 -0
  50. package/bin/types/plugin/PluginNotification.js +8 -0
  51. package/bin/types/plugin/PluginNotification.js.map +1 -0
  52. package/bin/workspace/store/LocalGroupDispatchSessionDataStore.d.ts +28 -0
  53. package/bin/workspace/store/LocalGroupDispatchSessionDataStore.d.ts.map +1 -0
  54. package/bin/workspace/store/LocalGroupDispatchSessionDataStore.js +102 -0
  55. package/bin/workspace/store/LocalGroupDispatchSessionDataStore.js.map +1 -0
  56. package/bin/workspace/store/LocalGroupSessionDataStore.d.ts +2 -0
  57. package/bin/workspace/store/LocalGroupSessionDataStore.d.ts.map +1 -1
  58. package/bin/workspace/store/LocalGroupSessionDataStore.js +25 -8
  59. package/bin/workspace/store/LocalGroupSessionDataStore.js.map +1 -1
  60. package/city-test/group.test.mjs +252 -1
  61. package/package.json +4 -4
  62. package/scripts/agent-multi-workspace.test.mjs +67 -0
  63. package/scripts/core-engine-context-compaction.test.mjs +49 -0
  64. package/scripts/core-engine-model-stream.test.mjs +69 -0
  65. package/src/agent/WorkspaceEntry.ts +1 -1
  66. package/src/city/types/PluginHostContext.ts +4 -0
  67. package/src/executor/core-engine/CoreEngineError.ts +8 -2
  68. package/src/executor/core-engine/CoreEngineRunner.ts +44 -0
  69. package/src/executor/model/ModelGenerate.ts +3 -1
  70. package/src/executor/model/ModelStepRunner.ts +36 -5
  71. package/src/executor/model/ModelStreamFailure.ts +44 -0
  72. package/src/group/GroupDispatchSession.ts +175 -0
  73. package/src/group/GroupSession.ts +83 -28
  74. package/src/index.ts +10 -0
  75. package/src/session/messages/SessionAssistantMessageWriter.ts +9 -5
  76. package/src/types/group/DispatchStrategy.ts +79 -19
  77. package/src/types/group/GroupDispatchSession.ts +80 -0
  78. package/src/types/group/GroupSession.ts +2 -0
  79. package/src/types/group/GroupSessionStore.ts +6 -1
  80. package/src/types/plugin/PluginNotification.ts +38 -0
  81. package/src/workspace/store/LocalGroupDispatchSessionDataStore.ts +118 -0
  82. package/src/workspace/store/LocalGroupSessionDataStore.ts +35 -9
  83. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * LocalGroupDispatchSessionDataStore:Group Dispatch Session 的追加式 Turn 日志。
3
+ *
4
+ * 每次状态迁移都追加完整快照;读取时按 dispatch_id 选择最后一条记录,因此中断前
5
+ * 已提交的状态不会被覆盖,文件尾部的非完整写入也可以安全修复。
6
+ */
7
+ import path from "node:path";
8
+ const dispatch_turn_statuses = new Set([
9
+ "queued",
10
+ "running",
11
+ "completed",
12
+ "failed",
13
+ "stopped",
14
+ ]);
15
+ /** 基于 GroupSession 私有目录的 Dispatch Session Store。 */
16
+ export class LocalGroupDispatchSessionDataStore {
17
+ files;
18
+ dispatch_root_path;
19
+ turns_file_path;
20
+ transaction_lock_path;
21
+ constructor(options) {
22
+ this.files = options.files;
23
+ this.dispatch_root_path = path.join(options.session_root_path, "dispatch");
24
+ this.turns_file_path = path.join(this.dispatch_root_path, "turns.jsonl");
25
+ this.transaction_lock_path = path.join(this.dispatch_root_path, ".lock");
26
+ }
27
+ /** 读取每个调度 Turn 最后一次成功提交的状态。 */
28
+ async list_turns() {
29
+ if (!(await this.files.path_exists(this.turns_file_path)))
30
+ return [];
31
+ await this.files.ensure_directory(this.dispatch_root_path);
32
+ return await this.files.with_file_lock(this.transaction_lock_path, async () => {
33
+ const records = await this.read_records(true);
34
+ const turns_by_id = new Map();
35
+ for (const record of records) {
36
+ turns_by_id.delete(record.dispatch_id);
37
+ turns_by_id.set(record.dispatch_id, record);
38
+ }
39
+ return [...turns_by_id.values()];
40
+ });
41
+ }
42
+ /** 追加一个完整状态快照,状态提交与其它调度 Turn 串行。 */
43
+ async append_turn(turn) {
44
+ assert_dispatch_turn(turn);
45
+ await this.files.ensure_directory(this.dispatch_root_path);
46
+ await this.files.with_file_lock(this.transaction_lock_path, async () => {
47
+ await this.files.append_file(this.turns_file_path, `${JSON.stringify(turn)}\n`);
48
+ });
49
+ }
50
+ /** 读取状态日志;只允许修复进程中断产生的最后一条残缺记录。 */
51
+ async read_records(repair_tail) {
52
+ const content = (await this.files.read_file(this.turns_file_path)).toString("utf8");
53
+ const lines = content.split("\n");
54
+ const records = [];
55
+ for (let line_index = 0; line_index < lines.length; line_index += 1) {
56
+ const line = lines[line_index];
57
+ if (!line.trim())
58
+ continue;
59
+ try {
60
+ const record = JSON.parse(line);
61
+ assert_dispatch_turn(record);
62
+ records.push(record);
63
+ }
64
+ catch (error) {
65
+ const is_tail = lines.slice(line_index + 1).every((item) => !item.trim());
66
+ if (!repair_tail || !is_tail)
67
+ throw error;
68
+ const repaired = records.map((record) => JSON.stringify(record)).join("\n");
69
+ await this.files.write_file_atomically(this.turns_file_path, repaired ? `${repaired}\n` : "");
70
+ break;
71
+ }
72
+ }
73
+ return records;
74
+ }
75
+ }
76
+ /** 防止损坏的持久化记录进入 Dispatch Session 恢复流程。 */
77
+ function assert_dispatch_turn(value) {
78
+ if (!value || typeof value !== "object")
79
+ throw new Error("Invalid Group dispatch turn record");
80
+ if (typeof value.dispatch_id !== "string" || !value.dispatch_id.trim()) {
81
+ throw new Error("Invalid Group dispatch turn id");
82
+ }
83
+ if (value.trigger !== "user" && value.trigger !== "auto") {
84
+ throw new Error(`Invalid Group dispatch trigger: ${String(value.trigger)}`);
85
+ }
86
+ if (typeof value.message_id !== "string" || !value.message_id.trim()) {
87
+ throw new Error(`Invalid Group dispatch message id: ${value.dispatch_id}`);
88
+ }
89
+ if (!Array.isArray(value.pending_message_ids) || value.pending_message_ids.some((item) => typeof item !== "string" || !item.trim())) {
90
+ throw new Error(`Invalid Group dispatch pending messages: ${value.dispatch_id}`);
91
+ }
92
+ if (!dispatch_turn_statuses.has(value.status)) {
93
+ throw new Error(`Invalid Group dispatch status: ${String(value.status)}`);
94
+ }
95
+ if (!Number.isFinite(value.created_at) || !Number.isFinite(value.updated_at)) {
96
+ throw new Error(`Invalid Group dispatch timestamps: ${value.dispatch_id}`);
97
+ }
98
+ if (value.status === "completed" && !value.decision) {
99
+ throw new Error(`Completed Group dispatch is missing its decision: ${value.dispatch_id}`);
100
+ }
101
+ }
102
+ //# sourceMappingURL=LocalGroupDispatchSessionDataStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalGroupDispatchSessionDataStore.js","sourceRoot":"","sources":["../../../src/workspace/store/LocalGroupDispatchSessionDataStore.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  /** LocalGroupSessionDataStore:GroupSession 的 metadata 与消息 JSONL 存储。 */
2
2
  import type { FileSystem } from "@downcity/workspace";
3
3
  import type { GroupMessage } from "../../types/group/Group.js";
4
+ import type { GroupDispatchSessionDataStore } from "../../types/group/GroupDispatchSession.js";
4
5
  import type { GroupSessionDataStore, GroupSessionHistoryMeta } from "../../types/group/GroupSessionStore.js";
5
6
  /** 单个 GroupSession 的本地文件存储。 */
6
7
  export declare class LocalGroupSessionDataStore implements GroupSessionDataStore {
7
8
  readonly session_id: string;
9
+ readonly dispatch_session: GroupDispatchSessionDataStore;
8
10
  private readonly files;
9
11
  private readonly group_id;
10
12
  private readonly session_root_path;
@@ -1 +1 @@
1
- {"version":3,"file":"LocalGroupSessionDataStore.d.ts","sourceRoot":"","sources":["../../../src/workspace/store/LocalGroupSessionDataStore.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAGvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EAExB,MAAM,oCAAoC,CAAC;AAE5C,+BAA+B;AAC/B,qBAAa,0BAA2B,YAAW,qBAAqB;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;gBAEnC,OAAO,EAAE;QACnB,kCAAkC;QAClC,KAAK,EAAE,UAAU,CAAC;QAClB,iCAAiC;QACjC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,0BAA0B;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,mBAAmB;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAeD,uCAAuC;IACjC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC,kBAAkB;IACZ,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI9C,0BAA0B;IACpB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1D,qBAAqB;IACf,aAAa,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAOvD,+BAA+B;YACjB,sBAAsB;IAkCpC,uBAAuB;IACjB,cAAc,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE,+BAA+B;YACjB,uBAAuB;IAWrC,wCAAwC;IAClC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAehG,8BAA8B;YAChB,wBAAwB;IActC,kCAAkC;YACpB,aAAa;IA0B3B,OAAO,CAAC,uBAAuB;CAWhC"}
1
+ {"version":3,"file":"LocalGroupSessionDataStore.d.ts","sourceRoot":"","sources":["../../../src/workspace/store/LocalGroupSessionDataStore.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAGvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAE3F,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EAExB,MAAM,oCAAoC,CAAC;AAE5C,+BAA+B;AAC/B,qBAAa,0BAA2B,YAAW,qBAAqB;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,6BAA6B,CAAC;IACzD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;gBAEnC,OAAO,EAAE;QACnB,kCAAkC;QAClC,KAAK,EAAE,UAAU,CAAC;QAClB,iCAAiC;QACjC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,0BAA0B;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,mBAAmB;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB;IAmBD,uCAAuC;IACjC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC,kBAAkB;IACZ,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI9C,0BAA0B;IACpB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1D,qBAAqB;IACf,aAAa,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAUvD,+BAA+B;YACjB,sBAAsB;IA0CpC,uBAAuB;IACjB,cAAc,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE,+BAA+B;YACjB,uBAAuB;IAWrC,wCAAwC;IAClC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAehG,8BAA8B;YAChB,wBAAwB;IActC,kCAAkC;YACpB,aAAa;IA0B3B,OAAO,CAAC,uBAAuB;CAWhC"}
@@ -1,8 +1,10 @@
1
1
  /** LocalGroupSessionDataStore:GroupSession 的 metadata 与消息 JSONL 存储。 */
2
2
  import path from "node:path";
3
+ import { LocalGroupDispatchSessionDataStore } from "./LocalGroupDispatchSessionDataStore.js";
3
4
  /** 单个 GroupSession 的本地文件存储。 */
4
5
  export class LocalGroupSessionDataStore {
5
6
  session_id;
7
+ dispatch_session;
6
8
  files;
7
9
  group_id;
8
10
  session_root_path;
@@ -16,6 +18,10 @@ export class LocalGroupSessionDataStore {
16
18
  if (!this.session_id)
17
19
  throw new Error("GroupSession store requires a non-empty session_id");
18
20
  this.session_root_path = path.join(path.resolve(options.storage_root_path), "sessions", encodeURIComponent(this.session_id));
21
+ this.dispatch_session = new LocalGroupDispatchSessionDataStore({
22
+ files: this.files,
23
+ session_root_path: this.session_root_path,
24
+ });
19
25
  this.metadata_file_path = path.join(this.session_root_path, "meta.json");
20
26
  this.messages_file_path = path.join(this.session_root_path, "messages.jsonl");
21
27
  this.transaction_lock_path = path.join(this.session_root_path, ".lock");
@@ -56,7 +62,7 @@ export class LocalGroupSessionDataStore {
56
62
  if (!(await this.files.path_exists(this.metadata_file_path))) {
57
63
  return this.create_initial_metadata();
58
64
  }
59
- return await this.read_metadata_unlocked();
65
+ return await this.files.with_file_lock(this.transaction_lock_path, async () => await this.read_metadata_unlocked());
60
66
  }
61
67
  /** 在调用方已经持有事务锁时读取 metadata。 */
62
68
  async read_metadata_unlocked() {
@@ -64,14 +70,17 @@ export class LocalGroupSessionDataStore {
64
70
  return this.create_initial_metadata();
65
71
  }
66
72
  const raw = JSON.parse((await this.files.read_file(this.metadata_file_path)).toString("utf8"));
73
+ if (raw.v !== 1 && raw.v !== 2) {
74
+ throw new Error(`Unsupported GroupSession metadata version: ${String(raw.v)}`);
75
+ }
67
76
  if (raw.session_id !== this.session_id) {
68
77
  throw new Error(`Invalid GroupSession ownership metadata: ${this.session_id}`);
69
78
  }
70
79
  if (raw.group_id && raw.group_id !== this.group_id) {
71
80
  throw new Error(`GroupSession "${this.session_id}" belongs to another Group`);
72
81
  }
73
- return {
74
- v: 1,
82
+ const metadata = {
83
+ v: 2,
75
84
  session_id: this.session_id,
76
85
  group_id: String(raw.group_id || this.group_id),
77
86
  ...(typeof raw.workspace_id === "string" && raw.workspace_id.trim() ? { workspace_id: raw.workspace_id.trim() } : {}),
@@ -83,12 +92,15 @@ export class LocalGroupSessionDataStore {
83
92
  ? { member_session_ids: normalize_member_session_ids(raw.member_session_ids) }
84
93
  : {}),
85
94
  ...(Array.isArray(raw.pending_turns)
86
- ? { pending_turns: normalize_pending_turns(raw.pending_turns) }
95
+ ? { pending_turns: normalize_pending_turns(raw.pending_turns, raw.v === 1 ? "auto" : undefined) }
87
96
  : {}),
88
97
  ...(Array.isArray(raw.auto_frontier_message_ids)
89
98
  ? { auto_frontier_message_ids: normalize_message_ids(raw.auto_frontier_message_ids) }
90
99
  : {}),
91
100
  };
101
+ if (raw.v === 1)
102
+ await this.write_metadata_unlocked(metadata);
103
+ return metadata;
92
104
  }
93
105
  /** 原子写入当前 metadata。 */
94
106
  async write_metadata(metadata) {
@@ -113,7 +125,7 @@ export class LocalGroupSessionDataStore {
113
125
  ...patch,
114
126
  session_id: this.session_id,
115
127
  group_id: this.group_id,
116
- v: 1,
128
+ v: 2,
117
129
  };
118
130
  await this.write_metadata_unlocked(next_metadata);
119
131
  return next_metadata;
@@ -166,7 +178,7 @@ export class LocalGroupSessionDataStore {
166
178
  create_initial_metadata() {
167
179
  const created_at = Date.now();
168
180
  return {
169
- v: 1,
181
+ v: 2,
170
182
  session_id: this.session_id,
171
183
  group_id: this.group_id,
172
184
  created_at,
@@ -178,7 +190,7 @@ export class LocalGroupSessionDataStore {
178
190
  function normalize_member_session_ids(input) {
179
191
  return Object.fromEntries(Object.entries(input).filter(([agent_id, session_id]) => Boolean(agent_id.trim()) && typeof session_id === "string" && session_id.trim()));
180
192
  }
181
- function normalize_pending_turns(input) {
193
+ function normalize_pending_turns(input, default_dispatch_stage) {
182
194
  return input.flatMap((item) => {
183
195
  if (!item || typeof item !== "object")
184
196
  return [];
@@ -188,7 +200,12 @@ function normalize_pending_turns(input) {
188
200
  const context_message_ids = Array.isArray(candidate.context_message_ids)
189
201
  ? normalize_message_ids(candidate.context_message_ids)
190
202
  : [];
191
- return turn_id && root_message_id ? [{ turn_id, root_message_id, context_message_ids }] : [];
203
+ const dispatch_stage = candidate.dispatch_stage === "user" || candidate.dispatch_stage === "auto"
204
+ ? candidate.dispatch_stage
205
+ : default_dispatch_stage;
206
+ return turn_id && root_message_id && dispatch_stage
207
+ ? [{ turn_id, root_message_id, context_message_ids, dispatch_stage }]
208
+ : [];
192
209
  });
193
210
  }
194
211
  function normalize_message_ids(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"LocalGroupSessionDataStore.js","sourceRoot":"","sources":["../../../src/workspace/store/LocalGroupSessionDataStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LocalGroupSessionDataStore.js","sourceRoot":"","sources":["../../../src/workspace/store/LocalGroupSessionDataStore.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,kCAAkC,EAAE,MAAM,yDAAyD,CAAC;AAO7G,+BAA+B;AAC/B,MAAM,OAAO,0BAA0B;IAC5B,UAAU,CAAS;IACnB,gBAAgB,CAAgC;IACxC,KAAK,CAAa;IAClB,QAAQ,CAAS;IACjB,iBAAiB,CAAS;IAC1B,kBAAkB,CAAS;IAC3B,kBAAkB,CAAS;IAC3B,qBAAqB,CAAS;IAE/C,YAAY,OASX;QACC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC5F,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAChC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EACvC,UAAU,EACV,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CACpC,CAAC;QACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,kCAAkC,CAAC;YAC7D,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C,CAAC,CAAC;QACH,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;QACzE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;QAC9E,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,uCAAuC;IACvC,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACrE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;gBAC7D,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;IAClB,KAAK,CAAC,aAAa;QACjB,OAAO,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IACpC,CAAC;IAED,0BAA0B;IAC1B,KAAK,CAAC,cAAc,CAAC,OAAqB;QACxC,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACtF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;YACrD,MAAM,IAAI,CAAC,uBAAuB,CAAC;gBACjC,GAAG,QAAQ;gBACX,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,QAAQ,CAAC,aAAa,GAAG,CAAC;gBACzC,YAAY,EAAE,OAAO,CAAC,IAAI;aAC3B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,qBAAqB;IACrB,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CACpC,IAAI,CAAC,qBAAqB,EAC1B,KAAK,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAChD,CAAC;IACJ,CAAC;IAED,+BAA+B;IACvB,KAAK,CAAC,sBAAsB;QAClC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAIvE,CAAC;QACF,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,8CAA8C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,UAAU,4BAA4B,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,QAAQ,GAA4B;YACxC,CAAC,EAAE,CAAC;YACJ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;YAC/C,GAAG,CAAC,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrH,UAAU,EAAE,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YAC5E,UAAU,EAAE,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnE,aAAa,EAAE,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC5E,GAAG,CAAC,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvG,GAAG,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,GAAG,CAAC,kBAAkB,KAAK,QAAQ;gBACtE,CAAC,CAAC,EAAE,kBAAkB,EAAE,4BAA4B,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE;gBAC9E,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;gBAClC,CAAC,CAAC,EAAE,aAAa,EAAE,uBAAuB,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE;gBACjG,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;gBAC9C,CAAC,CAAC,EAAE,yBAAyB,EAAE,qBAAqB,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE;gBACrF,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;QACF,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,uBAAuB;IACvB,KAAK,CAAC,cAAc,CAAC,QAAiC;QACpD,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,+BAA+B;IACvB,KAAK,CAAC,uBAAuB,CAAC,QAAiC;QACrE,IAAI,QAAQ,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnF,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CACpC,IAAI,CAAC,kBAAkB,EACvB,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzC,CAAC;IACJ,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,eAAe,CAAC,KAAuC;QAC3D,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,aAAa,GAAG;gBACpB,GAAG,CAAC,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBACxC,GAAG,KAAK;gBACR,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,CAAC,EAAE,CAAU;aACd,CAAC;YACF,MAAM,IAAI,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC;YAClD,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8BAA8B;IACtB,KAAK,CAAC,wBAAwB;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;QACrD,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,uBAAuB,CAAC;YACjC,GAAG,QAAQ;YACX,UAAU,EAAE,aAAa,EAAE,UAAU,IAAI,QAAQ,CAAC,UAAU;YAC5D,UAAU,EAAE,YAAY,EAAE,UAAU,IAAI,QAAQ,CAAC,UAAU;YAC3D,aAAa,EAAE,QAAQ,CAAC,MAAM;YAC9B,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC,CAAC;IACL,CAAC;IAED,kCAAkC;IAC1B,KAAK,CAAC,aAAa,CAAC,WAAW,GAAG,KAAK;QAC7C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QACxE,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,OAAqB,CAAC;YAC1B,IAAI,CAAC;gBACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC1E,IAAI,CAAC,WAAW,IAAI,CAAC,OAAO;oBAAE,MAAM,KAAK,CAAC;gBAC1C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjF,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACjH,MAAM;YACR,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YACvF,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,uBAAuB;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,OAAO;YACL,CAAC,EAAE,CAAC;YACJ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU;YACV,UAAU,EAAE,UAAU;YACtB,aAAa,EAAE,CAAC;SACjB,CAAC;IACJ,CAAC;CACF;AAED,SAAS,4BAA4B,CAAC,KAAa;IACjD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACvK,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAgB,EAChB,sBAAqE;IAErE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,IAA2C,CAAC;QAC9D,MAAM,OAAO,GAAG,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,MAAM,eAAe,GAAG,OAAO,SAAS,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9G,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC;YACtE,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,mBAAmB,CAAC;YACtD,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,KAAK,MAAM,IAAI,SAAS,CAAC,cAAc,KAAK,MAAM;YAC/F,CAAC,CAAC,SAAS,CAAC,cAAc;YAC1B,CAAC,CAAC,sBAAsB,CAAC;QAC3B,OAAO,OAAO,IAAI,eAAe,IAAI,cAAc;YACjD,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC;YACrE,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAgB;IAC7C,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACnI,CAAC"}
@@ -116,6 +116,8 @@ test("Group.model uses AI dispatch to select only the returned members", async (
116
116
  await group_session.prompt({ query: "请审查这个变更" });
117
117
  await wait_for_group_idle(group_session);
118
118
  assert.deepEqual(RecordingSession.created.map((entry) => entry.agent_id), ["reviewer"]);
119
+ assert.match(RecordingSession.created[0].query, /你已被 Group 调度选中,必须直接回复当前消息/);
120
+ assert.doesNotMatch(RecordingSession.created[0].query, /判断是否需要回复|如果不需要你发言/);
119
121
  await city.close();
120
122
  });
121
123
 
@@ -208,6 +210,50 @@ test("AI Dispatch 未调用 dispatch_group 时记录协议错误", async () => {
208
210
  await city.close();
209
211
  });
210
212
 
213
+ test("AI Dispatch 在同一调度 Turn 内纠正未调用工具的响应", async () => {
214
+ RecordingSession.created = [];
215
+ let dispatch_calls = 0;
216
+ const dispatch_model = new MockModelClient({
217
+ modelId: "recovering-dispatch-model",
218
+ doGenerate: async (call) => {
219
+ dispatch_calls += 1;
220
+ if (dispatch_calls === 1) {
221
+ return {
222
+ content: [{ type: "text", text: "我建议让 responder 回复。" }],
223
+ finishReason: { unified: "stop", raw: "stop" },
224
+ usage: { inputTokens: 1, outputTokens: 1, totalTokens: 2 },
225
+ warnings: [],
226
+ };
227
+ }
228
+ assert.equal(call.messages.some((message) => (
229
+ message.role === "user" && message.content.some((part) => (
230
+ part.type === "text" && part.text.includes("上一响应不符合调度协议")
231
+ ))
232
+ )), true);
233
+ return {
234
+ content: [create_dispatch_tool_call({ steps: [["responder"]], next: "stop" })],
235
+ finishReason: { unified: "tool-calls", raw: "tool_calls" },
236
+ usage: { inputTokens: 1, outputTokens: 1, totalTokens: 2 },
237
+ warnings: [],
238
+ };
239
+ },
240
+ });
241
+ const city = new City();
242
+ const agent = new Agent({ id: "responder", session_class: RecordingSession });
243
+ city.agents.add(agent);
244
+ const group = new Group({ id: "recovering-dispatch-group", model: dispatch_model, members: [agent] });
245
+ city.groups.add(group);
246
+ const group_session = await group.sessions.create();
247
+
248
+ await group_session.prompt({ query: "请回答" });
249
+ await wait_for_group_idle(group_session);
250
+
251
+ assert.equal(dispatch_calls, 2);
252
+ assert.deepEqual(RecordingSession.created.map((entry) => entry.agent_id), ["responder"]);
253
+ assert.equal((await group_session.messages()).some((message) => message.sender_type === "system"), false);
254
+ await city.close();
255
+ });
256
+
211
257
  test("AI Dispatch 拒绝未知成员并允许跨阶段重复投递", async () => {
212
258
  const inputs = [
213
259
  { input: { steps: [["unknown"]], next: "stop" }, expected_agent_ids: [] },
@@ -414,6 +460,157 @@ test("GroupSession 使用 City Storage 持久化并可恢复", async () => {
414
460
  await fs.rm(root_path, { recursive: true, force: true });
415
461
  });
416
462
 
463
+ test("GroupSession 持久化独享 Dispatch Session 的调度 Turn", async () => {
464
+ RecordingSession.created = [];
465
+ const root_path = await fs.mkdtemp(path.join(os.tmpdir(), "downcity-group-dispatch-session-"));
466
+ const city = new City({ storage: new LocalStorageProvider(root_path) });
467
+ const agent = new Agent({ id: "dispatch-member", session_class: RecordingSession });
468
+ city.agents.add(agent);
469
+ const group = new Group({ id: "dispatch-session-group", members: [agent], dispatch_strategy: test_dispatch_strategy });
470
+ city.groups.add(group);
471
+ const session = await group.sessions.create();
472
+
473
+ await session.prompt({ query: "persist dispatch" });
474
+ await wait_for_group_idle(session);
475
+
476
+ const turns_path = path.join(
477
+ root_path,
478
+ "groups",
479
+ "dispatch-session-group",
480
+ "sessions",
481
+ encodeURIComponent(session.id),
482
+ "dispatch",
483
+ "turns.jsonl",
484
+ );
485
+ const records = (await fs.readFile(turns_path, "utf8"))
486
+ .trim()
487
+ .split("\n")
488
+ .map((line) => JSON.parse(line));
489
+ const user_records = records.filter((record) => record.trigger === "user");
490
+ assert.deepEqual(user_records.map((record) => record.status), ["queued", "running", "completed"]);
491
+ assert.deepEqual(user_records.at(-1).decision.nodes[0].member_ids, ["dispatch-member"]);
492
+ assert.equal(
493
+ (await session.messages()).find((message) => message.sender_type === "agent").dispatch_id,
494
+ user_records.at(-1).dispatch_id,
495
+ );
496
+ await city.close();
497
+ await fs.rm(root_path, { recursive: true, force: true });
498
+ });
499
+
500
+ test("GroupSession stop 会中断 Dispatch Session 且不记录失败消息", async () => {
501
+ const root_path = await fs.mkdtemp(path.join(os.tmpdir(), "downcity-group-dispatch-stop-"));
502
+ let dispatch_started = false;
503
+ let dispatch_aborted = false;
504
+ let dispatch_invocations = 0;
505
+ const strategy = {
506
+ async decide_dispatch({ abort_signal }) {
507
+ dispatch_invocations += 1;
508
+ dispatch_started = true;
509
+ await new Promise((resolve, reject) => {
510
+ const abort = () => {
511
+ dispatch_aborted = true;
512
+ reject(abort_signal.reason);
513
+ };
514
+ if (abort_signal.aborted) abort();
515
+ else abort_signal.addEventListener("abort", abort, { once: true });
516
+ });
517
+ return { nodes: [], terminal: true };
518
+ },
519
+ };
520
+ const city = new City({ storage: new LocalStorageProvider(root_path) });
521
+ const agent = new Agent({ id: "unused-member", session_class: RecordingSession });
522
+ city.agents.add(agent);
523
+ const group = new Group({ id: "dispatch-stop-group", members: [agent], dispatch_strategy: strategy });
524
+ city.groups.add(group);
525
+ const session = await group.sessions.create();
526
+ await session.prompt({ query: "stop dispatch" });
527
+ await session.prompt({ query: "cancel queued dispatch" });
528
+ for (let attempt = 0; attempt < 200 && !dispatch_started; attempt += 1) {
529
+ await new Promise((resolve) => setTimeout(resolve, 5));
530
+ }
531
+
532
+ await session.stop();
533
+
534
+ assert.equal(dispatch_aborted, true);
535
+ assert.equal(dispatch_invocations, 1);
536
+ assert.deepEqual((await session.messages()).map((message) => message.text), [
537
+ "stop dispatch",
538
+ "cancel queued dispatch",
539
+ ]);
540
+ const turns_path = path.join(
541
+ root_path,
542
+ "groups",
543
+ "dispatch-stop-group",
544
+ "sessions",
545
+ encodeURIComponent(session.id),
546
+ "dispatch",
547
+ "turns.jsonl",
548
+ );
549
+ const records = (await fs.readFile(turns_path, "utf8"))
550
+ .trim()
551
+ .split("\n")
552
+ .map((line) => JSON.parse(line));
553
+ const latest_records = new Map(records.map((record) => [record.dispatch_id, record]));
554
+ assert.equal(latest_records.size, 2);
555
+ assert.deepEqual([...latest_records.values()].map((record) => record.status), ["stopped", "stopped"]);
556
+ await city.close();
557
+ await fs.rm(root_path, { recursive: true, force: true });
558
+ });
559
+
560
+ test("GroupSession 恢复时重新执行中断的用户调度", async () => {
561
+ RecordingSession.created = [];
562
+ const root_path = await fs.mkdtemp(path.join(os.tmpdir(), "downcity-group-dispatch-recovery-"));
563
+ let original_abort_signal;
564
+ let original_dispatch_started = false;
565
+ const original_city = new City({ storage: new LocalStorageProvider(root_path) });
566
+ const original_agent = new Agent({ id: "recovery-member", session_class: RecordingSession });
567
+ original_city.agents.add(original_agent);
568
+ const original_group = new Group({
569
+ id: "dispatch-recovery-group",
570
+ members: [original_agent],
571
+ dispatch_strategy: {
572
+ async decide_dispatch({ abort_signal }) {
573
+ original_abort_signal = abort_signal;
574
+ original_dispatch_started = true;
575
+ await new Promise((resolve, reject) => {
576
+ abort_signal.addEventListener("abort", () => reject(abort_signal.reason), { once: true });
577
+ });
578
+ return { nodes: [], terminal: true };
579
+ },
580
+ },
581
+ });
582
+ original_city.groups.add(original_group);
583
+ const original_session = await original_group.sessions.create();
584
+ await original_session.prompt({ query: "recover dispatch" });
585
+ for (let attempt = 0; attempt < 200 && !original_dispatch_started; attempt += 1) {
586
+ await new Promise((resolve) => setTimeout(resolve, 5));
587
+ }
588
+
589
+ const restored_city = new City({ storage: new LocalStorageProvider(root_path) });
590
+ const restored_agent = new Agent({ id: "recovery-member", session_class: RecordingSession });
591
+ restored_city.agents.add(restored_agent);
592
+ const restored_group = new Group({
593
+ id: "dispatch-recovery-group",
594
+ members: [restored_agent],
595
+ dispatch_strategy: test_dispatch_strategy,
596
+ });
597
+ restored_city.groups.add(restored_group);
598
+ const restored_session = await restored_group.sessions.get(original_session.id);
599
+ assert.ok(restored_session);
600
+ await wait_for_group_idle(restored_session);
601
+
602
+ assert.deepEqual(RecordingSession.created.map((entry) => entry.agent_id), ["recovery-member"]);
603
+ assert.deepEqual((await restored_session.messages()).map((message) => message.text), [
604
+ "recover dispatch",
605
+ "reply:recovery-member",
606
+ ]);
607
+ await original_session.stop();
608
+ assert.equal(original_abort_signal.aborted, true);
609
+ await restored_city.close();
610
+ await original_city.close();
611
+ await fs.rm(root_path, { recursive: true, force: true });
612
+ });
613
+
417
614
  test("GroupSession 持久化调度检查点并在收口后清理", async () => {
418
615
  const root_path = await fs.mkdtemp(path.join(os.tmpdir(), "downcity-group-checkpoint-"));
419
616
  const storage = new LocalStorageProvider(root_path);
@@ -450,6 +647,56 @@ test("GroupSession 持久化调度检查点并在收口后清理", async () => {
450
647
  await fs.rm(root_path, { recursive: true, force: true });
451
648
  });
452
649
 
650
+ test("GroupSession 列表首次读取时将 v1 metadata 原子迁移为 v2", async () => {
651
+ const root_path = await fs.mkdtemp(path.join(os.tmpdir(), "downcity-group-metadata-migration-"));
652
+ const group_id = "metadata-migration-group";
653
+ const session_id = "legacy-session";
654
+ const session_path = path.join(root_path, "groups", group_id, "sessions", session_id);
655
+ const meta_path = path.join(session_path, "meta.json");
656
+ await fs.mkdir(session_path, { recursive: true });
657
+ await fs.writeFile(meta_path, `${JSON.stringify({
658
+ v: 1,
659
+ session_id,
660
+ group_id,
661
+ created_at: 1,
662
+ updated_at: 2,
663
+ message_count: 1,
664
+ preview_text: "legacy message",
665
+ pending_turns: [{
666
+ turn_id: "legacy-turn",
667
+ root_message_id: "legacy-message",
668
+ context_message_ids: [],
669
+ }],
670
+ auto_frontier_message_ids: ["legacy-reply"],
671
+ }, null, 2)}\n`);
672
+
673
+ const city = new City({ storage: new LocalStorageProvider(root_path) });
674
+ const agent = new Agent({ id: "metadata-agent", session_class: RecordingSession });
675
+ city.agents.add(agent);
676
+ const group = new Group({ id: group_id, members: [agent], dispatch_strategy: test_dispatch_strategy });
677
+ city.groups.add(group);
678
+
679
+ assert.deepEqual(await group.sessions.list(), [{
680
+ id: session_id,
681
+ group_id,
682
+ created_at: 1,
683
+ updated_at: 2,
684
+ message_count: 1,
685
+ preview_text: "legacy message",
686
+ }]);
687
+ const migrated_metadata = JSON.parse(await fs.readFile(meta_path, "utf8"));
688
+ assert.equal(migrated_metadata.v, 2);
689
+ assert.deepEqual(migrated_metadata.pending_turns, [{
690
+ turn_id: "legacy-turn",
691
+ root_message_id: "legacy-message",
692
+ context_message_ids: [],
693
+ dispatch_stage: "auto",
694
+ }]);
695
+ assert.deepEqual(migrated_metadata.auto_frontier_message_ids, ["legacy-reply"]);
696
+ await city.close();
697
+ await fs.rm(root_path, { recursive: true, force: true });
698
+ });
699
+
453
700
  test("GroupSession 恢复时修复尾部损坏的消息记录", async () => {
454
701
  const root_path = await fs.mkdtemp(path.join(os.tmpdir(), "downcity-group-tail-"));
455
702
  const storage = new LocalStorageProvider(root_path);
@@ -628,7 +875,7 @@ test("唯一 auto dispatch 等待并合并并发输入批次", async () => {
628
875
  await city.close();
629
876
  });
630
877
 
631
- test("响应图依赖没有有效回复时不会继续投递下游节点", async () => {
878
+ test("成员返回空内容时记录失败且不继续投递下游节点", async () => {
632
879
  RecordingSession.created = [];
633
880
  class EmptySession extends Session {
634
881
  async prompt() {
@@ -665,6 +912,10 @@ test("响应图依赖没有有效回复时不会继续投递下游节点", async
665
912
  await group_session.prompt({ query: "请分析并审查" });
666
913
  await wait_for_group_idle(group_session);
667
914
  assert.deepEqual(RecordingSession.created.map((entry) => entry.agent_id), ["architect"]);
915
+ assert.deepEqual((await group_session.messages()).map((message) => [message.sender_type, message.text]), [
916
+ ["user", "请分析并审查"],
917
+ ["system", "architect 执行失败:未生成有效回复"],
918
+ ]);
668
919
  await city.close();
669
920
  });
670
921
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@downcity/agent",
3
- "version": "1.1.401",
3
+ "version": "1.1.408",
4
4
  "type": "module",
5
5
  "description": "Downcity 单 Agent SDK 与执行运行时",
6
6
  "main": "./bin/index.js",
@@ -28,9 +28,9 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@downcity/workspace": "^0.1.6",
32
- "@downcity/type": "0.1.200",
33
- "@downcity/federation": "^0.1.10",
31
+ "@downcity/workspace": "^0.1.7",
32
+ "@downcity/type": "0.1.202",
33
+ "@downcity/federation": "^0.1.15",
34
34
  "commander": "^15.0.0",
35
35
  "dotenv": "^17.4.2",
36
36
  "execa": "^9.6.1",