@cueai/omni-reader-mcp 1.6.0 → 1.7.1

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 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.
@@ -47,18 +47,40 @@ agent workspace remains the default allowed scope.
47
47
 
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
- error means the running Bridge release is not accepted for direct local-file parsing —
51
- install `@cueai/omni-reader-mcp@1.6.0` using the official setup instructions, then retry the
52
- same parse. Always run `doctor --json` first when diagnosing a parse failure.
53
-
54
- ## Free credits
50
+ error means the service does not accept the running Bridge release for direct local-file
51
+ parsing. Install the latest published `@cueai/omni-reader-mcp` release using the official
52
+ setup instructions, then retry once. If you are already running the latest published release,
53
+ do not reinstall or retry; run `doctor --json` and ask the service operator to verify Bridge
54
+ admission.
55
+
56
+ ## Billing and free credits
57
+
58
+ The server-side [onboarding policy](https://cuecue.cn/api/v1/billing/public/onboarding-policy)
59
+ is the authority for the current first-registration gift and daily grant. When reachable,
60
+ `doctor` reports those live policy values; when unavailable, it reports that status instead
61
+ of copying a stale number.
62
+
63
+ A terminal URL or local-file result may carry the operation-local settlement snapshot:
64
+
65
+ ```json
66
+ {
67
+ "billing": {
68
+ "credits_charged": 0.134,
69
+ "credits_remaining": 42.866
70
+ }
71
+ }
72
+ ```
55
73
 
56
- The server-side onboarding policy is the authority for the current first-registration gift
57
- and daily grant. When reachable, `doctor` reports those live policy values; when unavailable,
58
- it reports that status instead of copying a stale number.
74
+ The numbers above illustrate the response shape, not a price quote. The settled result is authoritative.
75
+ `credits_charged` is the amount deducted for that operation and
76
+ `credits_remaining` is the balance in the same immutable settlement snapshot. Bridge never
77
+ replaces it with a later balance lookup. Processing results have no billing block. New direct
78
+ canceled, failed, unsupported, or denied terminals are uncharged and carry no billing block.
79
+ Navigation and status calls preserve the same settled facts without creating another usage or
80
+ settlement identity.
59
81
 
60
82
  Bridge does not publish static document-page or media-duration conversions. Rates can change,
61
- and Phase 1 has no public rate response carrying an `effective_at` timestamp. Use only current
83
+ and there is no public rate response carrying an `effective_at` timestamp. Use only current
62
84
  authoritative billing/policy facts rather than estimating a charge from copied arithmetic.
63
85
 
64
86
  ## Installation and configuration
@@ -66,7 +88,7 @@ authoritative billing/policy facts rather than estimating a charge from copied a
66
88
  Always use an audited exact version, never an implicit `latest`:
67
89
 
68
90
  ```sh
69
- npx -y @cueai/omni-reader-mcp@1.6.0 setup
91
+ npx -y @cueai/omni-reader-mcp@1.7.1 setup
70
92
  ```
71
93
 
72
94
  The interactive setup supports Hermes, Cursor, Claude Desktop, and generic stdio
@@ -74,9 +96,9 @@ configuration. Non-interactive installation uses the same argument parsing and w
74
96
  logic:
75
97
 
76
98
  ```sh
77
- npx -y @cueai/omni-reader-mcp@1.6.0 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
78
- npx -y @cueai/omni-reader-mcp@1.6.0 setup --client cursor --add-root /absolute/minimum/root --yes --json
79
- npx -y @cueai/omni-reader-mcp@1.6.0 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
99
+ npx -y @cueai/omni-reader-mcp@1.7.1 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
100
+ npx -y @cueai/omni-reader-mcp@1.7.1 setup --client cursor --add-root /absolute/minimum/root --yes --json
101
+ npx -y @cueai/omni-reader-mcp@1.7.1 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
80
102
  ```
81
103
 
82
104
  When an agent or script runs under a pty (stdin is still a TTY), declare non-interactive
@@ -84,7 +106,7 @@ mode explicitly with `--headless` (alias `--non-interactive`): no `--yes` is req
84
106
  stdin is never read:
85
107
 
86
108
  ```sh
87
- npx -y @cueai/omni-reader-mcp@1.6.0 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
109
+ npx -y @cueai/omni-reader-mcp@1.7.1 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
88
110
  ```
89
111
 
90
112
  ## Windows configuration
@@ -103,14 +125,14 @@ automatically; the second is the most robust when you configure by hand.
103
125
  1. **`cmd` + `npx` (what `setup` writes on Windows)** — `cmd.exe` is a real executable,
104
126
  so a client's no-shell spawn works:
105
127
  ```json
106
- { "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.6.0"] }
128
+ { "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.7.1"] }
107
129
  ```
108
130
  2. **`node` + the package entry (most robust)** — skips `npx` entirely; the absolute
109
131
  path must be a stable install you control:
110
132
  ```json
111
133
  { "command": "node", "args": ["C:\\path\\to\\node_modules\\@cueai\\omni-reader-mcp\\dist\\index.js"] }
112
134
  ```
113
- A deliberate local `npm install @cueai/omni-reader-mcp@1.6.0` gives you that stable
135
+ A deliberate local `npm install @cueai/omni-reader-mcp@1.7.1` gives you that stable
114
136
  path. Do not point the entry at an `_npx` cache directory — its hash subdirectory
115
137
  changes between installs.
116
138
  3. **Never use a session/timestamp directory** — such paths are cleaned up, and the
@@ -149,6 +171,8 @@ Configuration never writes the API Key in plaintext. Hermes uses native separate
149
171
 
150
172
  ## Agent calling rules
151
173
 
174
+ `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.
175
+
152
176
  Agents pass the user-provided source string directly to `parse(source)`:
153
177
 
154
178
  - Only HTTP(S) is treated as a URL; a plain string is treated as a local path.
@@ -184,15 +208,15 @@ Safe fallbacks are:
184
208
  - Process cwd versus active workspace unknown → do not widen authorization; use cwd and
185
209
  explicit roots until the client provides evidence.
186
210
 
187
- The public tools are fixed:
211
+ The physical protocol surfaces stay fixed even though the user sees one Omni Reader:
212
+
213
+ - The remote-only connector advertises `parse`, `get_parse_status`, and `cancel_parse`.
214
+ - Bridge advertises those same three plus the local-artifact continuation tools
215
+ `read_result`, `read_outline`, `discard_result`, and `save_result`.
188
216
 
189
- - `parse`
190
- - `get_parse_status`
191
- - `cancel_parse`
192
- - `read_result`
193
- - `read_outline`
194
- - `discard_result`
195
- - `save_result`
217
+ `parse` remains the sole first call. The other six Bridge tools are continuation and
218
+ lifecycle primitives selected from structured operation/result state; they are not modes
219
+ for the user to choose.
196
220
 
197
221
  Every tool returns `structuredContent` with a strict `outputSchema`, plus an equivalent
198
222
  fallback for clients that only read legacy MCP `content[].text`:
@@ -209,6 +233,8 @@ fallback for clients that only read legacy MCP `content[].text`:
209
233
  anchored at that heading, so a long result can be jumped into directly instead of only
210
234
  advancing sequentially through `next_cursor`. An empty or absent outline is reported
211
235
  explicitly, never silently — it never blocks reading the result itself with `read_result`;
236
+ - Text output remains Markdown and may contain headings, lists, GFM tables, and raw HTML tables.
237
+ 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;
212
238
  - the `discard_result` text JSON explicitly returns `discarded`; never claim deletion on
213
239
  call success alone;
214
240
  - the `save_result` text JSON contains the written file `path` and `bytes` count; there is
@@ -280,16 +306,16 @@ satisfies the constraints.
280
306
  ## Commands
281
307
 
282
308
  ```sh
283
- npx -y @cueai/omni-reader-mcp@1.6.0 doctor
284
- npx -y @cueai/omni-reader-mcp@1.6.0 doctor --json
285
- npx -y @cueai/omni-reader-mcp@1.6.0 clean
286
- npx -y @cueai/omni-reader-mcp@1.6.0 uninstall --yes --json
309
+ npx -y @cueai/omni-reader-mcp@1.7.1 doctor
310
+ npx -y @cueai/omni-reader-mcp@1.7.1 doctor --json
311
+ npx -y @cueai/omni-reader-mcp@1.7.1 clean
312
+ npx -y @cueai/omni-reader-mcp@1.7.1 uninstall --yes --json
287
313
  ```
288
314
 
289
315
  Running the pinned version without a command starts the stdio MCP server:
290
316
 
291
317
  ```sh
292
- npx -y @cueai/omni-reader-mcp@1.6.0
318
+ npx -y @cueai/omni-reader-mcp@1.7.1
293
319
  ```
294
320
 
295
321
  Default `doctor --json` reports `inspection_scope: "current_process_env"`: its Key and
@@ -297,7 +323,7 @@ allowed-root facts describe the doctor process, not a separately running agent c
297
323
  inspect one caller-selected JSON entry without scanning or writing configuration, use:
298
324
 
299
325
  ```sh
300
- npx -y @cueai/omni-reader-mcp@1.6.0 doctor --json --config-path /absolute/client-config.json --server-name omni-reader
326
+ npx -y @cueai/omni-reader-mcp@1.7.1 doctor --json --config-path /absolute/client-config.json --server-name omni-reader
301
327
  ```
302
328
 
303
329
  The optional `explicit_config` block reports only closed redacted facts: entry/transport
@@ -315,14 +341,17 @@ definitively "available" until a real local-file parse validates the route.
315
341
 
316
342
  ## Network diagnostics
317
343
 
318
- Run `npx -y @cueai/omni-reader-mcp@1.6.0 doctor --json` first. Diagnose failures by
344
+ Run `npx -y @cueai/omni-reader-mcp@1.7.1 doctor --json` first. Diagnose failures by
319
345
  stage instead of guessing an endpoint:
320
346
 
321
347
  | Failure | Stage | Meaning |
322
348
  |---|---|---|
323
349
  | `CUBE_UNAVAILABLE` | before upload | the control plane could not create a parse grant |
350
+ | `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 |
351
+ | `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 |
352
+ | `UNSUPPORTED_DETAIL` | before upload | the requested parsing representation/profile is unavailable; do not retry unchanged or describe the account as text-only |
324
353
  | `PRINCIPAL_CONCURRENCY_LIMIT` | before upload | the principal already has the maximum active parses; wait for `retry_after`, then retry the same parse |
325
- | `BRIDGE_UPGRADE_REQUIRED` | before upload | this Bridge release is too old; install `@cueai/omni-reader-mcp@1.6.0` via the official setup, then retry the same parse |
354
+ | `BRIDGE_UPGRADE_REQUIRED` | before upload | install the latest published `@cueai/omni-reader-mcp` release, then retry once; if already running latest, do not reinstall or retry—run `doctor --json` and ask the service operator to verify Bridge admission |
326
355
  | a secure upload-stage failure | after grant creation | the file was granted, but the secure upload stage did not complete |
327
356
  | `CUBE_PROTOCOL_ERROR` | control-plane response | the response did not match the required contract |
328
357
  | `MCP error -32000: Connection closed` | before Bridge starts | the client launcher shape is invalid; see Windows configuration |
@@ -341,16 +370,16 @@ the same way from every client.
341
370
 
342
371
  ## Uninstall and rollback
343
372
 
344
- `uninstall --yes --json` removes only a trusted 1.5.5 or 1.6.0 Bridge entry, plus
373
+ `uninstall --yes --json` removes only a trusted 1.7.0 or 1.7.1 Bridge entry, plus
345
374
  the exact broken bare-`npx` Windows entry written by 1.5.1. When a matching trusted
346
375
  backup exists, it restores the original URL-only `omni-reader` entry. Uninstall never
347
376
  deletes user source files and never silently removes unexpired local results.
348
377
 
349
- To roll back from 1.6.0 to 1.5.5:
378
+ To roll back from 1.7.1 to 1.7.0:
350
379
 
351
- 1. stop recommending or installing 1.6.0;
380
+ 1. stop recommending or installing 1.7.1;
352
381
  2. run `uninstall --yes --json` to restore the trusted URL-only entry;
353
- 3. if the local facade is still required, run `npx -y @cueai/omni-reader-mcp@1.5.5 setup`;
382
+ 3. if the local facade is still required, run `npx -y @cueai/omni-reader-mcp@1.7.0 setup`;
354
383
  4. for already-uploaded operations, continue using status recovery so settlement and
355
384
  cleanup complete;
356
385
  5. keep local results, or have the user explicitly run `discard_result` / `clean`.
@@ -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 {};
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
- import { OmniBridgeError } from "./errors.js";
2
+ import { OmniBridgeError, unsupportedDetailError, } from "./errors.js";
3
3
  export const READER_CAPABILITIES_PROTOCOL = "omni.reader_capabilities.v1";
4
+ export const READER_CAPABILITIES_V2_PROTOCOL = "omni.reader_capabilities.v2";
4
5
  // Closed consumer-side schema for `omni.reader_capabilities.v1` (D2-D item 4).
5
6
  // Objects/arrays are closed: profile names and every tuple member are exact
6
7
  // literals, `details` is the exact ordered tuple ["grounded", "layout"], and a
@@ -40,6 +41,74 @@ const urlProfileSchema = z
40
41
  max_result_bytes: z.literal(16777216),
41
42
  })
42
43
  .strict();
44
+ export const DIRECT_TEXT_BILLING_PROFILE = {
45
+ profile: "omni.direct_text_billing.v1",
46
+ grant_protocol: "omni.parse_grant.v4",
47
+ stream_protocol: "omni.granted_parse_stream.v3",
48
+ operation_protocol: "omni.direct_operation.v3",
49
+ settlement_protocol: "omni.grant_settlement.v5",
50
+ release_protocol: "omni.release_decision.v3",
51
+ settlement_journal_protocol: "omni.direct_settlement_journal.v3",
52
+ usage_protocol: "omni_parse_usage.v2",
53
+ billing_protocol: "omni_billing.v2",
54
+ bridge_protocol: "omni.local_bridge_tools.v5",
55
+ details: ["text"],
56
+ max_result_bytes: 268435456,
57
+ };
58
+ export const DIRECT_GROUNDING_BILLING_PROFILE = {
59
+ profile: "omni.direct_grounding_billing.v1",
60
+ grant_protocol: "omni.parse_grant.v4",
61
+ stream_protocol: "omni.granted_parse_stream.v3",
62
+ operation_protocol: "omni.direct_operation.v3",
63
+ settlement_protocol: "omni.grant_settlement.v5",
64
+ release_protocol: "omni.release_decision.v3",
65
+ settlement_journal_protocol: "omni.direct_settlement_journal.v3",
66
+ usage_protocol: "omni_parse_usage.v2",
67
+ billing_protocol: "omni_billing.v2",
68
+ bridge_protocol: "omni.local_bridge_tools.v5",
69
+ bundle_protocol: "omni.result_bundle.v1",
70
+ grounding_schema: "omni.grounding.v1",
71
+ details: ["grounded", "layout"],
72
+ max_result_bytes: 67108864,
73
+ };
74
+ const directTextBillingProfileSchema = z
75
+ .object({
76
+ profile: z.literal(DIRECT_TEXT_BILLING_PROFILE.profile),
77
+ grant_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.grant_protocol),
78
+ stream_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.stream_protocol),
79
+ operation_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.operation_protocol),
80
+ settlement_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.settlement_protocol),
81
+ release_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.release_protocol),
82
+ settlement_journal_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.settlement_journal_protocol),
83
+ usage_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.usage_protocol),
84
+ billing_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.billing_protocol),
85
+ bridge_protocol: z.literal(DIRECT_TEXT_BILLING_PROFILE.bridge_protocol),
86
+ details: z.tuple([z.literal("text")]),
87
+ max_result_bytes: z.literal(DIRECT_TEXT_BILLING_PROFILE.max_result_bytes),
88
+ })
89
+ .strict();
90
+ const directGroundingBillingProfileSchema = z
91
+ .object({
92
+ profile: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.profile),
93
+ grant_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.grant_protocol),
94
+ stream_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.stream_protocol),
95
+ operation_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.operation_protocol),
96
+ settlement_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.settlement_protocol),
97
+ release_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.release_protocol),
98
+ settlement_journal_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.settlement_journal_protocol),
99
+ usage_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.usage_protocol),
100
+ billing_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.billing_protocol),
101
+ bridge_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.bridge_protocol),
102
+ bundle_protocol: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.bundle_protocol),
103
+ grounding_schema: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.grounding_schema),
104
+ details: z.tuple([z.literal("grounded"), z.literal("layout")]),
105
+ max_result_bytes: z.literal(DIRECT_GROUNDING_BILLING_PROFILE.max_result_bytes),
106
+ })
107
+ .strict();
108
+ const directProfileV2Schema = z.discriminatedUnion("profile", [
109
+ directTextBillingProfileSchema,
110
+ directGroundingBillingProfileSchema,
111
+ ]);
43
112
  const readerCapabilitiesSchema = z
44
113
  .object({
45
114
  protocol_version: z.literal(READER_CAPABILITIES_PROTOCOL),
@@ -48,6 +117,13 @@ const readerCapabilitiesSchema = z
48
117
  url_profiles: z.array(urlProfileSchema),
49
118
  })
50
119
  .strict();
120
+ const readerCapabilitiesV2Schema = z
121
+ .object({
122
+ protocol_version: z.literal(READER_CAPABILITIES_V2_PROTOCOL),
123
+ expires_at: z.string().datetime({ offset: true }),
124
+ direct_profiles: z.array(directProfileV2Schema).length(2),
125
+ })
126
+ .strict();
51
127
  function invalidCapabilities() {
52
128
  return new OmniBridgeError({
53
129
  code: "INVALID_READER_CAPABILITIES",
@@ -61,20 +137,6 @@ function invalidCapabilities() {
61
137
  retryable: false,
62
138
  });
63
139
  }
64
- function unsupportedDetail() {
65
- return new OmniBridgeError({
66
- code: "UNSUPPORTED_DETAIL",
67
- message: "This Omni service does not support the requested output detail.",
68
- failureScope: "service",
69
- userAction: "Use plain Markdown output for this source.",
70
- operationCreated: false,
71
- fileUploaded: false,
72
- parserStarted: false,
73
- billed: false,
74
- contentReleased: false,
75
- retryable: false,
76
- });
77
- }
78
140
  export function parseReaderCapabilities(value, now) {
79
141
  let parsed;
80
142
  try {
@@ -109,15 +171,56 @@ export function parseReaderCapabilities(value, now) {
109
171
  url_profiles: parsed.url_profiles,
110
172
  };
111
173
  }
112
- export function selectDirectProfile(value, detail) {
174
+ export function selectDirectProfile(value, detail, sourceKind) {
113
175
  const profile = value.direct_profiles.find((candidate) => candidate.details.includes(detail));
114
176
  if (profile === undefined)
115
- throw unsupportedDetail();
177
+ throw unsupportedDetailError(sourceKind);
116
178
  return profile;
117
179
  }
118
- export function selectUrlProfile(value, detail) {
180
+ export function selectUrlProfile(value, detail, sourceKind) {
119
181
  const profile = value.url_profiles.find((candidate) => candidate.details.includes(detail));
120
182
  if (profile === undefined)
121
- throw unsupportedDetail();
183
+ throw unsupportedDetailError(sourceKind);
184
+ return profile;
185
+ }
186
+ export function parseReaderCapabilitiesV2(value, now) {
187
+ let parsed;
188
+ try {
189
+ parsed = readerCapabilitiesV2Schema.parse(value);
190
+ }
191
+ catch {
192
+ throw invalidCapabilities();
193
+ }
194
+ const expiresAt = new Date(parsed.expires_at);
195
+ if (Number.isNaN(expiresAt.getTime()) ||
196
+ expiresAt.getTime() <= now.getTime()) {
197
+ throw invalidCapabilities();
198
+ }
199
+ const profileOrder = new Map([
200
+ [DIRECT_TEXT_BILLING_PROFILE.profile, 0],
201
+ [DIRECT_GROUNDING_BILLING_PROFILE.profile, 1],
202
+ ]);
203
+ const seen = new Set();
204
+ let previousOrder = -1;
205
+ for (const profile of parsed.direct_profiles) {
206
+ const order = profileOrder.get(profile.profile);
207
+ if (order === undefined ||
208
+ seen.has(profile.profile) ||
209
+ order <= previousOrder) {
210
+ throw invalidCapabilities();
211
+ }
212
+ seen.add(profile.profile);
213
+ previousOrder = order;
214
+ }
215
+ return {
216
+ protocol_version: parsed.protocol_version,
217
+ expires_at: expiresAt,
218
+ direct_profiles: parsed.direct_profiles,
219
+ };
220
+ }
221
+ export function selectDirectProfileV2(value, detail, sourceKind) {
222
+ const profile = value.direct_profiles.find((candidate) => candidate.details.includes(detail));
223
+ if (profile === undefined)
224
+ throw unsupportedDetailError(sourceKind);
122
225
  return profile;
123
226
  }
@@ -7,7 +7,7 @@ const PACKAGE_SPEC = `@cueai/omni-reader-mcp@${BRIDGE_RELEASE_VERSION}`;
7
7
  // The release that the current version is a trusted upgrade from: normal upgrade,
8
8
  // uninstall, and rollback recognize exactly {previous, current}. Bump this to the
9
9
  // version we just published when BRIDGE_RELEASE_VERSION advances.
10
- const PREVIOUS_RELEASE_VERSION = "1.5.5";
10
+ const PREVIOUS_RELEASE_VERSION = "1.7.0";
11
11
  const PREVIOUS_PACKAGE_SPEC = `@cueai/omni-reader-mcp@${PREVIOUS_RELEASE_VERSION}`;
12
12
  // Preserve the one evidenced two-release migration exception: 1.5.1 setup wrote a
13
13
  // bare `npx` launcher on Windows, so later setup/uninstall versions must still be able
@@ -641,7 +641,7 @@ export function expectedBridgeVersion(target, value, platform) {
641
641
  }
642
642
  function isLegacyBridgeEntry(target, value, platform) {
643
643
  // Defer the entire invocation-shape decision to the single platform policy:
644
- // exact pinned {1.5.5 previous, 1.6.0 current} plus the exact Windows 1.5.1
644
+ // exact pinned {1.7.0 previous, 1.7.1 current} plus the exact Windows 1.5.1
645
645
  // bare-npx migration source. The historical platform-agnostic acceptance of a
646
646
  // bare unpinned `npx -y @cueai/omni-reader-mcp` is removed: it widened the
647
647
  // frozen trust set to a floating latest on every OS, which expectedBridgeVersion
@@ -6,14 +6,18 @@ export declare const CUBE_GRANT_PROTOCOL_VERSION = "omni.parse_grant.v1";
6
6
  export declare const GRANTED_STREAM_PROTOCOL_VERSION = "omni.granted_parse_stream.v1";
7
7
  export declare const DEFAULT_CUBE_BASE_URL = "https://mcp.cuecue.cn";
8
8
  export declare const DEFAULT_IIIS_GRANTED_BASE_URL = "https://omni-upload.cuecue.cn/omni/granted/";
9
- export declare const BRIDGE_RELEASE_VERSION = "1.6.0";
9
+ export declare const BRIDGE_RELEASE_VERSION = "1.7.1";
10
10
  export declare const REMOTE_OMNI_MCP_URL = "https://mcp.cuecue.cn/api/omni-reader/mcp/";
11
11
  export declare const FOREGROUND_BUDGET_MS = 15000;
12
12
  export declare const STATUS_LONG_POLL_MAX_MS = 20000;
13
13
  export declare const STATUS_POLL_AFTER_SECONDS = 5;
14
14
  export declare const DELIVERY_TTL_SECONDS = 600;
15
+ export declare const CAPABILITIES_V1_PATH = "/api/omni-reader/capabilities/v1";
16
+ export declare const CAPABILITIES_V2_PATH = "/api/omni-reader/capabilities/v2";
15
17
  export declare const CUBE_CAPABILITIES_PATH = "/api/omni-reader/capabilities/v1";
16
18
  export declare const REMOTE_CAPABILITIES_CUSTOM_FIELD = "cue.omni-reader";
19
+ export declare const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_V1 = "omni.local_bridge_tools.v3";
20
+ export declare const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_V2 = "omni.local_bridge_tools.v5";
17
21
  export declare const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_VERSION = "omni.local_bridge_tools.v3";
18
22
  export declare const CAPABILITIES_PROTOCOL_VERSION = "omni.reader_capabilities.v1";
19
23
  export declare const CAPABILITIES_ENABLED_ENV = "OMNI_CAPABILITIES_ENABLED";
package/dist/constants.js CHANGED
@@ -6,15 +6,19 @@ export const CUBE_GRANT_PROTOCOL_VERSION = "omni.parse_grant.v1";
6
6
  export const GRANTED_STREAM_PROTOCOL_VERSION = "omni.granted_parse_stream.v1";
7
7
  export const DEFAULT_CUBE_BASE_URL = "https://mcp.cuecue.cn";
8
8
  export const DEFAULT_IIIS_GRANTED_BASE_URL = "https://omni-upload.cuecue.cn/omni/granted/";
9
- export const BRIDGE_RELEASE_VERSION = "1.6.0";
9
+ export const BRIDGE_RELEASE_VERSION = "1.7.1";
10
10
  export const REMOTE_OMNI_MCP_URL = "https://mcp.cuecue.cn/api/omni-reader/mcp/";
11
11
  export const FOREGROUND_BUDGET_MS = 15_000;
12
12
  export const STATUS_LONG_POLL_MAX_MS = 20_000;
13
13
  export const STATUS_POLL_AFTER_SECONDS = 5;
14
14
  export const DELIVERY_TTL_SECONDS = 600;
15
- export const CUBE_CAPABILITIES_PATH = "/api/omni-reader/capabilities/v1";
15
+ export const CAPABILITIES_V1_PATH = "/api/omni-reader/capabilities/v1";
16
+ export const CAPABILITIES_V2_PATH = "/api/omni-reader/capabilities/v2";
17
+ export const CUBE_CAPABILITIES_PATH = CAPABILITIES_V1_PATH;
16
18
  export const REMOTE_CAPABILITIES_CUSTOM_FIELD = "cue.omni-reader";
17
- export const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_VERSION = "omni.local_bridge_tools.v3";
19
+ export const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_V1 = "omni.local_bridge_tools.v3";
20
+ export const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_V2 = "omni.local_bridge_tools.v5";
21
+ export const SERVER_NEGOTIATED_BRIDGE_PROTOCOL_VERSION = SERVER_NEGOTIATED_BRIDGE_PROTOCOL_V1;
18
22
  // ── omni.reader_capabilities.v1 advertisement (D2-D item 4) ────────────────────────────────
19
23
  // The direct profile's 14 exact literal fields mirror the pinned cube-mcp accepted set
20
24
  // (contracts/cube-mcp/omni-capabilities/v1); the URL profile's 9 fields belong to the
@@ -1,5 +1,5 @@
1
1
  import { BRIDGE_RELEASE_VERSION } from "./constants.js";
2
- import { type ReaderCapabilitiesV1 } from "./capabilities.js";
2
+ import { type DirectProfile, type ReaderCapabilitiesV1, type ReaderCapabilitiesV2, type RequestedDirectDetailV2 } from "./capabilities.js";
3
3
  import { OperationJournal } from "./operation-journal.js";
4
4
  declare const BRIDGE_PACKAGE = "@cueai/omni-reader-mcp";
5
5
  export interface GrantRequestInput {
@@ -21,6 +21,8 @@ export interface GrantedOperation {
21
21
  readonly expiresAt: string;
22
22
  readonly maxBytes: number;
23
23
  readonly protocolVersion: string;
24
+ readonly directProfile: DirectProfile | null;
25
+ readonly requestedDetail: RequestedDirectDetailV2;
24
26
  }
25
27
  export interface CubeGrantClientOptions {
26
28
  readonly journal: OperationJournal;
@@ -46,6 +48,7 @@ export declare class CubeGrantClient {
46
48
  #private;
47
49
  constructor(options: CubeGrantClientOptions);
48
50
  getCapabilities(signal?: AbortSignal): Promise<ReaderCapabilitiesV1>;
51
+ getCapabilitiesV2(signal?: AbortSignal): Promise<ReaderCapabilitiesV2 | null>;
49
52
  createGrant(input: GrantRequestInput, clientRequestId: string, signal?: AbortSignal, options?: {
50
53
  journal?: boolean;
51
54
  }): Promise<GrantedOperation>;