duclaw-cli 1.8.30 → 1.8.32

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/dist/bundle.js CHANGED
@@ -30242,7 +30242,7 @@ function printHelp() {
30242
30242
  `);
30243
30243
  }
30244
30244
  function printVersion() {
30245
- console.log(`duclaw-cli v${true ? "1.8.30" : "unknown"}`);
30245
+ console.log(`duclaw-cli v${true ? "1.8.32" : "unknown"}`);
30246
30246
  }
30247
30247
  function getDuclawTemplate() {
30248
30248
  return {
@@ -41404,10 +41404,10 @@ var goalDelete = {
41404
41404
  };
41405
41405
 
41406
41406
  // src/tools/tools/department/DepartmentCreate.ts
41407
- var import_node_crypto4 = require("node:crypto");
41407
+ var import_node_crypto5 = require("node:crypto");
41408
41408
 
41409
41409
  // src/department/mailbox/mailbox.ts
41410
- var import_node_crypto3 = require("node:crypto");
41410
+ var import_node_crypto4 = require("node:crypto");
41411
41411
 
41412
41412
  // src/db/createDB.ts
41413
41413
  var import_better_sqlite3 = __toESM(require("better-sqlite3"));
@@ -41592,8 +41592,148 @@ var drainInterrupts = (userId) => {
41592
41592
  return messages;
41593
41593
  };
41594
41594
 
41595
- // src/department/mailbox/events.ts
41595
+ // src/agent/events.ts
41596
41596
  var import_node_crypto2 = require("node:crypto");
41597
+ var rowToEvent = (row) => ({
41598
+ id: row.id,
41599
+ userId: row.userId,
41600
+ type: row.type,
41601
+ source: row.source,
41602
+ sourceId: row.sourceId,
41603
+ status: row.status,
41604
+ payload: JSON.parse(row.payloadJson || "{}"),
41605
+ createdAt: row.createdAt,
41606
+ injectedAt: row.injectedAt ?? void 0,
41607
+ handledAt: row.handledAt ?? void 0,
41608
+ updatedAt: row.updatedAt
41609
+ });
41610
+ var recordAgentEvent = (input) => {
41611
+ const db3 = createSqliteDB();
41612
+ const now = Date.now();
41613
+ const id = `evt_${(0, import_node_crypto2.randomUUID)().slice(0, 12)}`;
41614
+ const payloadJson = JSON.stringify(input.payload);
41615
+ db3.prepare(`
41616
+ INSERT INTO agent_events (
41617
+ id, user_id, type, source, source_id, status, payload_json, created_at, updated_at
41618
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
41619
+ ON CONFLICT(type, source, source_id) DO UPDATE SET
41620
+ user_id = excluded.user_id,
41621
+ status = CASE
41622
+ WHEN agent_events.status IN ('handled', 'ignored') THEN agent_events.status
41623
+ ELSE excluded.status
41624
+ END,
41625
+ payload_json = excluded.payload_json,
41626
+ updated_at = excluded.updated_at
41627
+ `).run(
41628
+ id,
41629
+ input.userId,
41630
+ input.type,
41631
+ input.source,
41632
+ input.sourceId,
41633
+ input.status ?? "pending",
41634
+ payloadJson,
41635
+ now,
41636
+ now
41637
+ );
41638
+ const row = db3.prepare(`
41639
+ SELECT
41640
+ id,
41641
+ user_id as userId,
41642
+ type,
41643
+ source,
41644
+ source_id as sourceId,
41645
+ status,
41646
+ payload_json as payloadJson,
41647
+ created_at as createdAt,
41648
+ injected_at as injectedAt,
41649
+ handled_at as handledAt,
41650
+ updated_at as updatedAt
41651
+ FROM agent_events
41652
+ WHERE type = ? AND source = ? AND source_id = ?
41653
+ `).get(input.type, input.source, input.sourceId);
41654
+ return rowToEvent(row);
41655
+ };
41656
+ var listPendingAgentEvents = (userId, limit = 10) => {
41657
+ const db3 = createSqliteDB();
41658
+ const rows = db3.prepare(`
41659
+ SELECT
41660
+ id,
41661
+ user_id as userId,
41662
+ type,
41663
+ source,
41664
+ source_id as sourceId,
41665
+ status,
41666
+ payload_json as payloadJson,
41667
+ created_at as createdAt,
41668
+ injected_at as injectedAt,
41669
+ handled_at as handledAt,
41670
+ updated_at as updatedAt
41671
+ FROM agent_events
41672
+ WHERE user_id = ?
41673
+ AND status IN ('pending', 'processing')
41674
+ ORDER BY created_at ASC
41675
+ LIMIT ?
41676
+ `).all(userId, limit);
41677
+ return rows.map(rowToEvent);
41678
+ };
41679
+ var markAgentEventsInjected = (eventIds) => {
41680
+ if (eventIds.length === 0) return;
41681
+ const db3 = createSqliteDB();
41682
+ const now = Date.now();
41683
+ const stmt = db3.prepare(`
41684
+ UPDATE agent_events
41685
+ SET status = CASE WHEN status = 'pending' THEN 'processing' ELSE status END,
41686
+ injected_at = COALESCE(injected_at, ?),
41687
+ updated_at = ?
41688
+ WHERE id = ?
41689
+ AND status IN ('pending', 'processing')
41690
+ `);
41691
+ const tx = db3.transaction((ids) => {
41692
+ for (const id of ids) stmt.run(now, now, id);
41693
+ });
41694
+ tx(eventIds);
41695
+ };
41696
+ var markAgentEventsHandled = (eventIds, status = "handled") => {
41697
+ if (eventIds.length === 0) return;
41698
+ const db3 = createSqliteDB();
41699
+ const now = Date.now();
41700
+ const stmt = db3.prepare(`
41701
+ UPDATE agent_events
41702
+ SET status = ?,
41703
+ handled_at = COALESCE(handled_at, ?),
41704
+ updated_at = ?
41705
+ WHERE id = ?
41706
+ AND status IN ('pending', 'processing')
41707
+ `);
41708
+ const tx = db3.transaction((ids) => {
41709
+ for (const id of ids) stmt.run(status, now, now, id);
41710
+ });
41711
+ tx(eventIds);
41712
+ };
41713
+ var renderAgentEventReminder = (events) => {
41714
+ if (events.length === 0) return "";
41715
+ const lines = events.map((event) => {
41716
+ const owner = typeof event.payload.ownerMailboxId === "string" ? event.payload.ownerMailboxId : void 0;
41717
+ const mailboxMessageId = typeof event.payload.mailboxMessageId === "string" ? event.payload.mailboxMessageId : event.sourceId;
41718
+ const summary = typeof event.payload.summary === "string" ? event.payload.summary : typeof event.payload.contentPreview === "string" ? event.payload.contentPreview : "";
41719
+ return [
41720
+ `- eventId=${event.id}`,
41721
+ `type=${event.type}`,
41722
+ owner ? `owner=${owner}` : "",
41723
+ mailboxMessageId ? `mailboxMessageId=${mailboxMessageId}` : "",
41724
+ summary ? `summary=${summary}` : ""
41725
+ ].filter(Boolean).join(" ");
41726
+ }).join("\n");
41727
+ return `<system-reminder>
41728
+ \u672C\u8F6E\u6709 ${events.length} \u6761\u5185\u90E8\u4E8B\u4EF6\u53EF\u7528\uFF1A
41729
+ ${lines}
41730
+
41731
+ \u8FD9\u4E9B\u4E8B\u4EF6\u4E0D\u662F\u7528\u6237\u7684\u65B0\u8BF7\u6C42\uFF0C\u4E5F\u4E0D\u5E94\u8BE5\u4F5C\u4E3A\u7528\u6237\u786E\u8BA4\u3002\u82E5\u4E8B\u4EF6\u7C7B\u578B\u662F mailbox.message_received\uFF0C\u8868\u793A\u4F60\u7684 mailbox \u5728\u5F53\u524D\u5DE5\u4F5C\u671F\u95F4\u6536\u5230\u65B0\u5185\u90E8\u534F\u4F5C\u6D88\u606F\uFF1B\u8BF7\u5C3D\u5FEB\u8C03\u7528 list_mailbox \u67E5\u770B\u961F\u5217\uFF0C\u5E76\u5728\u9700\u8981\u65F6\u7528 get_mailbox(message_id) \u9886\u53D6\u5173\u8054\u6D88\u606F\u3002\u4E0D\u8981\u76F4\u63A5\u628A\u4E8B\u4EF6\u5F53\u4F5C\u5DF2\u9886\u53D6\u90AE\u4EF6\u3002\u8BF7\u53EA\u5728\u9700\u8981\u65F6\u81EA\u7136\u5730\u6C47\u603B\u7ED9\u7528\u6237\uFF1B\u5982\u9700\u7EE7\u7EED\u534F\u4F5C\uFF0C\u4F18\u5148\u4F7F\u7528\u4E8B\u4EF6\u4E2D\u5173\u8054\u7684 mailboxMessageId/thread \u7EE7\u7EED\u5904\u7406\u3002\u4E0D\u8981\u590D\u8FF0\u672C system-reminder\u3002
41732
+ </system-reminder>`;
41733
+ };
41734
+
41735
+ // src/department/mailbox/events.ts
41736
+ var import_node_crypto3 = require("node:crypto");
41597
41737
  var parseDetail = (detailJson) => {
41598
41738
  if (!detailJson) return void 0;
41599
41739
  try {
@@ -41634,7 +41774,7 @@ var mapMailboxEventRow = (row) => {
41634
41774
  var recordMailboxEvent = (input) => {
41635
41775
  const db3 = createSqliteDB();
41636
41776
  const event = {
41637
- id: (0, import_node_crypto2.randomUUID)().slice(0, 12),
41777
+ id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
41638
41778
  messageId: input.messageId,
41639
41779
  mailboxId: input.mailboxId,
41640
41780
  actorMailboxId: input.actorMailboxId,
@@ -41979,6 +42119,24 @@ var queueMailboxInterruptIfRunning = (msg) => {
41979
42119
  console.log(`[mailbox] \u76EE\u6807 agent ${msg.toMailboxId} \u6B63\u5728\u8FD0\u884C\uFF0C\u5DF2\u5C06\u65B0\u90AE\u4EF6 ${msg.id} \u4F5C\u4E3A\u4E2D\u65AD\u63D0\u9192\u5165\u961F`);
41980
42120
  }
41981
42121
  };
42122
+ var recordMailboxReceivedAgentEvent = (msg) => {
42123
+ if (msg.toMailboxId === "manager") return;
42124
+ recordAgentEvent({
42125
+ userId: msg.toMailboxId,
42126
+ type: "mailbox.message_received",
42127
+ source: "mailbox",
42128
+ sourceId: msg.id,
42129
+ payload: {
42130
+ ownerMailboxId: msg.toMailboxId,
42131
+ mailboxMessageId: msg.id,
42132
+ fromMailboxId: msg.fromMailboxId,
42133
+ toMailboxId: msg.toMailboxId,
42134
+ threadId: msg.threadId || msg.id,
42135
+ contentPreview: msg.content.slice(0, 160),
42136
+ summary: `\u6536\u5230\u6765\u81EA ${msg.fromMailboxId} \u7684\u65B0\u5185\u90E8\u534F\u4F5C\u6D88\u606F\uFF0C\u8BF7\u7528 list_mailbox/get_mailbox \u8BC4\u4F30\u5E76\u9886\u53D6\u3002`
42137
+ }
42138
+ });
42139
+ };
41982
42140
  var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
41983
42141
  const db3 = createSqliteDB();
41984
42142
  const stmt = db3.prepare(`insert into mailbox (
@@ -41993,7 +42151,7 @@ var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
41993
42151
  thread_id,
41994
42152
  parent_message_id
41995
42153
  ) values (?,?,?,?,?,?,?,?,?,?) `);
41996
- const id = (0, import_node_crypto3.randomUUID)().slice(0, 8);
42154
+ const id = (0, import_node_crypto4.randomUUID)().slice(0, 8);
41997
42155
  const threadId = options?.threadId || id;
41998
42156
  let mailboxMsg = {
41999
42157
  id,
@@ -42031,6 +42189,7 @@ var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
42031
42189
  },
42032
42190
  createdAt: mailboxMsg.sendTime
42033
42191
  });
42192
+ recordMailboxReceivedAgentEvent(mailboxMsg);
42034
42193
  queueMailboxInterruptIfRunning(mailboxMsg);
42035
42194
  return mailboxMsg;
42036
42195
  };
@@ -42109,7 +42268,7 @@ var departmentCreate = {
42109
42268
  return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
42110
42269
  }
42111
42270
  let departmentDefinition = {
42112
- id: (0, import_node_crypto4.randomUUID)().slice(0, 8),
42271
+ id: (0, import_node_crypto5.randomUUID)().slice(0, 8),
42113
42272
  name,
42114
42273
  charter,
42115
42274
  sourceGoalId,
@@ -42323,7 +42482,7 @@ var departmentList = {
42323
42482
  };
42324
42483
 
42325
42484
  // src/tools/tools/department/DepartmentMemberCreate.ts
42326
- var import_node_crypto5 = require("node:crypto");
42485
+ var import_node_crypto6 = require("node:crypto");
42327
42486
  var DESCRIPTION24 = `
42328
42487
  \u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
42329
42488
 
@@ -42389,7 +42548,7 @@ var departmentMemberCreate = {
42389
42548
  }
42390
42549
  }
42391
42550
  let departmentMember = {
42392
- id: (0, import_node_crypto5.randomUUID)().slice(0, 8),
42551
+ id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
42393
42552
  name,
42394
42553
  departmentId: department.id,
42395
42554
  mailBoxId: getMailBoxId(department.name, name),
@@ -42580,7 +42739,7 @@ ${replies}`;
42580
42739
  // src/department/learning.ts
42581
42740
  var import_node_fs4 = require("node:fs");
42582
42741
  var import_node_path12 = __toESM(require("node:path"));
42583
- var import_node_crypto6 = require("node:crypto");
42742
+ var import_node_crypto7 = require("node:crypto");
42584
42743
 
42585
42744
  // src/skill/SkillValidator.ts
42586
42745
  var import_node_fs3 = require("node:fs");
@@ -42818,7 +42977,7 @@ var listDepartmentMemories = (departmentName) => {
42818
42977
  var createDepartmentMemory = (departmentName, input) => {
42819
42978
  const now = Date.now();
42820
42979
  const memory = {
42821
- id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
42980
+ id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
42822
42981
  departmentName,
42823
42982
  title: input.title,
42824
42983
  content: input.content,
@@ -42869,7 +43028,7 @@ ${formatSkillValidationIssues(validation)}`);
42869
43028
  }
