duclaw-cli 1.8.38 → 1.8.40
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 +134 -15
- 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.40" : "unknown"}`);
|
|
30246
30246
|
}
|
|
30247
30247
|
function getDuclawTemplate() {
|
|
30248
30248
|
return {
|
|
@@ -42310,6 +42310,19 @@ var failCeoFollowup = (id, error) => {
|
|
|
42310
42310
|
AND status IN ('pending', 'processing', 'failed')
|
|
42311
42311
|
`).run(error.slice(0, 1e3), now, id);
|
|
42312
42312
|
};
|
|
42313
|
+
var recoverStaleProcessingCeoFollowups = (staleBefore) => {
|
|
42314
|
+
const db3 = createSqliteDB();
|
|
42315
|
+
const now = Date.now();
|
|
42316
|
+
const result = db3.prepare(`
|
|
42317
|
+
UPDATE ceo_followups
|
|
42318
|
+
SET status = 'failed',
|
|
42319
|
+
last_error = 'stale_processing_recovered',
|
|
42320
|
+
updated_at = ?
|
|
42321
|
+
WHERE status = 'processing'
|
|
42322
|
+
AND updated_at < ?
|
|
42323
|
+
`).run(now, staleBefore);
|
|
42324
|
+
return result.changes;
|
|
42325
|
+
};
|
|
42313
42326
|
var completePendingCeoFollowupsForUser = (originUserId) => {
|
|
42314
42327
|
const db3 = createSqliteDB();
|
|
42315
42328
|
const now = Date.now();
|
|
@@ -42669,6 +42682,18 @@ var departmentCreate = {
|
|
|
42669
42682
|
|
|
42670
42683
|
// src/tools/tools/department/DepartmentCommunicate.ts
|
|
42671
42684
|
var CEO_MAILBOX_ID = `manager`;
|
|
42685
|
+
var MANAGER_ALIAS_PATTERN = /(^|::)(manager|main[-_\s]?manager|ceo)$/i;
|
|
42686
|
+
var looksLikePseudoManagerMailbox = (mailboxId) => {
|
|
42687
|
+
if (mailboxId === CEO_MAILBOX_ID) return true;
|
|
42688
|
+
if (!mailboxId.includes(`::`)) return false;
|
|
42689
|
+
return MANAGER_ALIAS_PATTERN.test(mailboxId.trim());
|
|
42690
|
+
};
|
|
42691
|
+
var buildManagerRoutingRejection = (activeContext) => [
|
|
42692
|
+
`[departmentCommunicate] \u62D2\u7EDD\u53D1\u9001\u5230\u4F2A manager mailbox\u3002`,
|
|
42693
|
+
`Main Manager/CEO \u4E0D\u662F\u90E8\u95E8\u6210\u5458\uFF0C\u4E0D\u80FD\u7528 department_communicate \u53D1\u9001\u5230 manager\u3001Department::Manager\u3001CEO::Manager \u7B49\u5730\u5740\u3002`,
|
|
42694
|
+
activeContext ? `\u5982\u679C\u8981\u5411\u4E0A\u6E38 CEO \u6C47\u62A5\uFF0C\u8BF7\u8C03\u7528 reply_mailbox(message_id="${activeContext.id}", content="...") \u6B63\u5F0F\u56DE\u590D\u539F\u90AE\u4EF6\uFF1B\u82E5\u53EA\u662F\u540C\u6B65\u9636\u6BB5\u8FDB\u5C55\uFF0C\u8BF7\u8C03\u7528 mailbox_followup(message_id="${activeContext.id}", content="...", kind="progress")\u3002` : `\u5982\u679C\u8981\u5411\u4E0A\u6E38 CEO \u6C47\u62A5\uFF0C\u8BF7\u56DE\u5230\u539F manager \u90AE\u4EF6\uFF0C\u4F7F\u7528 reply_mailbox(message_id="\u539F\u90AE\u4EF6ID", content="...") \u6216 mailbox_followup(message_id="\u539F\u90AE\u4EF6ID", content="...", kind="progress")\u3002`
|
|
42695
|
+
].join(`
|
|
42696
|
+
`);
|
|
42672
42697
|
var getActiveMailboxContext = (actorMailboxId, messageId) => {
|
|
42673
42698
|
if (!messageId) return null;
|
|
42674
42699
|
const db3 = createSqliteDB();
|
|
@@ -42695,6 +42720,7 @@ var DESCRIPTION21 = `
|
|
|
42695
42720
|
- CEO \u9ED8\u8BA4\u901A\u8FC7 department_list \u53EA\u770B\u5230\u90E8\u95E8\u548C Department Head\uFF0C\u4E0D\u4E3B\u52A8\u66B4\u9732 Executor\u3002
|
|
42696
42721
|
- Department Head \u9ED8\u8BA4\u7BA1\u7406\u672C\u90E8\u95E8\u6210\u5458\u3002
|
|
42697
42722
|
- \u5982\u679C\u667A\u80FD\u4F53\u5DF2\u7ECF\u901A\u8FC7\u6B63\u5E38\u6C9F\u901A\u77E5\u9053\u4E86\u5176\u4ED6\u6210\u5458\u7684 mailbox \u5730\u5740\uFF0C\u5DE5\u5177\u4E0D\u4F1A\u786C\u6027\u963B\u6B62\u901A\u4FE1\uFF1B\u8FD9\u7C7B\u975E\u9ED8\u8BA4\u8DEF\u5F84\u4F1A\u5199\u5165\u5BA1\u8BA1\u4FE1\u606F\u3002
|
|
42723
|
+
- Main Manager/CEO \u7684 mailbox id \u56FA\u5B9A\u662F manager\u3002Department agent \u4E0D\u5E94\u4F7F\u7528 department_communicate \u7ED9 manager \u6216 Department::Manager \u53D1\u4FE1\uFF1B\u8981\u56DE\u590D\u4E0A\u6E38\u5FC5\u987B\u4F7F\u7528\u539F\u90AE\u4EF6\u7684 reply_mailbox \u6216 mailbox_followup\u3002
|
|
42698
42724
|
|
|
42699
42725
|
\u53C2\u6570\u8BF4\u660E\uFF1A
|
|
42700
42726
|
- department_name + member_name: \u9ED8\u8BA4\u5BFB\u5740\u65B9\u5F0F\u3002
|
|
@@ -42739,18 +42765,6 @@ var departmentCommunicate = {
|
|
|
42739
42765
|
const targetMailboxId = input.target_mailbox_id;
|
|
42740
42766
|
const content = input.content;
|
|
42741
42767
|
const reason = input.reason;
|
|
42742
|
-
let toMailboxId = targetMailboxId;
|
|
42743
|
-
let targetMember = targetMailboxId ? getDepartmentMemberByMailboxId(targetMailboxId) : null;
|
|
42744
|
-
if (!toMailboxId) {
|
|
42745
|
-
if (!departmentName || !memberName) {
|
|
42746
|
-
return `[departmentCommunicate] department_name/member_name \u6216 target_mailbox_id \u81F3\u5C11\u9700\u8981\u63D0\u4F9B\u4E00\u79CD`;
|
|
42747
|
-
}
|
|
42748
|
-
targetMember = getDepartmentMemberByName(departmentName, memberName);
|
|
42749
|
-
if (!targetMember) {
|
|
42750
|
-
return `[departmentCommunicate] \u4E0D\u5B58\u5728 ${departmentName} \u90E8\u95E8\u7684\u6210\u5458: ${memberName}`;
|
|
42751
|
-
}
|
|
42752
|
-
toMailboxId = getMailBoxId(departmentName, memberName);
|
|
42753
|
-
}
|
|
42754
42768
|
let fromMailboxId;
|
|
42755
42769
|
const departmentAgentId = userRequest.departmentAgentId;
|
|
42756
42770
|
const actorMember = departmentAgentId ? getDepartmentMemberByMailboxId(
|
|
@@ -42765,6 +42779,30 @@ var departmentCommunicate = {
|
|
|
42765
42779
|
} else {
|
|
42766
42780
|
fromMailboxId = CEO_MAILBOX_ID;
|
|
42767
42781
|
}
|
|
42782
|
+
const activeContext = departmentAgentId ? getActiveMailboxContext(fromMailboxId, userRequest.requestId) : null;
|
|
42783
|
+
let toMailboxId = targetMailboxId;
|
|
42784
|
+
let targetMember = targetMailboxId ? getDepartmentMemberByMailboxId(targetMailboxId) : null;
|
|
42785
|
+
if (departmentAgentId && targetMailboxId && looksLikePseudoManagerMailbox(targetMailboxId)) {
|
|
42786
|
+
return buildManagerRoutingRejection(activeContext);
|
|
42787
|
+
}
|
|
42788
|
+
if (departmentAgentId && targetMailboxId && !targetMember) {
|
|
42789
|
+
return [
|
|
42790
|
+
`[departmentCommunicate] \u62D2\u7EDD\u53D1\u9001\u5230\u4E0D\u5B58\u5728\u7684 mailbox: ${targetMailboxId}`,
|
|
42791
|
+
`Department agent \u4F7F\u7528 target_mailbox_id \u65F6\uFF0C\u76EE\u6807\u5FC5\u987B\u662F\u5DF2\u5B58\u5728\u7684\u90E8\u95E8\u6210\u5458 mailbox\u3002`,
|
|
42792
|
+
`\u5982\u679C\u4F60\u60F3\u56DE\u590D\u4E0A\u6E38 CEO/Main Manager\uFF0C\u8BF7\u4E0D\u8981\u4F2A\u9020 manager \u5730\u5740\uFF1B\u8BF7\u4F7F\u7528\u539F\u90AE\u4EF6\u7684 reply_mailbox \u6216 mailbox_followup\u3002`
|
|
42793
|
+
].join(`
|
|
42794
|
+
`);
|
|
42795
|
+
}
|
|
42796
|
+
if (!toMailboxId) {
|
|
42797
|
+
if (!departmentName || !memberName) {
|
|
42798
|
+
return `[departmentCommunicate] department_name/member_name \u6216 target_mailbox_id \u81F3\u5C11\u9700\u8981\u63D0\u4F9B\u4E00\u79CD`;
|
|
42799
|
+
}
|
|
42800
|
+
targetMember = getDepartmentMemberByName(departmentName, memberName);
|
|
42801
|
+
if (!targetMember) {
|
|
42802
|
+
return `[departmentCommunicate] \u4E0D\u5B58\u5728 ${departmentName} \u90E8\u95E8\u7684\u6210\u5458: ${memberName}`;
|
|
42803
|
+
}
|
|
42804
|
+
toMailboxId = getMailBoxId(departmentName, memberName);
|
|
42805
|
+
}
|
|
42768
42806
|
const isCrossDepartment = Boolean(actorMember && targetMember && actorMember.departmentId !== targetMember.departmentId);
|
|
42769
42807
|
const isKnownAddressPath = Boolean(targetMailboxId);
|
|
42770
42808
|
const options = {
|
|
@@ -42781,7 +42819,6 @@ var departmentCommunicate = {
|
|
|
42781
42819
|
options.originUserId = userRequest.userId;
|
|
42782
42820
|
options.originPlatform = userRequest.platform;
|
|
42783
42821
|
} else {
|
|
42784
|
-
const activeContext = getActiveMailboxContext(fromMailboxId, userRequest.requestId);
|
|
42785
42822
|
if (activeContext) {
|
|
42786
42823
|
options.originUserId = activeContext.originUserId;
|
|
42787
42824
|
options.originPlatform = activeContext.originPlatform;
|
|
@@ -47042,6 +47079,8 @@ var replyMailbox = {
|
|
|
47042
47079
|
|
|
47043
47080
|
// src/cron/mailbox.ts
|
|
47044
47081
|
var db2 = createSqliteDB();
|
|
47082
|
+
var DEFAULT_MAILBOX_PROCESSING_STALE_MS = 15 * 6e4;
|
|
47083
|
+
var PSEUDO_MANAGER_MAILBOX_PATTERN = /(^|::)(manager|main[-_\s]?manager|ceo)$/i;
|
|
47045
47084
|
var selectStmt = db2.prepare(`select
|
|
47046
47085
|
id,
|
|
47047
47086
|
to_mailbox_id as toMailboxId,
|
|
@@ -47057,6 +47096,79 @@ var selectStmt = db2.prepare(`select
|
|
|
47057
47096
|
work_item_role as workItemRole,
|
|
47058
47097
|
upstream_message_id as upstreamMessageId
|
|
47059
47098
|
from mailbox where status = ?`);
|
|
47099
|
+
var getMailboxLivenessSnapshot = () => {
|
|
47100
|
+
const mailboxRows = db2.prepare(`
|
|
47101
|
+
SELECT status, COUNT(*) as count
|
|
47102
|
+
FROM mailbox
|
|
47103
|
+
WHERE status IN ('pending', 'processing')
|
|
47104
|
+
GROUP BY status
|
|
47105
|
+
`).all();
|
|
47106
|
+
const followupRows = db2.prepare(`
|
|
47107
|
+
SELECT status, COUNT(*) as count
|
|
47108
|
+
FROM ceo_followups
|
|
47109
|
+
WHERE status IN ('pending', 'processing', 'failed')
|
|
47110
|
+
GROUP BY status
|
|
47111
|
+
`).all();
|
|
47112
|
+
const mailboxCount = (status) => mailboxRows.find((row) => row.status === status)?.count ?? 0;
|
|
47113
|
+
const followupCount = (status) => followupRows.find((row) => row.status === status)?.count ?? 0;
|
|
47114
|
+
return {
|
|
47115
|
+
pendingMailbox: mailboxCount("pending"),
|
|
47116
|
+
processingMailbox: mailboxCount("processing"),
|
|
47117
|
+
pendingCeoFollowups: followupCount("pending"),
|
|
47118
|
+
processingCeoFollowups: followupCount("processing"),
|
|
47119
|
+
failedCeoFollowups: followupCount("failed")
|
|
47120
|
+
};
|
|
47121
|
+
};
|
|
47122
|
+
var hasUnresolvedInternalWork = (snapshot) => snapshot.pendingMailbox > 0 || snapshot.processingMailbox > 0 || snapshot.pendingCeoFollowups > 0 || snapshot.processingCeoFollowups > 0 || snapshot.failedCeoFollowups > 0;
|
|
47123
|
+
var looksLikePseudoManagerMailbox2 = (mailboxId) => mailboxId !== "manager" && mailboxId.includes("::") && PSEUDO_MANAGER_MAILBOX_PATTERN.test(mailboxId.trim());
|
|
47124
|
+
var reportMailboxLiveness = async (snapshot) => {
|
|
47125
|
+
if (!hasUnresolvedInternalWork(snapshot)) return;
|
|
47126
|
+
await reportRuntimeActivity({
|
|
47127
|
+
kind: "mailbox",
|
|
47128
|
+
toolName: "mailbox_poller",
|
|
47129
|
+
status: "active",
|
|
47130
|
+
metadata: {
|
|
47131
|
+
...snapshot,
|
|
47132
|
+
inFlightDepartmentMailboxes: Array.from(inFlightDepartmentMailboxes),
|
|
47133
|
+
inFlightCeoFollowups: Array.from(inFlightCeoReplyMessages)
|
|
47134
|
+
}
|
|
47135
|
+
});
|
|
47136
|
+
};
|
|
47137
|
+
var recoverStaleProcessingMailboxMessages = () => {
|
|
47138
|
+
const staleMs = Number(process.env.MAILBOX_PROCESSING_STALE_MS ?? DEFAULT_MAILBOX_PROCESSING_STALE_MS);
|
|
47139
|
+
if (staleMs <= 0) return 0;
|
|
47140
|
+
const staleBefore = Date.now() - staleMs;
|
|
47141
|
+
const rows = db2.prepare(`
|
|
47142
|
+
SELECT
|
|
47143
|
+
id,
|
|
47144
|
+
to_mailbox_id as toMailboxId
|
|
47145
|
+
FROM mailbox
|
|
47146
|
+
WHERE status = 'processing'
|
|
47147
|
+
AND updated_at < ?
|
|
47148
|
+
`).all(staleBefore);
|
|
47149
|
+
let recovered = 0;
|
|
47150
|
+
for (const row of rows) {
|
|
47151
|
+
if (row.toMailboxId === "manager") continue;
|
|
47152
|
+
if (hasRunningAgent(row.toMailboxId) || inFlightDepartmentMailboxes.has(row.toMailboxId)) continue;
|
|
47153
|
+
if (updateMailboxMessageStatus(row.id, "pending", {
|
|
47154
|
+
fromStatus: "processing",
|
|
47155
|
+
actorMailboxId: row.toMailboxId,
|
|
47156
|
+
reason: "stale_processing_recovered"
|
|
47157
|
+
})) {
|
|
47158
|
+
recovered += 1;
|
|
47159
|
+
}
|
|
47160
|
+
}
|
|
47161
|
+
return recovered;
|
|
47162
|
+
};
|
|
47163
|
+
var recoverStaleProcessingWork = () => {
|
|
47164
|
+
const staleMs = Number(process.env.MAILBOX_PROCESSING_STALE_MS ?? DEFAULT_MAILBOX_PROCESSING_STALE_MS);
|
|
47165
|
+
if (staleMs <= 0) return;
|
|
47166
|
+
const mailboxRecovered = recoverStaleProcessingMailboxMessages();
|
|
47167
|
+
const followupsRecovered = recoverStaleProcessingCeoFollowups(Date.now() - staleMs);
|
|
47168
|
+
if (mailboxRecovered > 0 || followupsRecovered > 0) {
|
|
47169
|
+
console.warn(`[mailbox] \u5DF2\u6062\u590D stale processing: mailbox=${mailboxRecovered}, ceo_followups=${followupsRecovered}`);
|
|
47170
|
+
}
|
|
47171
|
+
};
|
|
47060
47172
|
var markMailboxStatus = (msgId, status) => {
|
|
47061
47173
|
const fromStatusMap = {
|
|
47062
47174
|
processing: ["pending"],
|
|
@@ -47163,6 +47275,11 @@ var wakeDepartmentAgent = async (mailboxId, msgIds) => {
|
|
|
47163
47275
|
const member = getDepartmentMemberByName(departmentName, memberName);
|
|
47164
47276
|
if (!member) {
|
|
47165
47277
|
console.warn(`[mailbox] \u76EE\u6807\u6210\u5458\u4E0D\u5B58\u5728\uFF08\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\uFF09: ${mailboxId}`);
|
|
47278
|
+
if (looksLikePseudoManagerMailbox2(mailboxId)) {
|
|
47279
|
+
for (const id of msgIds) markMailboxStatus(id, "cancelled");
|
|
47280
|
+
console.warn(`[mailbox] \u5DF2\u53D6\u6D88\u4F2A manager mailbox \u6295\u9012 ${mailboxId}\uFF0C\u4E0D\u518D\u751F\u6210 CEO \u7CFB\u7EDF\u566A\u58F0`);
|
|
47281
|
+
return;
|
|
47282
|
+
}
|
|
47166
47283
|
const notifyContent = `[\u7CFB\u7EDF\u901A\u77E5] \u90E8\u95E8\u6210\u5458 ${mailboxId} \u4E0D\u5B58\u5728\uFF08\u53EF\u80FD\u6240\u5C5E\u90E8\u95E8\u5DF2\u89E3\u6563\u6216\u6210\u5458\u5DF2\u88AB\u5220\u9664\uFF09\uFF0C\u4EE5\u4E0B\u6D88\u606F\u65E0\u6CD5\u6295\u9012\u5DF2\u88AB\u53D6\u6D88\u3002\u8BF7\u6839\u636E\u60C5\u51B5\u51B3\u5B9A\u662F\u5426\u9700\u8981\u91CD\u65B0\u7EC4\u5EFA\u90E8\u95E8\u6216\u8C03\u6574\u8BA1\u5212\u3002`;
|
|
47167
47284
|
const originStmt = db2.prepare(
|
|
47168
47285
|
`SELECT origin_user_id as originUserId, origin_platform as originPlatform
|
|
@@ -47303,6 +47420,8 @@ var pollMailbox = async () => {
|
|
|
47303
47420
|
if (polling) return;
|
|
47304
47421
|
polling = true;
|
|
47305
47422
|
try {
|
|
47423
|
+
recoverStaleProcessingWork();
|
|
47424
|
+
await reportMailboxLiveness(getMailboxLivenessSnapshot());
|
|
47306
47425
|
const mailBoxMsgs = selectStmt.all("pending");
|
|
47307
47426
|
const pendingFollowups = listPendingCeoFollowups();
|
|
47308
47427
|
if (mailBoxMsgs.length === 0 && pendingFollowups.length === 0) return;
|
|
@@ -52432,7 +52551,7 @@ var systemRoutes = new Hono2();
|
|
|
52432
52551
|
var startTime = Date.now();
|
|
52433
52552
|
systemRoutes.get("/system/info", (c) => {
|
|
52434
52553
|
return c.json({
|
|
52435
|
-
version: true ? "1.8.
|
|
52554
|
+
version: true ? "1.8.40" : "unknown",
|
|
52436
52555
|
uptime: Math.floor((Date.now() - startTime) / 1e3),
|
|
52437
52556
|
env: process.env.NODE_ENV || "development",
|
|
52438
52557
|
nodeVersion: process.version
|