@cueai/omni-reader-mcp 1.6.0 → 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 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,17 +48,37 @@ 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.6.0` 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
- 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.
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.
60
+
61
+ A terminal URL or local-file result may carry the operation-local settlement snapshot:
62
+
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.
59
79
 
60
80
  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
81
+ and there is no public rate response carrying an `effective_at` timestamp. Use only current
62
82
  authoritative billing/policy facts rather than estimating a charge from copied arithmetic.
63
83
 
64
84
  ## Installation and configuration
@@ -66,7 +86,7 @@ authoritative billing/policy facts rather than estimating a charge from copied a
66
86
  Always use an audited exact version, never an implicit `latest`:
67
87
 
68
88
  ```sh
69
- npx -y @cueai/omni-reader-mcp@1.6.0 setup
89
+ npx -y @cueai/omni-reader-mcp@1.7.0 setup
70
90
  ```
71
91
 
72
92
  The interactive setup supports Hermes, Cursor, Claude Desktop, and generic stdio
@@ -74,9 +94,9 @@ configuration. Non-interactive installation uses the same argument parsing and w
74
94
  logic:
75
95
 
76
96
  ```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
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
80
100
  ```
81
101
 
82
102
  When an agent or script runs under a pty (stdin is still a TTY), declare non-interactive
@@ -84,7 +104,7 @@ mode explicitly with `--headless` (alias `--non-interactive`): no `--yes` is req
84
104
  stdin is never read:
85
105
 
86
106
  ```sh
87
- npx -y @cueai/omni-reader-mcp@1.6.0 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
88
108
  ```
89
109
 
90
110
  ## Windows configuration
@@ -103,14 +123,14 @@ automatically; the second is the most robust when you configure by hand.
103
123
  1. **`cmd` + `npx` (what `setup` writes on Windows)** — `cmd.exe` is a real executable,
104
124
  so a client's no-shell spawn works:
105
125
  ```json
106
- { "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.6.0"] }
126
+ { "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.7.0"] }
107
127
  ```
108
128
  2. **`node` + the package entry (most robust)** — skips `npx` entirely; the absolute
109
129
  path must be a stable install you control:
110
130
  ```json
111
131
  { "command": "node", "args": ["C:\\path\\to\\node_modules\\@cueai\\omni-reader-mcp\\dist\\index.js"] }
112
132
  ```
113
- A deliberate local `npm install @cueai/omni-reader-mcp@1.6.0` gives you that stable
133
+ A deliberate local `npm install @cueai/omni-reader-mcp@1.7.0` gives you that stable
114
134
  path. Do not point the entry at an `_npx` cache directory — its hash subdirectory
115
135
  changes between installs.
116
136
  3. **Never use a session/timestamp directory** — such paths are cleaned up, and the
@@ -149,6 +169,8 @@ Configuration never writes the API Key in plaintext. Hermes uses native separate
149
169
 
150
170
  ## Agent calling rules
151
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
+
152
174
  Agents pass the user-provided source string directly to `parse(source)`:
153
175
 
154
176
  - Only HTTP(S) is treated as a URL; a plain string is treated as a local path.
@@ -184,15 +206,15 @@ Safe fallbacks are:
184
206
  - Process cwd versus active workspace unknown → do not widen authorization; use cwd and
185
207
  explicit roots until the client provides evidence.
186
208
 
187
- The public tools are fixed:
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`.
188
214
 
189
- - `parse`
190
- - `get_parse_status`
191
- - `cancel_parse`
192
- - `read_result`
193
- - `read_outline`
194
- - `discard_result`
195
- - `save_result`
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.
196
218
 
197
219
  Every tool returns `structuredContent` with a strict `outputSchema`, plus an equivalent
198
220
  fallback for clients that only read legacy MCP `content[].text`:
@@ -209,6 +231,8 @@ fallback for clients that only read legacy MCP `content[].text`:
209
231
  anchored at that heading, so a long result can be jumped into directly instead of only
210
232
  advancing sequentially through `next_cursor`. An empty or absent outline is reported
211
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;
212
236
  - the `discard_result` text JSON explicitly returns `discarded`; never claim deletion on
213
237
  call success alone;
214
238
  - the `save_result` text JSON contains the written file `path` and `bytes` count; there is
@@ -280,16 +304,16 @@ satisfies the constraints.
280
304
  ## Commands
281
305
 
282
306
  ```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
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
287
311
  ```
288
312
 
289
313
  Running the pinned version without a command starts the stdio MCP server:
290
314
 
291
315
  ```sh
292
- npx -y @cueai/omni-reader-mcp@1.6.0
316
+ npx -y @cueai/omni-reader-mcp@1.7.0
293
317
  ```
294
318
 
295
319
  Default `doctor --json` reports `inspection_scope: "current_process_env"`: its Key and
@@ -297,7 +321,7 @@ allowed-root facts describe the doctor process, not a separately running agent c
297
321
  inspect one caller-selected JSON entry without scanning or writing configuration, use:
298
322
 
299
323
  ```sh
300
- npx -y @cueai/omni-reader-mcp@1.6.0 doctor --json --config-path /absolute/client-config.json --server-name omni-reader
324
+ npx -y @cueai/omni-reader-mcp@1.7.0 doctor --json --config-path /absolute/client-config.json --server-name omni-reader
301
325
  ```
302
326
 
303
327
  The optional `explicit_config` block reports only closed redacted facts: entry/transport
@@ -315,14 +339,17 @@ definitively "available" until a real local-file parse validates the route.
315
339
 
316
340
  ## Network diagnostics
317
341
 
318
- Run `npx -y @cueai/omni-reader-mcp@1.6.0 doctor --json` first. Diagnose failures by
342
+ Run `npx -y @cueai/omni-reader-mcp@1.7.0 doctor --json` first. Diagnose failures by
319
343
  stage instead of guessing an endpoint:
320
344
 
321
345
  | Failure | Stage | Meaning |
322
346
  |---|---|---|
323
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 |
324
351
  | `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 |
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 |
326
353
  | a secure upload-stage failure | after grant creation | the file was granted, but the secure upload stage did not complete |
327
354
  | `CUBE_PROTOCOL_ERROR` | control-plane response | the response did not match the required contract |
328
355
  | `MCP error -32000: Connection closed` | before Bridge starts | the client launcher shape is invalid; see Windows configuration |
@@ -341,16 +368,16 @@ the same way from every client.
341
368
 
342
369
  ## Uninstall and rollback
343
370
 
344
- `uninstall --yes --json` removes only a trusted 1.5.5 or 1.6.0 Bridge entry, plus
371
+ `uninstall --yes --json` removes only a trusted 1.6.0 or 1.7.0 Bridge entry, plus
345
372
  the exact broken bare-`npx` Windows entry written by 1.5.1. When a matching trusted
346
373
  backup exists, it restores the original URL-only `omni-reader` entry. Uninstall never
347
374
  deletes user source files and never silently removes unexpired local results.
348
375
 
349
- To roll back from 1.6.0 to 1.5.5:
376
+ To roll back from 1.7.0 to 1.6.0:
350
377
 
351
- 1. stop recommending or installing 1.6.0;
378
+ 1. stop recommending or installing 1.7.0;
352
379
  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`;
380
+ 3. if the local facade is still required, run `npx -y @cueai/omni-reader-mcp@1.6.0 setup`;
354
381
  4. for already-uploaded operations, continue using status recovery so settlement and
355
382
  cleanup complete;
356
383
  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.6.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.6.0 previous, 1.7.0 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.0";
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.0";
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>;