duclaw-cli 1.8.1 → 1.8.3
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 +435 -86
- package/dist/main.js +1 -1
- package/dist/web/assets/{index-irglpeKE.js → index-CJCUJ0DH.js} +1 -1
- package/dist/web/assets/index-tSI9zUzw.css +1 -0
- package/dist/web/index.html +2 -2
- package/dist/worker-main.js +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-DAfUZGs6.css +0 -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.3" : "unknown"}`);
|
|
30246
30246
|
}
|
|
30247
30247
|
function getDuclawTemplate() {
|
|
30248
30248
|
return {
|
|
@@ -37937,20 +37937,29 @@ var getMessages = async (storage, userId, limit = 300, date, cronTitle) => {
|
|
|
37937
37937
|
const key = buildMessageKey(userId, date, cronTitle);
|
|
37938
37938
|
const data = await storage.get(key);
|
|
37939
37939
|
if (!data) return [];
|
|
37940
|
-
|
|
37941
|
-
|
|
37940
|
+
const repair = sanitizeMessagesWithReport(data, {
|
|
37941
|
+
mergeAdjacentNonProtocolMessages: false
|
|
37942
|
+
});
|
|
37943
|
+
const repairedData = repair.messages;
|
|
37944
|
+
if (repair.report.changed) {
|
|
37945
|
+
await storage.set(key, repairedData);
|
|
37946
|
+
logSanitizeRepair(repair.report);
|
|
37947
|
+
}
|
|
37948
|
+
if (repairedData.length === 0) return [];
|
|
37949
|
+
let start = Math.max(0, repairedData.length - limit);
|
|
37950
|
+
if (repairedData[start].role !== "user") {
|
|
37942
37951
|
let earlier = start - 1;
|
|
37943
|
-
while (earlier >= 0 &&
|
|
37952
|
+
while (earlier >= 0 && repairedData[earlier].role !== "user") earlier--;
|
|
37944
37953
|
if (earlier >= 0) {
|
|
37945
37954
|
start = earlier;
|
|
37946
37955
|
} else {
|
|
37947
37956
|
let later = start + 1;
|
|
37948
|
-
while (later <
|
|
37949
|
-
if (later >=
|
|
37957
|
+
while (later < repairedData.length && repairedData[later].role !== "user") later++;
|
|
37958
|
+
if (later >= repairedData.length) return [];
|
|
37950
37959
|
start = later;
|
|
37951
37960
|
}
|
|
37952
37961
|
}
|
|
37953
|
-
return sanitizeMessages(
|
|
37962
|
+
return sanitizeMessages(repairedData.slice(start));
|
|
37954
37963
|
};
|
|
37955
37964
|
var isInjectedMemoryContextMessage = (msg) => {
|
|
37956
37965
|
if (msg.role !== "user" || msg.content.length === 0) return false;
|
|
@@ -37961,44 +37970,113 @@ var isInjectedMemoryContextMessage = (msg) => {
|
|
|
37961
37970
|
var hasProtocolBlock = (msg) => {
|
|
37962
37971
|
return msg.content.some((block) => block.type === "tool_use" || block.type === "tool_result");
|
|
37963
37972
|
};
|
|
37964
|
-
var
|
|
37973
|
+
var createSanitizeReport = () => ({
|
|
37974
|
+
changed: false,
|
|
37975
|
+
removedToolUses: 0,
|
|
37976
|
+
removedToolResults: 0,
|
|
37977
|
+
removedEmptyMessages: 0,
|
|
37978
|
+
removedMemoryContextMessages: 0,
|
|
37979
|
+
droppedMessages: 0,
|
|
37980
|
+
shiftedLeadingMessages: 0,
|
|
37981
|
+
mergedAdjacentMessages: 0
|
|
37982
|
+
});
|
|
37983
|
+
var markSanitizeChanged = (report, index) => {
|
|
37984
|
+
report.changed = true;
|
|
37985
|
+
if (report.firstChangedIndex === void 0 || index < report.firstChangedIndex) {
|
|
37986
|
+
report.firstChangedIndex = index;
|
|
37987
|
+
}
|
|
37988
|
+
};
|
|
37989
|
+
var mergeSanitizeReport = (target, source) => {
|
|
37990
|
+
if (!source.changed) return;
|
|
37991
|
+
target.changed = true;
|
|
37992
|
+
if (source.firstChangedIndex !== void 0 && (target.firstChangedIndex === void 0 || source.firstChangedIndex < target.firstChangedIndex)) {
|
|
37993
|
+
target.firstChangedIndex = source.firstChangedIndex;
|
|
37994
|
+
}
|
|
37995
|
+
target.removedToolUses += source.removedToolUses;
|
|
37996
|
+
target.removedToolResults += source.removedToolResults;
|
|
37997
|
+
target.removedEmptyMessages += source.removedEmptyMessages;
|
|
37998
|
+
target.removedMemoryContextMessages += source.removedMemoryContextMessages;
|
|
37999
|
+
target.droppedMessages += source.droppedMessages;
|
|
38000
|
+
target.shiftedLeadingMessages += source.shiftedLeadingMessages;
|
|
38001
|
+
target.mergedAdjacentMessages += source.mergedAdjacentMessages;
|
|
38002
|
+
};
|
|
38003
|
+
var stripToolResultBlocks = (msg, report, index) => {
|
|
38004
|
+
const removed = msg.content.filter((block) => block.type === "tool_result").length;
|
|
37965
38005
|
const content = msg.content.filter((block) => block.type !== "tool_result");
|
|
38006
|
+
if (report && removed > 0 && index !== void 0) {
|
|
38007
|
+
report.removedToolResults += removed;
|
|
38008
|
+
markSanitizeChanged(report, index);
|
|
38009
|
+
}
|
|
37966
38010
|
if (content.length === 0) return null;
|
|
37967
38011
|
if (content.every((b) => b.type === "text" && !b.text?.trim())) return null;
|
|
37968
38012
|
return { ...msg, content };
|
|
37969
38013
|
};
|
|
37970
|
-
var stripToolUseBlocks = (msg) => {
|
|
38014
|
+
var stripToolUseBlocks = (msg, report, index) => {
|
|
38015
|
+
const removed = msg.content.filter((block) => block.type === "tool_use").length;
|
|
37971
38016
|
const content = msg.content.filter((block) => block.type !== "tool_use");
|
|
38017
|
+
if (report && removed > 0 && index !== void 0) {
|
|
38018
|
+
report.removedToolUses += removed;
|
|
38019
|
+
markSanitizeChanged(report, index);
|
|
38020
|
+
}
|
|
37972
38021
|
if (content.length === 0) return null;
|
|
37973
38022
|
if (content.every((b) => b.type === "text" && !b.text?.trim())) return null;
|
|
37974
38023
|
return { ...msg, content };
|
|
37975
38024
|
};
|
|
37976
|
-
var
|
|
37977
|
-
|
|
38025
|
+
var recordDroppedMessage = (report, index) => {
|
|
38026
|
+
report.droppedMessages++;
|
|
38027
|
+
markSanitizeChanged(report, index);
|
|
38028
|
+
};
|
|
38029
|
+
var logSanitizeRepair = (report) => {
|
|
38030
|
+
console.warn(
|
|
38031
|
+
`[sanitize] repaired message history removedToolUses=${report.removedToolUses} removedToolResults=${report.removedToolResults} droppedMessages=${report.droppedMessages} emptyMessages=${report.removedEmptyMessages} memoryContextMessages=${report.removedMemoryContextMessages} shiftedLeadingMessages=${report.shiftedLeadingMessages} firstIndex=${report.firstChangedIndex ?? -1}`
|
|
38032
|
+
);
|
|
38033
|
+
};
|
|
38034
|
+
var sanitizeMessagesWithReport = (messages, options = {}) => {
|
|
38035
|
+
const report = createSanitizeReport();
|
|
38036
|
+
const mergeAdjacentNonProtocolMessages2 = options.mergeAdjacentNonProtocolMessages ?? true;
|
|
38037
|
+
if (messages.length === 0) {
|
|
38038
|
+
return { messages, report };
|
|
38039
|
+
}
|
|
37978
38040
|
const result = [];
|
|
37979
38041
|
for (let i = 0; i < messages.length; i++) {
|
|
37980
38042
|
const msg = messages[i];
|
|
37981
|
-
if (isInjectedMemoryContextMessage(msg))
|
|
37982
|
-
|
|
37983
|
-
|
|
38043
|
+
if (isInjectedMemoryContextMessage(msg)) {
|
|
38044
|
+
report.removedMemoryContextMessages++;
|
|
38045
|
+
recordDroppedMessage(report, i);
|
|
38046
|
+
continue;
|
|
38047
|
+
}
|
|
38048
|
+
if (!msg.content || msg.content.length === 0) {
|
|
38049
|
+
report.removedEmptyMessages++;
|
|
38050
|
+
recordDroppedMessage(report, i);
|
|
38051
|
+
continue;
|
|
38052
|
+
}
|
|
38053
|
+
if (msg.content.every((b) => b.type === "text" && !b.text?.trim())) {
|
|
38054
|
+
report.removedEmptyMessages++;
|
|
38055
|
+
recordDroppedMessage(report, i);
|
|
38056
|
+
continue;
|
|
38057
|
+
}
|
|
37984
38058
|
let nextMsg = msg;
|
|
37985
38059
|
if (msg.role === "assistant") {
|
|
37986
38060
|
const toolUses = msg.content.filter((b) => b.type === "tool_use");
|
|
37987
38061
|
if (toolUses.length > 0) {
|
|
37988
38062
|
const next = messages[i + 1];
|
|
37989
38063
|
if (!next || next.role !== "user") {
|
|
37990
|
-
|
|
37991
|
-
|
|
37992
|
-
|
|
38064
|
+
nextMsg = stripToolUseBlocks(msg, report, i);
|
|
38065
|
+
if (!nextMsg) {
|
|
38066
|
+
recordDroppedMessage(report, i);
|
|
38067
|
+
continue;
|
|
38068
|
+
}
|
|
37993
38069
|
} else {
|
|
37994
38070
|
const resultIds = new Set(
|
|
37995
38071
|
next.content.filter((b) => b.type === "tool_result").map((b) => b.tool_use_id)
|
|
37996
38072
|
);
|
|
37997
38073
|
const allMatched = toolUses.every((tu) => resultIds.has(tu.id));
|
|
37998
38074
|
if (!allMatched) {
|
|
37999
|
-
|
|
38000
|
-
|
|
38001
|
-
|
|
38075
|
+
nextMsg = stripToolUseBlocks(msg, report, i);
|
|
38076
|
+
if (!nextMsg) {
|
|
38077
|
+
recordDroppedMessage(report, i);
|
|
38078
|
+
continue;
|
|
38079
|
+
}
|
|
38002
38080
|
}
|
|
38003
38081
|
}
|
|
38004
38082
|
}
|
|
@@ -38012,23 +38090,39 @@ var sanitizeMessages = (messages) => {
|
|
|
38012
38090
|
);
|
|
38013
38091
|
const allResultsMatched = toolResults.every((tr) => prevToolUseIds.has(tr.tool_use_id));
|
|
38014
38092
|
if (!prev2 || prev2.role !== "assistant" || prevToolUseIds.size === 0 || !allResultsMatched) {
|
|
38015
|
-
|
|
38016
|
-
|
|
38017
|
-
|
|
38093
|
+
nextMsg = stripToolResultBlocks(nextMsg, report, i);
|
|
38094
|
+
if (!nextMsg) {
|
|
38095
|
+
recordDroppedMessage(report, i);
|
|
38096
|
+
continue;
|
|
38097
|
+
}
|
|
38018
38098
|
}
|
|
38019
38099
|
}
|
|
38020
38100
|
}
|
|
38021
38101
|
const prev = result[result.length - 1];
|
|
38022
|
-
if (prev && prev.role === nextMsg.role && !hasProtocolBlock(prev) && !hasProtocolBlock(nextMsg)) {
|
|
38102
|
+
if (mergeAdjacentNonProtocolMessages2 && prev && prev.role === nextMsg.role && !hasProtocolBlock(prev) && !hasProtocolBlock(nextMsg)) {
|
|
38023
38103
|
prev.content = [...prev.content, ...nextMsg.content];
|
|
38104
|
+
report.mergedAdjacentMessages++;
|
|
38105
|
+
markSanitizeChanged(report, i);
|
|
38024
38106
|
} else {
|
|
38025
38107
|
result.push({ ...nextMsg, content: [...nextMsg.content] });
|
|
38026
38108
|
}
|
|
38027
38109
|
}
|
|
38028
38110
|
while (result.length > 0 && result[0].role !== "user") {
|
|
38029
38111
|
result.shift();
|
|
38112
|
+
report.shiftedLeadingMessages++;
|
|
38113
|
+
markSanitizeChanged(report, 0);
|
|
38030
38114
|
}
|
|
38031
|
-
|
|
38115
|
+
if (report.shiftedLeadingMessages > 0) {
|
|
38116
|
+
const revalidated = sanitizeMessagesWithReport(result, options);
|
|
38117
|
+
if (revalidated.report.changed) {
|
|
38118
|
+
mergeSanitizeReport(report, revalidated.report);
|
|
38119
|
+
return { messages: revalidated.messages, report };
|
|
38120
|
+
}
|
|
38121
|
+
}
|
|
38122
|
+
return { messages: result, report };
|
|
38123
|
+
};
|
|
38124
|
+
var sanitizeMessages = (messages) => {
|
|
38125
|
+
return sanitizeMessagesWithReport(messages).messages;
|
|
38032
38126
|
};
|
|
38033
38127
|
var addMessage = async (storage, userId, message, date, cronTitle) => {
|
|
38034
38128
|
const key = buildMessageKey(userId, date, cronTitle);
|
|
@@ -40566,6 +40660,128 @@ var isTextBlock = (block) => block.type === `text`;
|
|
|
40566
40660
|
var isToolUseBlock = (block) => block.type === "tool_use";
|
|
40567
40661
|
var extractText = (blocks) => blocks.filter(isTextBlock).map((b) => b.text).join("\n");
|
|
40568
40662
|
|
|
40663
|
+
// src/tools/tools/ImageUnderstandMetering.ts
|
|
40664
|
+
var import_node_crypto = require("node:crypto");
|
|
40665
|
+
var ImageUnderstandMeteringError = class extends Error {
|
|
40666
|
+
constructor(message, statusCode, meteringStatus) {
|
|
40667
|
+
super(message);
|
|
40668
|
+
this.statusCode = statusCode;
|
|
40669
|
+
this.meteringStatus = meteringStatus;
|
|
40670
|
+
this.name = "ImageUnderstandMeteringError";
|
|
40671
|
+
}
|
|
40672
|
+
statusCode;
|
|
40673
|
+
meteringStatus;
|
|
40674
|
+
};
|
|
40675
|
+
async function reportImageUnderstandUsage(input) {
|
|
40676
|
+
const baseUrl = input.baseUrl?.trim().replace(/\/+$/, "");
|
|
40677
|
+
const token = input.token?.trim();
|
|
40678
|
+
const tenantId = input.tenantId?.trim();
|
|
40679
|
+
if (!baseUrl || !token || !tenantId) {
|
|
40680
|
+
return { status: "disabled" };
|
|
40681
|
+
}
|
|
40682
|
+
const payload = buildImageUnderstandMeteringPayload({
|
|
40683
|
+
...input,
|
|
40684
|
+
tenantId
|
|
40685
|
+
});
|
|
40686
|
+
const response = await fetch(`${baseUrl}/internal/metering/image-understand`, {
|
|
40687
|
+
method: "POST",
|
|
40688
|
+
headers: {
|
|
40689
|
+
"content-type": "application/json",
|
|
40690
|
+
authorization: `Bearer ${token}`
|
|
40691
|
+
},
|
|
40692
|
+
body: JSON.stringify(payload)
|
|
40693
|
+
});
|
|
40694
|
+
const body = await parseResponseJson(response);
|
|
40695
|
+
const result = body && typeof body === "object" && "result" in body ? body.result : void 0;
|
|
40696
|
+
if (result?.status === "credit_exhausted") {
|
|
40697
|
+
throw new ImageUnderstandMeteringError(
|
|
40698
|
+
"[ImageUnderstand] credit_exhausted",
|
|
40699
|
+
response.status,
|
|
40700
|
+
result.status
|
|
40701
|
+
);
|
|
40702
|
+
}
|
|
40703
|
+
if (!response.ok || result?.status === "failed") {
|
|
40704
|
+
throw new ImageUnderstandMeteringError(
|
|
40705
|
+
`[ImageUnderstand] \u56FE\u7247\u7406\u89E3\u6263\u8D39\u4E0A\u62A5\u5931\u8D25: ${result?.status ?? response.status}`,
|
|
40706
|
+
response.status,
|
|
40707
|
+
result?.status
|
|
40708
|
+
);
|
|
40709
|
+
}
|
|
40710
|
+
return {
|
|
40711
|
+
status: result?.status === "skipped_existing" ? "skipped_existing" : "charged",
|
|
40712
|
+
creditAmount: result?.creditAmount ?? null
|
|
40713
|
+
};
|
|
40714
|
+
}
|
|
40715
|
+
function buildImageUnderstandMeteringPayload(input) {
|
|
40716
|
+
const metadata = input.userRequest?.metadata ?? {};
|
|
40717
|
+
const messageId = stringValue(metadata.message_id) ?? nestedMessageId(metadata) ?? stringValue(input.userRequest?.requestId);
|
|
40718
|
+
const imageKey = stringValue(metadata.imageKey) ?? stringValue(metadata.image_key) ?? firstString(metadata.imageKeys);
|
|
40719
|
+
return {
|
|
40720
|
+
tenantId: input.tenantId,
|
|
40721
|
+
provider: input.provider,
|
|
40722
|
+
model: input.model,
|
|
40723
|
+
requestId: stringValue(input.userRequest?.requestId),
|
|
40724
|
+
messageId,
|
|
40725
|
+
imageKey,
|
|
40726
|
+
imageFingerprint: fingerprintImageSource(input.imageSource),
|
|
40727
|
+
toolCallId: stringValue(metadata.toolCallId),
|
|
40728
|
+
promptChars: input.prompt.length,
|
|
40729
|
+
resultChars: input.resultText.length,
|
|
40730
|
+
platform: stringValue(input.userRequest?.platform),
|
|
40731
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40732
|
+
metadata: {
|
|
40733
|
+
imageSourceKind: imageSourceKind(input.imageSource),
|
|
40734
|
+
chatType: stringValue(input.userRequest?.chatType),
|
|
40735
|
+
authStyle: stringValue(input.authStyle)
|
|
40736
|
+
}
|
|
40737
|
+
};
|
|
40738
|
+
}
|
|
40739
|
+
function inferImageProvider(baseUrl) {
|
|
40740
|
+
if (!baseUrl) return "moonshot";
|
|
40741
|
+
try {
|
|
40742
|
+
const host = new URL(baseUrl).hostname.toLowerCase();
|
|
40743
|
+
if (host.includes("moonshot")) return "moonshot";
|
|
40744
|
+
if (host.includes("anthropic")) return "anthropic";
|
|
40745
|
+
if (host.includes("bigmodel") || host.includes("zhipu")) return "zhipu";
|
|
40746
|
+
return host.replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "custom";
|
|
40747
|
+
} catch {
|
|
40748
|
+
return "custom";
|
|
40749
|
+
}
|
|
40750
|
+
}
|
|
40751
|
+
function fingerprintImageSource(imageSource) {
|
|
40752
|
+
return (0, import_node_crypto.createHash)("sha256").update(imageSource).digest("hex");
|
|
40753
|
+
}
|
|
40754
|
+
function imageSourceKind(imageSource) {
|
|
40755
|
+
if (imageSource.startsWith("http://") || imageSource.startsWith("https://")) return "url";
|
|
40756
|
+
if (imageSource.startsWith("/") || imageSource.startsWith(".") || /^[A-Za-z]:[\\/]/.test(imageSource)) return "local_file";
|
|
40757
|
+
return "base64";
|
|
40758
|
+
}
|
|
40759
|
+
function nestedMessageId(metadata) {
|
|
40760
|
+
const message = metadata.message;
|
|
40761
|
+
if (!message || typeof message !== "object" || Array.isArray(message)) return null;
|
|
40762
|
+
return stringValue(message.message_id);
|
|
40763
|
+
}
|
|
40764
|
+
function firstString(value) {
|
|
40765
|
+
if (!Array.isArray(value)) return null;
|
|
40766
|
+
for (const item of value) {
|
|
40767
|
+
const normalized = stringValue(item);
|
|
40768
|
+
if (normalized) return normalized;
|
|
40769
|
+
}
|
|
40770
|
+
return null;
|
|
40771
|
+
}
|
|
40772
|
+
function stringValue(value) {
|
|
40773
|
+
if (typeof value !== "string") return null;
|
|
40774
|
+
const normalized = value.trim();
|
|
40775
|
+
return normalized ? normalized : null;
|
|
40776
|
+
}
|
|
40777
|
+
async function parseResponseJson(response) {
|
|
40778
|
+
try {
|
|
40779
|
+
return await response.json();
|
|
40780
|
+
} catch {
|
|
40781
|
+
return null;
|
|
40782
|
+
}
|
|
40783
|
+
}
|
|
40784
|
+
|
|
40569
40785
|
// src/tools/tools/ImageUnderstand.ts
|
|
40570
40786
|
var guessMediaTypeFromData = (base64Data) => {
|
|
40571
40787
|
if (base64Data.startsWith("/9j/")) return "image/jpeg";
|
|
@@ -40643,11 +40859,12 @@ var imageUnderstand = {
|
|
|
40643
40859
|
if (!url) throw new Error(`[ImageUnderstand] TOOL_IMAGE_ANTHROPIC_BASE_URL\u672A\u914D\u7F6E`);
|
|
40644
40860
|
if (!key) throw new Error(`[ImageUnderstand] TOOL_IMAGE_ANTHROPIC_AUTH_TOKEN\u672A\u914D\u7F6E`);
|
|
40645
40861
|
if (!model) throw new Error(`[ImageUnderstand] TOOL_IMAGE_ANTHROPIC_MODEL\u672A\u914D\u7F6E`);
|
|
40862
|
+
const authStyle = process.env.TOOL_IMAGE_ANTHROPIC_AUTH_STYLE || "bearer";
|
|
40646
40863
|
const anthropicOption = {
|
|
40647
40864
|
baseURL: url,
|
|
40648
40865
|
apiKey: key,
|
|
40649
40866
|
model,
|
|
40650
|
-
authStyle
|
|
40867
|
+
authStyle
|
|
40651
40868
|
};
|
|
40652
40869
|
const llmClient = createAnthropicAdapter(anthropicOption);
|
|
40653
40870
|
const imageBlock = await resolveImageBlock(imageSource);
|
|
@@ -40657,7 +40874,20 @@ var imageUnderstand = {
|
|
|
40657
40874
|
[imageMessage],
|
|
40658
40875
|
system
|
|
40659
40876
|
);
|
|
40660
|
-
|
|
40877
|
+
const resultText = extractText(response.content);
|
|
40878
|
+
await reportImageUnderstandUsage({
|
|
40879
|
+
baseUrl: process.env.DUCLAW_CONTROL_PLANE_BASE_URL,
|
|
40880
|
+
token: process.env.DUCLAW_CONTROL_PLANE_METERING_TOKEN,
|
|
40881
|
+
tenantId: process.env.DUCLAW_TENANT_ID,
|
|
40882
|
+
provider: inferImageProvider(url),
|
|
40883
|
+
model,
|
|
40884
|
+
prompt,
|
|
40885
|
+
resultText,
|
|
40886
|
+
imageSource,
|
|
40887
|
+
authStyle,
|
|
40888
|
+
userRequest
|
|
40889
|
+
});
|
|
40890
|
+
return resultText;
|
|
40661
40891
|
}
|
|
40662
40892
|
};
|
|
40663
40893
|
|
|
@@ -41084,10 +41314,10 @@ var goalDelete = {
|
|
|
41084
41314
|
};
|
|
41085
41315
|
|
|
41086
41316
|
// src/tools/tools/department/DepartmentCreate.ts
|
|
41087
|
-
var
|
|
41317
|
+
var import_node_crypto4 = require("node:crypto");
|
|
41088
41318
|
|
|
41089
41319
|
// src/department/mailbox/mailbox.ts
|
|
41090
|
-
var
|
|
41320
|
+
var import_node_crypto3 = require("node:crypto");
|
|
41091
41321
|
|
|
41092
41322
|
// src/db/createDB.ts
|
|
41093
41323
|
var import_better_sqlite3 = __toESM(require("better-sqlite3"));
|
|
@@ -41214,7 +41444,7 @@ var create_mailbox_events_table = () => {
|
|
|
41214
41444
|
};
|
|
41215
41445
|
|
|
41216
41446
|
// src/department/mailbox/events.ts
|
|
41217
|
-
var
|
|
41447
|
+
var import_node_crypto2 = require("node:crypto");
|
|
41218
41448
|
var parseDetail = (detailJson) => {
|
|
41219
41449
|
if (!detailJson) return void 0;
|
|
41220
41450
|
try {
|
|
@@ -41255,7 +41485,7 @@ var mapMailboxEventRow = (row) => {
|
|
|
41255
41485
|
var recordMailboxEvent = (input) => {
|
|
41256
41486
|
const db3 = createSqliteDB();
|
|
41257
41487
|
const event = {
|
|
41258
|
-
id: (0,
|
|
41488
|
+
id: (0, import_node_crypto2.randomUUID)().slice(0, 12),
|
|
41259
41489
|
messageId: input.messageId,
|
|
41260
41490
|
mailboxId: input.mailboxId,
|
|
41261
41491
|
actorMailboxId: input.actorMailboxId,
|
|
@@ -41579,7 +41809,7 @@ var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
|
|
|
41579
41809
|
thread_id,
|
|
41580
41810
|
parent_message_id
|
|
41581
41811
|
) values (?,?,?,?,?,?,?,?,?,?) `);
|
|
41582
|
-
const id = (0,
|
|
41812
|
+
const id = (0, import_node_crypto3.randomUUID)().slice(0, 8);
|
|
41583
41813
|
const threadId = options?.threadId || id;
|
|
41584
41814
|
let mailboxMsg = {
|
|
41585
41815
|
id,
|
|
@@ -41694,7 +41924,7 @@ var departmentCreate = {
|
|
|
41694
41924
|
return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
|
|
41695
41925
|
}
|
|
41696
41926
|
let departmentDefinition = {
|
|
41697
|
-
id: (0,
|
|
41927
|
+
id: (0, import_node_crypto4.randomUUID)().slice(0, 8),
|
|
41698
41928
|
name,
|
|
41699
41929
|
charter,
|
|
41700
41930
|
sourceGoalId,
|
|
@@ -41908,7 +42138,7 @@ var departmentList = {
|
|
|
41908
42138
|
};
|
|
41909
42139
|
|
|
41910
42140
|
// src/tools/tools/department/DepartmentMemberCreate.ts
|
|
41911
|
-
var
|
|
42141
|
+
var import_node_crypto5 = require("node:crypto");
|
|
41912
42142
|
var DESCRIPTION24 = `
|
|
41913
42143
|
\u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
|
|
41914
42144
|
|
|
@@ -41974,7 +42204,7 @@ var departmentMemberCreate = {
|
|
|
41974
42204
|
}
|
|
41975
42205
|
}
|
|
41976
42206
|
let departmentMember = {
|
|
41977
|
-
id: (0,
|
|
42207
|
+
id: (0, import_node_crypto5.randomUUID)().slice(0, 8),
|
|
41978
42208
|
name,
|
|
41979
42209
|
departmentId: department.id,
|
|
41980
42210
|
mailBoxId: getMailBoxId(department.name, name),
|
|
@@ -42157,7 +42387,7 @@ ${replies}`;
|
|
|
42157
42387
|
// src/department/learning.ts
|
|
42158
42388
|
var import_node_fs3 = require("node:fs");
|
|
42159
42389
|
var import_node_path11 = __toESM(require("node:path"));
|
|
42160
|
-
var
|
|
42390
|
+
var import_node_crypto6 = require("node:crypto");
|
|
42161
42391
|
var ensureDir = (dir) => (0, import_node_fs3.mkdirSync)(dir, { recursive: true });
|
|
42162
42392
|
var readJsonArray = (filePath) => {
|
|
42163
42393
|
if (!(0, import_node_fs3.existsSync)(filePath)) return [];
|
|
@@ -42193,7 +42423,7 @@ var listDepartmentMemories = (departmentName) => {
|
|
|
42193
42423
|
var createDepartmentMemory = (departmentName, input) => {
|
|
42194
42424
|
const now = Date.now();
|
|
42195
42425
|
const memory = {
|
|
42196
|
-
id: (0,
|
|
42426
|
+
id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
|
|
42197
42427
|
departmentName,
|
|
42198
42428
|
title: input.title,
|
|
42199
42429
|
content: input.content,
|
|
@@ -42235,7 +42465,7 @@ var proposeDepartmentSkill = (departmentName, input) => {
|
|
|
42235
42465
|
}
|
|
42236
42466
|
const now = Date.now();
|
|
42237
42467
|
const skill = {
|
|
42238
|
-
id: (0,
|
|
42468
|
+
id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
|
|
42239
42469
|
departmentName,
|
|
42240
42470
|
skillName: input.skillName,
|
|
42241
42471
|
description: input.description,
|
|
@@ -42272,7 +42502,7 @@ var createDepartmentProposal = (input) => {
|
|
|
42272
42502
|
const records = readJsonArray(proposalsPath());
|
|
42273
42503
|
const proposal = {
|
|
42274
42504
|
...input,
|
|
42275
|
-
id: (0,
|
|
42505
|
+
id: (0, import_node_crypto6.randomUUID)().slice(0, 8),
|
|
42276
42506
|
status: "pending",
|
|
42277
42507
|
createdAt: Date.now()
|
|
42278
42508
|
};
|
|
@@ -43297,7 +43527,7 @@ var readDreamHistoryLimit = () => {
|
|
|
43297
43527
|
var import_node_fs5 = require("node:fs");
|
|
43298
43528
|
var import_node_os2 = require("node:os");
|
|
43299
43529
|
var import_node_path12 = require("node:path");
|
|
43300
|
-
var
|
|
43530
|
+
var import_node_crypto7 = require("node:crypto");
|
|
43301
43531
|
var SkillForgeEngine = class {
|
|
43302
43532
|
proposalStorage;
|
|
43303
43533
|
draftRoot;
|
|
@@ -43326,7 +43556,7 @@ var SkillForgeEngine = class {
|
|
|
43326
43556
|
if (pending.some((p) => p.skillName === skillName)) {
|
|
43327
43557
|
return null;
|
|
43328
43558
|
}
|
|
43329
|
-
const id = (0,
|
|
43559
|
+
const id = (0, import_node_crypto7.randomBytes)(4).toString("hex");
|
|
43330
43560
|
const draftDir = (0, import_node_path12.join)(this.draftRoot, userId, id);
|
|
43331
43561
|
(0, import_node_fs5.mkdirSync)(draftDir, { recursive: true });
|
|
43332
43562
|
(0, import_node_fs5.writeFileSync)((0, import_node_path12.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
|
|
@@ -43574,7 +43804,7 @@ var skillForgeDrop = (engine) => ({
|
|
|
43574
43804
|
});
|
|
43575
43805
|
|
|
43576
43806
|
// src/memory/MemoryEngine.ts
|
|
43577
|
-
var
|
|
43807
|
+
var import_node_crypto8 = require("node:crypto");
|
|
43578
43808
|
var MemoryEngine = class {
|
|
43579
43809
|
storage;
|
|
43580
43810
|
recallIndexStorage;
|
|
@@ -43602,7 +43832,7 @@ var MemoryEngine = class {
|
|
|
43602
43832
|
}
|
|
43603
43833
|
const now = Date.now();
|
|
43604
43834
|
const memory = {
|
|
43605
|
-
id: (0,
|
|
43835
|
+
id: (0, import_node_crypto8.randomBytes)(4).toString("hex"),
|
|
43606
43836
|
userId,
|
|
43607
43837
|
title,
|
|
43608
43838
|
content,
|
|
@@ -44794,7 +45024,14 @@ ${memoryInjection}` : "") + dreamInjection;
|
|
|
44794
45024
|
}
|
|
44795
45025
|
}
|
|
44796
45026
|
}
|
|
44797
|
-
const
|
|
45027
|
+
const toolRequest = {
|
|
45028
|
+
...request,
|
|
45029
|
+
metadata: {
|
|
45030
|
+
...request.metadata ?? {},
|
|
45031
|
+
toolCallId: useBlock.id
|
|
45032
|
+
}
|
|
45033
|
+
};
|
|
45034
|
+
const result = await toolExecutor.execute(useBlock.name, useBlock.input, toolRequest);
|
|
44798
45035
|
return toolResult(useBlock.id, result);
|
|
44799
45036
|
} catch (error) {
|
|
44800
45037
|
const err = error;
|
|
@@ -45075,10 +45312,24 @@ var executeJob = async (job) => {
|
|
|
45075
45312
|
const resultFilePath = saveResultToFile(job, result);
|
|
45076
45313
|
console.log(`[cron\u6267\u884C\u5B8C\u6210] \u5B9A\u65F6\u4EFB\u52A1\u6267\u884C\u7ED3\u679C: ${resultFilePath}`);
|
|
45077
45314
|
updateJobLastRunTime(job.id);
|
|
45315
|
+
return { ok: true, resultFilePath };
|
|
45078
45316
|
} catch (error) {
|
|
45079
|
-
|
|
45317
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
45318
|
+
console.error(`[cron] \u4EFB\u52A1\u6267\u884C\u5931\u8D25: ${job.id} - ${message}`);
|
|
45319
|
+
return { ok: false, error: message };
|
|
45080
45320
|
}
|
|
45081
45321
|
};
|
|
45322
|
+
var runJobById = async (jobId) => {
|
|
45323
|
+
const job = listJobs().find((item) => item.id === jobId);
|
|
45324
|
+
if (!job) {
|
|
45325
|
+
return { ok: false, error: "job_not_found" };
|
|
45326
|
+
}
|
|
45327
|
+
if (!job.enabled) {
|
|
45328
|
+
return { ok: false, error: "job_disabled", job };
|
|
45329
|
+
}
|
|
45330
|
+
const result = await executeJob(job);
|
|
45331
|
+
return { ...result, job };
|
|
45332
|
+
};
|
|
45082
45333
|
var executeAgentJob = async (job) => {
|
|
45083
45334
|
const { registry: registry2, executor } = getCronTools();
|
|
45084
45335
|
const tools = getAllTools(registry2);
|
|
@@ -49761,6 +50012,23 @@ cronRoutes.get("/cron/jobs/:id/history", (c) => {
|
|
|
49761
50012
|
return c.json({ error: err.message || "Failed to get job history" }, 500);
|
|
49762
50013
|
}
|
|
49763
50014
|
});
|
|
50015
|
+
cronRoutes.post("/cron/jobs/:id/run", async (c) => {
|
|
50016
|
+
const id = c.req.param("id");
|
|
50017
|
+
try {
|
|
50018
|
+
const result = await runJobById(id);
|
|
50019
|
+
if (!result.ok) {
|
|
50020
|
+
const status = result.error === "job_not_found" ? 404 : 400;
|
|
50021
|
+
return c.json({ error: result.error || "Failed to run job" }, status);
|
|
50022
|
+
}
|
|
50023
|
+
return c.json({
|
|
50024
|
+
ok: true,
|
|
50025
|
+
jobId: result.job?.id ?? id,
|
|
50026
|
+
resultFilePath: result.resultFilePath
|
|
50027
|
+
});
|
|
50028
|
+
} catch (err) {
|
|
50029
|
+
return c.json({ error: err.message || "Failed to run job" }, 500);
|
|
50030
|
+
}
|
|
50031
|
+
});
|
|
49764
50032
|
|
|
49765
50033
|
// src/server/routes/mailbox.ts
|
|
49766
50034
|
var mailboxRoutes = new Hono2();
|
|
@@ -50039,7 +50307,16 @@ var extractMemoryUserIdsFromKeys = (keys) => {
|
|
|
50039
50307
|
};
|
|
50040
50308
|
var collectCompactSummaries = async (userId) => {
|
|
50041
50309
|
if (isFileBackedRuntime()) {
|
|
50042
|
-
|
|
50310
|
+
const { compactSummaryStorage: compactSummaryStorage2 } = getSharedDeps();
|
|
50311
|
+
const records2 = [];
|
|
50312
|
+
const prefix2 = `agent:compact:summary:${userId}:`;
|
|
50313
|
+
for (const key of extractFileBackedStorageKeysForTest(getDuclawDataDir())) {
|
|
50314
|
+
if (!key.startsWith(prefix2)) continue;
|
|
50315
|
+
const logicalKey = key.startsWith("agent:") ? key.slice("agent:".length) : key;
|
|
50316
|
+
const value = await compactSummaryStorage2.get(logicalKey);
|
|
50317
|
+
if (value?.length) records2.push(...value);
|
|
50318
|
+
}
|
|
50319
|
+
return records2.sort((a, b) => b.createdAt - a.createdAt);
|
|
50043
50320
|
}
|
|
50044
50321
|
const client2 = await getRedisClient();
|
|
50045
50322
|
const { compactSummaryStorage } = getSharedDeps();
|
|
@@ -50054,6 +50331,61 @@ var collectCompactSummaries = async (userId) => {
|
|
|
50054
50331
|
}
|
|
50055
50332
|
return records.sort((a, b) => b.createdAt - a.createdAt);
|
|
50056
50333
|
};
|
|
50334
|
+
var isMailboxScopedUserId = (userId) => userId === "manager" || userId.includes("::") || userId.startsWith("cron-") || userId.startsWith("kanban:goal:");
|
|
50335
|
+
var collectManagerRelatedUserIds = (userId) => {
|
|
50336
|
+
if (isMailboxScopedUserId(userId)) return [userId];
|
|
50337
|
+
try {
|
|
50338
|
+
const db3 = createSqliteDB();
|
|
50339
|
+
const rows = db3.prepare(
|
|
50340
|
+
`SELECT DISTINCT to_mailbox_id AS toMailboxId, from_mailbox_id AS fromMailboxId
|
|
50341
|
+
FROM mailbox
|
|
50342
|
+
WHERE origin_user_id = ?
|
|
50343
|
+
ORDER BY to_mailbox_id ASC, from_mailbox_id ASC`
|
|
50344
|
+
).all(userId);
|
|
50345
|
+
const ids = /* @__PURE__ */ new Set([userId]);
|
|
50346
|
+
for (const row of rows) {
|
|
50347
|
+
addPlausibleUserId(ids, row.toMailboxId || void 0);
|
|
50348
|
+
addPlausibleUserId(ids, row.fromMailboxId || void 0);
|
|
50349
|
+
}
|
|
50350
|
+
ids.delete("manager");
|
|
50351
|
+
return Array.from(ids);
|
|
50352
|
+
} catch (err) {
|
|
50353
|
+
console.warn(`[memoryRoutes] \u83B7\u53D6 Main Manager \u5173\u8054\u4E0A\u4E0B\u6587\u5931\u8D25 userId=${userId}: ${err.message}`);
|
|
50354
|
+
return [userId];
|
|
50355
|
+
}
|
|
50356
|
+
};
|
|
50357
|
+
var collectMemoryScopeUserIds = (userId) => collectManagerRelatedUserIds(userId);
|
|
50358
|
+
var aggregateMemorySummaries = async (userId, localConversationUserIds) => {
|
|
50359
|
+
const { memoryEngine, dreamStorage, dreamStateStorage, topicStorage } = getSharedDeps();
|
|
50360
|
+
const relatedUserIds = collectMemoryScopeUserIds(userId);
|
|
50361
|
+
const details = await Promise.all(relatedUserIds.map(async (scopeUserId) => {
|
|
50362
|
+
const [memories, dreamContent, dreamState, topics] = await Promise.all([
|
|
50363
|
+
memoryEngine.list(scopeUserId),
|
|
50364
|
+
dreamStorage.get(`dream:latest:${scopeUserId}`),
|
|
50365
|
+
dreamStateStorage.get(`dream:state:${scopeUserId}`),
|
|
50366
|
+
topicStorage.get(`topics:${scopeUserId}`)
|
|
50367
|
+
]);
|
|
50368
|
+
return {
|
|
50369
|
+
userId: scopeUserId,
|
|
50370
|
+
memoryCount: memories.length,
|
|
50371
|
+
hasDream: !!dreamContent,
|
|
50372
|
+
hasConversation: (topics?.length ?? 0) > 0 || localConversationUserIds.has(scopeUserId),
|
|
50373
|
+
lastDreamAt: dreamState?.lastDreamAt ?? null,
|
|
50374
|
+
lastActivityAt: dreamState?.lastActivityAt ?? null
|
|
50375
|
+
};
|
|
50376
|
+
}));
|
|
50377
|
+
const memoryCount = details.reduce((sum, detail) => sum + detail.memoryCount, 0);
|
|
50378
|
+
return {
|
|
50379
|
+
userId,
|
|
50380
|
+
memoryCount,
|
|
50381
|
+
hasMemory: memoryCount > 0,
|
|
50382
|
+
hasDream: details.some((detail) => detail.hasDream),
|
|
50383
|
+
hasConversation: details.some((detail) => detail.hasConversation),
|
|
50384
|
+
lastDreamAt: Math.max(0, ...details.map((detail) => detail.lastDreamAt ?? 0)) || null,
|
|
50385
|
+
lastActivityAt: Math.max(0, ...details.map((detail) => detail.lastActivityAt ?? 0)) || null,
|
|
50386
|
+
relatedUserIds: relatedUserIds.length > 1 ? relatedUserIds : void 0
|
|
50387
|
+
};
|
|
50388
|
+
};
|
|
50057
50389
|
var collectUserIds = async () => {
|
|
50058
50390
|
const userIds = /* @__PURE__ */ new Set();
|
|
50059
50391
|
const localConversationUserIds = collectLocalConversationUserIds();
|
|
@@ -50075,26 +50407,10 @@ var collectUserIds = async () => {
|
|
|
50075
50407
|
var memoryRoutes = new Hono2();
|
|
50076
50408
|
memoryRoutes.get("/memory/users", async (c) => {
|
|
50077
50409
|
try {
|
|
50078
|
-
const { memoryEngine, dreamStorage, dreamStateStorage, topicStorage } = getSharedDeps();
|
|
50079
50410
|
const { userIds, localConversationUserIds } = await collectUserIds();
|
|
50080
|
-
const summaries = await Promise.all(userIds.map(
|
|
50081
|
-
|
|
50082
|
-
|
|
50083
|
-
dreamStorage.get(`dream:latest:${userId}`),
|
|
50084
|
-
dreamStateStorage.get(`dream:state:${userId}`),
|
|
50085
|
-
topicStorage.get(`topics:${userId}`)
|
|
50086
|
-
]);
|
|
50087
|
-
const summary = {
|
|
50088
|
-
userId,
|
|
50089
|
-
memoryCount: memories.length,
|
|
50090
|
-
hasMemory: memories.length > 0,
|
|
50091
|
-
hasDream: !!dreamContent,
|
|
50092
|
-
hasConversation: (topics?.length ?? 0) > 0 || localConversationUserIds.has(userId),
|
|
50093
|
-
lastDreamAt: dreamState?.lastDreamAt ?? null,
|
|
50094
|
-
lastActivityAt: dreamState?.lastActivityAt ?? null
|
|
50095
|
-
};
|
|
50096
|
-
return summary;
|
|
50097
|
-
}));
|
|
50411
|
+
const summaries = await Promise.all(userIds.map(
|
|
50412
|
+
(userId) => aggregateMemorySummaries(userId, localConversationUserIds)
|
|
50413
|
+
));
|
|
50098
50414
|
summaries.sort(
|
|
50099
50415
|
(a, b) => (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0) || a.userId.localeCompare(b.userId)
|
|
50100
50416
|
);
|
|
@@ -50108,7 +50424,9 @@ memoryRoutes.get("/memory", async (c) => {
|
|
|
50108
50424
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50109
50425
|
try {
|
|
50110
50426
|
const { memoryEngine } = getSharedDeps();
|
|
50111
|
-
const memories = await
|
|
50427
|
+
const memories = (await Promise.all(
|
|
50428
|
+
collectMemoryScopeUserIds(userId).map((scopeUserId) => memoryEngine.list(scopeUserId))
|
|
50429
|
+
)).flat();
|
|
50112
50430
|
return c.json(sortMemories(memories));
|
|
50113
50431
|
} catch (err) {
|
|
50114
50432
|
return c.json({ error: err.message || "Failed to list memories" }, 500);
|
|
@@ -50171,16 +50489,27 @@ memoryRoutes.get("/memory/dream", async (c) => {
|
|
|
50171
50489
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50172
50490
|
try {
|
|
50173
50491
|
const { dreamStorage, dreamHistoryStorage, dreamStateStorage } = getSharedDeps();
|
|
50174
|
-
const
|
|
50175
|
-
|
|
50176
|
-
|
|
50177
|
-
|
|
50178
|
-
|
|
50492
|
+
const scoped = await Promise.all(collectMemoryScopeUserIds(userId).map(async (scopeUserId) => {
|
|
50493
|
+
const [dreamContent2, dreamHistory2, state2] = await Promise.all([
|
|
50494
|
+
dreamStorage.get(`dream:latest:${scopeUserId}`),
|
|
50495
|
+
dreamHistoryStorage.get(`dream:history:${scopeUserId}`),
|
|
50496
|
+
dreamStateStorage.get(`dream:state:${scopeUserId}`)
|
|
50497
|
+
]);
|
|
50498
|
+
return { userId: scopeUserId, dreamContent: dreamContent2 || "", dreamHistory: dreamHistory2 || [], state: state2 || null };
|
|
50499
|
+
}));
|
|
50500
|
+
const dreamContent = scoped.filter((item) => item.dreamContent.trim()).map((item) => scoped.length > 1 ? `## ${item.userId}
|
|
50501
|
+
${item.dreamContent}` : item.dreamContent).join("\n\n");
|
|
50502
|
+
const dreamHistory = scoped.flatMap((item) => item.dreamHistory.map((entry) => ({
|
|
50503
|
+
...entry,
|
|
50504
|
+
content: scoped.length > 1 ? `[${item.userId}]
|
|
50505
|
+
${entry.content}` : entry.content
|
|
50506
|
+
}))).sort((a, b) => b.createdAt - a.createdAt);
|
|
50507
|
+
const state = scoped.map((item) => item.state).filter((item) => !!item).sort((a, b) => b.lastActivityAt - a.lastActivityAt)[0] ?? null;
|
|
50179
50508
|
return c.json({
|
|
50180
50509
|
userId,
|
|
50181
|
-
dreamContent
|
|
50182
|
-
dreamHistory
|
|
50183
|
-
state
|
|
50510
|
+
dreamContent,
|
|
50511
|
+
dreamHistory,
|
|
50512
|
+
state
|
|
50184
50513
|
});
|
|
50185
50514
|
} catch (err) {
|
|
50186
50515
|
return c.json({ error: err.message || "Failed to get dream summary" }, 500);
|
|
@@ -50190,7 +50519,9 @@ memoryRoutes.get("/memory/compact", async (c) => {
|
|
|
50190
50519
|
const userId = requireUserId(c.req.query("userId"));
|
|
50191
50520
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50192
50521
|
try {
|
|
50193
|
-
const summaries = await
|
|
50522
|
+
const summaries = (await Promise.all(
|
|
50523
|
+
collectMemoryScopeUserIds(userId).map((scopeUserId) => collectCompactSummaries(scopeUserId))
|
|
50524
|
+
)).flat().sort((a, b) => b.createdAt - a.createdAt);
|
|
50194
50525
|
return c.json({
|
|
50195
50526
|
userId,
|
|
50196
50527
|
summaries
|
|
@@ -50207,19 +50538,25 @@ memoryRoutes.get("/memory/recall", async (c) => {
|
|
|
50207
50538
|
const limit = Math.min(Number(c.req.query("limit")) || 20, 50);
|
|
50208
50539
|
try {
|
|
50209
50540
|
const { recallIndexStorage } = getSharedDeps();
|
|
50541
|
+
const scopeUserIds = collectMemoryScopeUserIds(userId);
|
|
50210
50542
|
if (query) {
|
|
50211
|
-
const
|
|
50543
|
+
const scopedResults = await Promise.all(scopeUserIds.map(
|
|
50544
|
+
(scopeUserId) => searchRecallIndex(recallIndexStorage, scopeUserId, query, date, limit)
|
|
50545
|
+
));
|
|
50546
|
+
const matches = scopedResults.flatMap((result) => result.matches).sort((a, b) => b.score - a.score).slice(0, limit);
|
|
50212
50547
|
return c.json({
|
|
50213
50548
|
userId,
|
|
50214
50549
|
query,
|
|
50215
|
-
total: result.total,
|
|
50216
|
-
entries:
|
|
50550
|
+
total: scopedResults.reduce((sum, result) => sum + result.total, 0),
|
|
50551
|
+
entries: matches.map((match2) => ({
|
|
50217
50552
|
...match2.entry,
|
|
50218
50553
|
score: match2.score
|
|
50219
50554
|
}))
|
|
50220
50555
|
});
|
|
50221
50556
|
}
|
|
50222
|
-
const entries = await
|
|
50557
|
+
const entries = (await Promise.all(
|
|
50558
|
+
scopeUserIds.map((scopeUserId) => recallIndexStorage.get(`recall:index:${scopeUserId}`))
|
|
50559
|
+
)).flatMap((items) => items ?? []);
|
|
50223
50560
|
const filtered = date ? entries.filter((entry) => entry.date === date) : entries;
|
|
50224
50561
|
filtered.sort((a, b) => b.createdAt - a.createdAt);
|
|
50225
50562
|
return c.json({
|
|
@@ -50237,10 +50574,18 @@ memoryRoutes.get("/memory/context", async (c) => {
|
|
|
50237
50574
|
if (!userId) return c.json({ error: "userId is required" }, 400);
|
|
50238
50575
|
try {
|
|
50239
50576
|
const { memoryEngine, dreamStorage } = getSharedDeps();
|
|
50240
|
-
const
|
|
50241
|
-
|
|
50242
|
-
|
|
50243
|
-
|
|
50577
|
+
const scoped = await Promise.all(collectMemoryScopeUserIds(userId).map(async (scopeUserId) => {
|
|
50578
|
+
const [memoryContextBlock2, dreamContent2] = await Promise.all([
|
|
50579
|
+
memoryEngine.buildContextBlock(scopeUserId),
|
|
50580
|
+
dreamStorage.get(`dream:latest:${scopeUserId}`)
|
|
50581
|
+
]);
|
|
50582
|
+
return { userId: scopeUserId, memoryContextBlock: memoryContextBlock2, dreamContent: dreamContent2 };
|
|
50583
|
+
}));
|
|
50584
|
+
const memoryContextBlock = scoped.filter((item) => item.memoryContextBlock.trim()).map((item) => scoped.length > 1 ? `<main-manager-context-source userId="${item.userId}">
|
|
50585
|
+
${item.memoryContextBlock}
|
|
50586
|
+
</main-manager-context-source>` : item.memoryContextBlock).join("\n\n");
|
|
50587
|
+
const dreamContent = scoped.filter((item) => item.dreamContent?.trim()).map((item) => scoped.length > 1 ? `## ${item.userId}
|
|
50588
|
+
${item.dreamContent}` : item.dreamContent).join("\n\n");
|
|
50244
50589
|
const dreamContextBlock = dreamContent ? [
|
|
50245
50590
|
"<memory-context>",
|
|
50246
50591
|
"\u4EE5\u4E0B\u662F\u4F60\u901A\u8FC7\u505A\u68A6\u4FDD\u7559\u7684\u8DE8\u5929\u8BB0\u5FC6\u3002\u8BB0\u4F4F\u8FD9\u4E9B\u4FE1\u606F\uFF0C\u4F46\u4E0D\u8981\u4E3B\u52A8\u63D0\u53CA\u2014\u2014\u9664\u975E\u7528\u6237\u7684\u8BDD\u9898\u76F8\u5173\u3002",
|
|
@@ -50313,7 +50658,7 @@ var systemRoutes = new Hono2();
|
|
|
50313
50658
|
var startTime = Date.now();
|
|
50314
50659
|
systemRoutes.get("/system/info", (c) => {
|
|
50315
50660
|
return c.json({
|
|
50316
|
-
version: true ? "1.8.
|
|
50661
|
+
version: true ? "1.8.3" : "unknown",
|
|
50317
50662
|
uptime: Math.floor((Date.now() - startTime) / 1e3),
|
|
50318
50663
|
env: process.env.NODE_ENV || "development",
|
|
50319
50664
|
nodeVersion: process.version
|
|
@@ -50414,8 +50759,12 @@ async function main() {
|
|
|
50414
50759
|
} else {
|
|
50415
50760
|
console.log(`[main] Core Channel Gateway \u5DF2\u8DF3\u8FC7\uFF0C\u5F53\u524D\u5916\u90E8\u6D88\u606F\u5165\u53E3\u7531 SaaS \u5C42\u63A5\u7BA1`);
|
|
50416
50761
|
}
|
|
50417
|
-
|
|
50418
|
-
|
|
50762
|
+
if (process.env.DUCLAW_CRON_SCHEDULER === "saas") {
|
|
50763
|
+
console.log(`[main] \u5B9A\u65F6\u4EFB\u52A1\u8C03\u5EA6\u5668\u5DF2\u8DF3\u8FC7\uFF0C\u5F53\u524D\u7531 SaaS \u5C42\u63A5\u7BA1`);
|
|
50764
|
+
} else {
|
|
50765
|
+
startScheduler();
|
|
50766
|
+
console.log(`[main] \u5B9A\u65F6\u4EFB\u52A1\u8C03\u5EA6\u5668\u5DF2\u542F\u52A8`);
|
|
50767
|
+
}
|
|
50419
50768
|
startMailboxPoller();
|
|
50420
50769
|
console.log(`[main] \u591A\u667A\u80FD\u4F53\u90AE\u7BB1\u8F6E\u8BE2\u5DF2\u542F\u52A8`);
|
|
50421
50770
|
const kanbanPort = Number(process.env.KANBAN_PORT || 3e3);
|