@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.
- package/NATIVE_V1.md +3 -1
- package/README.md +54 -114
- package/README.zh.md +61 -121
- package/SPEC.md +46 -51
- package/dist/THIRD_PARTY_NOTICES.md +1 -56
- package/dist/client.js +5045 -2779
- package/dist/embedding.js +34 -9
- package/dist/engines.js +49 -4
- package/dist/image-host.js +837 -505
- package/dist/index.js +6790 -4126
- package/dist/ocr-host.js +1036 -175
- package/dist/ocr.js +4 -1
- package/dist/translation.js +43 -14
- package/dist/types/adapters/host/dsh/agent-tools.d.ts +1 -1
- package/dist/types/adapters/host/dsh/document-status.d.ts +0 -1
- package/dist/types/adapters/host/dsh/form-guidance.d.ts +2 -2
- package/dist/types/adapters/host/dsh/image-backends.d.ts +19 -3
- package/dist/types/adapters/host/dsh/image-tools.d.ts +15 -0
- package/dist/types/adapters/host/dsh/image-transport.d.ts +8 -7
- package/dist/types/adapters/host/dsh/index.d.ts +3 -2
- package/dist/types/adapters/host/dsh/model-cache-identity.d.ts +26 -0
- package/dist/types/adapters/host/dsh/ocr-session-llm.d.ts +2 -3
- package/dist/types/adapters/host/dsh/ocr-tool.d.ts +4 -2
- package/dist/types/adapters/host/dsh/page-content.d.ts +27 -0
- package/dist/types/adapters/host/dsh/pdf-evidence-meta.d.ts +13 -148
- package/dist/types/adapters/host/dsh/retrieval-prefetch.d.ts +49 -0
- package/dist/types/adapters/host/dsh/retrieval.d.ts +132 -25
- package/dist/types/adapters/host/dsh/translation-model.d.ts +3 -5
- package/dist/types/adapters/host/ocr/local-backend.d.ts +4 -0
- package/dist/types/contracts/indexing.d.ts +156 -0
- package/dist/types/embedding/registry.d.ts +2 -1
- package/dist/types/embedding/types.d.ts +10 -2
- package/dist/types/entrypoints/image-understanding-host.d.ts +2 -8
- package/dist/types/host/image-understanding-plugin.d.ts +1 -1
- package/dist/types/modules/document/index.d.ts +7 -0
- package/dist/types/modules/document/page-content-error.d.ts +3 -0
- package/dist/types/modules/document/page-content-native.d.ts +10 -0
- package/dist/types/modules/document/page-content-ocr.d.ts +5 -0
- package/dist/types/modules/document/page-content-text.d.ts +12 -0
- package/dist/types/modules/document/page-content.d.ts +158 -0
- package/dist/types/modules/engines/cache-identity.d.ts +16 -0
- package/dist/types/modules/engines/catalog.d.ts +20 -0
- package/dist/types/modules/engines/directory.d.ts +1 -0
- package/dist/types/modules/engines/index.d.ts +3 -0
- package/dist/types/modules/engines/serialization.d.ts +3 -0
- package/dist/types/modules/engines/types.d.ts +13 -0
- package/dist/types/modules/evidence/agent-page-image.d.ts +9 -112
- package/dist/types/modules/evidence/agent-page-read.d.ts +36 -2
- package/dist/types/modules/evidence/image-capture.d.ts +1 -6
- package/dist/types/modules/evidence/index.d.ts +9 -136
- package/dist/types/modules/evidence/provenance.d.ts +8 -0
- package/dist/types/modules/evidence/reference-store.d.ts +91 -1
- package/dist/types/modules/evidence/status.d.ts +17 -0
- package/dist/types/modules/evidence/text-range.d.ts +28 -0
- package/dist/types/modules/evidence/text-target.d.ts +7 -1
- package/dist/types/modules/forms/index.d.ts +4 -4
- package/dist/types/modules/forms/inspection-references.d.ts +1 -1
- package/dist/types/modules/forms/validation.d.ts +4 -8
- package/dist/types/modules/image-understanding/service.d.ts +24 -42
- package/dist/types/modules/model-write/index.d.ts +1 -2
- package/dist/types/modules/ocr/service.d.ts +51 -3
- package/dist/types/modules/retrieval/cache.d.ts +44 -2
- package/dist/types/modules/retrieval/document-policy.d.ts +83 -0
- package/dist/types/modules/retrieval/index.d.ts +4 -1
- package/dist/types/modules/retrieval/page-content.d.ts +4 -0
- package/dist/types/modules/retrieval/paragraphs.d.ts +1 -12
- package/dist/types/modules/retrieval/shared-source.d.ts +25 -0
- package/dist/types/modules/retrieval/text.d.ts +19 -1
- package/dist/types/modules/retrieval/types.d.ts +83 -9
- package/dist/types/modules/retrieval/vector.d.ts +3 -0
- package/dist/types/modules/working-copy/index.d.ts +1 -1
- package/dist/types/modules/working-copy/ports.d.ts +11 -0
- package/dist/types/modules/working-copy/service.d.ts +13 -1
- package/dist/types/ocr/types.d.ts +2 -1
- package/dist/types/shared/contracts.d.ts +4 -0
- package/dist/types/shared/geometry/native-viewport.d.ts +0 -18
- package/dist/types/shared/geometry/text-target.d.ts +2 -6
- package/dist/types/shared/native.d.ts +2 -1
- package/dist/types/shared/passive-poll.d.ts +4 -0
- package/dist/types/translation/locales.d.ts +4 -3
- package/dist/types/translation/schema.d.ts +14 -0
- package/dist/types/translation/types.d.ts +12 -2
- package/docs/AI_READER_TOOLS.md +87 -210
- package/docs/ARCHITECTURE_V2.md +64 -18
- package/docs/ENGINE_EXTENSIONS.md +295 -25
- package/docs/RETRIEVAL_EXPERIMENT.md +169 -47
- package/docs/UX_TYPOGRAPHY.md +3 -3
- package/package.json +13 -13
- 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:
|
|
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-
|
|
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
|
-
|
|
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 =
|
|
14747
|
-
if (!Array.isArray(vector) || vector.length !==
|
|
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
|
-
|
|
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:
|
|
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-
|
|
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,
|
|
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
|