@sparkelf/dsh-plugin-document-attachments 0.1.0-rc.10

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/lib/mineru.js ADDED
@@ -0,0 +1,213 @@
1
+ import { r as DocumentParserError } from "./types-gD1pbaLm.js";
2
+ import z from "@deepseek-ai/schemastery";
3
+ import { unzipSync } from "fflate";
4
+ //#region lib/types/provider.js
5
+ /** Synchronous MinerU `/file_parse` document parser provider. */
6
+ /** Stable parser-provider id recorded with durable parse provenance. */
7
+ const MINERU_PROVIDER_ID = "mineru";
8
+ function logProviderError(operation, error) {
9
+ console.error(`document-parser-mineru: ${operation}`, error);
10
+ }
11
+ /** MinerU external parser implementation. */
12
+ var MinerUDocumentParserProvider = class {
13
+ id = MINERU_PROVIDER_ID;
14
+ endpoint;
15
+ timeoutMs;
16
+ maxResponseBytes;
17
+ constructor(options) {
18
+ const endpoint = parseEndpoint(options.endpoint);
19
+ if (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs <= 0) throw new Error("document-parser-mineru: timeoutMs must be a positive safe integer");
20
+ if (!Number.isSafeInteger(options.maxResponseBytes) || options.maxResponseBytes <= 0) throw new Error("document-parser-mineru: maxResponseBytes must be a positive safe integer");
21
+ this.endpoint = endpoint;
22
+ this.timeoutMs = options.timeoutMs;
23
+ this.maxResponseBytes = options.maxResponseBytes;
24
+ }
25
+ async parse(request, signal) {
26
+ const timeout = AbortSignal.timeout(this.timeoutMs);
27
+ const combined = signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
28
+ const form = new FormData();
29
+ const fileBytes = new Uint8Array(request.data.byteLength);
30
+ fileBytes.set(request.data);
31
+ form.append("files", new Blob([fileBytes.buffer], { type: request.attachment.mediaType }), request.attachment.name);
32
+ form.append("return_md", "true");
33
+ form.append("return_middle_json", "false");
34
+ form.append("return_model_output", "false");
35
+ form.append("return_content_list", "true");
36
+ form.append("return_images", "true");
37
+ form.append("response_format_zip", "true");
38
+ form.append("return_original_file", "false");
39
+ let response;
40
+ try {
41
+ response = await fetch(this.endpoint, {
42
+ method: "POST",
43
+ redirect: "error",
44
+ body: form,
45
+ signal: combined
46
+ });
47
+ } catch (error) {
48
+ logProviderError("request failed", error);
49
+ if (signal?.aborted === true) throw new DocumentParserError("Document parsing was cancelled.", "DOCUMENT_PARSE_ABORTED", { cause: error });
50
+ if (timeout.aborted) throw new DocumentParserError(`Document parsing exceeded the configured ${this.timeoutMs} ms timeout.`, "DOCUMENT_PARSE_TIMEOUT", { cause: error });
51
+ throw new DocumentParserError("Unable to reach the configured document parser.", "DOCUMENT_PARSE_FAILED", { cause: error });
52
+ }
53
+ if (!response.ok) throw new DocumentParserError(`Document parser returned HTTP ${response.status}.`, "DOCUMENT_PARSE_FAILED");
54
+ const declaredLength = response.headers.get("content-length");
55
+ if (declaredLength !== null) {
56
+ const bytes = Number(declaredLength);
57
+ if (Number.isFinite(bytes) && bytes > this.maxResponseBytes) throw new DocumentParserError("Document parser response exceeds the configured byte limit.", "DOCUMENT_PARSE_RESPONSE_TOO_LARGE");
58
+ }
59
+ let archive;
60
+ try {
61
+ archive = await readBoundedBody(response, this.maxResponseBytes);
62
+ } catch (error) {
63
+ logProviderError("response read failed", error);
64
+ if (error instanceof DocumentParserError) throw error;
65
+ if (signal?.aborted === true) throw new DocumentParserError("Document parsing was cancelled.", "DOCUMENT_PARSE_ABORTED", { cause: error });
66
+ if (timeout.aborted) throw new DocumentParserError(`Document parsing exceeded the configured ${this.timeoutMs} ms timeout.`, "DOCUMENT_PARSE_TIMEOUT", { cause: error });
67
+ throw new DocumentParserError("Unable to read the document parser response.", "DOCUMENT_PARSE_FAILED", { cause: error });
68
+ }
69
+ return parseArchive(unzipBounded(archive, this.maxResponseBytes));
70
+ }
71
+ };
72
+ /** Read a response body and reject as soon as accumulated compressed bytes exceed the configured bound. */
73
+ async function readBoundedBody(response, maxBytes) {
74
+ if (response.body === null) return new Uint8Array();
75
+ const reader = response.body.getReader();
76
+ const chunks = [];
77
+ let totalBytes = 0;
78
+ try {
79
+ while (true) {
80
+ const part = await reader.read();
81
+ if (part.done) break;
82
+ const value = part.value;
83
+ totalBytes += value.byteLength;
84
+ if (totalBytes > maxBytes) {
85
+ try {
86
+ await reader.cancel();
87
+ } catch (error) {
88
+ logProviderError("oversized response cancellation failed", error);
89
+ }
90
+ throw new DocumentParserError("Document parser response exceeds the configured byte limit.", "DOCUMENT_PARSE_RESPONSE_TOO_LARGE");
91
+ }
92
+ chunks.push(value);
93
+ }
94
+ } finally {
95
+ reader.releaseLock();
96
+ }
97
+ const body = new Uint8Array(totalBytes);
98
+ let offset = 0;
99
+ for (const chunk of chunks) {
100
+ body.set(chunk, offset);
101
+ offset += chunk.byteLength;
102
+ }
103
+ return body;
104
+ }
105
+ /** Reject archives whose declared aggregate uncompressed size exceeds the bound before fflate allocates the entries. */
106
+ function unzipBounded(archive, maxBytes) {
107
+ let declaredBytes = 0;
108
+ let entries;
109
+ try {
110
+ entries = unzipSync(archive, { filter(file) {
111
+ if (declaredBytes > maxBytes) return false;
112
+ declaredBytes += file.originalSize;
113
+ return declaredBytes <= maxBytes;
114
+ } });
115
+ } catch (error) {
116
+ logProviderError("ZIP extraction failed", error);
117
+ throw new DocumentParserError("Document parser returned an invalid ZIP archive.", "DOCUMENT_PARSE_INVALID_OUTPUT", { cause: error });
118
+ }
119
+ if (declaredBytes > maxBytes) throw new DocumentParserError("Document parser extracted output exceeds the configured byte limit.", "DOCUMENT_PARSE_RESPONSE_TOO_LARGE");
120
+ return entries;
121
+ }
122
+ /** Validate a configured HTTP(S) parser endpoint without silently rewriting it. */
123
+ function parseEndpoint(value) {
124
+ let url;
125
+ try {
126
+ url = new URL(value);
127
+ } catch (error) {
128
+ logProviderError("endpoint parsing failed", error);
129
+ throw new Error("document-parser-mineru: endpoint must be an absolute URL", { cause: error });
130
+ }
131
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("document-parser-mineru: endpoint must use http or https");
132
+ return url.toString();
133
+ }
134
+ /**
135
+ * Select exactly one v1 Markdown and content-list output plus every extracted raster image.
136
+ * @param entries - bounded in-memory ZIP entries from one synchronous MinerU response.
137
+ * @returns validated complete transient parser output bytes.
138
+ */
139
+ function parseArchive(entries) {
140
+ const files = Object.entries(entries).filter(([name]) => !name.endsWith("/"));
141
+ const markdown = files.filter(([name]) => name.toLowerCase().endsWith(".md"));
142
+ const contentLists = files.filter(([name]) => {
143
+ const lower = name.toLowerCase();
144
+ return lower.endsWith("_content_list.json") && !lower.endsWith("_content_list_v2.json");
145
+ });
146
+ const markdownEntry = markdown[0];
147
+ const contentListEntry = contentLists[0];
148
+ if (markdown.length !== 1 || contentLists.length !== 1 || markdownEntry === void 0 || contentListEntry === void 0) throw new DocumentParserError("Document parser ZIP must contain exactly one Markdown file and one content-list JSON file.", "DOCUMENT_PARSE_INVALID_OUTPUT");
149
+ const markdownBytes = markdownEntry[1];
150
+ const contentListBytes = contentListEntry[1];
151
+ validateUtf8(markdownBytes, "Markdown");
152
+ const contentListText = validateUtf8(contentListBytes, "content-list JSON");
153
+ try {
154
+ const parsed = JSON.parse(contentListText);
155
+ if (!Array.isArray(parsed)) throw new Error("content list is not an array");
156
+ } catch (error) {
157
+ logProviderError("content-list validation failed", error);
158
+ throw new DocumentParserError("Document parser content-list output is not a JSON array.", "DOCUMENT_PARSE_INVALID_OUTPUT", { cause: error });
159
+ }
160
+ const images = [];
161
+ for (const [path, data] of files) {
162
+ if (!path.split("/").includes("images")) continue;
163
+ const name = path.slice(path.lastIndexOf("/") + 1);
164
+ const mediaType = imageMediaType(name);
165
+ if (mediaType === void 0) throw new DocumentParserError(`Document parser returned unsupported extracted image type for "${name}".`, "DOCUMENT_PARSE_INVALID_OUTPUT");
166
+ images.push({
167
+ name,
168
+ mediaType,
169
+ data
170
+ });
171
+ }
172
+ return {
173
+ markdown: markdownBytes,
174
+ contentList: contentListBytes,
175
+ images
176
+ };
177
+ }
178
+ /** Strict UTF-8 decoder used before parser output is accepted for durable persistence. */
179
+ function validateUtf8(data, label) {
180
+ try {
181
+ return new TextDecoder("utf-8", { fatal: true }).decode(data);
182
+ } catch (error) {
183
+ logProviderError(`${label} UTF-8 decoding failed`, error);
184
+ throw new DocumentParserError(`Document parser ${label} is not valid UTF-8.`, "DOCUMENT_PARSE_INVALID_OUTPUT", { cause: error });
185
+ }
186
+ }
187
+ /** MIME owned by the existing raster attachment admission path. */
188
+ function imageMediaType(name) {
189
+ const lower = name.toLowerCase();
190
+ if (lower.endsWith(".png")) return "image/png";
191
+ if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
192
+ if (lower.endsWith(".webp")) return "image/webp";
193
+ if (lower.endsWith(".gif")) return "image/gif";
194
+ }
195
+ //#endregion
196
+ //#region lib/types/mineru.js
197
+ /** MinerU implementation of the external document-parser seam. @module @sparkelf/dsh-plugin-document-attachments/mineru */
198
+ /** Cordis plugin name used by loader diagnostics. */
199
+ const name = "document-parser-mineru";
200
+ /** Provider registers into the provider-neutral parser seam. */
201
+ const inject = ["documentParser"];
202
+ /** MinerU provider configuration has no implicit endpoint, timeout, or size policy. */
203
+ const Config = z.object({
204
+ endpoint: z.string().required(),
205
+ timeoutMs: z.number().step(1).min(1).required(),
206
+ maxResponseBytes: z.number().step(1).min(1).required()
207
+ });
208
+ /** Register the MinerU provider into `ctx.documentParser`. */
209
+ function apply(ctx, config) {
210
+ ctx.documentParser.registerProvider(new MinerUDocumentParserProvider(config));
211
+ }
212
+ //#endregion
213
+ export { Config, MINERU_PROVIDER_ID, MinerUDocumentParserProvider, apply, inject, name };
@@ -0,0 +1,10 @@
1
+ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ type Props = PropsRuntime<'conversation.input.attachments.documents'> & PropsLocale<'documentAttachments'>;
3
+ /**
4
+ * Render browser-owned Document drafts with remove controls.
5
+ * @param props - nested composer slot owner data and locale translator.
6
+ * @returns the draft rail, or null when empty.
7
+ */
8
+ export declare function DraftDocuments({ documents, onRemoveDocument, t }: Props): import("react").JSX.Element | null;
9
+ export {};
10
+ //# sourceMappingURL=DraftDocuments.d.ts.map
@@ -0,0 +1,17 @@
1
+ import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ type Props = PropsRuntime<'conversation.message.images.documents'> & PropsLocale<'documentAttachments'>;
3
+ type TrajectoryProps = PropsRuntime<'conversation.trajectory.images.documents'> & PropsLocale<'documentAttachments'>;
4
+ /**
5
+ * Render durable Document cards in Chat history.
6
+ * @param props - nested Chat attachment owner data and locale translator.
7
+ * @returns the history card row, or null when empty.
8
+ */
9
+ export declare function MessageDocuments({ documents, t }: Props): import("react").JSX.Element;
10
+ /**
11
+ * Render durable Document cards in Trajectory history.
12
+ * @param props - nested Trajectory attachment owner data and locale translator.
13
+ * @returns the history card row, or null when empty.
14
+ */
15
+ export declare function TrajectoryDocuments({ documents, t }: TrajectoryProps): import("react").JSX.Element;
16
+ export {};
17
+ //# sourceMappingURL=MessageDocuments.d.ts.map
@@ -0,0 +1,62 @@
1
+ /** Browser Document prompt transport, localized intake validation, and nested card registrations. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import type { SessionRequestId } from '@deepseek-ai/dsh-api-session-controller/types';
4
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
5
+ import type { DocumentDraft, DocumentLimits } from './types.ts';
6
+ export declare const name = "document-attachments-client";
7
+ export declare const inject: string[];
8
+ interface DocumentPromptRequest {
9
+ readonly sessionId: SessionId;
10
+ readonly requestId: SessionRequestId;
11
+ readonly mode: 'queue' | 'steer';
12
+ readonly content: readonly unknown[];
13
+ readonly signal?: AbortSignal;
14
+ }
15
+ type DocumentPromptResponse = {
16
+ readonly ok: true;
17
+ readonly value: {
18
+ readonly accepted: true;
19
+ };
20
+ } | {
21
+ readonly ok: false;
22
+ readonly error: {
23
+ readonly code: string;
24
+ readonly message: string;
25
+ readonly details: Record<string, unknown>;
26
+ };
27
+ };
28
+ /** Localized Document intake and authenticated prompt transport consumed by Conversation. */
29
+ export interface DocumentPromptClient {
30
+ /** @returns localized rejection text for slash-command submissions. */
31
+ commandUnsupported(): string;
32
+ /**
33
+ * @param limits - actual Host Document limits.
34
+ * @returns localized mixed file drop invitation.
35
+ */
36
+ dropLabels(limits: DocumentLimits): {
37
+ readonly title: string;
38
+ readonly desc: string;
39
+ };
40
+ /**
41
+ * @param files - newly selected browser Documents.
42
+ * @param existing - live Document drafts already registered.
43
+ * @param limits - actual Host attachment-provider limits.
44
+ * @returns localized rejection text, or null when intake may proceed.
45
+ */
46
+ validateIntake(files: readonly File[], existing: readonly DocumentDraft[], limits: DocumentLimits): string | null;
47
+ /**
48
+ * @param request - prepared mixed browser prompt.
49
+ * @returns Session-compatible prompt admission result.
50
+ */
51
+ submit(request: DocumentPromptRequest): Promise<DocumentPromptResponse>;
52
+ }
53
+ declare module '@deepseek-ai/cordis' {
54
+ interface Context {
55
+ /** Browser Document intake and prompt transport. */
56
+ documentPrompt: DocumentPromptClient;
57
+ }
58
+ }
59
+ /** Install browser transport, localized validation, and Document card contributions. */
60
+ export declare function apply(ctx: Context): void;
61
+ export {};
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,47 @@
1
+ export declare const en: {
2
+ readonly 'intake.count': "Attach up to {count} documents per message.";
3
+ readonly 'intake.type': "Choose a PDF, DOCX, PPTX, or XLSX file whose extension matches its type.";
4
+ readonly 'intake.fileSize': "Each document must be {size} or smaller.";
5
+ readonly 'intake.totalSize': "Documents in one message must total {size} or less.";
6
+ readonly 'submit.failed': "Unable to submit the document prompt.";
7
+ readonly 'command.unsupported': "Slash commands do not accept document attachments.";
8
+ readonly 'drop.title': "Drop images or documents here";
9
+ readonly 'drop.desc': "PDF, DOCX, PPTX, or XLSX; up to {count} documents, {size} each.";
10
+ readonly 'draft.group': "Draft documents";
11
+ readonly 'draft.remove': "Remove {name}";
12
+ readonly 'history.group': "Attached documents";
13
+ readonly 'format.pdf': "PDF";
14
+ readonly 'format.docx': "DOCX";
15
+ readonly 'format.pptx': "PPTX";
16
+ readonly 'format.xlsx': "XLSX";
17
+ readonly 'format.mib': "{value} MiB";
18
+ readonly 'format.kib': "{value} KiB";
19
+ };
20
+ export declare const zh: {
21
+ readonly 'intake.count': "每条消息最多可附加 {count} 个文档。";
22
+ readonly 'intake.type': "请选择扩展名与类型一致的 PDF、DOCX、PPTX 或 XLSX 文件。";
23
+ readonly 'intake.fileSize': "每个文档不得超过 {size}。";
24
+ readonly 'intake.totalSize': "单条消息中的文档总大小不得超过 {size}。";
25
+ readonly 'submit.failed': "无法提交文档消息。";
26
+ readonly 'command.unsupported': "斜杠命令不接受文档附件。";
27
+ readonly 'drop.title': "将图片或文档拖放到此处";
28
+ readonly 'drop.desc': "支持 PDF、DOCX、PPTX 或 XLSX;最多 {count} 个文档,每个不超过 {size}。";
29
+ readonly 'draft.group': "待发送文档";
30
+ readonly 'draft.remove': "移除 {name}";
31
+ readonly 'history.group': "已附加文档";
32
+ readonly 'format.pdf': "PDF";
33
+ readonly 'format.docx': "DOCX";
34
+ readonly 'format.pptx': "PPTX";
35
+ readonly 'format.xlsx': "XLSX";
36
+ readonly 'format.mib': "{value} MiB";
37
+ readonly 'format.kib': "{value} KiB";
38
+ };
39
+ type DocumentLocaleKey = keyof typeof en;
40
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
41
+ interface LocaleNamespaceMap {
42
+ /** Product copy for document intake and durable document cards. */
43
+ documentAttachments: DocumentLocaleKey;
44
+ }
45
+ }
46
+ export {};
47
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,49 @@
1
+ /** Browser-only Document draft, limits, and presentation owner data. */
2
+ import type { DraftAttachmentId } from '@deepseek-ai/dsh-client-ui-conversation/client';
3
+ /** Browser-owned Document draft before Host admission. */
4
+ export interface DocumentDraft {
5
+ readonly kind: 'document';
6
+ readonly id: DraftAttachmentId;
7
+ readonly file: File;
8
+ }
9
+ /** Host-projected Document admission limits consumed by browser intake. */
10
+ export interface DocumentLimits {
11
+ readonly maxDocumentBytes: number;
12
+ readonly maxDocumentsPerMessage: number;
13
+ readonly maxMessageDocumentBytes: number;
14
+ readonly mediaTypes: readonly string[];
15
+ }
16
+ /** Plain durable Document metadata rendered by history cards. */
17
+ interface DocumentCardData {
18
+ readonly name: string;
19
+ readonly mediaType: string;
20
+ readonly bytes: number;
21
+ }
22
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
23
+ interface SlotMap {
24
+ 'conversation.input.attachments.documents': {
25
+ kind: 'single';
26
+ scope: 'session-maybe';
27
+ owner: {
28
+ documents: readonly DocumentDraft[];
29
+ onRemoveDocument: (id: DraftAttachmentId) => void;
30
+ };
31
+ };
32
+ 'conversation.message.images.documents': {
33
+ kind: 'single';
34
+ scope: 'session';
35
+ owner: {
36
+ documents: readonly DocumentCardData[];
37
+ };
38
+ };
39
+ 'conversation.trajectory.images.documents': {
40
+ kind: 'single';
41
+ scope: 'session';
42
+ owner: {
43
+ documents: readonly DocumentCardData[];
44
+ };
45
+ };
46
+ }
47
+ }
48
+ export {};
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,14 @@
1
+ /** Document parser failures crossing provider and Host admission. @module @deepseek-ai/dsh-document-parser/error */
2
+ import type { DocumentParserErrorCode } from './types.ts';
3
+ /** Failure crossing the document-parser capability seam. */
4
+ export declare class DocumentParserError extends Error {
5
+ /** Stable machine-routing failure code. */
6
+ readonly code: DocumentParserErrorCode;
7
+ /**
8
+ * @param message - user-safe failure description without original bytes or parser temporary paths.
9
+ * @param code - stable parser failure code.
10
+ * @param options - optional chained cause.
11
+ */
12
+ constructor(message: string, code: DocumentParserErrorCode, options?: ErrorOptions);
13
+ }
14
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1,56 @@
1
+ /** Optional external document-parser capability (`ctx.documentParser`). @module @sparkelf/dsh-plugin-document-attachments */
2
+ import { Context, Service } from '@deepseek-ai/cordis';
3
+ import z from '@deepseek-ai/schemastery';
4
+ import type { DocumentParseRequest, DocumentParseResult, DocumentParserProvider } from './types.ts';
5
+ export { DocumentParserError } from './error.ts';
6
+ export type { DocumentAttachmentRef, DocumentMediaType, DocumentParseRequest, DocumentParseResult, DocumentParserErrorCode, DocumentParserProvider, ParsedDocumentImage, } from './types.ts';
7
+ declare module '@deepseek-ai/cordis' {
8
+ interface Context {
9
+ documentParser: DocumentParserRuntime;
10
+ }
11
+ }
12
+ /** Deployment choices owned by the provider-neutral parser seam. */
13
+ export interface Config {
14
+ /** Explicit parser provider id; omission auto-selects exactly one registered provider. */
15
+ provider?: string;
16
+ /** Maximum aggregate rendered-document bytes, including delimiters and metadata, accepted for direct-context version one. */
17
+ maxDirectMarkdownBytes: number;
18
+ /** Maximum encoded JSON bytes accepted by the authenticated mixed prompt route. */
19
+ maxRequestBytes: number;
20
+ }
21
+ /** Parser seam configuration; the direct-context budget is intentionally required. */
22
+ export declare const Config: z<Config>;
23
+ /** Provider-neutral parser registry and direct-context policy owner. */
24
+ export declare class DocumentParserRuntime extends Service {
25
+ static inject: string[];
26
+ private providers;
27
+ private readonly providerId;
28
+ /** Maximum aggregate rendered-document bytes Host admission may attach in one submitted message. */
29
+ readonly maxDirectMarkdownBytes: number;
30
+ constructor(ctx: Context, config: Config);
31
+ /**
32
+ * Register one parser provider until the owning Cordis fiber disposes.
33
+ * @param provider - provider implementation keyed by its non-empty id.
34
+ * @returns disposer that withdraws exactly this registration.
35
+ */
36
+ registerProvider(provider: DocumentParserProvider): () => void;
37
+ /**
38
+ * Report whether current registry state resolves the configured provider selection.
39
+ * This does not probe provider health or external endpoint availability.
40
+ * @returns true only when a parse call can select exactly one registered provider.
41
+ */
42
+ isSelectionResolvable(): boolean;
43
+ /**
44
+ * Parse one already-persisted document through the deployment-selected provider.
45
+ * @param request - verified original bytes and their durable metadata.
46
+ * @param signal - optional cancellation forwarded to the provider.
47
+ * @returns provider id together with the complete transient parse bundle.
48
+ */
49
+ parse(request: DocumentParseRequest, signal?: AbortSignal): Promise<{
50
+ parser: string;
51
+ result: DocumentParseResult;
52
+ }>;
53
+ private resolveProvider;
54
+ }
55
+ export default DocumentParserRuntime;
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,12 @@
1
+ /** Authenticated mixed prompt admission for parsed document attachments. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import type { DocumentParserRuntime } from './index.ts';
4
+ /**
5
+ * Register the authenticated mixed prompt route for this capability.
6
+ * @param ctx - Host context carrying WebServer, Connection, Attachment, and Session Controller services.
7
+ * @param parser - provider-neutral parser runtime.
8
+ * @param maxRequestBytes - exact encoded HTTP body limit.
9
+ * @returns route disposer owned by the Document parser Service fiber.
10
+ */
11
+ export declare function registerDocumentPromptRoute(ctx: Context, parser: DocumentParserRuntime, maxRequestBytes: number): () => void;
12
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Package-owned invariant companion for `@sparkelf/dsh-plugin-document-attachments`.
3
+ * @module @sparkelf/dsh-plugin-document-attachments/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "document-parser-mineru-invariant";
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export declare const inject: string[];
10
+ /** Register this package's invariant companion. */
11
+ export declare const apply: (ctx: Context) => Promise<() => void>;
12
+ //# sourceMappingURL=invariant.d.ts.map
@@ -0,0 +1,23 @@
1
+ /** MinerU implementation of the external document-parser seam. @module @sparkelf/dsh-plugin-document-attachments/mineru */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import z from '@deepseek-ai/schemastery';
4
+ export { MINERU_PROVIDER_ID, MinerUDocumentParserProvider, } from './provider.ts';
5
+ export type { MinerUProviderOptions } from './provider.ts';
6
+ /** Cordis plugin name used by loader diagnostics. */
7
+ export declare const name = "document-parser-mineru";
8
+ /** Provider registers into the provider-neutral parser seam. */
9
+ export declare const inject: string[];
10
+ /** External MinerU endpoint and bounded synchronous parse policy. */
11
+ export interface Config {
12
+ /** Absolute MinerU synchronous `/file_parse` endpoint. */
13
+ endpoint: string;
14
+ /** Maximum wall-clock milliseconds for one parse. */
15
+ timeoutMs: number;
16
+ /** Maximum compressed response and aggregate extracted output bytes. */
17
+ maxResponseBytes: number;
18
+ }
19
+ /** MinerU provider configuration has no implicit endpoint, timeout, or size policy. */
20
+ export declare const Config: z<Config>;
21
+ /** Register the MinerU provider into `ctx.documentParser`. */
22
+ export declare function apply(ctx: Context, config: Config): void;
23
+ //# sourceMappingURL=mineru.d.ts.map
@@ -0,0 +1,23 @@
1
+ /** Synchronous MinerU `/file_parse` document parser provider. */
2
+ import { type DocumentParseRequest, type DocumentParseResult, type DocumentParserProvider } from './index.ts';
3
+ /** Stable parser-provider id recorded with durable parse provenance. */
4
+ export declare const MINERU_PROVIDER_ID = "mineru";
5
+ /** Fully resolved MinerU HTTP policy. Every value is deployment-owned. */
6
+ export interface MinerUProviderOptions {
7
+ /** Absolute synchronous `POST /file_parse` endpoint. */
8
+ endpoint: string;
9
+ /** Maximum wall-clock time for one parse request. */
10
+ timeoutMs: number;
11
+ /** Maximum compressed HTTP body and aggregate extracted output bytes. */
12
+ maxResponseBytes: number;
13
+ }
14
+ /** MinerU external parser implementation. */
15
+ export declare class MinerUDocumentParserProvider implements DocumentParserProvider {
16
+ readonly id = "mineru";
17
+ private readonly endpoint;
18
+ private readonly timeoutMs;
19
+ private readonly maxResponseBytes;
20
+ constructor(options: MinerUProviderOptions);
21
+ parse(request: DocumentParseRequest, signal?: AbortSignal): Promise<DocumentParseResult>;
22
+ }
23
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1,66 @@
1
+ /** Provider-neutral document parsing vocabulary. @module @sparkelf/dsh-plugin-document-attachments/types */
2
+ import type { AttachmentId, ImageAttachmentRef, ImageMediaType } from '@deepseek-ai/dsh-attachment';
3
+ /** Document formats admitted by the Plus generic source integration. */
4
+ export type DocumentMediaType = 'application/pdf' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | 'application/vnd.openxmlformats-officedocument.presentationml.presentation' | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
5
+ /** Durable original-document reference shared structurally with the patched attachment service. */
6
+ export interface DocumentAttachmentRef {
7
+ attachmentId: AttachmentId;
8
+ mediaType: DocumentMediaType;
9
+ bytes: number;
10
+ name: string;
11
+ }
12
+ /** Generic durable file metadata shared structurally with the patched AttachmentStore. */
13
+ export interface FileAttachmentRef {
14
+ attachmentId: AttachmentId;
15
+ mediaType: string;
16
+ bytes: number;
17
+ name?: string;
18
+ }
19
+ /** Durable parser outputs stored before a Document block enters a Session. */
20
+ export interface ParsedDocumentRef {
21
+ parser: string;
22
+ markdown: FileAttachmentRef;
23
+ modelText: FileAttachmentRef;
24
+ contentList: FileAttachmentRef;
25
+ images: ImageAttachmentRef[];
26
+ }
27
+ /** Stable parser failure codes used by Host admission and provider diagnostics. */
28
+ export type DocumentParserErrorCode = 'DOCUMENT_PARSER_DUPLICATE_PROVIDER' | 'DOCUMENT_PARSER_CONFIGURED_MISSING' | 'DOCUMENT_PARSER_UNAVAILABLE' | 'DOCUMENT_PARSER_AMBIGUOUS' | 'DOCUMENT_PARSE_FAILED' | 'DOCUMENT_PARSE_INVALID_OUTPUT' | 'DOCUMENT_PARSE_RESPONSE_TOO_LARGE' | 'DOCUMENT_PARSE_TIMEOUT' | 'DOCUMENT_PARSE_ABORTED' | 'DOCUMENT_PARSE_CONTEXT_TOO_LARGE';
29
+ /** One already-persisted original document supplied to a parser provider. */
30
+ export interface DocumentParseRequest {
31
+ /** Durable original-document metadata. */
32
+ attachment: DocumentAttachmentRef;
33
+ /** Exact original bytes resolved from the durable attachment store. */
34
+ data: Uint8Array;
35
+ }
36
+ /** One extracted raster image returned by a parser before durable persistence. */
37
+ export interface ParsedDocumentImage {
38
+ /** Parser-relative display name only; never a host storage path. */
39
+ name: string;
40
+ /** Declared raster media type validated again by the attachment store on persistence. */
41
+ mediaType: ImageMediaType;
42
+ /** Exact extracted image bytes. */
43
+ data: Uint8Array;
44
+ }
45
+ /** Complete parser output required by the version-one durable document path. */
46
+ export interface DocumentParseResult {
47
+ /** Complete UTF-8 Markdown bytes used for direct model projection. */
48
+ markdown: Uint8Array;
49
+ /** Complete UTF-8 JSON bytes for the parser's reading-order content list. */
50
+ contentList: Uint8Array;
51
+ /** Extracted raster images in parser output order. */
52
+ images: readonly ParsedDocumentImage[];
53
+ }
54
+ /** External parser implementation registered into {@link DocumentParserRuntime}. */
55
+ export interface DocumentParserProvider {
56
+ /** Stable provider id used by explicit deployment selection and durable parse provenance. */
57
+ readonly id: string;
58
+ /**
59
+ * Parse one original document into the complete version-one output bundle.
60
+ * @param request - original durable metadata and verified bytes.
61
+ * @param signal - optional caller cancellation.
62
+ * @returns complete Markdown, content-list JSON, and extracted images.
63
+ */
64
+ parse(request: DocumentParseRequest, signal?: AbortSignal): Promise<DocumentParseResult>;
65
+ }
66
+ //# sourceMappingURL=types.d.ts.map