@cueai/omni-reader-mcp 1.5.5 → 1.7.0

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 (42) hide show
  1. package/README.md +106 -46
  2. package/dist/artifact-store.d.ts +2 -0
  3. package/dist/artifact-store.js +45 -10
  4. package/dist/capabilities.d.ts +129 -2
  5. package/dist/capabilities.js +122 -19
  6. package/dist/cli/agent-config.js +2 -2
  7. package/dist/cli/arguments.d.ts +8 -4
  8. package/dist/cli/arguments.js +62 -7
  9. package/dist/cli/config-inspection.d.ts +59 -0
  10. package/dist/cli/config-inspection.js +307 -0
  11. package/dist/cli/doctor.d.ts +7 -0
  12. package/dist/cli/doctor.js +37 -2
  13. package/dist/cli/setup.js +13 -2
  14. package/dist/constants.d.ts +6 -1
  15. package/dist/constants.js +9 -4
  16. package/dist/cube-client.d.ts +4 -1
  17. package/dist/cube-client.js +286 -32
  18. package/dist/cursor.d.ts +4 -0
  19. package/dist/cursor.js +11 -13
  20. package/dist/errors.d.ts +1 -0
  21. package/dist/errors.js +15 -0
  22. package/dist/iiis-client.d.ts +33 -2
  23. package/dist/iiis-client.js +368 -40
  24. package/dist/index.js +10 -1
  25. package/dist/operation-journal.d.ts +17 -1
  26. package/dist/operation-journal.js +260 -15
  27. package/dist/operation-manager.d.ts +6 -2
  28. package/dist/operation-manager.js +448 -89
  29. package/dist/path-normalization.d.ts +5 -0
  30. package/dist/path-normalization.js +25 -0
  31. package/dist/path-security.d.ts +2 -1
  32. package/dist/path-security.js +49 -28
  33. package/dist/protocol.d.ts +10 -2
  34. package/dist/protocol.js +23 -7
  35. package/dist/remote-client.js +3 -13
  36. package/dist/result-contract.d.ts +76 -32
  37. package/dist/result-contract.js +121 -5
  38. package/dist/task-runtime.d.ts +3 -2
  39. package/dist/task-runtime.js +2 -2
  40. package/dist/tools.d.ts +4 -0
  41. package/dist/tools.js +41 -31
  42. package/package.json +1 -1
package/README.md CHANGED
@@ -28,7 +28,7 @@ rather than stopping at "parse done".
28
28
 
29
29
  - Node.js 20.12 or newer.
30
30
  - Cue API Key: <https://cuecue.cn/hub/api-key>.
