@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.
- package/README.md +106 -46
- package/dist/artifact-store.d.ts +2 -0
- package/dist/artifact-store.js +45 -10
- package/dist/capabilities.d.ts +129 -2
- package/dist/capabilities.js +122 -19
- package/dist/cli/agent-config.js +2 -2
- package/dist/cli/arguments.d.ts +8 -4
- package/dist/cli/arguments.js +62 -7
- package/dist/cli/config-inspection.d.ts +59 -0
- package/dist/cli/config-inspection.js +307 -0
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.js +37 -2
- package/dist/cli/setup.js +13 -2
- package/dist/constants.d.ts +6 -1
- package/dist/constants.js +9 -4
- package/dist/cube-client.d.ts +4 -1
- package/dist/cube-client.js +286 -32
- package/dist/cursor.d.ts +4 -0
- package/dist/cursor.js +11 -13
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +15 -0
- package/dist/iiis-client.d.ts +33 -2
- package/dist/iiis-client.js +368 -40
- package/dist/index.js +10 -1
- package/dist/operation-journal.d.ts +17 -1
- package/dist/operation-journal.js +260 -15
- package/dist/operation-manager.d.ts +6 -2
- package/dist/operation-manager.js +448 -89
- package/dist/path-normalization.d.ts +5 -0
- package/dist/path-normalization.js +25 -0
- package/dist/path-security.d.ts +2 -1
- package/dist/path-security.js +49 -28
- package/dist/protocol.d.ts +10 -2
- package/dist/protocol.js +23 -7
- package/dist/remote-client.js +3 -13
- package/dist/result-contract.d.ts +76 -32
- package/dist/result-contract.js +121 -5
- package/dist/task-runtime.d.ts +3 -2
- package/dist/task-runtime.js +2 -2
- package/dist/tools.d.ts +4 -0
- package/dist/tools.js +41 -31
- 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.
|
|
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
|
-
##
|
|
54
|
+
## Billing and free credits
|
|
55
55
|
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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.
|
|
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.
|
|
84
|
-
npx -y @cueai/omni-reader-mcp@1.
|
|
85
|
-
npx -y @cueai/omni-reader-mcp@1.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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.
|
|
265
|
-
npx -y @cueai/omni-reader-mcp@1.
|
|
266
|
-
npx -y @cueai/omni-reader-mcp@1.
|
|
267
|
-
npx -y @cueai/omni-reader-mcp@1.
|
|
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.
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
376
|
+
To roll back from 1.7.0 to 1.6.0:
|
|
318
377
|
|
|
319
|
-
1. stop recommending or installing
|
|
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.
|
|
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
|
-
|
|
383
|
+
5. keep local results, or have the user explicitly run `discard_result` / `clean`.
|
package/dist/artifact-store.d.ts
CHANGED
|
@@ -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;
|
package/dist/artifact-store.js
CHANGED
|
@@ -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:
|
|
32
|
-
fileUploaded:
|
|
33
|
-
parserStarted:
|
|
34
|
-
billed:
|
|
35
|
-
contentReleased:
|
|
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
|
|
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
|
|
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
|
}
|
package/dist/capabilities.d.ts
CHANGED
|
@@ -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 {};
|