duclaw-cli 1.8.31 → 1.8.33
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 +276 -175
- package/dist/main.js +1 -1
- package/dist/worker-main.js +1 -1
- package/package.json +1 -1
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.
|
|
30245
|
+
console.log(`duclaw-cli v${true ? "1.8.33" : "unknown"}`);
|
|
30246
30246
|
}
|
|
30247
30247
|
function getDuclawTemplate() {
|
|
30248
30248
|
return {
|
|
@@ -37599,7 +37599,10 @@ var createAnthropicAdapter = (options) => {
|
|
|
37599
37599
|
}, chatOptions?.requestId ? {
|
|
37600
37600
|
headers: {
|
|
37601
37601
|
"X-Duclaw-Request-Id": chatOptions.requestId
|
|
37602
|
-
}
|
|
37602
|
+
},
|
|
37603
|
+
signal: chatOptions.signal
|
|
37604
|
+
} : chatOptions?.signal ? {
|
|
37605
|
+
signal: chatOptions.signal
|
|
37603
37606
|
} : void 0);
|
|
37604
37607
|
if (!sdkResponse.stop_reason) {
|
|
37605
37608
|
console.error(`${sdkResponse}`);
|
|
@@ -41404,10 +41407,10 @@ var goalDelete = {
|
|
|
41404
41407
|
};
|
|
41405
41408
|
|
|
41406
41409
|
// src/tools/tools/department/DepartmentCreate.ts
|
|
41407
|
-
var
|
|
41410
|
+
var import_node_crypto5 = require("node:crypto");
|
|
41408
41411
|
|
|
41409
41412
|
// src/department/mailbox/mailbox.ts
|
|
41410
|
-
var
|
|
41413
|
+
var import_node_crypto4 = require("node:crypto");
|
|
41411
41414
|
|
|
41412
41415
|
// src/db/createDB.ts
|
|
41413
41416
|
var import_better_sqlite3 = __toESM(require("better-sqlite3"));
|
|
@@ -41567,7 +41570,7 @@ var markRunning = (userId) => {
|
|
|
41567
41570
|
current.startedAt = Date.now();
|
|
41568
41571
|
return;
|
|
41569
41572
|
}
|
|
41570
|
-
registry.set(userId, { messages: [], startedAt: Date.now() });
|
|
41573
|
+
registry.set(userId, { messages: [], startedAt: Date.now(), listeners: /* @__PURE__ */ new Set() });
|
|
41571
41574
|
};
|
|
41572
41575
|
var markDone = (userId) => {
|
|
41573
41576
|
registry.delete(userId);
|
|
@@ -41581,8 +41584,23 @@ var queueInterrupt = (userId, message) => {
|
|
|
41581
41584
|
const interruptMessage = typeof message === "string" ? { content: message } : message;
|
|
41582
41585
|
entry.messages.push(interruptMessage);
|
|
41583
41586
|
console.log(`[interrupt] \u7528\u6237 ${userId} \u65B0\u6D88\u606F\u5DF2\u5165\u961F\uFF0C\u5F53\u524D\u961F\u5217\u957F\u5EA6: ${entry.messages.length}`);
|
|
41587
|
+
for (const listener of entry.listeners) {
|
|
41588
|
+
try {
|
|
41589
|
+
listener();
|
|
41590
|
+
} catch (err) {
|
|
41591
|
+
console.warn(`[interrupt] \u7528\u6237 ${userId} \u4E2D\u65AD\u76D1\u542C\u5668\u6267\u884C\u5931\u8D25: ${err.message}`);
|
|
41592
|
+
}
|
|
41593
|
+
}
|
|
41584
41594
|
return true;
|
|
41585
41595
|
};
|
|
41596
|
+
var registerInterruptListener = (userId, listener) => {
|
|
41597
|
+
const entry = registry.get(userId);
|
|
41598
|
+
if (!entry) return () => void 0;
|
|
41599
|
+
entry.listeners.add(listener);
|
|
41600
|
+
return () => {
|
|
41601
|
+
entry.listeners.delete(listener);
|
|
41602
|
+
};
|
|
41603
|
+
};
|
|
41586
41604
|
var drainInterrupts = (userId) => {
|
|
41587
41605
|
const entry = registry.get(userId);
|
|
41588
41606
|
if (!entry || entry.messages.length === 0) return [];
|
|
@@ -41592,8 +41610,148 @@ var drainInterrupts = (userId) => {
|
|
|
41592
41610
|
return messages;
|
|
41593
41611
|
};
|
|
41594
41612
|
|
|
41595
|
-
// src/
|
|
41613
|
+
// src/agent/events.ts
|
|
41596
41614
|
var import_node_crypto2 = require("node:crypto");
|
|
41615
|
+
var rowToEvent = (row) => ({
|
|
41616
|
+
id: row.id,
|
|
41617
|
+
userId: row.userId,
|
|
41618
|
+
type: row.type,
|
|
41619
|
+
source: row.source,
|
|
41620
|
+
sourceId: row.sourceId,
|
|
41621
|
+
status: row.status,
|
|
41622
|
+
payload: JSON.parse(row.payloadJson || "{}"),
|
|
41623
|
+
createdAt: row.createdAt,
|
|
41624
|
+
injectedAt: row.injectedAt ?? void 0,
|
|
41625
|
+
handledAt: row.handledAt ?? void 0,
|
|
41626
|
+
updatedAt: row.updatedAt
|
|
41627
|
+
});
|
|
41628
|
+
var recordAgentEvent = (input) => {
|
|
41629
|
+
const db3 = createSqliteDB();
|
|
41630
|
+
const now = Date.now();
|
|
41631
|
+
const id = `evt_${(0, import_node_crypto2.randomUUID)().slice(0, 12)}`;
|
|
41632
|
+
const payloadJson = JSON.stringify(input.payload);
|
|
41633
|
+
db3.prepare(`
|
|
41634
|
+
INSERT INTO agent_events (
|
|
41635
|
+
id, user_id, type, source, source_id, status, payload_json, created_at, updated_at
|
|
41636
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
41637
|
+
ON CONFLICT(type, source, source_id) DO UPDATE SET
|
|
41638
|
+
user_id = excluded.user_id,
|
|
41639
|
+
status = CASE
|
|
41640
|
+
WHEN agent_events.status IN ('handled', 'ignored') THEN agent_events.status
|
|
41641
|
+
ELSE excluded.status
|
|
41642
|
+
END,
|
|
41643
|
+
payload_json = excluded.payload_json,
|
|
41644
|
+
updated_at = excluded.updated_at
|
|
41645
|
+
`).run(
|
|
41646
|
+
id,
|
|
41647
|
+
input.userId,
|
|
41648
|
+
input.type,
|
|
41649
|
+
input.source,
|
|
41650
|
+
input.sourceId,
|
|
41651
|
+
input.status ?? "pending",
|
|
41652
|
+
payloadJson,
|
|
41653
|
+
now,
|
|
41654
|
+
now
|
|
41655
|
+
);
|
|
41656
|
+
const row = db3.prepare(`
|
|
41657
|
+
SELECT
|
|
41658
|
+
id,
|
|
41659
|
+
user_id as userId,
|
|
41660
|
+
type,
|
|
41661
|
+
source,
|
|
41662
|
+
source_id as sourceId,
|
|
41663
|
+
status,
|
|
41664
|
+
payload_json as payloadJson,
|
|
41665
|
+
created_at as createdAt,
|
|
41666
|
+
injected_at as injectedAt,
|
|
41667
|
+
handled_at as handledAt,
|
|
41668
|
+
updated_at as updatedAt
|
|
41669
|
+
FROM agent_events
|
|
41670
|
+
WHERE type = ? AND source = ? AND source_id = ?
|
|
41671
|
+
`).get(input.type, input.source, input.sourceId);
|
|
41672
|
+
return rowToEvent(row);
|
|
41673
|
+
};
|
|
41674
|
+
var listPendingAgentEvents = (userId, limit = 10) => {
|
|
41675
|
+
const db3 = createSqliteDB();
|
|
41676
|
+
const rows = db3.prepare(`
|
|
41677
|
+
SELECT
|
|
41678
|
+
id,
|
|
41679
|
+
user_id as userId,
|
|
41680
|
+
type,
|
|
41681
|
+
source,
|
|
41682
|
+
source_id as sourceId,
|
|
41683
|
+
status,
|
|
41684
|
+
payload_json as payloadJson,
|
|
41685
|
+
created_at as createdAt,
|
|
41686
|
+
injected_at as injectedAt,
|
|
41687
|
+
handled_at as handledAt,
|
|
41688
|
+
updated_at as updatedAt
|
|
41689
|
+
FROM agent_events
|
|
41690
|
+
WHERE user_id = ?
|
|
41691
|
+
AND status IN ('pending', 'processing')
|
|
41692
|
+
ORDER BY created_at ASC
|
|
41693
|
+
LIMIT ?
|
|
41694
|
+
`).all(userId, limit);
|
|
41695
|
+
return rows.map(rowToEvent);
|
|
41696
|
+
};
|
|
41697
|
+
var markAgentEventsInjected = (eventIds) => {
|
|
41698
|
+
if (eventIds.length === 0) return;
|
|
41699
|
+
const db3 = createSqliteDB();
|
|
41700
|
+
const now = Date.now();
|
|
41701
|
+
const stmt = db3.prepare(`
|
|
41702
|
+
UPDATE agent_events
|
|
41703
|
+
SET status = CASE WHEN status = 'pending' THEN 'processing' ELSE status END,
|
|
41704
|
+
injected_at = COALESCE(injected_at, ?),
|
|
41705
|
+
updated_at = ?
|
|
41706
|
+
WHERE id = ?
|
|
41707
|
+
AND status IN ('pending', 'processing')
|
|
41708
|
+
`);
|
|
41709
|
+
const tx = db3.transaction((ids) => {
|
|
41710
|
+
for (const id of ids) stmt.run(now, now, id);
|
|
41711
|
+
});
|
|
41712
|
+
tx(eventIds);
|
|
41713
|
+
};
|
|
41714
|
+
var markAgentEventsHandled = (eventIds, status = "handled") => {
|
|
41715
|
+
if (eventIds.length === 0) return;
|
|
41716
|
+
const db3 = createSqliteDB();
|
|
41717
|
+
const now = Date.now();
|
|
41718
|
+
const stmt = db3.prepare(`
|
|
41719
|
+
UPDATE agent_events
|
|
41720
|
+
SET status = ?,
|
|
41721
|
+
handled_at = COALESCE(handled_at, ?),
|
|
41722
|
+
updated_at = ?
|
|
41723
|
+
WHERE id = ?
|
|
41724
|
+
AND status IN ('pending', 'processing')
|
|
41725
|
+
`);
|
|
41726
|
+
const tx = db3.transaction((ids) => {
|
|
41727
|
+
for (const id of ids) stmt.run(status, now, now, id);
|
|
41728
|
+
});
|
|
41729
|
+
tx(eventIds);
|
|
41730
|
+
};
|
|
41731
|
+
var renderAgentEventReminder = (events) => {
|
|
41732
|
+
if (events.length === 0) return "";
|
|
41733
|
+
const lines = events.map((event) => {
|
|
41734
|
+
const owner = typeof event.payload.ownerMailboxId === "string" ? event.payload.ownerMailboxId : void 0;
|
|
41735
|
+
const mailboxMessageId = typeof event.payload.mailboxMessageId === "string" ? event.payload.mailboxMessageId : event.sourceId;
|
|
41736
|
+
const summary = typeof event.payload.summary === "string" ? event.payload.summary : typeof event.payload.contentPreview === "string" ? event.payload.contentPreview : "";
|
|
41737
|
+
return [
|
|
41738
|
+
`- eventId=${event.id}`,
|
|
41739
|
+
`type=${event.type}`,
|
|
41740
|
+
owner ? `owner=${owner}` : "",
|
|
41741
|
+
mailboxMessageId ? `mailboxMessageId=${mailboxMessageId}` : "",
|
|
41742
|
+
summary ? `summary=${summary}` : ""
|
|
41743
|
+
].filter(Boolean).join(" ");
|
|
41744
|
+
}).join("\n");
|
|
41745
|
+
return `<system-reminder>
|
|
41746
|
+
\u672C\u8F6E\u6709 ${events.length} \u6761\u5185\u90E8\u4E8B\u4EF6\u53EF\u7528\uFF1A
|
|
41747
|
+
${lines}
|
|
41748
|
+
|
|
41749
|
+
\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
|
|
41750
|
+
</system-reminder>`;
|
|
41751
|
+
};
|
|
41752
|
+
|
|
41753
|
+
// src/department/mailbox/events.ts
|
|
41754
|
+
var import_node_crypto3 = require("node:crypto");
|
|
41597
41755
|
var parseDetail = (detailJson) => {
|
|
41598
41756
|
if (!detailJson) return void 0;
|
|
41599
41757
|
try {
|
|
@@ -41634,7 +41792,7 @@ var mapMailboxEventRow = (row) => {
|
|
|
41634
41792
|
var recordMailboxEvent = (input) => {
|
|
41635
41793
|
const db3 = createSqliteDB();
|
|
41636
41794
|
const event = {
|
|
41637
|
-
id: (0,
|
|
41795
|
+
id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
|
|
41638
41796
|
messageId: input.messageId,
|
|
41639
41797
|
mailboxId: input.mailboxId,
|
|
41640
41798
|
actorMailboxId: input.actorMailboxId,
|
|
@@ -41979,6 +42137,24 @@ var queueMailboxInterruptIfRunning = (msg) => {
|
|
|
41979
42137
|
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
42138
|
}
|
|
41981
42139
|
};
|
|
42140
|
+
var recordMailboxReceivedAgentEvent = (msg) => {
|
|
42141
|
+
if (msg.toMailboxId === "manager") return;
|
|
42142
|
+
recordAgentEvent({
|
|
42143
|
+
userId: msg.toMailboxId,
|
|
42144
|
+
type: "mailbox.message_received",
|
|
42145
|
+
source: "mailbox",
|
|
42146
|
+
sourceId: msg.id,
|
|
42147
|
+
payload: {
|
|
42148
|
+
ownerMailboxId: msg.toMailboxId,
|
|
42149
|
+
mailboxMessageId: msg.id,
|
|
42150
|
+
fromMailboxId: msg.fromMailboxId,
|
|
42151
|
+
toMailboxId: msg.toMailboxId,
|
|
42152
|
+
threadId: msg.threadId || msg.id,
|
|
42153
|
+
contentPreview: msg.content.slice(0, 160),
|
|
42154
|
+
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`
|
|
42155
|
+
}
|
|
42156
|
+
});
|
|
42157
|
+
};
|
|
41982
42158
|
var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
|
|
41983
42159
|
const db3 = createSqliteDB();
|
|
41984
42160
|
const stmt = db3.prepare(`insert into mailbox (
|
|
@@ -41993,7 +42169,7 @@ var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
|
|
|
41993
42169
|
thread_id,
|
|
41994
42170
|
parent_message_id
|
|
41995
42171
|
) values (?,?,?,?,?,?,?,?,?,?) `);
|
|
41996
|
-
const id = (0,
|
|
42172
|
+
const id = (0, import_node_crypto4.randomUUID)().slice(0, 8);
|
|
41997
42173
|
const threadId = options?.threadId || id;
|
|
41998
42174
|
let mailboxMsg = {
|
|
41999
42175
|
id,
|
|
@@ -42031,6 +42207,7 @@ var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
|
|
|
42031
42207
|
},
|
|
42032
42208
|
createdAt: mailboxMsg.sendTime
|
|
42033
42209
|
});
|
|
42210
|
+
recordMailboxReceivedAgentEvent(mailboxMsg);
|
|
42034
42211
|
queueMailboxInterruptIfRunning(mailboxMsg);
|
|
42035
42212
|
return mailboxMsg;
|
|
42036
42213
|
};
|
|
@@ -42109,7 +42286,7 @@ var departmentCreate = {
|
|
|
42109
42286
|
return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
|
|
42110
42287
|
}
|
|
42111
42288
|
let departmentDefinition = {
|
|
42112
|
-
id: (0,
|
|
42289
|
+
id: (0, import_node_crypto5.randomUUID)().slice(0, 8),
|
|
42113
42290
|
name,
|
|
42114
42291
|
charter,
|
|
42115
42292
|
sourceGoalId,
|
|
@@ -42323,7 +42500,7 @@ var departmentList = {
|
|
|
42323
42500
|
};
|
|
42324
42501
|
|
|
42325
42502
|
// src/tools/tools/department/DepartmentMemberCreate.ts
|
|
42326
|
-
var
|
|
42503
|
+
var import_node_crypto6 = require("node:crypto");
|
|
42327
42504
|
var DESCRIPTION24 = `
|
|
42328
42505
|
\u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
|
|
42329
42506
|
|
|
@@ -42389,7 +42566,7 @@ var departmentMemberCreate = {
|
|
|
42389
42566
|
}
|
|
42390
42567
|
}
|
|
42391
42568
|
let departmentMember = {
|
|
42392
|
-
id: (0,
|
|
42569
|
+
id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
|
|
42393
42570
|
name,
|
|
42394
42571
|
departmentId: department.id,
|
|
42395
42572
|
mailBoxId: getMailBoxId(department.name, name),
|
|
@@ -42580,7 +42757,7 @@ ${replies}`;
|
|
|
42580
42757
|
// src/department/learning.ts
|
|
42581
42758
|
var import_node_fs4 = require("node:fs");
|
|
42582
42759
|
var import_node_path12 = __toESM(require("node:path"));
|
|
42583
|
-
var
|
|
42760
|
+
var import_node_crypto7 = require("node:crypto");
|
|
42584
42761
|
|
|
42585
42762
|
// src/skill/SkillValidator.ts
|
|
42586
42763
|
var import_node_fs3 = require("node:fs");
|
|
@@ -42818,7 +42995,7 @@ var listDepartmentMemories = (departmentName) => {
|
|
|
42818
42995
|
var createDepartmentMemory = (departmentName, input) => {
|
|
42819
42996
|
const now = Date.now();
|
|
42820
42997
|
const memory = {
|
|
42821
|
-
id: (0,
|
|
42998
|
+
id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
|
|
42822
42999
|
departmentName,
|
|
42823
43000
|
title: input.title,
|
|
42824
43001
|
content: input.content,
|
|
@@ -42869,7 +43046,7 @@ ${formatSkillValidationIssues(validation)}`);
|
|
|
42869
43046
|
}
|
|
42870
43047
|
const now = Date.now();
|
|
42871
43048
|
const skill = {
|
|
42872
|
-
id: (0,
|
|
43049
|
+
id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
|
|
42873
43050
|
departmentName,
|
|
42874
43051
|
skillName: input.skillName,
|
|
42875
43052
|
description: input.description,
|
|
@@ -42921,7 +43098,7 @@ var createDepartmentProposal = (input) => {
|
|
|
42921
43098
|
const records = readJsonArray(proposalsPath());
|
|
42922
43099
|
const proposal = {
|
|
42923
43100
|
...input,
|
|
42924
|
-
id: (0,
|
|
43101
|
+
id: (0, import_node_crypto7.randomUUID)().slice(0, 8),
|
|
42925
43102
|
status: "pending",
|
|
42926
43103
|
createdAt: Date.now()
|
|
42927
43104
|
};
|
|
@@ -43252,7 +43429,7 @@ var mailboxFollowup = {
|
|
|
43252
43429
|
|
|
43253
43430
|
// src/tools/tools/Bash.ts
|
|
43254
43431
|
var import_node_child_process = require("node:child_process");
|
|
43255
|
-
var
|
|
43432
|
+
var import_node_crypto8 = require("node:crypto");
|
|
43256
43433
|
var import_node_fs5 = require("node:fs");
|
|
43257
43434
|
var DESCRIPTION29 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
|
|
43258
43435
|
|
|
@@ -43456,7 +43633,7 @@ var bashTool = {
|
|
|
43456
43633
|
...options,
|
|
43457
43634
|
stdio: ["pipe", "pipe", "pipe"]
|
|
43458
43635
|
});
|
|
43459
|
-
const id = (0,
|
|
43636
|
+
const id = (0, import_node_crypto8.randomUUID)().slice(0, 8);
|
|
43460
43637
|
const session = {
|
|
43461
43638
|
id,
|
|
43462
43639
|
command,
|
|
@@ -44037,7 +44214,7 @@ var readDreamHistoryLimit = () => {
|
|
|
44037
44214
|
var import_node_fs6 = require("node:fs");
|
|
44038
44215
|
var import_node_os2 = require("node:os");
|
|
44039
44216
|
var import_node_path13 = require("node:path");
|
|
44040
|
-
var
|
|
44217
|
+
var import_node_crypto9 = require("node:crypto");
|
|
44041
44218
|
var SkillForgeEngine = class {
|
|
44042
44219
|
proposalStorage;
|
|
44043
44220
|
draftRoot;
|
|
@@ -44071,7 +44248,7 @@ ${formatSkillValidationIssues(validation)}`);
|
|
|
44071
44248
|
if (pending.some((p) => p.skillName === skillName)) {
|
|
44072
44249
|
return null;
|
|
44073
44250
|
}
|
|
44074
|
-
const id = (0,
|
|
44251
|
+
const id = (0, import_node_crypto9.randomBytes)(4).toString("hex");
|
|
44075
44252
|
const draftDir = (0, import_node_path13.join)(this.draftRoot, userId, id);
|
|
44076
44253
|
(0, import_node_fs6.mkdirSync)(draftDir, { recursive: true });
|
|
44077
44254
|
(0, import_node_fs6.writeFileSync)((0, import_node_path13.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
|
|
@@ -44353,7 +44530,7 @@ var skillForgeDrop = (engine) => ({
|
|
|
44353
44530
|
});
|
|
44354
44531
|
|
|
44355
44532
|
// src/memory/MemoryEngine.ts
|
|
44356
|
-
var
|
|
44533
|
+
var import_node_crypto10 = require("node:crypto");
|
|
44357
44534
|
var MemoryEngine = class {
|
|
44358
44535
|
storage;
|
|
44359
44536
|
recallIndexStorage;
|
|
@@ -44381,7 +44558,7 @@ var MemoryEngine = class {
|
|
|
44381
44558
|
}
|
|
44382
44559
|
const now = Date.now();
|
|
44383
44560
|
const memory = {
|
|
44384
|
-
id: (0,
|
|
44561
|
+
id: (0, import_node_crypto10.randomBytes)(4).toString("hex"),
|
|
44385
44562
|
userId,
|
|
44386
44563
|
title,
|
|
44387
44564
|
content,
|
|
@@ -45033,146 +45210,6 @@ var microCompactMessages = (messages, config2) => {
|
|
|
45033
45210
|
};
|
|
45034
45211
|
};
|
|
45035
45212
|
|
|
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
45213
|
// src/agent/createAgent.ts
|
|
45177
45214
|
var DEFAULT_WORKSPACE_PATH = getDuclawWorkspaceDir();
|
|
45178
45215
|
var assistantMessageFromResponse = (response) => ({
|
|
@@ -45182,6 +45219,10 @@ var assistantMessageFromResponse = (response) => ({
|
|
|
45182
45219
|
...response.providerResponseId ? { providerResponseId: response.providerResponseId } : {},
|
|
45183
45220
|
...response.model ? { model: response.model } : {}
|
|
45184
45221
|
});
|
|
45222
|
+
var isAbortError2 = (error) => {
|
|
45223
|
+
if (!(error instanceof Error)) return false;
|
|
45224
|
+
return error.name === "AbortError" || error.message.includes("aborted") || error.message.includes("AbortError");
|
|
45225
|
+
};
|
|
45185
45226
|
var llmRequestIdForTurn = (request, messages, system, tools) => {
|
|
45186
45227
|
const hash = (0, import_node_crypto11.createHash)("sha256").update(request.requestId).update("\0").update(system).update("\0").update(JSON.stringify(messages)).update("\0").update(JSON.stringify(tools.map((tool) => tool.name).sort())).digest("hex").slice(0, 40);
|
|
45187
45228
|
return `dreq_${hash}`;
|
|
@@ -45454,6 +45495,32 @@ var createAgent = (config2 = getDefaultAgentConfig()) => {
|
|
|
45454
45495
|
const { userId, content, job } = request;
|
|
45455
45496
|
const internalOnly = request.metadata?.internalOnly === true;
|
|
45456
45497
|
const injectedEventIds = /* @__PURE__ */ new Set();
|
|
45498
|
+
const interruptQueuedEventIds = /* @__PURE__ */ new Set();
|
|
45499
|
+
let durableEventPoller;
|
|
45500
|
+
let activeTurnAbortController;
|
|
45501
|
+
let unregisterInterruptListener;
|
|
45502
|
+
const markInterruptEventIdsInjected = (metadata) => {
|
|
45503
|
+
const ids = Array.isArray(metadata?.agentEventIds) ? metadata.agentEventIds.filter((id) => typeof id === "string") : [];
|
|
45504
|
+
if (ids.length === 0) return;
|
|
45505
|
+
for (const id of ids) injectedEventIds.add(id);
|
|
45506
|
+
markAgentEventsInjected(ids);
|
|
45507
|
+
};
|
|
45508
|
+
const queuePendingDurableEvents = () => {
|
|
45509
|
+
try {
|
|
45510
|
+
const events = listPendingAgentEvents(userId, 10).filter((event) => !injectedEventIds.has(event.id)).filter((event) => !interruptQueuedEventIds.has(event.id));
|
|
45511
|
+
if (events.length === 0) return;
|
|
45512
|
+
for (const event of events) interruptQueuedEventIds.add(event.id);
|
|
45513
|
+
queueInterrupt(userId, {
|
|
45514
|
+
content: renderAgentEventReminder(events),
|
|
45515
|
+
metadata: {
|
|
45516
|
+
trigger: "agent_events.pending",
|
|
45517
|
+
agentEventIds: events.map((event) => event.id)
|
|
45518
|
+
}
|
|
45519
|
+
});
|
|
45520
|
+
} catch (err) {
|
|
45521
|
+
console.warn(`[agent_events] durable event poll failed: ${err.message}`);
|
|
45522
|
+
}
|
|
45523
|
+
};
|
|
45457
45524
|
const prev = signals.get(userId);
|
|
45458
45525
|
if (prev) {
|
|
45459
45526
|
prev.abort();
|
|
@@ -45466,6 +45533,10 @@ var createAgent = (config2 = getDefaultAgentConfig()) => {
|
|
|
45466
45533
|
};
|
|
45467
45534
|
signals.set(userId, signal);
|
|
45468
45535
|
markRunning(userId);
|
|
45536
|
+
unregisterInterruptListener = registerInterruptListener(userId, () => {
|
|
45537
|
+
activeTurnAbortController?.abort();
|
|
45538
|
+
});
|
|
45539
|
+
durableEventPoller = setInterval(queuePendingDurableEvents, 1e3);
|
|
45469
45540
|
try {
|
|
45470
45541
|
if (dreamEngine) {
|
|
45471
45542
|
try {
|
|
@@ -45596,6 +45667,7 @@ ${notifText}
|
|
|
45596
45667
|
const interrupts = drainInterrupts(userId);
|
|
45597
45668
|
if (interrupts.length > 0) {
|
|
45598
45669
|
for (const interrupt of interrupts) {
|
|
45670
|
+
markInterruptEventIdsInjected(interrupt.metadata);
|
|
45599
45671
|
const msg = interrupt.content;
|
|
45600
45672
|
console.log(`[agent] \u6536\u5230\u4E2D\u65AD\u6D88\u606F\uFF0C\u6CE8\u5165\u5BF9\u8BDD: ${msg.slice(0, 80)}...`);
|
|
45601
45673
|
if (interrupt.metadata) {
|
|
@@ -45690,19 +45762,32 @@ ${memoryInjection}` : "") + dreamInjection;
|
|
|
45690
45762
|
}
|
|
45691
45763
|
}
|
|
45692
45764
|
let response;
|
|
45765
|
+
const turnAbortController = new AbortController();
|
|
45766
|
+
activeTurnAbortController = turnAbortController;
|
|
45693
45767
|
try {
|
|
45694
45768
|
response = await llm.chat(
|
|
45695
45769
|
messages,
|
|
45696
45770
|
effectiveSystemPrompt,
|
|
45697
45771
|
tools,
|
|
45698
|
-
{
|
|
45772
|
+
{
|
|
45773
|
+
requestId: llmRequestIdForTurn(request, messages, effectiveSystemPrompt, tools),
|
|
45774
|
+
signal: turnAbortController.signal
|
|
45775
|
+
}
|
|
45699
45776
|
);
|
|
45700
45777
|
} catch (error) {
|
|
45778
|
+
if (isAbortError2(error)) {
|
|
45779
|
+
console.log(`[agent] \u5F53\u524D LLM \u8C03\u7528\u88AB\u4E2D\u65AD\uFF0C\u51C6\u5907\u6CE8\u5165 interrupt \u540E\u91CD\u65B0\u51B3\u7B56 userId=${userId}`);
|
|
45780
|
+
continue;
|
|
45781
|
+
}
|
|
45701
45782
|
if (compactConfig.enabled && isPromptTooLongError(error) && contextRecoveryAttempts < compactConfig.maxFailures) {
|
|
45702
45783
|
await recoverFromContextOverflow("prompt_too_long", messages, effectiveSystemPrompt);
|
|
45703
45784
|
continue;
|
|
45704
45785
|
}
|
|
45705
45786
|
throw error;
|
|
45787
|
+
} finally {
|
|
45788
|
+
if (activeTurnAbortController === turnAbortController) {
|
|
45789
|
+
activeTurnAbortController = void 0;
|
|
45790
|
+
}
|
|
45706
45791
|
}
|
|
45707
45792
|
if (response.stopReason === "model_context_window_exceeded") {
|
|
45708
45793
|
await recoverFromContextOverflow("model_context_window_exceeded", messages, effectiveSystemPrompt);
|
|
@@ -45796,6 +45881,7 @@ ${memoryInjection}` : "") + dreamInjection;
|
|
|
45796
45881
|
if (lateInterrupts.length > 0) {
|
|
45797
45882
|
console.log(`[agent] \u9000\u51FA\u524D\u53D1\u73B0 ${lateInterrupts.length} \u6761\u8FDF\u5230\u7684\u4E2D\u65AD\u6D88\u606F\uFF0C\u7EE7\u7EED\u5904\u7406`);
|
|
45798
45883
|
for (const interrupt of lateInterrupts) {
|
|
45884
|
+
markInterruptEventIdsInjected(interrupt.metadata);
|
|
45799
45885
|
const msg = interrupt.content;
|
|
45800
45886
|
if (interrupt.metadata) {
|
|
45801
45887
|
request.metadata = {
|
|
@@ -45828,6 +45914,7 @@ ${msg}</user-interrupt>`
|
|
|
45828
45914
|
if (lateInterrupts.length > 0) {
|
|
45829
45915
|
console.log(`[agent] \u9000\u51FA\u524D\u53D1\u73B0 ${lateInterrupts.length} \u6761\u8FDF\u5230\u7684\u4E2D\u65AD\u6D88\u606F\uFF0C\u7EE7\u7EED\u5904\u7406`);
|
|
45830
45916
|
for (const interrupt of lateInterrupts) {
|
|
45917
|
+
markInterruptEventIdsInjected(interrupt.metadata);
|
|
45831
45918
|
const msg = interrupt.content;
|
|
45832
45919
|
if (interrupt.metadata) {
|
|
45833
45920
|
request.metadata = {
|
|
@@ -45872,6 +45959,9 @@ ${msg}</user-interrupt>`
|
|
|
45872
45959
|
}
|
|
45873
45960
|
throw new Error(`\u8FBE\u5230\u6700\u5927\u8FED\u4EE3\u6B21\u6570:${maxIterations}`);
|
|
45874
45961
|
} finally {
|
|
45962
|
+
if (durableEventPoller) clearInterval(durableEventPoller);
|
|
45963
|
+
unregisterInterruptListener?.();
|
|
45964
|
+
activeTurnAbortController?.abort();
|
|
45875
45965
|
markDone(userId);
|
|
45876
45966
|
signals.delete(userId);
|
|
45877
45967
|
}
|
|
@@ -46719,6 +46809,8 @@ var finalizeDepartmentAgentUnrepliedMessages = (mailboxId, msgIds, result) => {
|
|
|
46719
46809
|
}
|
|
46720
46810
|
};
|
|
46721
46811
|
var polling = false;
|
|
46812
|
+
var inFlightDepartmentMailboxes = /* @__PURE__ */ new Set();
|
|
46813
|
+
var inFlightCeoReplyMessages = /* @__PURE__ */ new Set();
|
|
46722
46814
|
var pollMailbox = async () => {
|
|
46723
46815
|
if (polling) return;
|
|
46724
46816
|
polling = true;
|
|
@@ -46735,21 +46827,30 @@ var pollMailbox = async () => {
|
|
|
46735
46827
|
const ceoMsgs = grouped.get("manager") || [];
|
|
46736
46828
|
grouped.delete("manager");
|
|
46737
46829
|
for (const msg of ceoMsgs) {
|
|
46830
|
+
if (inFlightCeoReplyMessages.has(msg.id)) continue;
|
|
46831
|
+
inFlightCeoReplyMessages.add(msg.id);
|
|
46738
46832
|
console.log(`[mailbox] \u6536\u5230 department agent \u56DE\u4FE1\uFF08\u6765\u81EA ${msg.fromMailboxId}\uFF09\uFF0C\u6B63\u5728\u5524\u9192\u4E3B agent...`);
|
|
46739
|
-
|
|
46740
|
-
|
|
46741
|
-
|
|
46742
|
-
|
|
46743
|
-
|
|
46744
|
-
|
|
46745
|
-
|
|
46746
|
-
|
|
46833
|
+
void (async () => {
|
|
46834
|
+
try {
|
|
46835
|
+
markMailboxStatus(msg.id, "processing");
|
|
46836
|
+
await handleCeoReply(msg);
|
|
46837
|
+
markMailboxStatus(msg.id, "done");
|
|
46838
|
+
} catch (err) {
|
|
46839
|
+
console.error(`[mailbox] \u5524\u9192\u4E3B agent \u5904\u7406\u56DE\u4FE1\u5931\u8D25:`, err);
|
|
46840
|
+
markMailboxStatus(msg.id, "failed");
|
|
46841
|
+
} finally {
|
|
46842
|
+
inFlightCeoReplyMessages.delete(msg.id);
|
|
46843
|
+
}
|
|
46844
|
+
})();
|
|
46747
46845
|
}
|
|
46748
|
-
const
|
|
46846
|
+
for (const [mailboxId, msgs] of grouped.entries()) {
|
|
46847
|
+
if (inFlightDepartmentMailboxes.has(mailboxId)) continue;
|
|
46848
|
+
inFlightDepartmentMailboxes.add(mailboxId);
|
|
46749
46849
|
const msgIds = msgs.map((m) => m.id);
|
|
46750
|
-
|
|
46751
|
-
|
|
46752
|
-
|
|
46850
|
+
void wakeDepartmentAgent(mailboxId, msgIds).finally(() => {
|
|
46851
|
+
inFlightDepartmentMailboxes.delete(mailboxId);
|
|
46852
|
+
});
|
|
46853
|
+
}
|
|
46753
46854
|
} catch (err) {
|
|
46754
46855
|
console.error("[mailbox] \u62C9\u53D6\u5931\u8D25:", err);
|
|
46755
46856
|
} finally {
|
|
@@ -51831,7 +51932,7 @@ var systemRoutes = new Hono2();
|
|
|
51831
51932
|
var startTime = Date.now();
|
|
51832
51933
|
systemRoutes.get("/system/info", (c) => {
|
|
51833
51934
|
return c.json({
|
|
51834
|
-
version: true ? "1.8.
|
|
51935
|
+
version: true ? "1.8.33" : "unknown",
|
|
51835
51936
|
uptime: Math.floor((Date.now() - startTime) / 1e3),
|
|
51836
51937
|
env: process.env.NODE_ENV || "development",
|
|
51837
51938
|
nodeVersion: process.version
|