31
- - New accounts can try Omni without paying; see [Free credits](#free-credits) below. The
31
+ - New accounts can try Omni without paying; see [Free credits](#billing-and-free-credits) below. The
32
32
  server-side onboarding policy and the `doctor` output are the live authority for current
33
33
  allowances.
34
34
  - Configure `CUE_API_KEY` in the agent's secret store or local environment.
@@ -48,31 +48,45 @@ agent workspace remains the default allowed scope.
48
48
  For a local file, Bridge requests a Cube parse grant and uses the returned controlled
49
49
  granted-data-plane URL to upload the file and stream the result. A `BRIDGE_UPGRADE_REQUIRED`
50
50
  error means the running Bridge release is not accepted for direct local-file parsing —
51
- install `@cueai/omni-reader-mcp@1.5.5` using the official setup instructions, then retry the
51
+ install `@cueai/omni-reader-mcp@1.7.0` using the official setup instructions, then retry the
52
52
  same parse. Always run `doctor --json` first when diagnosing a parse failure.
53
53
 
54
- ## Free credits
54
+ ## Billing and free credits
55
55
 
56
- As of 2026-08-14:
56
+ The server-side [onboarding policy](https://cuecue.cn/api/v1/billing/public/onboarding-policy)
57
+ is the authority for the current first-registration gift and daily grant. When reachable,
58
+ `doctor` reports those live policy values; when unavailable, it reports that status instead
59
+ of copying a stale number.
57
60
 
58
- - every account receives 10 free credits daily roughly 150 pages of ordinary documents,
59
- 75 pages of scanned images or charts, 30 minutes of audio, or 4 minutes of video;
60
- - new accounts receive a one-time 50-credit gift when obtaining `CUE_API_KEY` (60 credits
61
- available on day one, including the daily grant);
62
- - inviting a new user who registers gives both the inviter and the invitee 50 credits, with
63
- no invite limit; when an invited user subscribes, the inviter additionally receives 10% of
64
- the invitee's first-month credit quota as a bonus.
61
+ A terminal URL or local-file result may carry the operation-local settlement snapshot:
65
62
 
66
- When available, the `doctor` output reports the live first-registration gift and daily grant;
67
- referral rules and conversion ratios follow the server-side onboarding policy. If live values
68
- differ from the numbers above, report the live values.
63
+ ```json
64
+ {
65
+ "billing": {
66
+ "credits_charged": 0.134,
67
+ "credits_remaining": 42.866
68
+ }
69
+ }
70
+ ```
71
+
72
+ The numbers above illustrate the response shape, not a price quote. The settled result is authoritative.
73
+ `credits_charged` is the amount deducted for that operation and
74
+ `credits_remaining` is the balance in the same immutable settlement snapshot. Bridge never
75
+ replaces it with a later balance lookup. Processing results have no billing block. New direct
76
+ canceled, failed, unsupported, or denied terminals are uncharged and carry no billing block.
77
+ Navigation and status calls preserve the same settled facts without creating another usage or
78
+ settlement identity.
79
+
80
+ Bridge does not publish static document-page or media-duration conversions. Rates can change,
81
+ and there is no public rate response carrying an `effective_at` timestamp. Use only current
82
+ authoritative billing/policy facts rather than estimating a charge from copied arithmetic.
69
83
 
70
84
  ## Installation and configuration
71
85
 
72
86
  Always use an audited exact version, never an implicit `latest`:
73
87
 
74
88
  ```sh
75
- npx -y @cueai/omni-reader-mcp@1.5.5 setup
89
+ npx -y @cueai/omni-reader-mcp@1.7.0 setup
76
90
  ```
77
91
 
78
92
  The interactive setup supports Hermes, Cursor, Claude Desktop, and generic stdio
@@ -80,9 +94,9 @@ configuration. Non-interactive installation uses the same argument parsing and w
80
94
  logic:
81
95
 
82
96
  ```sh
83
- npx -y @cueai/omni-reader-mcp@1.5.5 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
84
- npx -y @cueai/omni-reader-mcp@1.5.5 setup --client cursor --add-root /absolute/minimum/root --yes --json
85
- npx -y @cueai/omni-reader-mcp@1.5.5 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
97
+ npx -y @cueai/omni-reader-mcp@1.7.0 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
98
+ npx -y @cueai/omni-reader-mcp@1.7.0 setup --client cursor --add-root /absolute/minimum/root --yes --json
99
+ npx -y @cueai/omni-reader-mcp@1.7.0 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
86
100
  ```
87
101
 
88
102
  When an agent or script runs under a pty (stdin is still a TTY), declare non-interactive
@@ -90,7 +104,7 @@ mode explicitly with `--headless` (alias `--non-interactive`): no `--yes` is req
90
104
  stdin is never read:
91
105
 
92
106
  ```sh
93
- npx -y @cueai/omni-reader-mcp@1.5.5 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
107
+ npx -y @cueai/omni-reader-mcp@1.7.0 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
94
108
  ```
95
109
 
96
110
  ## Windows configuration
@@ -109,14 +123,14 @@ automatically; the second is the most robust when you configure by hand.
109
123
  1. **`cmd` + `npx` (what `setup` writes on Windows)** — `cmd.exe` is a real executable,
110
124
  so a client's no-shell spawn works:
111
125
  ```json
112
- { "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.5.5"] }
126
+ { "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.7.0"] }
113
127
  ```
114
128
  2. **`node` + the package entry (most robust)** — skips `npx` entirely; the absolute
115
129
  path must be a stable install you control:
116
130
  ```json
117
131
  { "command": "node", "args": ["C:\\path\\to\\node_modules\\@cueai\\omni-reader-mcp\\dist\\index.js"] }
118
132
  ```
119
- A deliberate local `npm install @cueai/omni-reader-mcp@1.5.5` gives you that stable
133
+ A deliberate local `npm install @cueai/omni-reader-mcp@1.7.0` gives you that stable
120
134
  path. Do not point the entry at an `_npx` cache directory — its hash subdirectory
121
135
  changes between installs.
122
136
  3. **Never use a session/timestamp directory** — such paths are cleaned up, and the
@@ -155,6 +169,8 @@ Configuration never writes the API Key in plaintext. Hermes uses native separate
155
169
 
156
170
  ## Agent calling rules
157
171
 
172
+ `parse` is the only first-call entry for both HTTP(S) URLs and local paths. Agents choose continuation tools automatically from the structured result instead of presenting a tool menu to the user.
173
+
158
174
  Agents pass the user-provided source string directly to `parse(source)`:
159
175
 
160
176
  - Only HTTP(S) is treated as a URL; a plain string is treated as a local path.
@@ -165,15 +181,40 @@ Agents pass the user-provided source string directly to `parse(source)`:
165
181
  - Prefer the existing `operation_id` for status recovery; never re-upload or duplicate a
166
182
  parse for a timeout.
167
183
 
168
- The public tools are fixed:
184
+ Use the result contract in this order:
185
+
186
+ ```text
187
+ Answer directly → use inline text when present; otherwise read_result
188
+ Find one section → read_outline, then pass its cursor to read_result
189
+ Read all content → read_result until next_cursor is absent
190
+ Deliver a file → save_result
191
+ ```
192
+
193
+ Outline navigation does not require `save_result`: call `read_outline`, then pass a selected
194
+ node cursor directly to `read_result`. `result_delivery="artifact"` is appropriate for saving, section navigation, multiple documents, or strict context control; omitted or `auto` preserves
195
+ inline delivery when possible. For multiple sources, use bounded concurrent independent `parse` calls and keep each operation/result handle separate. There is no `batch_parse` tool,
196
+ and Bridge does not invent one universal concurrency number before client evidence exists.
197
+
198
+ Client capabilities are classified exactly as `supported | unsupported | unknown`; they are
199
+ discovered from the actual initialize exchange, client documentation/settings, a local
200
+ non-billable harness, or explicit redacted config facts—not guessed from another MCP host.
201
+ Safe fallbacks are:
169
202
 
170
- - `parse`
171
- - `get_parse_status`
172
- - `cancel_parse`
173
- - `read_result`
174
- - `read_outline`
175
- - `discard_result`
176
- - `save_result`
203
+ - Tasks unknown → ordinary `parse` / `get_parse_status` polling.
204
+ - Roots unknown → process cwd and explicitly configured roots only.
205
+ - Host timeout unknown → retain the bounded 20-second status wait.
206
+ - Process cwd versus active workspace unknown → do not widen authorization; use cwd and
207
+ explicit roots until the client provides evidence.
208
+
209
+ The physical protocol surfaces stay fixed even though the user sees one Omni Reader:
210
+
211
+ - The remote-only connector advertises `parse`, `get_parse_status`, and `cancel_parse`.
212
+ - Bridge advertises those same three plus the local-artifact continuation tools
213
+ `read_result`, `read_outline`, `discard_result`, and `save_result`.
214
+
215
+ `parse` remains the sole first call. The other six Bridge tools are continuation and
216
+ lifecycle primitives selected from structured operation/result state; they are not modes
217
+ for the user to choose.
177
218
 
178
219
  Every tool returns `structuredContent` with a strict `outputSchema`, plus an equivalent
179
220
  fallback for clients that only read legacy MCP `content[].text`:
@@ -190,6 +231,8 @@ fallback for clients that only read legacy MCP `content[].text`:
190
231
  anchored at that heading, so a long result can be jumped into directly instead of only
191
232
  advancing sequentially through `next_cursor`. An empty or absent outline is reported
192
233
  explicitly, never silently — it never blocks reading the result itself with `read_result`;
234
+ - Text output remains Markdown and may contain headings, lists, GFM tables, and raw HTML tables.
235
+ It omits grounding/layout sidecars, not all textual structure. An empty outline means no recognized headings; it does not mean the text has no structure;
193
236
  - the `discard_result` text JSON explicitly returns `discarded`; never claim deletion on
194
237
  call success alone;
195
238
  - the `save_result` text JSON contains the written file `path` and `bytes` count; there is
@@ -261,36 +304,52 @@ satisfies the constraints.
261
304
  ## Commands
262
305
 
263
306
  ```sh
264
- npx -y @cueai/omni-reader-mcp@1.5.5 doctor
265
- npx -y @cueai/omni-reader-mcp@1.5.5 doctor --json
266
- npx -y @cueai/omni-reader-mcp@1.5.5 clean
267
- npx -y @cueai/omni-reader-mcp@1.5.5 uninstall --yes --json
307
+ npx -y @cueai/omni-reader-mcp@1.7.0 doctor
308
+ npx -y @cueai/omni-reader-mcp@1.7.0 doctor --json
309
+ npx -y @cueai/omni-reader-mcp@1.7.0 clean
310
+ npx -y @cueai/omni-reader-mcp@1.7.0 uninstall --yes --json
268
311
  ```
269
312
 
270
313
  Running the pinned version without a command starts the stdio MCP server:
271
314
 
272
315
  ```sh
273
- npx -y @cueai/omni-reader-mcp@1.5.5
316
+ npx -y @cueai/omni-reader-mcp@1.7.0
317
+ ```
318
+
319
+ Default `doctor --json` reports `inspection_scope: "current_process_env"`: its Key and
320
+ allowed-root facts describe the doctor process, not a separately running agent child. To
321
+ inspect one caller-selected JSON entry without scanning or writing configuration, use:
322
+
323
+ ```sh
324
+ npx -y @cueai/omni-reader-mcp@1.7.0 doctor --json --config-path /absolute/client-config.json --server-name omni-reader
274
325
  ```
275
326
 
276
- `doctor --json` returns package/npm/client adapter, Key present/absent, allowed-root
277
- safety status, the authenticated Cube control/configuration facts, artifacts, cache
278
- mode, onboarding, and reload status; it never prints the Key, private source paths,
279
- or content. The `endpoints.direct_upload` field is a fact about the release, not a
280
- probe: the granted data plane is reached only through a Cube grant and is never
327
+ The optional `explicit_config` block reports only closed redacted facts: entry/transport
328
+ shape, command basename/category, exact package version when derivable, Key configuration
329
+ shape, and allowed-root count/safety. It never resolves or prints a Key, uses a configured
330
+ Key for a network call, prints the config path, scans unrelated entries, or claims that the
331
+ running child process can use the selected entry.
332
+
333
+ `doctor --json` also returns package/npm/client adapter, authenticated Cube
334
+ control/configuration facts, artifacts, cache mode, onboarding, and reload status. The
335
+ `endpoints.direct_upload` field is a fact about the release, not a probe: the granted data
336
+ plane is reached only through a Cube grant and is never
281
337
  definitively "available" until a real local-file parse validates the route.
282
338
 
283
339
 
284
340
  ## Network diagnostics
285
341
 
286
- Run `npx -y @cueai/omni-reader-mcp@1.5.5 doctor --json` first. Diagnose failures by
342
+ Run `npx -y @cueai/omni-reader-mcp@1.7.0 doctor --json` first. Diagnose failures by
287
343
  stage instead of guessing an endpoint:
288
344
 
289
345
  | Failure | Stage | Meaning |
290
346
  |---|---|---|
291
347
  | `CUBE_UNAVAILABLE` | before upload | the control plane could not create a parse grant |
348
+ | `DIRECT_UPLOAD_UNAVAILABLE` | before upload | the service's direct-upload route is unavailable; this is not an account restriction, and HTTP 403 is the account-entitlement signal |
349
+ | `DETAIL_CAPABILITIES_UNAVAILABLE` | before grant | this service does not currently advertise grounded/layout parsing; use text only when Markdown without grounding/layout sidecars is acceptable |
350
+ | `UNSUPPORTED_DETAIL` | before upload | the requested parsing representation/profile is unavailable; do not retry unchanged or describe the account as text-only |
292
351
  | `PRINCIPAL_CONCURRENCY_LIMIT` | before upload | the principal already has the maximum active parses; wait for `retry_after`, then retry the same parse |
293
- | `BRIDGE_UPGRADE_REQUIRED` | before upload | this Bridge release is too old; install `@cueai/omni-reader-mcp@1.5.5` via the official setup, then retry the same parse |
352
+ | `BRIDGE_UPGRADE_REQUIRED` | before upload | this Bridge release is too old; install `@cueai/omni-reader-mcp@1.7.0` via the official setup, then retry the same parse |
294
353
  | a secure upload-stage failure | after grant creation | the file was granted, but the secure upload stage did not complete |
295
354
  | `CUBE_PROTOCOL_ERROR` | control-plane response | the response did not match the required contract |
296
355
  | `MCP error -32000: Connection closed` | before Bridge starts | the client launcher shape is invalid; see Windows configuration |
@@ -309,15 +368,16 @@ the same way from every client.
309
368
 
310
369
  ## Uninstall and rollback
311
370
 
312
- `uninstall --yes --json` removes only a trusted 1.5.4 or 1.5.5 Bridge entry, plus
371
+ `uninstall --yes --json` removes only a trusted 1.6.0 or 1.7.0 Bridge entry, plus
313
372
  the exact broken bare-`npx` Windows entry written by 1.5.1. When a matching trusted
314
373
  backup exists, it restores the original URL-only `omni-reader` entry. Uninstall never
315
374
  deletes user source files and never silently removes unexpired local results.
316
375
 
317
- To roll back from 1.5.5:
376
+ To roll back from 1.7.0 to 1.6.0:
318
377
 
319
- 1. stop recommending or installing that version;
378
+ 1. stop recommending or installing 1.7.0;
320
379
  2. run `uninstall --yes --json` to restore the trusted URL-only entry;
321
- 3. for already-uploaded operations, continue using status recovery so settlement and
380
+ 3. if the local facade is still required, run `npx -y @cueai/omni-reader-mcp@1.6.0 setup`;
381
+ 4. for already-uploaded operations, continue using status recovery so settlement and
322
382
  cleanup complete;
323
- 4. keep local results, or have the user explicitly run `discard_result` / `clean`.
383
+ 5. keep local results, or have the user explicitly run `discard_result` / `clean`.
@@ -109,8 +109,10 @@ export declare class ArtifactStore {
109
109
  static open(options?: ArtifactStoreOptions): Promise<ArtifactStore>;
110
110
  get rootDirectory(): string;
111
111
  createRetention(): LocalResultRetention;
112
+ preflightWrite(): Promise<void>;
112
113
  read(resultId: string, cursor?: string, maxBytes?: number): Promise<ArtifactReadResult>;
113
114
  readOutline(resultId: string): Promise<OutlineResult>;
115
+ mintReadCursor(resultId: string, byteOffset: number): Promise<string>;
114
116
  mintOutlineCursor(resultId: string, byteOffset: number): Promise<string>;
115
117
  exportResult(resultId: string): Promise<{
116
118
  path: string;
@@ -5,7 +5,7 @@ import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { z } from "zod";
7
7
  import { ARTIFACT_TTL_MS, INLINE_RESULT_MAX_BYTES, RESULT_CHUNK_MAX_BYTES } from "./constants.js";
8
- import { CursorCodec } from "./cursor.js";
8
+ import { CursorCodec, CursorCodecError } from "./cursor.js";
9
9
  import { OmniBridgeError } from "./errors.js";
10
10
  import { extractOutline } from "./outline.js";
11
11
  import { GROUNDING_SCHEMA_VERSION, RESULT_BUNDLE_PROTOCOL_VERSION } from "./protocol.js";
@@ -28,11 +28,11 @@ function artifactError(code, message, retryable = false) {
28
28
  return new OmniBridgeError({
29
29
  code,
30
30
  message,
31
- operationCreated: true,
32
- fileUploaded: true,
33
- parserStarted: true,
34
- billed: true,
35
- contentReleased: true,
31
+ operationCreated: false,
32
+ fileUploaded: false,
33
+ parserStarted: false,
34
+ billed: false,
35
+ contentReleased: false,
36
36
  retryable,
37
37
  });
38
38
  }
@@ -48,6 +48,17 @@ function cacheError(code, message) {
48
48
  retryable: false,
49
49
  });
50
50
  }
51
+ function decodeCursor(action) {
52
+ try {
53
+ return action();
54
+ }
55
+ catch (error) {
56
+ if (error instanceof CursorCodecError) {
57
+ throw artifactError(error.code, error.message);
58
+ }
59
+ throw error;
60
+ }
61
+ }
51
62
  function errno(error, code) {
52
63
  return error instanceof Error && error.code === code;
53
64
  }
@@ -475,6 +486,27 @@ export class ArtifactStore {
475
486
  this.#requireOpen();
476
487
  return new LocalResultRetention(this);
477
488
  }
489
+ async preflightWrite() {
490
+ this.#requireOpen();
491
+ const probePath = path.join(this.#resultsDirectory, `.tmp-preflight-${randomBytes(18).toString("base64url")}`);
492
+ let handle;
493
+ try {
494
+ handle = await open(probePath, "wx", 0o600);
495
+ await handle.writeFile("omni-artifact-preflight-v1\n", "utf8");
496
+ await handle.sync();
497
+ await handle.close();
498
+ handle = undefined;
499
+ await removeIfPresent(probePath);
500
+ await syncDirectory(this.#resultsDirectory);
501
+ }
502
+ catch (error) {
503
+ await handle?.close().catch(() => undefined);
504
+ await removeIfPresent(probePath).catch(() => false);
505
+ if (error instanceof OmniBridgeError)
506
+ throw error;
507
+ throw artifactError("ARTIFACT_PREFLIGHT_FAILED", "The local result cache is not writable.", true);
508
+ }
509
+ }
478
510
  async read(resultId, cursor, maxBytes = RESULT_CHUNK_MAX_BYTES) {
479
511
  this.#requireOpen();
480
512
  let metadata;
@@ -496,7 +528,7 @@ export class ArtifactStore {
496
528
  }
497
529
  let offset = 0;
498
530
  if (cursor !== undefined) {
499
- const payload = this.#cursor.decode(cursor);
531
+ const payload = decodeCursor(() => this.#cursor.decode(cursor));
500
532
  if (payload.resultId !== resultId || payload.expiresAt !== metadata.expiresAt) {
501
533
  throw artifactError("RESULT_CURSOR_MISMATCH", "The result cursor does not match this artifact.");
502
534
  }
@@ -559,7 +591,7 @@ export class ArtifactStore {
559
591
  }
560
592
  return extractOutline(fullText);
561
593
  }
562
- async mintOutlineCursor(resultId, byteOffset) {
594
+ async mintReadCursor(resultId, byteOffset) {
563
595
  this.#requireOpen();
564
596
  const metadata = await this.#loadMetadata(resultId);
565
597
  if (Date.parse(metadata.expiresAt) <= this.#now().getTime()) {
@@ -567,10 +599,13 @@ export class ArtifactStore {
567
599
  throw artifactError("RESULT_EXPIRED", "The local result artifact has expired.");
568
600
  }
569
601
  if (!Number.isSafeInteger(byteOffset) || byteOffset < 0 || byteOffset > metadata.resultBytes) {
570
- throw artifactError("INVALID_RESULT_CURSOR", "The outline node offset is invalid.");
602
+ throw artifactError("INVALID_RESULT_CURSOR", "The result cursor offset is invalid.");
571
603
  }
572
604
  return this.#cursor.encode({ resultId, offset: byteOffset, expiresAt: metadata.expiresAt });
573
605
  }
606
+ async mintOutlineCursor(resultId, byteOffset) {
607
+ return this.mintReadCursor(resultId, byteOffset);
608
+ }
574
609
  // The full content text in one read, regardless of storage shape (a flat
575
610
  // v1 artifact, or a v2 bundle's "content" part). save_result's only
576
611
  // consumer: read_result's chunked/cursor contract stays the single way an
@@ -657,7 +692,7 @@ export class ArtifactStore {
657
692
  // against the actual bytes before any chunk is returned.
658
693
  async readBundlePart(resultId, cursor, maxBytes = RESULT_CHUNK_MAX_BYTES) {
659
694
  this.#requireOpen();
660
- const payload = this.#cursor.decodeBundle(cursor);
695
+ const payload = decodeCursor(() => this.#cursor.decodeBundle(cursor));
661
696
  if (payload.resultId !== resultId) {
662
697
  throw artifactError("RESULT_CURSOR_MISMATCH", "The result cursor does not match this artifact.");
663
698
  }
@@ -1,6 +1,9 @@
1
1
  import { z } from "zod";
2
+ import { type OmniSourceKind } from "./errors.js";
2
3
  export declare const READER_CAPABILITIES_PROTOCOL = "omni.reader_capabilities.v1";
4
+ export declare const READER_CAPABILITIES_V2_PROTOCOL = "omni.reader_capabilities.v2";
3
5
  export type RequestedDetail = "grounded" | "layout";
6
+ export type RequestedDirectDetailV2 = "text" | RequestedDetail;
4
7
  declare const directProfileSchema: z.ZodObject<{
5
8
  profile: z.ZodLiteral<"omni.direct_grounding.v1">;
6
9
  grant_protocol: z.ZodLiteral<"omni.parse_grant.v3">;
@@ -78,15 +81,139 @@ declare const urlProfileSchema: z.ZodObject<{
78
81
  details: ["grounded", "layout"];
79
82
  max_result_bytes: 16777216;
80
83
  }>;
84
+ export declare const DIRECT_TEXT_BILLING_PROFILE: {
85
+ readonly profile: "omni.direct_text_billing.v1";
86
+ readonly grant_protocol: "omni.parse_grant.v4";
87
+ readonly stream_protocol: "omni.granted_parse_stream.v3";
88
+ readonly operation_protocol: "omni.direct_operation.v3";
89
+ readonly settlement_protocol: "omni.grant_settlement.v5";
90
+ readonly release_protocol: "omni.release_decision.v3";
91
+ readonly settlement_journal_protocol: "omni.direct_settlement_journal.v3";
92
+ readonly usage_protocol: "omni_parse_usage.v2";
93
+ readonly billing_protocol: "omni_billing.v2";
94
+ readonly bridge_protocol: "omni.local_bridge_tools.v5";
95
+ readonly details: readonly ["text"];
96
+ readonly max_result_bytes: 268435456;
97
+ };
98
+ export declare const DIRECT_GROUNDING_BILLING_PROFILE: {
99
+ readonly profile: "omni.direct_grounding_billing.v1";
100
+ readonly grant_protocol: "omni.parse_grant.v4";
101
+ readonly stream_protocol: "omni.granted_parse_stream.v3";
102
+ readonly operation_protocol: "omni.direct_operation.v3";
103
+ readonly settlement_protocol: "omni.grant_settlement.v5";
104
+ readonly release_protocol: "omni.release_decision.v3";
105
+ readonly settlement_journal_protocol: "omni.direct_settlement_journal.v3";
106
+ readonly usage_protocol: "omni_parse_usage.v2";
107
+ readonly billing_protocol: "omni_billing.v2";
108
+ readonly bridge_protocol: "omni.local_bridge_tools.v5";
109
+ readonly bundle_protocol: "omni.result_bundle.v1";
110
+ readonly grounding_schema: "omni.grounding.v1";
111
+ readonly details: readonly ["grounded", "layout"];
112
+ readonly max_result_bytes: 67108864;
113
+ };
114
+ declare const directProfileV2Schema: z.ZodDiscriminatedUnion<"profile", [z.ZodObject<{
115
+ profile: z.ZodLiteral<"omni.direct_text_billing.v1">;
116
+ grant_protocol: z.ZodLiteral<"omni.parse_grant.v4">;
117
+ stream_protocol: z.ZodLiteral<"omni.granted_parse_stream.v3">;
118
+ operation_protocol: z.ZodLiteral<"omni.direct_operation.v3">;
119
+ settlement_protocol: z.ZodLiteral<"omni.grant_settlement.v5">;
120
+ release_protocol: z.ZodLiteral<"omni.release_decision.v3">;
121
+ settlement_journal_protocol: z.ZodLiteral<"omni.direct_settlement_journal.v3">;
122
+ usage_protocol: z.ZodLiteral<"omni_parse_usage.v2">;
123
+ billing_protocol: z.ZodLiteral<"omni_billing.v2">;
124
+ bridge_protocol: z.ZodLiteral<"omni.local_bridge_tools.v5">;
125
+ details: z.ZodTuple<[z.ZodLiteral<"text">], null>;
126
+ max_result_bytes: z.ZodLiteral<268435456>;
127
+ }, "strict", z.ZodTypeAny, {
128
+ profile: "omni.direct_text_billing.v1";
129
+ grant_protocol: "omni.parse_grant.v4";
130
+ stream_protocol: "omni.granted_parse_stream.v3";
131
+ operation_protocol: "omni.direct_operation.v3";
132
+ settlement_protocol: "omni.grant_settlement.v5";
133
+ release_protocol: "omni.release_decision.v3";
134
+ settlement_journal_protocol: "omni.direct_settlement_journal.v3";
135
+ usage_protocol: "omni_parse_usage.v2";
136
+ billing_protocol: "omni_billing.v2";
137
+ bridge_protocol: "omni.local_bridge_tools.v5";
138
+ details: ["text"];
139
+ max_result_bytes: 268435456;
140
+ }, {
141
+ profile: "omni.direct_text_billing.v1";
142
+ grant_protocol: "omni.parse_grant.v4";
143
+ stream_protocol: "omni.granted_parse_stream.v3";
144
+ operation_protocol: "omni.direct_operation.v3";
145
+ settlement_protocol: "omni.grant_settlement.v5";
146
+ release_protocol: "omni.release_decision.v3";
147
+ settlement_journal_protocol: "omni.direct_settlement_journal.v3";
148
+ usage_protocol: "omni_parse_usage.v2";
149
+ billing_protocol: "omni_billing.v2";
150
+ bridge_protocol: "omni.local_bridge_tools.v5";
151
+ details: ["text"];
152
+ max_result_bytes: 268435456;
153
+ }>, z.ZodObject<{
154
+ profile: z.ZodLiteral<"omni.direct_grounding_billing.v1">;
155
+ grant_protocol: z.ZodLiteral<"omni.parse_grant.v4">;
156
+ stream_protocol: z.ZodLiteral<"omni.granted_parse_stream.v3">;
157
+ operation_protocol: z.ZodLiteral<"omni.direct_operation.v3">;
158
+ settlement_protocol: z.ZodLiteral<"omni.grant_settlement.v5">;
159
+ release_protocol: z.ZodLiteral<"omni.release_decision.v3">;
160
+ settlement_journal_protocol: z.ZodLiteral<"omni.direct_settlement_journal.v3">;
161
+ usage_protocol: z.ZodLiteral<"omni_parse_usage.v2">;
162
+ billing_protocol: z.ZodLiteral<"omni_billing.v2">;
163
+ bridge_protocol: z.ZodLiteral<"omni.local_bridge_tools.v5">;
164
+ bundle_protocol: z.ZodLiteral<"omni.result_bundle.v1">;
165
+ grounding_schema: z.ZodLiteral<"omni.grounding.v1">;
166
+ details: z.ZodTuple<[z.ZodLiteral<"grounded">, z.ZodLiteral<"layout">], null>;
167
+ max_result_bytes: z.ZodLiteral<67108864>;
168
+ }, "strict", z.ZodTypeAny, {
169
+ profile: "omni.direct_grounding_billing.v1";
170
+ grant_protocol: "omni.parse_grant.v4";
171
+ stream_protocol: "omni.granted_parse_stream.v3";
172
+ operation_protocol: "omni.direct_operation.v3";
173
+ settlement_protocol: "omni.grant_settlement.v5";
174
+ release_protocol: "omni.release_decision.v3";
175
+ settlement_journal_protocol: "omni.direct_settlement_journal.v3";
176
+ usage_protocol: "omni_parse_usage.v2";
177
+ billing_protocol: "omni_billing.v2";
178
+ bridge_protocol: "omni.local_bridge_tools.v5";
179
+ bundle_protocol: "omni.result_bundle.v1";
180
+ grounding_schema: "omni.grounding.v1";
181
+ details: ["grounded", "layout"];
182
+ max_result_bytes: 67108864;
183
+ }, {
184
+ profile: "omni.direct_grounding_billing.v1";
185
+ grant_protocol: "omni.parse_grant.v4";
186
+ stream_protocol: "omni.granted_parse_stream.v3";
187
+ operation_protocol: "omni.direct_operation.v3";
188
+ settlement_protocol: "omni.grant_settlement.v5";
189
+ release_protocol: "omni.release_decision.v3";
190
+ settlement_journal_protocol: "omni.direct_settlement_journal.v3";
191
+ usage_protocol: "omni_parse_usage.v2";
192
+ billing_protocol: "omni_billing.v2";
193
+ bridge_protocol: "omni.local_bridge_tools.v5";
194
+ bundle_protocol: "omni.result_bundle.v1";
195
+ grounding_schema: "omni.grounding.v1";
196
+ details: ["grounded", "layout"];
197
+ max_result_bytes: 67108864;
198
+ }>]>;
81
199
  export type DirectProfileV1 = z.infer<typeof directProfileSchema>;
82
200
  export type UrlProfileV1 = z.infer<typeof urlProfileSchema>;
201
+ export type DirectProfileV2 = z.infer<typeof directProfileV2Schema>;
202
+ export type DirectProfile = DirectProfileV1["profile"] | DirectProfileV2["profile"];
83
203
  export interface ReaderCapabilitiesV1 {
84
204
  readonly protocol_version: typeof READER_CAPABILITIES_PROTOCOL;
85
205
  readonly expires_at: Date;
86
206
  readonly direct_profiles: readonly DirectProfileV1[];
87
207
  readonly url_profiles: readonly UrlProfileV1[];
88
208
  }
209
+ export interface ReaderCapabilitiesV2 {
210
+ readonly protocol_version: typeof READER_CAPABILITIES_V2_PROTOCOL;
211
+ readonly expires_at: Date;
212
+ readonly direct_profiles: readonly DirectProfileV2[];
213
+ }
89
214
  export declare function parseReaderCapabilities(value: unknown, now: Date): ReaderCapabilitiesV1;
90
- export declare function selectDirectProfile(value: ReaderCapabilitiesV1, detail: RequestedDetail): DirectProfileV1;
91
- export declare function selectUrlProfile(value: ReaderCapabilitiesV1, detail: RequestedDetail): UrlProfileV1;
215
+ export declare function selectDirectProfile(value: ReaderCapabilitiesV1, detail: RequestedDetail, sourceKind?: OmniSourceKind): DirectProfileV1;
216
+ export declare function selectUrlProfile(value: ReaderCapabilitiesV1, detail: RequestedDetail, sourceKind?: OmniSourceKind): UrlProfileV1;
217
+ export declare function parseReaderCapabilitiesV2(value: unknown, now: Date): ReaderCapabilitiesV2;
218
+ export declare function selectDirectProfileV2(value: ReaderCapabilitiesV2, detail: RequestedDirectDetailV2, sourceKind?: OmniSourceKind): DirectProfileV2;
92
219
  export {};