42870
43029
  const now = Date.now();
42871
43030
  const skill = {
42872
- id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
43031
+ id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
42873
43032
  departmentName,
42874
43033
  skillName: input.skillName,
42875
43034
  description: input.description,
@@ -42921,7 +43080,7 @@ var createDepartmentProposal = (input) => {
42921
43080
  const records = readJsonArray(proposalsPath());
42922
43081
  const proposal = {
42923
43082
  ...input,
42924
- id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
43083
+ id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
42925
43084
  status: "pending",
42926
43085
  createdAt: Date.now()
42927
43086
  };
@@ -43252,7 +43411,7 @@ var mailboxFollowup = {
43252
43411
 
43253
43412
  // src/tools/tools/Bash.ts
43254
43413
  var import_node_child_process = require("node:child_process");
43255
- var import_node_crypto7 = require("node:crypto");
43414
+ var import_node_crypto8 = require("node:crypto");
43256
43415
  var import_node_fs5 = require("node:fs");
43257
43416
  var DESCRIPTION29 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
43258
43417
 
@@ -43456,7 +43615,7 @@ var bashTool = {
43456
43615
  ...options,
43457
43616
  stdio: ["pipe", "pipe", "pipe"]
43458
43617
  });
43459
- const id = (0, import_node_crypto7.randomUUID)().slice(0, 8);
43618
+ const id = (0, import_node_crypto8.randomUUID)().slice(0, 8);
43460
43619
  const session = {
43461
43620
  id,
43462
43621
  command,
@@ -44037,7 +44196,7 @@ var readDreamHistoryLimit = () => {
44037
44196
  var import_node_fs6 = require("node:fs");
44038
44197
  var import_node_os2 = require("node:os");
44039
44198
  var import_node_path13 = require("node:path");
44040
- var import_node_crypto8 = require("node:crypto");
44199
+ var import_node_crypto9 = require("node:crypto");
44041
44200
  var SkillForgeEngine = class {
44042
44201
  proposalStorage;
44043
44202
  draftRoot;
@@ -44071,7 +44230,7 @@ ${formatSkillValidationIssues(validation)}`);
44071
44230
  if (pending.some((p) => p.skillName === skillName)) {
44072
44231
  return null;
44073
44232
  }
44074
- const id = (0, import_node_crypto8.randomBytes)(4).toString("hex");
44233
+ const id = (0, import_node_crypto9.randomBytes)(4).toString("hex");
44075
44234
  const draftDir = (0, import_node_path13.join)(this.draftRoot, userId, id);
44076
44235
  (0, import_node_fs6.mkdirSync)(draftDir, { recursive: true });
44077
44236
  (0, import_node_fs6.writeFileSync)((0, import_node_path13.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
@@ -44353,7 +44512,7 @@ var skillForgeDrop = (engine) => ({
44353
44512
  });
44354
44513
 
44355
44514
  // src/memory/MemoryEngine.ts
44356
- var import_node_crypto9 = require("node:crypto");
44515
+ var import_node_crypto10 = require("node:crypto");
44357
44516
  var MemoryEngine = class {
44358
44517
  storage;
44359
44518
  recallIndexStorage;
@@ -44381,7 +44540,7 @@ var MemoryEngine = class {
44381
44540
  }
44382
44541
  const now = Date.now();
44383
44542
  const memory = {
44384
- id: (0, import_node_crypto9.randomBytes)(4).toString("hex"),
44543
+ id: (0, import_node_crypto10.randomBytes)(4).toString("hex"),
44385
44544
  userId,
44386
44545
  title,
44387
44546
  content,
@@ -45033,146 +45192,6 @@ var microCompactMessages = (messages, config2) => {
45033
45192
  };
45034
45193
  };
45035
45194
 
45036
- // src/agent/events.ts
45037
- var import_node_crypto10 = require("node:crypto");
45038
- var rowToEvent = (row) => ({
45039
- id: row.id,
45040
- userId: row.userId,
45041
- type: row.type,
45042
- source: row.source,
45043
- sourceId: row.sourceId,
45044
- status: row.status,
45045
- payload: JSON.parse(row.payloadJson || "{}"),
45046
- createdAt: row.createdAt,
45047
- injectedAt: row.injectedAt ?? void 0,
45048
- handledAt: row.handledAt ?? void 0,
45049
- updatedAt: row.updatedAt
45050
- });
45051
- var recordAgentEvent = (input) => {
45052
- const db3 = createSqliteDB();
45053
- const now = Date.now();
45054
- const id = `evt_${(0, import_node_crypto10.randomUUID)().slice(0, 12)}`;
45055
- const payloadJson = JSON.stringify(input.payload);
45056
- db3.prepare(`
45057
- INSERT INTO agent_events (
45058
- id, user_id, type, source, source_id, status, payload_json, created_at, updated_at
45059
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
45060
- ON CONFLICT(type, source, source_id) DO UPDATE SET
45061
- user_id = excluded.user_id,
45062
- status = CASE
45063
- WHEN agent_events.status IN ('handled', 'ignored') THEN agent_events.status
45064
- ELSE excluded.status
45065
- END,
45066
- payload_json = excluded.payload_json,
45067
- updated_at = excluded.updated_at
45068
- `).run(
45069
- id,
45070
- input.userId,
45071
- input.type,
45072
- input.source,
45073
- input.sourceId,
45074
- input.status ?? "pending",
45075
- payloadJson,
45076
- now,
45077
- now
45078
- );
45079
- const row = db3.prepare(`
45080
- SELECT
45081
- id,
45082
- user_id as userId,
45083
- type,
45084
- source,
45085
- source_id as sourceId,
45086
- status,
45087
- payload_json as payloadJson,
45088
- created_at as createdAt,
45089
- injected_at as injectedAt,
45090
- handled_at as handledAt,
45091
- updated_at as updatedAt
45092
- FROM agent_events
45093
- WHERE type = ? AND source = ? AND source_id = ?
45094
- `).get(input.type, input.source, input.sourceId);
45095
- return rowToEvent(row);
45096
- };
45097
- var listPendingAgentEvents = (userId, limit = 10) => {
45098
- const db3 = createSqliteDB();
45099
- const rows = db3.prepare(`
45100
- SELECT
45101
- id,
45102
- user_id as userId,
45103
- type,
45104
- source,
45105
- source_id as sourceId,
45106
- status,
45107
- payload_json as payloadJson,
45108
- created_at as createdAt,
45109
- injected_at as injectedAt,
45110
- handled_at as handledAt,
45111
- updated_at as updatedAt
45112
- FROM agent_events
45113
- WHERE user_id = ?
45114
- AND status IN ('pending', 'processing')
45115
- ORDER BY created_at ASC
45116
- LIMIT ?
45117
- `).all(userId, limit);
45118
- return rows.map(rowToEvent);
45119
- };
45120
- var markAgentEventsInjected = (eventIds) => {
45121
- if (eventIds.length === 0) return;
45122
- const db3 = createSqliteDB();
45123
- const now = Date.now();
45124
- const stmt = db3.prepare(`
45125
- UPDATE agent_events
45126
- SET status = CASE WHEN status = 'pending' THEN 'processing' ELSE status END,
45127
- injected_at = COALESCE(injected_at, ?),
45128
- updated_at = ?
45129
- WHERE id = ?
45130
- AND status IN ('pending', 'processing')
45131
- `);
45132
- const tx = db3.transaction((ids) => {
45133
- for (const id of ids) stmt.run(now, now, id);
45134
- });
45135
- tx(eventIds);
45136
- };
45137
- var markAgentEventsHandled = (eventIds, status = "handled") => {
45138
- if (eventIds.length === 0) return;
45139
- const db3 = createSqliteDB();
45140
- const now = Date.now();
45141
- const stmt = db3.prepare(`
45142
- UPDATE agent_events
45143
- SET status = ?,
45144
- handled_at = COALESCE(handled_at, ?),
45145
- updated_at = ?
45146
- WHERE id = ?
45147
- AND status IN ('pending', 'processing')
45148
- `);
45149
- const tx = db3.transaction((ids) => {
45150
- for (const id of ids) stmt.run(status, now, now, id);
45151
- });
45152
- tx(eventIds);
45153
- };
45154
- var renderAgentEventReminder = (events) => {
45155
- if (events.length === 0) return "";
45156
- const lines = events.map((event) => {
45157
- const owner = typeof event.payload.ownerMailboxId === "string" ? event.payload.ownerMailboxId : void 0;
45158
- const mailboxMessageId = typeof event.payload.mailboxMessageId === "string" ? event.payload.mailboxMessageId : event.sourceId;
45159
- const summary = typeof event.payload.summary === "string" ? event.payload.summary : typeof event.payload.contentPreview === "string" ? event.payload.contentPreview : "";
45160
- return [
45161
- `- eventId=${event.id}`,
45162
- `type=${event.type}`,
45163
- owner ? `owner=${owner}` : "",
45164
- mailboxMessageId ? `mailboxMessageId=${mailboxMessageId}` : "",
45165
- summary ? `summary=${summary}` : ""
45166
- ].filter(Boolean).join(" ");
45167
- }).join("\n");
45168
- return `<system-reminder>
45169
- \u672C\u8F6E\u6709 ${events.length} \u6761\u5185\u90E8\u4E8B\u4EF6\u53EF\u7528\uFF1A
45170
- ${lines}
45171
-
45172
- \u8FD9\u4E9B\u4E8B\u4EF6\u4E0D\u662F\u7528\u6237\u7684\u65B0\u8BF7\u6C42\uFF0C\u4E5F\u4E0D\u5E94\u8BE5\u4F5C\u4E3A\u7528\u6237\u786E\u8BA4\u3002\u8BF7\u53EA\u5728\u9700\u8981\u65F6\u81EA\u7136\u5730\u6C47\u603B\u7ED9\u7528\u6237\uFF1B\u5982\u9700\u7EE7\u7EED\u534F\u4F5C\uFF0C\u4F18\u5148\u4F7F\u7528\u4E8B\u4EF6\u4E2D\u5173\u8054\u7684 mailboxMessageId/thread \u7EE7\u7EED\u5904\u7406\u3002\u4E0D\u8981\u590D\u8FF0\u672C system-reminder\u3002
45173
- </system-reminder>`;
45174
- };
45175
-
45176
45195
  // src/agent/createAgent.ts
45177
45196
  var DEFAULT_WORKSPACE_PATH = getDuclawWorkspaceDir();
45178
45197
  var assistantMessageFromResponse = (response) => ({
@@ -46600,15 +46619,16 @@ var wakeDepartmentAgent = async (mailboxId, msgIds) => {
46600
46619
  }
46601
46620
  const department = getDepartmentById(member.departmentId);
46602
46621
  const workspacePath = department?.workpath;
46603
- const agentConfig = getDepartmentAgentConfig(void 0, member.focusOn, workspacePath, department?.name);
46622
+ const agentConfig = getDepartmentAgentConfig(void 0, member.focusOn, workspacePath, department?.name, member.role, member.name);
46604
46623
  const agent = createAgent(agentConfig);
46624
+ const roleSpecificReminder = member.role === "department_head" ? `\u4F60\u662F Department Head\u3002\u8BFB\u53D6\u90AE\u4EF6\u540E\uFF0C\u5982\u679C\u8FD9\u662F\u590D\u6742\u6267\u884C\u5DE5\u4F5C\uFF08\u4F8B\u5982\u5199\u4EE3\u7801\u3001\u8BFB\u4EE3\u7801\u5B9A\u4F4D\u3001\u8DD1\u6D4B\u8BD5\u3001\u8C03\u8BD5\u3001\u90E8\u7F72\u3001\u5168\u9762\u9A8C\u8BC1\u6216\u751F\u6210\u590D\u6742\u4EA7\u7269\uFF09\uFF0C\u4E0D\u8981\u9ED8\u8BA4\u81EA\u5DF1\u4E0B\u573A\u6267\u884C\uFF1B\u5148\u7528 department_member_list \u67E5\u770B\u6210\u5458\uFF0C\u9009\u62E9\u6216\u521B\u5EFA\u5408\u9002 Executor\uFF0C\u5E76\u7528 department_communicate \u5206\u6D3E\u5177\u4F53\u4EFB\u52A1\u3002\u4F60\u8D1F\u8D23\u62C6\u89E3\u3001\u534F\u8C03\u3001\u8FFD\u95EE\u3001\u9A8C\u6536\u548C\u6C47\u603B\u3002` : `\u4F60\u662F Executor\u3002\u8BFB\u53D6\u90AE\u4EF6\u540E\u76F4\u63A5\u5904\u7406\u5206\u6D3E\u7ED9\u4F60\u7684\u5177\u4F53\u6267\u884C\u4EFB\u52A1\uFF1B\u4E0D\u8981\u5C1D\u8BD5\u67E5\u770B\u5B8C\u6574\u90E8\u95E8\u6210\u5458\u76EE\u5F55\u6216\u521B\u5EFA\u6210\u5458\u3002`;
46605
46625
  const request = {
46606
46626
  platform: "mailbox",
46607
46627
  userId: mailboxId,
46608
46628
  requestId: msgIds[0],
46609
46629
  departmentAgentId: mailboxId,
46610
46630
  workspacePath,
46611
- content: `\u4F60\u7684\u90AE\u7BB1\u4E2D\u6709 ${msgIds.length} \u5C01\u5F85\u5904\u7406\u90AE\u4EF6\u3002\u8BF7\u4F7F\u7528 list_mailbox \u67E5\u770B\u90AE\u4EF6\u5217\u8868\uFF0C\u6839\u636E\u91CD\u8981\u6027\u548C\u65F6\u6548\u6027\u9009\u62E9\u4E00\u5C01\u90AE\u4EF6\uFF0C\u518D\u7528 get_mailbox \u9886\u53D6\u5E76\u8BFB\u53D6\u8BE5\u90AE\u4EF6\u3002\u5B8C\u6210\u8FD9\u5C01\u90AE\u4EF6\u540E\u5FC5\u987B\u4F7F\u7528 reply_mailbox \u56DE\u590D\u5E76\u7ED3\u675F\u5B83\uFF1B\u5982\u679C\u67D0\u5C01\u90AE\u4EF6\u53EA\u662F\u786E\u8BA4\u6027\u56DE\u6267\u3001\u91CD\u590D\u901A\u77E5\u6216\u65E0\u9700\u4E1A\u52A1\u56DE\u590D\uFF0C\u5FC5\u987B\u4F7F\u7528 discard_mailbox \u4E22\u5F03\u5E76\u7ED3\u675F\u5B83\u3002\u7136\u540E\u7EE7\u7EED list_mailbox \u51B3\u5B9A\u4E0B\u4E00\u5C01\u3002`
46631
+ content: `\u4F60\u7684\u90AE\u7BB1\u4E2D\u6709 ${msgIds.length} \u5C01\u5F85\u5904\u7406\u90AE\u4EF6\u3002\u8BF7\u4F7F\u7528 list_mailbox \u67E5\u770B\u90AE\u4EF6\u5217\u8868\uFF0C\u6839\u636E\u91CD\u8981\u6027\u548C\u65F6\u6548\u6027\u9009\u62E9\u4E00\u5C01\u90AE\u4EF6\uFF0C\u518D\u7528 get_mailbox \u9886\u53D6\u5E76\u8BFB\u53D6\u8BE5\u90AE\u4EF6\u3002${roleSpecificReminder} \u5B8C\u6210\u8FD9\u5C01\u90AE\u4EF6\u540E\u5FC5\u987B\u4F7F\u7528 reply_mailbox \u56DE\u590D\u5E76\u7ED3\u675F\u5B83\uFF1B\u5982\u679C\u67D0\u5C01\u90AE\u4EF6\u53EA\u662F\u786E\u8BA4\u6027\u56DE\u6267\u3001\u91CD\u590D\u901A\u77E5\u6216\u65E0\u9700\u4E1A\u52A1\u56DE\u590D\uFF0C\u5FC5\u987B\u4F7F\u7528 discard_mailbox \u4E22\u5F03\u5E76\u7ED3\u675F\u5B83\u3002\u7136\u540E\u7EE7\u7EED list_mailbox \u51B3\u5B9A\u4E0B\u4E00\u5C01\u3002`
46612
46632
  };
46613
46633
  const result = await agent(request);
46614
46634
  console.log(`[mailbox] department agent ${mailboxId} \u5904\u7406\u5B8C\u6210, alreadySent=${result.alreadySent}`);
@@ -46801,13 +46821,19 @@ var createDepartmentAgentTools = () => {
46801
46821
  registerTool(registry2, departmentProposalCreate);
46802
46822
  return { registry: registry2, executor };
46803
46823
  };
46804
- var getDepartmentAgentConfig = (tools, memberFocusOn, workspacePath, departmentName) => {
46824
+ var getDepartmentAgentConfig = (tools, memberFocusOn, workspacePath, departmentName, memberRole, memberName) => {
46805
46825
  loadEnv();
46806
46826
  const defaultSystemPrompt = `
46807
46827
  You are a department member agent in an AI company collaboration system. You communicate with other agents through a mailbox system \u2014 you do NOT interact with end users directly.
46808
46828
 
46809
46829
  <Role>
46810
46830
  Your role is to process messages from other department agents, complete your assigned tasks, and respond with clear results. Focus on your department role and collaborate effectively with other agents.
46831
+ ${departmentName ? `
46832
+ Your department: ${departmentName}` : ""}
46833
+ ${memberName ? `
46834
+ Your member name: ${memberName}` : ""}
46835
+ ${memberRole ? `
46836
+ Your organization role: ${memberRole}` : ""}
46811
46837
  ${memberFocusOn ? `
46812
46838
  Your specialization: ${memberFocusOn}` : ""}
46813
46839
  </Role>
@@ -46843,6 +46869,19 @@ ${workspacePath ? `
46843
46869
  - \u56DE\u590D\u5185\u5BB9\u5E94\u6E05\u6670\u3001\u7ED3\u6784\u5316\uFF0C\u4FBF\u4E8E\u5BF9\u65B9\u89E3\u6790\u548C\u7EE7\u7EED\u5DE5\u4F5C
46844
46870
  </Mailbox Workflow>
46845
46871
 
46872
+ <Department Head Delegation Rules>
46873
+ \u5982\u679C\u4F60\u7684 organization role \u662F department_head\uFF0C\u4F60\u662F\u7BA1\u7406\u5C42\u548C\u9A8C\u6536\u8005\uFF0C\u4E0D\u662F\u9ED8\u8BA4\u6267\u884C\u5C42\u3002
46874
+
46875
+ \u786C\u89C4\u5219\uFF1A
46876
+ 1. \u5BF9\u4E8E\u5199\u4EE3\u7801\u3001\u8BFB\u4EE3\u7801\u5B9A\u4F4D\u95EE\u9898\u3001\u6539\u6587\u4EF6\u3001\u8DD1\u6D4B\u8BD5\u3001\u8C03\u8BD5\u3001\u90E8\u7F72\u3001\u6570\u636E\u5904\u7406\u3001\u5916\u90E8 API \u9A8C\u8BC1\u3001\u751F\u6210\u590D\u6742\u4EA7\u7269\u3001\u5168\u9762\u6D4B\u8BD5\u7B49\u5177\u4F53\u6267\u884C\u5DE5\u4F5C\uFF0C\u5FC5\u987B\u5148\u5224\u65AD\u662F\u5426\u53EF\u4EE5\u5206\u6D3E\u7ED9\u672C\u90E8\u95E8 Executor\u3002
46877
+ 2. \u5904\u7406\u8FD9\u7C7B\u590D\u6742\u6267\u884C\u90AE\u4EF6\u65F6\uFF0C\u7B2C\u4E00\u6B65\u5E94\u4F7F\u7528 department_member_list \u67E5\u770B\u672C\u90E8\u95E8\u6210\u5458\uFF1B\u5982\u679C\u5DF2\u6709\u5408\u9002 Executor\uFF0C\u4F7F\u7528 department_communicate \u628A\u5177\u4F53\u6267\u884C\u4EFB\u52A1\u6D3E\u7ED9 Executor\u3002
46878
+ 3. \u5982\u679C\u6CA1\u6709\u5408\u9002 Executor\uFF0C\u4F18\u5148\u4F7F\u7528 department_member_create \u521B\u5EFA\u4E00\u4E2A\u804C\u8D23\u660E\u786E\u7684 Executor\uFF0C\u518D\u4F7F\u7528 department_communicate \u5206\u6D3E\u4EFB\u52A1\u3002
46879
+ 4. Department Head \u53EF\u4EE5\u81EA\u5DF1\u505A\u4EFB\u52A1\u62C6\u89E3\u3001\u6D4B\u8BD5\u8BA1\u5212\u3001\u9A8C\u6536\u6807\u51C6\u3001\u98CE\u9669\u5224\u65AD\u3001\u8FDB\u5EA6\u8FFD\u95EE\u548C\u6700\u7EC8\u6C47\u603B\uFF1B\u4E0D\u8981\u9ED8\u8BA4\u81EA\u5DF1\u8C03\u7528 bash/read/write/edit/grep/codesearch/websearch \u53BB\u5B8C\u6210 Executor \u5E94\u8BE5\u505A\u7684\u4E13\u4E1A\u6267\u884C\u3002
46880
+ 5. Executor \u672A\u56DE\u4FE1\u6216\u8FDB\u5EA6\u6162\uFF0C\u4E0D\u662F Department Head \u81EA\u5DF1\u4E0B\u573A\u5E72\u6D3B\u7684\u7406\u7531\uFF1B\u5E94\u901A\u8FC7 mailbox_followup \u6216 department_communicate \u8FFD\u95EE/\u8865\u5145\u4E0A\u4E0B\u6587\uFF0C\u5E76\u5411\u4E0A\u6E38\u8BF4\u660E\u6B63\u5728\u7B49\u5F85\u6267\u884C\u5C42\u7ED3\u679C\u3002
46881
+ 6. \u53EA\u6709\u5F53\u90AE\u4EF6\u660E\u786E\u8981\u6C42 Department Head \u4EB2\u81EA\u6267\u884C\u3001\u5F53\u524D\u90E8\u95E8\u6CA1\u6709\u53EF\u7528 Executor \u4E14\u77ED\u671F\u65E0\u6CD5\u521B\u5EFA\u3001\u6216 Executor \u660E\u786E\u5931\u8D25\u4E14\u4E0A\u6E38\u540C\u610F Head \u63A5\u7BA1\u65F6\uFF0CDepartment Head \u624D\u80FD\u4EB2\u81EA\u4F7F\u7528\u6267\u884C\u7C7B\u5DE5\u5177\u5B8C\u6210\u4E13\u4E1A\u6267\u884C\u3002
46882
+ 7. \u6536\u5230 Executor \u56DE\u4FE1\u540E\uFF0CDepartment Head \u5E94\u505A\u9A8C\u6536\u548C\u6C47\u603B\uFF1A\u5FC5\u8981\u65F6\u53EF\u4EE5\u68C0\u67E5\u5C11\u91CF\u5173\u952E\u8BC1\u636E\uFF0C\u4F46\u4E0D\u8981\u628A Executor \u7684\u5B8C\u6574\u6267\u884C\u804C\u8D23\u91CD\u65B0\u81EA\u5DF1\u505A\u4E00\u904D\u3002
46883
+ </Department Head Delegation Rules>
46884
+
46846
46885
  <Task Execution>
46847
46886
  - Use available tools to complete the work.
46848
46887
  - For file operations, use the dedicated file tools:
@@ -51811,7 +51850,7 @@ var systemRoutes = new Hono2();
51811
51850
  var startTime = Date.now();
51812
51851
  systemRoutes.get("/system/info", (c) => {
51813
51852
  return c.json({
51814
- version: true ? "1.8.30" : "unknown",
51853
+ version: true ? "1.8.32" : "unknown",
51815
51854
  uptime: Math.floor((Date.now() - startTime) / 1e3),
51816
51855
  env: process.env.NODE_ENV || "development",
51817
51856
  nodeVersion: process.version