@agent_memory/dsh 0.5.0 → 0.5.2
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/client/client.js +53 -0
- package/dist/plugin.mjs +114 -2
- package/dist/plugin.mjs.map +3 -3
- package/package.json +1 -1
package/client/client.js
CHANGED
|
@@ -588,6 +588,8 @@ function MemoryPage() {
|
|
|
588
588
|
const [tagDraft, setTagDraft] = React2.useState("");
|
|
589
589
|
const [relationTarget, setRelationTarget] = React2.useState("");
|
|
590
590
|
const [relationType, setRelationType] = React2.useState("relates_to");
|
|
591
|
+
const [updateInfo, setUpdateInfo] = React2.useState(null);
|
|
592
|
+
const [updateBusy, setUpdateBusy] = React2.useState(false);
|
|
591
593
|
React2.useEffect(() => {
|
|
592
594
|
persistTheme(theme);
|
|
593
595
|
}, [theme]);
|
|
@@ -705,6 +707,41 @@ function MemoryPage() {
|
|
|
705
707
|
fetch("/api/agent-memory/rules", { headers: { accept: "application/json" } }).then((response) => response.json()).then((data2) => setRulesText(data2.text || "")).catch(() => setNotice("读取规则失败"));
|
|
706
708
|
fetch("/api/agent-memory/soul-path", { headers: { accept: "application/json" } }).then((response) => response.json()).then((data2) => setSoulPath(data2)).catch(() => setSoulPath(null));
|
|
707
709
|
};
|
|
710
|
+
const checkUpdate = () => {
|
|
711
|
+
setUpdateBusy(true);
|
|
712
|
+
setUpdateInfo({ checking: true });
|
|
713
|
+
fetch("/api/agent-memory/update/check", { headers: { accept: "application/json" } }).then(async (response) => {
|
|
714
|
+
const text = await response.text();
|
|
715
|
+
let data2;
|
|
716
|
+
try {
|
|
717
|
+
data2 = JSON.parse(text);
|
|
718
|
+
} catch {
|
|
719
|
+
throw new Error(`更新接口返回非 JSON(HTTP ${response.status}):${text.slice(0, 80)}`);
|
|
720
|
+
}
|
|
721
|
+
if (!response.ok) throw new Error(data2.error || `HTTP ${response.status}`);
|
|
722
|
+
return data2;
|
|
723
|
+
}).then((data2) => setUpdateInfo(data2)).catch((error) => setUpdateInfo({ error: String(error) })).finally(() => setUpdateBusy(false));
|
|
724
|
+
};
|
|
725
|
+
const applyUpdate = () => {
|
|
726
|
+
if (updateInfo === null || typeof updateInfo.latest !== "string") return;
|
|
727
|
+
setUpdateBusy(true);
|
|
728
|
+
setUpdateInfo((previous) => ({ ...previous || {}, applying: true }));
|
|
729
|
+
fetch("/api/agent-memory/update/apply", {
|
|
730
|
+
method: "POST",
|
|
731
|
+
headers: { accept: "application/json", "content-type": "application/json" },
|
|
732
|
+
body: JSON.stringify({ version: updateInfo.latest })
|
|
733
|
+
}).then(async (response) => {
|
|
734
|
+
const text = await response.text();
|
|
735
|
+
let data2;
|
|
736
|
+
try {
|
|
737
|
+
data2 = JSON.parse(text);
|
|
738
|
+
} catch {
|
|
739
|
+
throw new Error(`更新接口返回非 JSON(HTTP ${response.status}):${text.slice(0, 80)}`);
|
|
740
|
+
}
|
|
741
|
+
if (!response.ok || data2.ok === false) throw new Error(data2.error || `HTTP ${response.status}`);
|
|
742
|
+
return data2;
|
|
743
|
+
}).then((data2) => setUpdateInfo((previous) => ({ ...previous || {}, applied: data2 }))).catch((error) => setUpdateInfo((previous) => ({ ...previous || {}, applyError: String(error) }))).finally(() => setUpdateBusy(false));
|
|
744
|
+
};
|
|
708
745
|
const openCreate = (kind) => {
|
|
709
746
|
setPanel("create");
|
|
710
747
|
setCreateKind(kind);
|
|
@@ -1640,6 +1677,22 @@ ${lines.join("\n")}`);
|
|
|
1640
1677
|
),
|
|
1641
1678
|
React2.createElement("p", { style: styles.small }, soulPath.hint)
|
|
1642
1679
|
),
|
|
1680
|
+
React2.createElement("h2", { style: styles.groupTitle }, "插件更新"),
|
|
1681
|
+
React2.createElement(
|
|
1682
|
+
"div",
|
|
1683
|
+
{ style: styles.actions },
|
|
1684
|
+
React2.createElement(
|
|
1685
|
+
AmButton,
|
|
1686
|
+
{ variant: "ghost", disabled: updateBusy, onClick: checkUpdate },
|
|
1687
|
+
"检查更新"
|
|
1688
|
+
),
|
|
1689
|
+
updateInfo !== null && updateInfo.update_available === true ? React2.createElement(
|
|
1690
|
+
AmButton,
|
|
1691
|
+
{ variant: "primary", disabled: updateBusy, onClick: applyUpdate },
|
|
1692
|
+
`升级到 ${updateInfo.latest}`
|
|
1693
|
+
) : null
|
|
1694
|
+
),
|
|
1695
|
+
updateInfo === null ? React2.createElement("p", { style: styles.small }, "不会自动联网;点一下才会检查。") : updateInfo.checking === true ? React2.createElement("p", { style: styles.small }, "正在检查…") : updateInfo.error !== void 0 ? React2.createElement("p", { style: styles.small }, `检查失败:${updateInfo.error}`) : updateInfo.applied !== void 0 ? React2.createElement("p", { style: styles.small }, "新版本已安装,请完整重启 DSH 后生效。") : updateInfo.applyError !== void 0 ? React2.createElement("p", { style: styles.small }, `升级失败:${updateInfo.applyError}`) : updateInfo.applying === true ? React2.createElement("p", { style: styles.small }, "正在安装…") : updateInfo.update_available === true ? React2.createElement("p", { style: styles.small }, `当前 ${updateInfo.current},最新 ${updateInfo.latest}。`) : React2.createElement("p", { style: styles.small }, `已是最新版本(${updateInfo.current})。`),
|
|
1643
1696
|
React2.createElement("button", { style: { ...styles.button, marginTop: "12px" }, onClick: () => setPanel(null) }, "返回列表")
|
|
1644
1697
|
) : null,
|
|
1645
1698
|
panel !== null ? null : React2.createElement(
|
package/dist/plugin.mjs
CHANGED
|
@@ -6524,6 +6524,31 @@ function guiRoutes(deps) {
|
|
|
6524
6524
|
}
|
|
6525
6525
|
}
|
|
6526
6526
|
};
|
|
6527
|
+
const updateCheck = {
|
|
6528
|
+
path: "/api/agent-memory/update/check",
|
|
6529
|
+
methods: ["GET"],
|
|
6530
|
+
requestBody: "buffered",
|
|
6531
|
+
fetch: async () => {
|
|
6532
|
+
if (deps.update === void 0) return errorResponse("update service unavailable", 503);
|
|
6533
|
+
try {
|
|
6534
|
+
return json(await deps.update.check());
|
|
6535
|
+
} catch (error) {
|
|
6536
|
+
return errorResponse(error instanceof Error ? error.message : String(error), 502);
|
|
6537
|
+
}
|
|
6538
|
+
}
|
|
6539
|
+
};
|
|
6540
|
+
const updateApply = {
|
|
6541
|
+
path: "/api/agent-memory/update/apply",
|
|
6542
|
+
methods: ["POST"],
|
|
6543
|
+
requestBody: "buffered",
|
|
6544
|
+
fetch: async (request) => {
|
|
6545
|
+
if (deps.update === void 0) return errorResponse("update service unavailable", 503);
|
|
6546
|
+
const body = await readJson(request);
|
|
6547
|
+
const version = typeof body.version === "string" ? body.version : "";
|
|
6548
|
+
const result = await deps.update.apply(version);
|
|
6549
|
+
return json(result, result.ok ? 200 : 409);
|
|
6550
|
+
}
|
|
6551
|
+
};
|
|
6527
6552
|
return [
|
|
6528
6553
|
status,
|
|
6529
6554
|
list,
|
|
@@ -6544,7 +6569,9 @@ function guiRoutes(deps) {
|
|
|
6544
6569
|
soulPathRoute,
|
|
6545
6570
|
sealRoute,
|
|
6546
6571
|
profileRoute,
|
|
6547
|
-
rulesRoute
|
|
6572
|
+
rulesRoute,
|
|
6573
|
+
updateCheck,
|
|
6574
|
+
updateApply
|
|
6548
6575
|
];
|
|
6549
6576
|
}
|
|
6550
6577
|
function registerGuiRoutes(connection, deps, effect) {
|
|
@@ -6556,6 +6583,88 @@ function registerGuiRoutes(connection, deps, effect) {
|
|
|
6556
6583
|
else install();
|
|
6557
6584
|
}
|
|
6558
6585
|
|
|
6586
|
+
// packages/dsh/src/update.ts
|
|
6587
|
+
var PLUGIN_VERSION = "0.5.2";
|
|
6588
|
+
var PACKAGE_NAME = "@agent_memory/dsh";
|
|
6589
|
+
var REGISTRY_LATEST = [
|
|
6590
|
+
"https://registry.npmjs.org/@agent_memory%2Fdsh/latest",
|
|
6591
|
+
"https://registry.npmmirror.com/@agent_memory%2Fdsh/latest"
|
|
6592
|
+
];
|
|
6593
|
+
function compareVersions(left, right) {
|
|
6594
|
+
const parse = (value) => {
|
|
6595
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(value);
|
|
6596
|
+
return match === null ? [0, 0, 0] : [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
6597
|
+
};
|
|
6598
|
+
const a = parse(left);
|
|
6599
|
+
const b = parse(right);
|
|
6600
|
+
for (let index = 0; index < 3; index += 1) {
|
|
6601
|
+
if (a[index] !== b[index]) return a[index] > b[index] ? 1 : -1;
|
|
6602
|
+
}
|
|
6603
|
+
return 0;
|
|
6604
|
+
}
|
|
6605
|
+
function createUpdateService(manager, fetcher = fetch) {
|
|
6606
|
+
return {
|
|
6607
|
+
async check() {
|
|
6608
|
+
let lastError;
|
|
6609
|
+
for (const endpoint of REGISTRY_LATEST) {
|
|
6610
|
+
try {
|
|
6611
|
+
const response = await fetcher(endpoint, {
|
|
6612
|
+
headers: { accept: "application/json" },
|
|
6613
|
+
signal: AbortSignal.timeout(8e3)
|
|
6614
|
+
});
|
|
6615
|
+
const text = await response.text();
|
|
6616
|
+
if (!response.ok) {
|
|
6617
|
+
throw new Error(`registry returned HTTP ${response.status}: ${text.slice(0, 120)}`);
|
|
6618
|
+
}
|
|
6619
|
+
let body;
|
|
6620
|
+
try {
|
|
6621
|
+
body = JSON.parse(text);
|
|
6622
|
+
} catch {
|
|
6623
|
+
throw new Error(`registry returned non-JSON: ${text.slice(0, 120)}`);
|
|
6624
|
+
}
|
|
6625
|
+
if (typeof body.version !== "string" || !/^\d+\.\d+\.\d+/.test(body.version)) {
|
|
6626
|
+
throw new Error("registry response has no valid version");
|
|
6627
|
+
}
|
|
6628
|
+
return {
|
|
6629
|
+
current: PLUGIN_VERSION,
|
|
6630
|
+
latest: body.version,
|
|
6631
|
+
update_available: compareVersions(body.version, PLUGIN_VERSION) > 0,
|
|
6632
|
+
...typeof body.dist?.tarball === "string" ? { tarball: body.dist.tarball } : {}
|
|
6633
|
+
};
|
|
6634
|
+
} catch (error) {
|
|
6635
|
+
lastError = error;
|
|
6636
|
+
}
|
|
6637
|
+
}
|
|
6638
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
6639
|
+
},
|
|
6640
|
+
async apply(version) {
|
|
6641
|
+
if (!/^\d+\.\d+\.\d+$/.test(version) || compareVersions(version, PLUGIN_VERSION) <= 0) {
|
|
6642
|
+
return { ok: false, version, restart_required: false, error: "invalid upgrade version" };
|
|
6643
|
+
}
|
|
6644
|
+
if (manager === void 0) {
|
|
6645
|
+
return {
|
|
6646
|
+
ok: false,
|
|
6647
|
+
version,
|
|
6648
|
+
restart_required: false,
|
|
6649
|
+
manual: true,
|
|
6650
|
+
error: "\u5BBF\u4E3B\u672A\u63D0\u4F9B\u63D2\u4EF6\u7BA1\u7406\u670D\u52A1\uFF0C\u8BF7\u5728 \u8BBE\u7F6E \u2192 \u63D2\u4EF6 \u4E2D\u66F4\u65B0"
|
|
6651
|
+
};
|
|
6652
|
+
}
|
|
6653
|
+
try {
|
|
6654
|
+
const result = await manager.installBundle(`${PACKAGE_NAME}@${version}`, { enabled: true });
|
|
6655
|
+
return { ok: true, version, restart_required: true, result };
|
|
6656
|
+
} catch (error) {
|
|
6657
|
+
return {
|
|
6658
|
+
ok: false,
|
|
6659
|
+
version,
|
|
6660
|
+
restart_required: false,
|
|
6661
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6662
|
+
};
|
|
6663
|
+
}
|
|
6664
|
+
}
|
|
6665
|
+
};
|
|
6666
|
+
}
|
|
6667
|
+
|
|
6559
6668
|
// packages/dsh/src/service.ts
|
|
6560
6669
|
function speakerOf(type) {
|
|
6561
6670
|
if (type.startsWith("assistant")) return "assistant";
|
|
@@ -6874,9 +6983,12 @@ function apply(ctx) {
|
|
|
6874
6983
|
const effectful = ctx;
|
|
6875
6984
|
const effect = (install, label) => typeof effectful.effect === "function" ? effectful.effect(install, label) : install();
|
|
6876
6985
|
const installRoutes = (connection) => {
|
|
6986
|
+
const update = createUpdateService(
|
|
6987
|
+
service(ctx, "pluginManager")
|
|
6988
|
+
);
|
|
6877
6989
|
registerGuiRoutes(
|
|
6878
6990
|
connection,
|
|
6879
|
-
{ store: host.store, home, mode: host.mode, modules: moduleHealth, config: host.runtime.config },
|
|
6991
|
+
{ store: host.store, home, mode: host.mode, modules: moduleHealth, config: host.runtime.config, update },
|
|
6880
6992
|
effect
|
|
6881
6993
|
);
|
|
6882
6994
|
try {
|