@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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
+ # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
+ # after editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write packages/plus/document-attachments/README.md
5
+ README.md: 51f203b7094d3d5a55c3fb2a95a1923dd74e8498
6
+ README.zh.md: e306fffb40200cf2996c99ed3b6e5a6be85a5899
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ ---
2
+ description: "Durable document intake, MinerU parsing, bounded model projection, and composer, Chat, and Trajectory cards."
3
+ kind: "package-reference"
4
+ ---
5
+
6
+ # @sparkelf/dsh-plugin-document-attachments
7
+
8
+ English | [中文](README.zh.md)
9
+
10
+ ## Summary
11
+
12
+ This complete Host and Client plugin owns document wire admission, the provider-neutral parser Service and MinerU HTTP provider, browser transport and localized validation, deterministic model delimiters, and cards for the composer, Chat, and Trajectory. With its independently retireable official-source patch, Plus accepts PDF, DOCX, PPTX, and XLSX files, persists originals and parsed artifacts, records document blocks, and projects bounded Markdown.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Model Experience](#model-experience)
18
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
19
+ - [Dev Note](#dev-note)
20
+
21
+ -----
22
+
23
+ <a id="use-this-package"></a>
24
+ ## Use this package
25
+
26
+ Set `DSH_MINERU_ENDPOINT` to an absolute synchronous MinerU `/file_parse` URL. The Plus profile mounts a 1 MiB direct-Markdown budget and the MinerU provider with a 120-second timeout and 64 MiB response limit; without the endpoint, both rows stay disabled and no incomplete capability is advertised.
27
+
28
+ -----
29
+
30
+ <a id="model-experience"></a>
31
+ ## Model Experience
32
+
33
+ ### Durable document content
34
+
35
+ #### What the model sees
36
+
37
+ Each accepted document contributes only `parsed.modelText`, wrapped with the original name and media type in deterministic delimiters. Parser paths, raw Office archives, content-list JSON, and extracted images remain out of model context.
38
+
39
+ #### Token effect
40
+
41
+ The document adds the bounded UTF-8 model-text length plus fixed delimiter text to its user message. Aggregate rendered bytes are checked before admission.
42
+
43
+ #### KV Cache effect
44
+
45
+ One durable parser result produces deterministic model text. Later turns can reuse the unchanged user-message prefix containing that document.
46
+
47
+ ## Known Limitations and Deferred Work
48
+
49
+ <a id="known-limitations-and-deferred-work"></a>
50
+
51
+ - **Temporary official integration patch**: the selected official revision exposes only image attachment integration; `@sparkelf/dsh-patch-document-attachments` supplies generic storage, durable content, model projection, mixed draft intake, Host limits, file selection, and presentation slots until official DSH publishes equivalent points.
52
+
53
+ <a id="dev-note"></a>
54
+ ### Dev Note
55
+
56
+ <details>
57
+ <summary>Working context for maintainers, click to expand</summary>
58
+
59
+ This Dev Note is working context for maintainers; shipped behavior, limits, and rationale live in the sections above, the package code, and the linked Agent Note.
60
+
61
+ - `src/index.ts` and `src/mineru.ts` own admission and parsing; `src/client` owns intake and cards. The [distribution Agent Note](../../../.agents/notes/proposed/architecture/2026-08-29-ranged-plus-patchset-distribution.md) owns the patch retirement rule.
62
+
63
+ </details>
package/README.zh.md ADDED
@@ -0,0 +1,63 @@
1
+ ---
2
+ description: "durable document intake、MinerU parsing、bounded model projection以及composer、Chat、Trajectory cards。"
3
+ kind: "package-reference"
4
+ ---
5
+
6
+ # @sparkelf/dsh-plugin-document-attachments
7
+
8
+ [English](README.md) | 中文
9
+
10
+ ## 概述
11
+
12
+ 该完整Host及Client plugin持有document wire admission、provider-neutral parser Service及MinerU HTTP provider、browser transport及localized validation、deterministic model delimiters,以及composer、Chat和Trajectory cards。配合independently retireable official-source patch,Plus接受PDF、DOCX、PPTX及XLSX files,persist original及parsed artifacts,记录document blocks并project bounded Markdown。
13
+
14
+ ## 目录
15
+
16
+ - [使用此软件包](#use-this-package)
17
+ - [模型体验](#model-experience)
18
+ - [已知限制和延期工作](#known-limitations-and-deferred-work)
19
+ - [开发备注](#dev-note)
20
+
21
+ -----
22
+
23
+ <a id="use-this-package"></a>
24
+ ## 使用此软件包
25
+
26
+ 把`DSH_MINERU_ENDPOINT`设为absolute synchronous MinerU `/file_parse` URL。Plus profile会mount 1 MiB direct-Markdown budget及带120-second timeout和64 MiB response limit的MinerU provider;缺少endpoint时两行保持disabled,且不会advertise incomplete capability。
27
+
28
+ -----
29
+
30
+ <a id="model-experience"></a>
31
+ ## 模型体验
32
+
33
+ ### Durable document content
34
+
35
+ #### 模型看到什么
36
+
37
+ 每个accepted document只贡献`parsed.modelText`,并用deterministic delimiters包裹original name及media type。Parser paths、raw Office archives、content-list JSON及extracted images不会进入model context。
38
+
39
+ #### Token 影响
40
+
41
+ Document向其user message加入bounded UTF-8 model-text length及fixed delimiter text。Aggregate rendered bytes会在admission前检查。
42
+
43
+ #### KV Cache 影响
44
+
45
+ 一个durable parser result产生deterministic model text。Later turns可复用包含该document的unchanged user-message prefix。
46
+
47
+ ## 已知限制和延期工作
48
+
49
+ <a id="known-limitations-and-deferred-work"></a>
50
+
51
+ - **Temporary official integration patch**:selected official revision只暴露image attachment integration;`@sparkelf/dsh-patch-document-attachments`会提供generic storage、durable content、model projection、mixed draft intake、Host limits、file selection及presentation slots,直到official DSH发布equivalent points。
52
+
53
+ <a id="dev-note"></a>
54
+ ### 开发备注
55
+
56
+ <details>
57
+ <summary>维护者工作上下文,点击展开</summary>
58
+
59
+ 该开发备注是maintainer working context;shipped behavior、limits及rationale以以上sections、package code及linked Agent Note为准。
60
+
61
+ - `src/index.ts`和`src/mineru.ts`持有admission及parsing;`src/client`持有intake及cards。[Distribution Agent Note](../../../.agents/notes/proposed/architecture/2026-08-29-ranged-plus-patchset-distribution.zh.md)持有patch retirement rule。
62
+
63
+ </details>
package/lib/client.js ADDED
@@ -0,0 +1,319 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "@sparkelf/dsh-plugin-document-attachments",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let _deepseek_ai_cordis = require("@deepseek-ai/cordis");
8
+ let react_jsx_runtime = require("react/jsx-runtime");
9
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
10
+ //#region \0dsh-css:/home/runner/work/deepseek-harness-plus/deepseek-harness-plus/packages/plus/document-attachments/src/client/Documents.module.css.mjs
11
+ const css = ".WD_fRa_list,.WD_fRa_history{scrollbar-width:none;gap:8px;padding:2px 0;display:flex;overflow-x:auto}.WD_fRa_list::-webkit-scrollbar,.WD_fRa_history::-webkit-scrollbar{display:none}.WD_fRa_card,.WD_fRa_historyCard{border:1px solid var(--dsw-alias-border-l2-darkmode-thin);background:var(--dsw-specific-input-major);border-radius:6px;grid-template-columns:42px minmax(96px,220px) auto 24px;align-items:center;gap:8px;min-height:48px;padding:6px 8px;display:grid}.WD_fRa_historyCard{grid-template-columns:42px minmax(96px,220px) auto}.WD_fRa_kind{background:var(--dsw-alias-interactive-bg-hover-solid);width:42px;height:28px;color:var(--dsw-alias-label-secondary);letter-spacing:0;border-radius:4px;justify-content:center;align-items:center;font-size:10px;font-weight:600;display:inline-flex}.WD_fRa_name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;overflow:hidden}.WD_fRa_size{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:11px}.WD_fRa_remove{width:24px;height:24px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;padding:0;display:inline-flex}.WD_fRa_remove:hover,.WD_fRa_remove:focus-visible{background:var(--dsw-alias-interactive-bg-hover-solid);color:var(--dsw-alias-label-primary)}";
12
+ const tagId = "@sparkelf/dsh-plugin-document-attachments/Documents.module.css";
13
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
14
+ const tag = document.createElement("style");
15
+ tag.dataset.plugin = "@sparkelf/dsh-plugin-document-attachments";
16
+ tag.dataset.pluginCss = tagId;
17
+ tag.textContent = css;
18
+ document.head.appendChild(tag);
19
+ }
20
+ var Documents_module_css_default = {
21
+ "card": "WD_fRa_card",
22
+ "history": "WD_fRa_history",
23
+ "historyCard": "WD_fRa_historyCard",
24
+ "kind": "WD_fRa_kind",
25
+ "list": "WD_fRa_list",
26
+ "name": "WD_fRa_name",
27
+ "remove": "WD_fRa_remove",
28
+ "size": "WD_fRa_size"
29
+ };
30
+ //#endregion
31
+ //#region lib/types/client/DraftDocuments.js
32
+ function fileKind$1(mediaType, t) {
33
+ if (mediaType === "application/pdf") return t("format.pdf");
34
+ if (mediaType.includes("wordprocessingml")) return t("format.docx");
35
+ if (mediaType.includes("presentationml")) return t("format.pptx");
36
+ return t("format.xlsx");
37
+ }
38
+ function formatBytes$2(bytes, t) {
39
+ if (bytes >= 1024 * 1024) return t("format.mib", { value: (bytes / (1024 * 1024)).toFixed(1) });
40
+ return t("format.kib", { value: Math.max(1, Math.ceil(bytes / 1024)) });
41
+ }
42
+ /**
43
+ * Render browser-owned Document drafts with remove controls.
44
+ * @param props - nested composer slot owner data and locale translator.
45
+ * @returns the draft rail, or null when empty.
46
+ */
47
+ function DraftDocuments({ documents, onRemoveDocument, t }) {
48
+ if (documents.length === 0) return null;
49
+ return (0, react_jsx_runtime.jsx)("div", {
50
+ className: Documents_module_css_default.list,
51
+ "aria-label": t("draft.group"),
52
+ children: documents.map((document) => (0, react_jsx_runtime.jsxs)("div", {
53
+ className: Documents_module_css_default.card,
54
+ children: [
55
+ (0, react_jsx_runtime.jsx)("span", {
56
+ className: Documents_module_css_default.kind,
57
+ children: fileKind$1(document.file.type, t)
58
+ }),
59
+ (0, react_jsx_runtime.jsx)("span", {
60
+ className: Documents_module_css_default.name,
61
+ title: document.file.name,
62
+ children: document.file.name
63
+ }),
64
+ (0, react_jsx_runtime.jsx)("span", {
65
+ className: Documents_module_css_default.size,
66
+ children: formatBytes$2(document.file.size, t)
67
+ }),
68
+ (0, react_jsx_runtime.jsx)("button", {
69
+ type: "button",
70
+ className: Documents_module_css_default.remove,
71
+ "aria-label": t("draft.remove", { name: document.file.name }),
72
+ title: t("draft.remove", { name: document.file.name }),
73
+ onClick: () => {
74
+ onRemoveDocument(document.id);
75
+ },
76
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseFill14, { "aria-hidden": true })
77
+ })
78
+ ]
79
+ }, document.id))
80
+ });
81
+ }
82
+ //#endregion
83
+ //#region lib/types/client/MessageDocuments.js
84
+ function fileKind(mediaType, t) {
85
+ if (mediaType === "application/pdf") return t("format.pdf");
86
+ if (mediaType.includes("wordprocessingml")) return t("format.docx");
87
+ if (mediaType.includes("presentationml")) return t("format.pptx");
88
+ return t("format.xlsx");
89
+ }
90
+ function formatBytes$1(bytes, t) {
91
+ if (bytes >= 1024 * 1024) return t("format.mib", { value: (bytes / (1024 * 1024)).toFixed(1) });
92
+ return t("format.kib", { value: Math.max(1, Math.ceil(bytes / 1024)) });
93
+ }
94
+ /**
95
+ * Render durable Document cards in Chat history.
96
+ * @param props - nested Chat attachment owner data and locale translator.
97
+ * @returns the history card row, or null when empty.
98
+ */
99
+ function MessageDocuments({ documents, t }) {
100
+ return (0, react_jsx_runtime.jsx)(DocumentCards, {
101
+ documents,
102
+ label: t("history.group"),
103
+ t
104
+ });
105
+ }
106
+ /**
107
+ * Render durable Document cards in Trajectory history.
108
+ * @param props - nested Trajectory attachment owner data and locale translator.
109
+ * @returns the history card row, or null when empty.
110
+ */
111
+ function TrajectoryDocuments({ documents, t }) {
112
+ return (0, react_jsx_runtime.jsx)(DocumentCards, {
113
+ documents,
114
+ label: t("history.group"),
115
+ t
116
+ });
117
+ }
118
+ function DocumentCards({ documents, label, t }) {
119
+ if (documents.length === 0) return null;
120
+ return (0, react_jsx_runtime.jsx)("div", {
121
+ className: Documents_module_css_default.history,
122
+ "aria-label": label,
123
+ children: documents.map((document, index) => (0, react_jsx_runtime.jsxs)("div", {
124
+ className: Documents_module_css_default.historyCard,
125
+ children: [
126
+ (0, react_jsx_runtime.jsx)("span", {
127
+ className: Documents_module_css_default.kind,
128
+ children: fileKind(document.mediaType, t)
129
+ }),
130
+ (0, react_jsx_runtime.jsx)("span", {
131
+ className: Documents_module_css_default.name,
132
+ title: document.name,
133
+ children: document.name
134
+ }),
135
+ (0, react_jsx_runtime.jsx)("span", {
136
+ className: Documents_module_css_default.size,
137
+ children: formatBytes$1(document.bytes, t)
138
+ })
139
+ ]
140
+ }, `${document.name}:${index}`))
141
+ });
142
+ }
143
+ //#endregion
144
+ //#region lib/types/client/locales.js
145
+ const en = {
146
+ "intake.count": "Attach up to {count} documents per message.",
147
+ "intake.type": "Choose a PDF, DOCX, PPTX, or XLSX file whose extension matches its type.",
148
+ "intake.fileSize": "Each document must be {size} or smaller.",
149
+ "intake.totalSize": "Documents in one message must total {size} or less.",
150
+ "submit.failed": "Unable to submit the document prompt.",
151
+ "command.unsupported": "Slash commands do not accept document attachments.",
152
+ "drop.title": "Drop images or documents here",
153
+ "drop.desc": "PDF, DOCX, PPTX, or XLSX; up to {count} documents, {size} each.",
154
+ "draft.group": "Draft documents",
155
+ "draft.remove": "Remove {name}",
156
+ "history.group": "Attached documents",
157
+ "format.pdf": "PDF",
158
+ "format.docx": "DOCX",
159
+ "format.pptx": "PPTX",
160
+ "format.xlsx": "XLSX",
161
+ "format.mib": "{value} MiB",
162
+ "format.kib": "{value} KiB"
163
+ };
164
+ const zh = {
165
+ "intake.count": "每条消息最多可附加 {count} 个文档。",
166
+ "intake.type": "请选择扩展名与类型一致的 PDF、DOCX、PPTX 或 XLSX 文件。",
167
+ "intake.fileSize": "每个文档不得超过 {size}。",
168
+ "intake.totalSize": "单条消息中的文档总大小不得超过 {size}。",
169
+ "submit.failed": "无法提交文档消息。",
170
+ "command.unsupported": "斜杠命令不接受文档附件。",
171
+ "drop.title": "将图片或文档拖放到此处",
172
+ "drop.desc": "支持 PDF、DOCX、PPTX 或 XLSX;最多 {count} 个文档,每个不超过 {size}。",
173
+ "draft.group": "待发送文档",
174
+ "draft.remove": "移除 {name}",
175
+ "history.group": "已附加文档",
176
+ "format.pdf": "PDF",
177
+ "format.docx": "DOCX",
178
+ "format.pptx": "PPTX",
179
+ "format.xlsx": "XLSX",
180
+ "format.mib": "{value} MiB",
181
+ "format.kib": "{value} KiB"
182
+ };
183
+ //#endregion
184
+ //#region lib/types/client/index.js
185
+ /** Browser Document prompt transport, localized intake validation, and nested card registrations. */
186
+ const name = "document-attachments-client";
187
+ const inject = ["locale", "slots"];
188
+ const NS = "documentAttachments";
189
+ const PATH = "/api/document.prompt";
190
+ function browserHostUrl(path) {
191
+ return new URL(path.replace(/^[/]/u, ""), document.baseURI).toString();
192
+ }
193
+ function extension(mediaType) {
194
+ switch (mediaType) {
195
+ case "application/pdf": return ".pdf";
196
+ case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": return ".docx";
197
+ case "application/vnd.openxmlformats-officedocument.presentationml.presentation": return ".pptx";
198
+ case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": return ".xlsx";
199
+ default: return "";
200
+ }
201
+ }
202
+ function isRecord(value) {
203
+ return typeof value === "object" && value !== null && !Array.isArray(value);
204
+ }
205
+ function parsePromptResponse(value) {
206
+ if (!isRecord(value) || typeof value.ok !== "boolean") throw new Error("Document prompt response is invalid.");
207
+ if (value.ok) {
208
+ if (!isRecord(value.value) || value.value.accepted !== true) throw new Error("Document prompt success response is invalid.");
209
+ return {
210
+ ok: true,
211
+ value: { accepted: true }
212
+ };
213
+ }
214
+ if (!isRecord(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string" || !isRecord(value.error.details)) throw new Error("Document prompt failure response is invalid.");
215
+ return {
216
+ ok: false,
217
+ error: {
218
+ code: value.error.code,
219
+ message: value.error.message,
220
+ details: value.error.details
221
+ }
222
+ };
223
+ }
224
+ function formatBytes(bytes) {
225
+ if (bytes >= 1024 * 1024) return `${Math.floor(bytes / (1024 * 1024))} MiB`;
226
+ return `${Math.floor(bytes / 1024)} KiB`;
227
+ }
228
+ var DocumentPromptClientService = class extends _deepseek_ai_cordis.Service {
229
+ constructor(ctx) {
230
+ super(ctx, "documentPrompt");
231
+ }
232
+ commandUnsupported() {
233
+ return this.ctx.locale.bind(NS)("command.unsupported");
234
+ }
235
+ dropLabels(limits) {
236
+ const t = this.ctx.locale.bind(NS);
237
+ return {
238
+ title: t("drop.title"),
239
+ desc: t("drop.desc", {
240
+ count: limits.maxDocumentsPerMessage,
241
+ size: formatBytes(limits.maxDocumentBytes)
242
+ })
243
+ };
244
+ }
245
+ validateIntake(files, existing, limits) {
246
+ const t = this.ctx.locale.bind(NS);
247
+ if (existing.length + files.length > limits.maxDocumentsPerMessage) return t("intake.count", { count: limits.maxDocumentsPerMessage });
248
+ let total = existing.reduce((sum, document) => sum + document.file.size, 0);
249
+ for (const file of files) {
250
+ const expectedExtension = extension(file.type);
251
+ if (!limits.mediaTypes.includes(file.type) || expectedExtension === "" || !file.name.toLowerCase().endsWith(expectedExtension)) return t("intake.type");
252
+ if (file.size > limits.maxDocumentBytes) return t("intake.fileSize", { size: formatBytes(limits.maxDocumentBytes) });
253
+ total += file.size;
254
+ }
255
+ if (total > limits.maxMessageDocumentBytes) return t("intake.totalSize", { size: formatBytes(limits.maxMessageDocumentBytes) });
256
+ return null;
257
+ }
258
+ async submit(request) {
259
+ try {
260
+ const response = await fetch(browserHostUrl(PATH), {
261
+ method: "POST",
262
+ headers: { "content-type": "application/json" },
263
+ body: JSON.stringify({
264
+ sessionId: request.sessionId,
265
+ requestId: request.requestId,
266
+ mode: request.mode === "steer" ? "steer" : "followup",
267
+ content: request.content,
268
+ clientTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
269
+ }),
270
+ ...request.signal === void 0 ? {} : { signal: request.signal }
271
+ });
272
+ const value = parsePromptResponse(await response.json());
273
+ if (!response.ok || !value.ok) return value.ok ? {
274
+ ok: false,
275
+ error: {
276
+ code: "DOCUMENT_PROMPT_FAILED",
277
+ message: this.ctx.locale.bind(NS)("submit.failed"),
278
+ details: {}
279
+ }
280
+ } : value;
281
+ return {
282
+ ok: true,
283
+ value: { accepted: true }
284
+ };
285
+ } catch (error) {
286
+ console.error("document-attachments: client prompt failed", error);
287
+ throw error;
288
+ }
289
+ }
290
+ };
291
+ /** Install browser transport, localized validation, and Document card contributions. */
292
+ function apply(ctx) {
293
+ ctx.effect(() => ctx.locale.register(NS, {
294
+ zh,
295
+ en
296
+ }), "document-attachments: client dictionaries");
297
+ new DocumentPromptClientService(ctx);
298
+ ctx.slots.inject("conversation.input.attachments.documents", () => ctx.slots.register({
299
+ name: "conversation.input.attachments.documents",
300
+ locale: NS
301
+ }, DraftDocuments));
302
+ ctx.slots.inject("conversation.message.images.documents", () => ctx.slots.register({
303
+ name: "conversation.message.images.documents",
304
+ locale: NS
305
+ }, MessageDocuments));
306
+ ctx.slots.inject("conversation.trajectory.images.documents", () => ctx.slots.register({
307
+ name: "conversation.trajectory.images.documents",
308
+ locale: NS
309
+ }, TrajectoryDocuments));
310
+ }
311
+ //#endregion
312
+ exports.apply = apply;
313
+ exports.inject = inject;
314
+ exports.name = name;
315
+ return module.exports;
316
+ }
317
+ });
318
+
319
+ //# sourceMappingURL=client.js.map
package/lib/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { n as DocumentParserRuntime, r as DocumentParserError, t as Config } from "./types-gD1pbaLm.js";
2
+ export { Config, DocumentParserError, DocumentParserRuntime, DocumentParserRuntime as default };
@@ -0,0 +1,16 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@sparkelf/dsh-plugin-document-attachments`.
4
+ * @module @sparkelf/dsh-plugin-document-attachments/invariant
5
+ */
6
+ const PACKAGE_NAME = "@sparkelf/dsh-plugin-document-attachments";
7
+ /** Cordis companion plugin name. */
8
+ const name = "document-parser-mineru-invariant";
9
+ /** Service required before the companion can reserve package ownership. */
10
+ const inject = ["invariants"];
11
+ /** No runtime invariant: parse transport has no independent durable state beyond attachment refs validated by its consumers. */
12
+ const install = () => {};
13
+ /** Register this package's invariant companion. */
14
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
15
+ //#endregion
16
+ export { apply, inject, name };