dsh-plugin-library 0.1.2 → 0.1.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.
Files changed (2) hide show
  1. package/dist/host.js +54 -3
  2. package/package.json +1 -1
package/dist/host.js CHANGED
@@ -1415,6 +1415,50 @@ var LibraryManager = class {
1415
1415
  if (asset.status === "removed") throw new FeatureError2("library/not-found", "\u8D44\u6599\u5DF2\u79FB\u9664\u3002");
1416
1416
  return asset;
1417
1417
  }
1418
+ /**
1419
+ * Resolve whatever identifier a caller supplied into a live asset id.
1420
+ *
1421
+ * The model-facing tools address a document by `asset_id`, but the text a
1422
+ * model actually reads (the search results) leads with the *name*. A model
1423
+ * that passes the name used to get `library/not-found` — "资料不存在或已移除"
1424
+ * — for a document that was perfectly readable, which reads as data loss.
1425
+ * So a name is accepted too, with two deliberate refusals:
1426
+ *
1427
+ * - **Ambiguous** (two live documents share a name): refused with every
1428
+ * candidate's id listed. Silently picking one would read the wrong document.
1429
+ * - **Unknown**: refused with a message that names both possibilities and
1430
+ * points at `library_search`, instead of the bare "not found" that hints
1431
+ * nothing about what was wrong with the identifier.
1432
+ * @param {string} identifier - an asset id, or a document name.
1433
+ * @returns {string} the live asset id.
1434
+ * @throws {FeatureError} `library/invalid-request`, `library/ambiguous` or `library/not-found`.
1435
+ */
1436
+ resolveAssetId(identifier) {
1437
+ const text = typeof identifier === "string" ? identifier.trim() : "";
1438
+ if (text.length === 0) {
1439
+ throw new FeatureError2("library/invalid-request", "\u9700\u8981 asset_id\uFF1A\u7528 library_search \u641C\u5230\u8D44\u6599\u540E\uFF0C\u628A\u5B83\u8FD4\u56DE\u7684 asset_id \u539F\u6837\u4F20\u8FDB\u6765\u3002");
1440
+ }
1441
+ const state = this.load();
1442
+ const direct = state.assets[text];
1443
+ const directNode = direct === void 0 ? void 0 : state.nodes[text];
1444
+ if (direct !== void 0 && direct.status !== "removed" && directNode !== void 0 && directNode.removedAt === void 0) {
1445
+ return text;
1446
+ }
1447
+ const live = Object.values(state.assets).filter((asset) => asset.status !== "removed").map((asset) => ({ asset, node: state.nodes[asset.id] })).filter((row) => row.node !== void 0 && row.node.removedAt === void 0 && row.node.kind === "asset");
1448
+ const exact = live.filter((row) => row.node.name === text);
1449
+ const matches = exact.length > 0 ? exact : live.filter((row) => row.node.name.toLocaleLowerCase() === text.toLocaleLowerCase());
1450
+ if (matches.length === 1) return matches[0].asset.id;
1451
+ if (matches.length > 1) {
1452
+ throw new FeatureError2(
1453
+ "library/ambiguous",
1454
+ `\u6709 ${matches.length} \u4EFD\u8D44\u6599\u53EB\u300C${text}\u300D\uFF0C\u65E0\u6CD5\u786E\u5B9A\u8BFB\u54EA\u4E00\u4EFD\uFF1B\u8BF7\u628A asset_id \u6362\u6210\u5176\u4E2D\u4E00\u4E2A\uFF1A` + matches.map((row) => `${row.node.name}\uFF08${row.asset.id}\uFF09`).join("\u3001")
1455
+ );
1456
+ }
1457
+ throw new FeatureError2(
1458
+ "library/not-found",
1459
+ `\u6CA1\u627E\u5230\u8D44\u6599\u300C${text}\u300D\uFF1A\u5B83\u65E2\u4E0D\u662F asset_id\uFF0C\u4E5F\u4E0D\u662F\u73B0\u6709\u8D44\u6599\u7684\u540D\u79F0\u3002\u8D44\u6599\u5728\u8D44\u6599\u5E93\u91CC\u3001\u4E0D\u5728\u5DE5\u4F5C\u533A\u6587\u4EF6\u7CFB\u7EDF\u91CC\uFF0C\u5148\u7528 library_search \u641C\u7D22\uFF0C\u518D\u628A\u8FD4\u56DE\u7684 asset_id \u539F\u6837\u4F20\u7ED9\u672C\u5DE5\u5177\u3002`
1460
+ );
1461
+ }
1418
1462
  /** An asset record a read is allowed to resolve: present and enabled. */
1419
1463
  requireReadableAsset(state, assetId) {
1420
1464
  const asset = this.requireAsset(state, assetId);
@@ -1586,7 +1630,13 @@ async function registerLibraryTools(ctx, manager) {
1586
1630
  },
1587
1631
  render: (_args, value) => [{
1588
1632
  type: "text",
1633
+ // The id is printed here, not just carried in the structured payload:
1634
+ // this rendered text is what the model actually reads, and the read /
1635
+ // edit tools address a document by `asset_id`. Leaving it out (v0.1.x)
1636
+ // made models pass the *name* instead and get "资料不存在或已移除" for a
1637
+ // document that was perfectly readable.
1589
1638
  text: value.hits.length > 0 ? value.hits.map((hit) => `${hit.name} (${hit.folder_path} \xB7 ${hit.kind} \xB7 \u4FEE\u8BA2 ${hit.revision_number} \xB7 ${hit.conversion_status})
1639
+ asset_id: ${hit.asset_id}
1590
1640
  ${hit.excerpt}`).join("\n\n") : "\u8D44\u6599\u5E93\u91CC\u6CA1\u6709\u5339\u914D\u7684\u8D44\u6599\u3002"
1591
1641
  }]
1592
1642
  },
@@ -1626,15 +1676,16 @@ ${hit.excerpt}`).join("\n\n") : "\u8D44\u6599\u5E93\u91CC\u6CA1\u6709\u5339\u914
1626
1676
  if (!Number.isInteger(offset) || offset < 0 || !Number.isInteger(limit) || limit < 1 || limit > 2e4) {
1627
1677
  throw new Error("library/invalid-page");
1628
1678
  }
1629
- const detail = manager.assetDetail(args.asset_id);
1679
+ const assetId = manager.resolveAssetId(args.asset_id);
1680
+ const detail = manager.assetDetail(assetId);
1630
1681
  const revisionId = args.revision_id ?? detail.asset.currentRevisionId;
1631
1682
  const revision = detail.revisions.find((row) => row.id === revisionId);
1632
- const complete = await manager.readText(args.asset_id, revisionId);
1683
+ const complete = await manager.readText(assetId, revisionId);
1633
1684
  const content = complete.slice(offset, offset + limit);
1634
1685
  const next = offset + content.length;
1635
1686
  const truncated = next < complete.length;
1636
1687
  return {
1637
- asset_id: args.asset_id,
1688
+ asset_id: assetId,
1638
1689
  revision_id: revisionId,
1639
1690
  conversion_status: revision?.conversionStatus ?? "ready",
1640
1691
  content,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-library",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "本地文件资料库:内容寻址的不可变修订、派生的可检索正文、文件夹与模型工具。",
5
5
  "type": "module",
6
6
  "main": "dist/host.js",