exomind 0.15.0 → 0.16.0
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/cli.js +45 -6
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3119,7 +3119,7 @@ var {
|
|
|
3119
3119
|
// package.json
|
|
3120
3120
|
var package_default = {
|
|
3121
3121
|
name: "exomind",
|
|
3122
|
-
version: "0.
|
|
3122
|
+
version: "0.16.0",
|
|
3123
3123
|
description: "ExoMind \u8DE8\u5E73\u53F0\u547D\u4EE4\u884C\u5BA2\u6237\u7AEF \u2014 \u901A\u8FC7 REST \u4E0E ExoMind \u77E5\u8BC6\u98DE\u8F6E\u4EA4\u4E92(ingest/query/search/review),\u66FF\u4EE3 Windows \u4E0D\u53EF\u7528\u7684 MCP \u5BA2\u6237\u7AEF\u3002",
|
|
3124
3124
|
bin: {
|
|
3125
3125
|
exomind: "dist/cli.js"
|
|
@@ -3302,6 +3302,12 @@ function saveConfig(cfg) {
|
|
|
3302
3302
|
} catch {
|
|
3303
3303
|
}
|
|
3304
3304
|
}
|
|
3305
|
+
function invalidateKeywordCache() {
|
|
3306
|
+
try {
|
|
3307
|
+
fs.unlinkSync(CACHE_KEYWORDS);
|
|
3308
|
+
} catch {
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3305
3311
|
function resolveConfig(overrides) {
|
|
3306
3312
|
const base = loadConfig();
|
|
3307
3313
|
return {
|
|
@@ -3632,13 +3638,27 @@ async function getEntityDesc(client, name, deadline = Number.POSITIVE_INFINITY)
|
|
|
3632
3638
|
return { name, description: "" };
|
|
3633
3639
|
}
|
|
3634
3640
|
}
|
|
3641
|
+
var SHORT_ASCII = /^[a-z0-9._#+-]{2,4}$/;
|
|
3642
|
+
function escapeRegExp(s) {
|
|
3643
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3644
|
+
}
|
|
3645
|
+
function hitsPrompt(promptLower, candLower) {
|
|
3646
|
+
if (SHORT_ASCII.test(candLower)) {
|
|
3647
|
+
try {
|
|
3648
|
+
return new RegExp(`(?<![a-z0-9])${escapeRegExp(candLower)}(?![a-z0-9])`).test(promptLower);
|
|
3649
|
+
} catch {
|
|
3650
|
+
return promptLower.includes(candLower);
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
return promptLower.includes(candLower);
|
|
3654
|
+
}
|
|
3635
3655
|
function matchEntities(prompt2, candidates) {
|
|
3636
3656
|
const lower = prompt2.toLowerCase();
|
|
3637
3657
|
const hits = /* @__PURE__ */ new Set();
|
|
3638
3658
|
for (const name of candidates) {
|
|
3639
3659
|
const nl = name.toLowerCase().trim();
|
|
3640
3660
|
if (nl.length < 2) continue;
|
|
3641
|
-
if (lower
|
|
3661
|
+
if (hitsPrompt(lower, nl)) hits.add(name);
|
|
3642
3662
|
}
|
|
3643
3663
|
return [...hits].sort((a, b) => b.length - a.length);
|
|
3644
3664
|
}
|
|
@@ -3664,22 +3684,39 @@ ${desc}
|
|
|
3664
3684
|
}
|
|
3665
3685
|
async function buildContext(client, msg, dedup, now, deadline = Number.POSITIVE_INFINITY) {
|
|
3666
3686
|
const index = await getKeywordIndex(client, deadline);
|
|
3667
|
-
if (!index)
|
|
3687
|
+
if (!index) {
|
|
3688
|
+
return '[ExoMind] \u77E5\u8BC6\u98DE\u8F6E\u4E0A\u4E0B\u6587\u672C\u6B21\u672A\u6CE8\u5165(\u5173\u952E\u8BCD\u8868\u62C9\u53D6\u8D85\u65F6\u6216\u5931\u8D25);\u9700\u8981\u53CD\u67E5\u53EF\u8FD0\u884C `exomind search "\u5173\u952E\u8BCD"`\u3002';
|
|
3689
|
+
}
|
|
3668
3690
|
const candidates = [...index.names || [], ...index.aliases || []];
|
|
3669
3691
|
const matched = matchEntities(msg, candidates);
|
|
3670
3692
|
if (!matched.length) return "";
|
|
3671
3693
|
const picked = [];
|
|
3694
|
+
const pickedCanonical = /* @__PURE__ */ new Set();
|
|
3695
|
+
const cooled = [];
|
|
3672
3696
|
for (const name of matched) {
|
|
3673
3697
|
if (picked.length >= 3) break;
|
|
3674
3698
|
if (budgetMs(deadline) <= 200) break;
|
|
3675
3699
|
const canonical = name;
|
|
3676
|
-
if (dedup.injected[canonical] && now - dedup.injected[canonical] < COOLDOWN_MS)
|
|
3700
|
+
if (dedup.injected[canonical] && now - dedup.injected[canonical] < COOLDOWN_MS) {
|
|
3701
|
+
cooled.push(name);
|
|
3702
|
+
continue;
|
|
3703
|
+
}
|
|
3677
3704
|
const desc = await getEntityDesc(client, name, deadline);
|
|
3678
3705
|
if (desc.description || desc.relationships?.length) {
|
|
3679
|
-
picked.push(desc);
|
|
3680
3706
|
dedup.injected[canonical] = now;
|
|
3707
|
+
const norm = (desc.name || name).toLowerCase();
|
|
3708
|
+
if (pickedCanonical.has(norm)) continue;
|
|
3709
|
+
pickedCanonical.add(norm);
|
|
3710
|
+
picked.push(desc);
|
|
3681
3711
|
}
|
|
3682
3712
|
}
|
|
3713
|
+
if (!picked.length && cooled.length) {
|
|
3714
|
+
const remainMin = Math.ceil(
|
|
3715
|
+
(COOLDOWN_MS - (now - Math.max(...cooled.map((n) => dedup.injected[n] ?? 0)))) / 6e4
|
|
3716
|
+
);
|
|
3717
|
+
const sample = cooled.slice(0, 2).map((n) => `"${n}"`).join("\u3001");
|
|
3718
|
+
return `[ExoMind] ${sample} \u7B49\u5173\u952E\u8BCD\u7684\u4E0A\u4E0B\u6587\u5DF2\u6CE8\u5165\u8FC7,30 \u5206\u949F\u53BB\u91CD\u51B7\u5374\u8FD8\u5269 ${remainMin} \u5206\u949F,\u672C\u6B21\u8DF3\u8FC7;\u9700\u8981\u8BE6\u60C5\u53EF\u8FD0\u884C \`exomind entity "${cooled[0]}"\`\u3002`;
|
|
3719
|
+
}
|
|
3683
3720
|
return contextBlock(picked);
|
|
3684
3721
|
}
|
|
3685
3722
|
async function runHook(client) {
|
|
@@ -4070,7 +4107,9 @@ async function ingestWithRetry(client, payload, timeoutMs, url = "/ingest") {
|
|
|
4070
4107
|
let transientAttempts = 0;
|
|
4071
4108
|
while (true) {
|
|
4072
4109
|
try {
|
|
4073
|
-
|
|
4110
|
+
const res = await client.post(url, payload, { timeoutMs });
|
|
4111
|
+
invalidateKeywordCache();
|
|
4112
|
+
return res;
|
|
4074
4113
|
} catch (e) {
|
|
4075
4114
|
if (!(e instanceof ApiError)) throw e;
|
|
4076
4115
|
if (e.status === 429) {
|