@dylanl1/dsh-plugin-pdf 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 (89) hide show
  1. package/NATIVE_V1.md +3 -1
  2. package/README.md +54 -114
  3. package/README.zh.md +61 -121
  4. package/SPEC.md +46 -51
  5. package/dist/THIRD_PARTY_NOTICES.md +1 -56
  6. package/dist/client.js +5045 -2779
  7. package/dist/embedding.js +34 -9
  8. package/dist/engines.js +49 -4
  9. package/dist/image-host.js +837 -505
  10. package/dist/index.js +6790 -4126
  11. package/dist/ocr-host.js +1036 -175
  12. package/dist/ocr.js +4 -1
  13. package/dist/translation.js +43 -14
  14. package/dist/types/adapters/host/dsh/agent-tools.d.ts +1 -1
  15. package/dist/types/adapters/host/dsh/document-status.d.ts +0 -1
  16. package/dist/types/adapters/host/dsh/form-guidance.d.ts +2 -2
  17. package/dist/types/adapters/host/dsh/image-backends.d.ts +19 -3
  18. package/dist/types/adapters/host/dsh/image-tools.d.ts +15 -0
  19. package/dist/types/adapters/host/dsh/image-transport.d.ts +8 -7
  20. package/dist/types/adapters/host/dsh/index.d.ts +3 -2
  21. package/dist/types/adapters/host/dsh/model-cache-identity.d.ts +26 -0
  22. package/dist/types/adapters/host/dsh/ocr-session-llm.d.ts +2 -3
  23. package/dist/types/adapters/host/dsh/ocr-tool.d.ts +4 -2
  24. package/dist/types/adapters/host/dsh/page-content.d.ts +27 -0
  25. package/dist/types/adapters/host/dsh/pdf-evidence-meta.d.ts +13 -148
  26. package/dist/types/adapters/host/dsh/retrieval-prefetch.d.ts +49 -0
  27. package/dist/types/adapters/host/dsh/retrieval.d.ts +132 -25
  28. package/dist/types/adapters/host/dsh/translation-model.d.ts +3 -5
  29. package/dist/types/adapters/host/ocr/local-backend.d.ts +4 -0
  30. package/dist/types/contracts/indexing.d.ts +156 -0
  31. package/dist/types/embedding/registry.d.ts +2 -1
  32. package/dist/types/embedding/types.d.ts +10 -2
  33. package/dist/types/entrypoints/image-understanding-host.d.ts +2 -8
  34. package/dist/types/host/image-understanding-plugin.d.ts +1 -1
  35. package/dist/types/modules/document/index.d.ts +7 -0
  36. package/dist/types/modules/document/page-content-error.d.ts +3 -0
  37. package/dist/types/modules/document/page-content-native.d.ts +10 -0
  38. package/dist/types/modules/document/page-content-ocr.d.ts +5 -0
  39. package/dist/types/modules/document/page-content-text.d.ts +12 -0
  40. package/dist/types/modules/document/page-content.d.ts +158 -0
  41. package/dist/types/modules/engines/cache-identity.d.ts +16 -0
  42. package/dist/types/modules/engines/catalog.d.ts +20 -0
  43. package/dist/types/modules/engines/directory.d.ts +1 -0
  44. package/dist/types/modules/engines/index.d.ts +3 -0
  45. package/dist/types/modules/engines/serialization.d.ts +3 -0
  46. package/dist/types/modules/engines/types.d.ts +13 -0
  47. package/dist/types/modules/evidence/agent-page-image.d.ts +9 -112
  48. package/dist/types/modules/evidence/agent-page-read.d.ts +36 -2
  49. package/dist/types/modules/evidence/image-capture.d.ts +1 -6
  50. package/dist/types/modules/evidence/index.d.ts +9 -136
  51. package/dist/types/modules/evidence/provenance.d.ts +8 -0
  52. package/dist/types/modules/evidence/reference-store.d.ts +91 -1
  53. package/dist/types/modules/evidence/status.d.ts +17 -0
  54. package/dist/types/modules/evidence/text-range.d.ts +28 -0
  55. package/dist/types/modules/evidence/text-target.d.ts +7 -1
  56. package/dist/types/modules/forms/index.d.ts +4 -4
  57. package/dist/types/modules/forms/inspection-references.d.ts +1 -1
  58. package/dist/types/modules/forms/validation.d.ts +4 -8
  59. package/dist/types/modules/image-understanding/service.d.ts +24 -42
  60. package/dist/types/modules/model-write/index.d.ts +1 -2
  61. package/dist/types/modules/ocr/service.d.ts +51 -3
  62. package/dist/types/modules/retrieval/cache.d.ts +44 -2
  63. package/dist/types/modules/retrieval/document-policy.d.ts +83 -0
  64. package/dist/types/modules/retrieval/index.d.ts +4 -1
  65. package/dist/types/modules/retrieval/page-content.d.ts +4 -0
  66. package/dist/types/modules/retrieval/paragraphs.d.ts +1 -12
  67. package/dist/types/modules/retrieval/shared-source.d.ts +25 -0
  68. package/dist/types/modules/retrieval/text.d.ts +19 -1
  69. package/dist/types/modules/retrieval/types.d.ts +83 -9
  70. package/dist/types/modules/retrieval/vector.d.ts +3 -0
  71. package/dist/types/modules/working-copy/index.d.ts +1 -1
  72. package/dist/types/modules/working-copy/ports.d.ts +11 -0
  73. package/dist/types/modules/working-copy/service.d.ts +13 -1
  74. package/dist/types/ocr/types.d.ts +2 -1
  75. package/dist/types/shared/contracts.d.ts +4 -0
  76. package/dist/types/shared/geometry/native-viewport.d.ts +0 -18
  77. package/dist/types/shared/geometry/text-target.d.ts +2 -6
  78. package/dist/types/shared/native.d.ts +2 -1
  79. package/dist/types/shared/passive-poll.d.ts +4 -0
  80. package/dist/types/translation/locales.d.ts +4 -3
  81. package/dist/types/translation/schema.d.ts +14 -0
  82. package/dist/types/translation/types.d.ts +12 -2
  83. package/docs/AI_READER_TOOLS.md +87 -210
  84. package/docs/ARCHITECTURE_V2.md +64 -18
  85. package/docs/ENGINE_EXTENSIONS.md +295 -25
  86. package/docs/RETRIEVAL_EXPERIMENT.md +169 -47
  87. package/docs/UX_TYPOGRAPHY.md +3 -3
  88. package/package.json +13 -13
  89. package/dist/types/adapters/host/dsh/image-auxiliary.d.ts +0 -20
package/dist/embedding.js CHANGED
@@ -14542,19 +14542,26 @@ function date4(params) {
14542
14542
  config(en_default());
14543
14543
 
14544
14544
  // src/modules/engines/types.ts
14545
+ var engineCapabilities = ["ocr-text", "image-description"];
14545
14546
  var configurationFieldSchema = external_exports.object({
14546
14547
  key: external_exports.string().regex(/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/),
14547
14548
  label: external_exports.string().min(1).max(200),
14548
14549
  type: external_exports.enum(["string", "number", "boolean", "secret-reference"]),
14549
14550
  required: external_exports.boolean().optional()
14550
14551
  }).strict();
14552
+ var engineExecutionSchema = external_exports.enum(["disabled", "local", "remote", "service"]);
14551
14553
  var engineDescriptorSchema = external_exports.object({
14552
14554
  id: external_exports.string().regex(/^[a-zA-Z0-9@][a-zA-Z0-9@/_.:-]{0,199}$/),
14553
14555
  name: external_exports.string().min(1).max(200),
14554
14556
  version: external_exports.string().min(1).max(128),
14555
- execution: external_exports.enum(["disabled", "local", "remote"]),
14557
+ execution: engineExecutionSchema,
14558
+ /** Omitted metadata makes no capability claim; consumers must opt in explicitly. */
14559
+ capabilities: external_exports.array(external_exports.enum(engineCapabilities)).max(engineCapabilities.length).optional(),
14556
14560
  configurationFields: external_exports.array(configurationFieldSchema).max(32).optional()
14557
14561
  }).superRefine((descriptor, ctx) => {
14562
+ if (descriptor.capabilities && new Set(descriptor.capabilities).size !== descriptor.capabilities.length) {
14563
+ ctx.addIssue({ code: "custom", message: "Duplicate engine capability" });
14564
+ }
14558
14565
  const fields = descriptor.configurationFields ?? [];
14559
14566
  if (new Set(fields.map((field) => field.key)).size !== fields.length) ctx.addIssue({ code: "custom", message: "Duplicate engine configuration field" });
14560
14567
  });
@@ -14583,7 +14590,7 @@ function validateEngineConfiguration(descriptor, input = {}) {
14583
14590
  }
14584
14591
  const type = field.type === "secret-reference" ? "string" : field.type;
14585
14592
  if (typeof value !== type || type === "number" && !Number.isFinite(value)) throw new Error(`Invalid engine configuration: ${field.label}`);
14586
- if (field.type === "secret-reference" && !/^[a-zA-Z0-9][a-zA-Z0-9/_.:-]{0,199}$/.test(String(value))) {
14593
+ if (field.type === "secret-reference" && !/^[a-zA-Z0-9_][a-zA-Z0-9/_.:-]{0,199}$/.test(String(value))) {
14587
14594
  throw new Error("A credential reference, not a secret, is required");
14588
14595
  }
14589
14596
  }
@@ -14611,7 +14618,7 @@ var EngineDirectory = class {
14611
14618
  const descriptor = engineDescriptorSchema.parse(this.describe(implementation));
14612
14619
  if (this.entries.has(descriptor.id)) throw new Error(`Engine already registered: ${descriptor.id}`);
14613
14620
  if (this.entries.size >= 128) throw new Error("Engine directory limit exceeded");
14614
- const entry = { implementation, descriptor: structuredClone(descriptor) };
14621
+ const entry = { implementation, descriptor: structuredClone(descriptor), generation: crypto.randomUUID() };
14615
14622
  this.entries.set(descriptor.id, entry);
14616
14623
  this.changed();
14617
14624
  return () => {
@@ -14627,6 +14634,9 @@ var EngineDirectory = class {
14627
14634
  get(id) {
14628
14635
  return this.entries.get(id)?.implementation;
14629
14636
  }
14637
+ generation(id) {
14638
+ return this.entries.get(id)?.generation;
14639
+ }
14630
14640
  has(id) {
14631
14641
  return this.entries.has(id);
14632
14642
  }
@@ -14740,21 +14750,36 @@ var EmbeddingRegistry = class {
14740
14750
  return this.run(engine, request.signal, request.timeoutMs, async (signal, timeoutMs) => {
14741
14751
  const output = await engine.embed({ texts, purpose: request.purpose, signal, timeoutMs }, config2);
14742
14752
  signal.throwIfAborted();
14743
- if (!Array.isArray(output) || output.length !== texts.length) {
14753
+ let resultModel = model;
14754
+ let returned = output;
14755
+ const currentModel = this.model(engine, config2);
14756
+ if (output && typeof output === "object" && "vectors" in output && "model" in output) {
14757
+ const reported = output.model;
14758
+ const identity = ["engineId", "engineVersion", "model", "modelRevision", "dimensions", "encoding", "fingerprint", "documentFingerprint"];
14759
+ if (!reported || identity.some((key) => reported[key] !== currentModel[key])) {
14760
+ throw new EmbeddingError("invalid-result", "The embedding response has an unverified model identity.");
14761
+ }
14762
+ returned = output.vectors;
14763
+ resultModel = currentModel;
14764
+ } else if (currentModel.fingerprint !== model.fingerprint || currentModel.documentFingerprint !== model.documentFingerprint) {
14765
+ throw new EmbeddingError("invalid-result", "The embedding model changed during the request.");
14766
+ }
14767
+ if (!Array.isArray(returned) || returned.length !== texts.length || texts.length > resultModel.maxBatchSize || texts.some((text) => text.length > resultModel.maxInputCharacters)) {
14744
14768
  throw new EmbeddingError("invalid-result", "The embedding response has an incorrect vector count.");
14745
14769
  }
14746
- const vectors = output.map((vector) => {
14747
- if (!Array.isArray(vector) || vector.length !== model.dimensions || vector.some((value) => typeof value !== "number" || !Number.isFinite(value))) {
14770
+ const vectors = returned.map((vector) => {
14771
+ if (!Array.isArray(vector) || vector.length !== resultModel.dimensions || vector.some((value) => typeof value !== "number" || !Number.isFinite(value))) {
14748
14772
  throw new EmbeddingError("invalid-result", "The embedding response has invalid vector dimensions or values.");
14749
14773
  }
14750
14774
  const norm = Math.hypot(...vector);
14751
14775
  if (!Number.isFinite(norm) || norm < 1e-12) throw new EmbeddingError("invalid-result", "The embedding response contains an empty vector.");
14752
14776
  return vector.map((value) => value / norm);
14753
14777
  });
14754
- if (this.model(engine, config2).fingerprint !== model.fingerprint) {
14778
+ const finalModel = this.model(engine, config2);
14779
+ if (finalModel.fingerprint !== resultModel.fingerprint || finalModel.documentFingerprint !== resultModel.documentFingerprint) {
14755
14780
  throw new EmbeddingError("invalid-result", "The embedding model changed during the request.");
14756
14781
  }
14757
- return { vectors, model };
14782
+ return { vectors, model: resultModel };
14758
14783
  });
14759
14784
  }
14760
14785
  dispose() {
@@ -14783,7 +14808,7 @@ var EmbeddingRegistry = class {
14783
14808
  if (error51 instanceof EmbeddingError) throw error51;
14784
14809
  throw new EmbeddingError("invalid-request", "The embedding engine configuration is invalid.");
14785
14810
  }
14786
- if (!model || model.engineId !== engine.descriptor.id || model.engineVersion !== engine.descriptor.version || [model.model, model.modelRevision, model.encoding, model.fingerprint].some((value) => typeof value !== "string" || !value || value.length > 512) || !Number.isSafeInteger(model.dimensions) || model.dimensions < 1 || model.dimensions > this.limits.maxDimensions || !Number.isSafeInteger(model.maxBatchSize) || model.maxBatchSize < 1 || !Number.isSafeInteger(model.maxInputCharacters) || model.maxInputCharacters < 1) {
14811
+ if (!model || model.engineId !== engine.descriptor.id || model.engineVersion !== engine.descriptor.version || [model.model, model.modelRevision, model.encoding, model.fingerprint].some((value) => typeof value !== "string" || !value || value.length > 512) || model.documentFingerprint !== void 0 && (typeof model.documentFingerprint !== "string" || !model.documentFingerprint || model.documentFingerprint.length > 512) || !Number.isSafeInteger(model.dimensions) || model.dimensions < 1 || model.dimensions > this.limits.maxDimensions || !Number.isSafeInteger(model.maxBatchSize) || model.maxBatchSize < 1 || !Number.isSafeInteger(model.maxInputCharacters) || model.maxInputCharacters < 1) {
14787
14812
  throw new EmbeddingError("invalid-result", "The embedding engine returned an invalid model description.");
14788
14813
  }
14789
14814
  return {
package/dist/engines.js CHANGED
@@ -14520,19 +14520,26 @@ config(en_default());
14520
14520
 
14521
14521
  // src/modules/engines/types.ts
14522
14522
  var engineKinds = ["ocr", "image", "translation", "embedding"];
14523
+ var engineCapabilities = ["ocr-text", "image-description"];
14523
14524
  var configurationFieldSchema = external_exports.object({
14524
14525
  key: external_exports.string().regex(/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/),
14525
14526
  label: external_exports.string().min(1).max(200),
14526
14527
  type: external_exports.enum(["string", "number", "boolean", "secret-reference"]),
14527
14528
  required: external_exports.boolean().optional()
14528
14529
  }).strict();
14530
+ var engineExecutionSchema = external_exports.enum(["disabled", "local", "remote", "service"]);
14529
14531
  var engineDescriptorSchema = external_exports.object({
14530
14532
  id: external_exports.string().regex(/^[a-zA-Z0-9@][a-zA-Z0-9@/_.:-]{0,199}$/),
14531
14533
  name: external_exports.string().min(1).max(200),
14532
14534
  version: external_exports.string().min(1).max(128),
14533
- execution: external_exports.enum(["disabled", "local", "remote"]),
14535
+ execution: engineExecutionSchema,
14536
+ /** Omitted metadata makes no capability claim; consumers must opt in explicitly. */
14537
+ capabilities: external_exports.array(external_exports.enum(engineCapabilities)).max(engineCapabilities.length).optional(),
14534
14538
  configurationFields: external_exports.array(configurationFieldSchema).max(32).optional()
14535
14539
  }).superRefine((descriptor, ctx) => {
14540
+ if (descriptor.capabilities && new Set(descriptor.capabilities).size !== descriptor.capabilities.length) {
14541
+ ctx.addIssue({ code: "custom", message: "Duplicate engine capability" });
14542
+ }
14536
14543
  const fields = descriptor.configurationFields ?? [];
14537
14544
  if (new Set(fields.map((field) => field.key)).size !== fields.length) ctx.addIssue({ code: "custom", message: "Duplicate engine configuration field" });
14538
14545
  });
@@ -14561,7 +14568,7 @@ function validateEngineConfiguration(descriptor, input = {}) {
14561
14568
  }
14562
14569
  const type = field.type === "secret-reference" ? "string" : field.type;
14563
14570
  if (typeof value !== type || type === "number" && !Number.isFinite(value)) throw new Error(`Invalid engine configuration: ${field.label}`);
14564
- if (field.type === "secret-reference" && !/^[a-zA-Z0-9][a-zA-Z0-9/_.:-]{0,199}$/.test(String(value))) {
14571
+ if (field.type === "secret-reference" && !/^[a-zA-Z0-9_][a-zA-Z0-9/_.:-]{0,199}$/.test(String(value))) {
14565
14572
  throw new Error("A credential reference, not a secret, is required");
14566
14573
  }
14567
14574
  }
@@ -14592,7 +14599,7 @@ var EngineDirectory = class {
14592
14599
  const descriptor = engineDescriptorSchema.parse(this.describe(implementation));
14593
14600
  if (this.entries.has(descriptor.id)) throw new Error(`Engine already registered: ${descriptor.id}`);
14594
14601
  if (this.entries.size >= 128) throw new Error("Engine directory limit exceeded");
14595
- const entry = { implementation, descriptor: structuredClone(descriptor) };
14602
+ const entry = { implementation, descriptor: structuredClone(descriptor), generation: crypto.randomUUID() };
14596
14603
  this.entries.set(descriptor.id, entry);
14597
14604
  this.changed();
14598
14605
  return () => {
@@ -14608,6 +14615,9 @@ var EngineDirectory = class {
14608
14615
  get(id) {
14609
14616
  return this.entries.get(id)?.implementation;
14610
14617
  }
14618
+ generation(id) {
14619
+ return this.entries.get(id)?.generation;
14620
+ }
14611
14621
  has(id) {
14612
14622
  return this.entries.has(id);
14613
14623
  }
@@ -14643,6 +14653,9 @@ var EngineDirectory = class {
14643
14653
  }
14644
14654
  };
14645
14655
 
14656
+ // src/shared/passive-poll.ts
14657
+ var PASSIVE_POLL_TIMEOUT_MS = 5e3;
14658
+
14646
14659
  // src/modules/engines/catalog.ts
14647
14660
  var engineCatalogSchema = external_exports.object({
14648
14661
  revision: external_exports.string().min(1).max(128),
@@ -14697,7 +14710,7 @@ var EngineCatalog = class {
14697
14710
  reject(signal.reason);
14698
14711
  };
14699
14712
  const stop = this.subscribe(changed);
14700
- const timer = setTimeout(changed, 15e3);
14713
+ const timer = setTimeout(changed, PASSIVE_POLL_TIMEOUT_MS);
14701
14714
  signal.addEventListener("abort", aborted2, { once: true });
14702
14715
  if (revision !== this.snapshot.revision || this.disposed) changed();
14703
14716
  });
@@ -14744,16 +14757,48 @@ async function engineProbe(tasks, provider, signal, errors, operation) {
14744
14757
  tasks.delete(controller);
14745
14758
  }
14746
14759
  }
14760
+
14761
+ // src/modules/engines/serialization.ts
14762
+ function canonicalEngineJson(value) {
14763
+ if (Array.isArray(value)) return `[${value.map(canonicalEngineJson).join(",")}]`;
14764
+ if (value !== null && typeof value === "object") {
14765
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalEngineJson(value[key])}`).join(",")}}`;
14766
+ }
14767
+ return JSON.stringify(value);
14768
+ }
14769
+
14770
+ // src/modules/engines/cache-identity.ts
14771
+ function engineCacheIdentity(descriptor, config2, generation, sessionId, backendIdentity, hash2, context = null) {
14772
+ const identity = typeof backendIdentity === "string" ? backendIdentity : backendIdentity?.identity;
14773
+ if (identity !== void 0 && (typeof identity !== "string" || !identity.trim() || identity.length > 16384)) {
14774
+ throw new Error("The engine returned an invalid cache identity");
14775
+ }
14776
+ const reusable = typeof backendIdentity === "string";
14777
+ const fingerprint = hash2(canonicalEngineJson({
14778
+ backendId: descriptor.id,
14779
+ backendVersion: descriptor.version,
14780
+ config: { ...config2 },
14781
+ capabilities: descriptor.capabilities ? [...descriptor.capabilities].sort() : null,
14782
+ identity: identity ?? null,
14783
+ context,
14784
+ ...reusable ? {} : { generation, sessionId }
14785
+ }));
14786
+ return { fingerprint, generation, reusable, backendId: descriptor.id, backendVersion: descriptor.version };
14787
+ }
14747
14788
  export {
14748
14789
  EngineCatalog,
14749
14790
  EngineDirectory,
14791
+ canonicalEngineJson,
14750
14792
  configurationFieldSchema,
14751
14793
  engineBinding,
14794
+ engineCacheIdentity,
14795
+ engineCapabilities,
14752
14796
  engineCatalogRequestSchema,
14753
14797
  engineCatalogSchema,
14754
14798
  engineConfigurationSchema,
14755
14799
  engineConfigurationsSchema,
14756
14800
  engineDescriptorSchema,
14801
+ engineExecutionSchema,
14757
14802
  engineKinds,
14758
14803
  engineProbe,
14759
14804
  validateEngineConfiguration