@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
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
const MSYS_DRIVE_PATH = /^\/([A-Za-z])(?:\/|$)/u;
|
|
3
|
+
export class PathNormalizationError extends Error {
|
|
4
|
+
code = "INVALID_WINDOWS_PATH";
|
|
5
|
+
constructor() {
|
|
6
|
+
super("Use an absolute Windows drive path such as C:\\Reports or exact MSYS syntax such as /c/Reports.");
|
|
7
|
+
this.name = "PathNormalizationError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function normalizePlatformPath(value, platform = process.platform) {
|
|
11
|
+
if (platform !== "win32")
|
|
12
|
+
return value;
|
|
13
|
+
if (value.startsWith("//") || value.startsWith("\\\\"))
|
|
14
|
+
return value;
|
|
15
|
+
const match = MSYS_DRIVE_PATH.exec(value);
|
|
16
|
+
if (match !== null) {
|
|
17
|
+
const drive = match[1].toUpperCase();
|
|
18
|
+
const remainder = value.slice(match[0].length).replaceAll("/", "\\");
|
|
19
|
+
return path.win32.normalize(`${drive}:\\${remainder}`);
|
|
20
|
+
}
|
|
21
|
+
if (value.startsWith("/") || value.startsWith("\\")) {
|
|
22
|
+
throw new PathNormalizationError();
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
package/dist/path-security.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface OpenAllowedFileOptions {
|
|
|
9
9
|
workspace: string;
|
|
10
10
|
extraRoots?: readonly string[];
|
|
11
11
|
homeDirectory?: string;
|
|
12
|
+
platform?: NodeJS.Platform;
|
|
12
13
|
fileSystem?: PathSecurityFileSystem;
|
|
13
14
|
}
|
|
14
15
|
export interface OpenedAllowedFile {
|
|
@@ -19,5 +20,5 @@ export interface OpenedAllowedFile {
|
|
|
19
20
|
createReadStream(): ReadStream;
|
|
20
21
|
close(): Promise<void>;
|
|
21
22
|
}
|
|
22
|
-
export declare function splitAllowedRoots(value: string | undefined): string[];
|
|
23
|
+
export declare function splitAllowedRoots(value: string | undefined, platform?: NodeJS.Platform): string[];
|
|
23
24
|
export declare function openAllowedFile(input: string, options: OpenAllowedFileOptions): Promise<OpenedAllowedFile>;
|
package/dist/path-security.js
CHANGED
|
@@ -5,6 +5,7 @@ import { homedir } from "node:os";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { MAX_FILE_BYTES } from "./constants.js";
|
|
7
7
|
import { OmniBridgeError } from "./errors.js";
|
|
8
|
+
import { PathNormalizationError, normalizePlatformPath, } from "./path-normalization.js";
|
|
8
9
|
const CONTENT_TYPES = {
|
|
9
10
|
".pdf": "application/pdf",
|
|
10
11
|
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
@@ -92,29 +93,44 @@ function bridgeError(code, message, retryable, constraints) {
|
|
|
92
93
|
...(constraints === undefined ? {} : { constraints }),
|
|
93
94
|
});
|
|
94
95
|
}
|
|
96
|
+
function pathsFor(platform) {
|
|
97
|
+
return platform === "win32" ? path.win32 : path.posix;
|
|
98
|
+
}
|
|
95
99
|
function validatePathText(value) {
|
|
96
100
|
if (value.length === 0 || value.includes("\0")) {
|
|
97
101
|
throw bridgeError("INVALID_LOCAL_PATH", "Provide one valid local file path.", false);
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
|
-
function
|
|
104
|
+
function normalizedPath(value, platform) {
|
|
105
|
+
validatePathText(value);
|
|
106
|
+
try {
|
|
107
|
+
return normalizePlatformPath(value, platform);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error instanceof PathNormalizationError) {
|
|
111
|
+
throw bridgeError(error.code, error.message, false);
|
|
112
|
+
}
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function expandHomeOnly(value, homeDirectory, paths) {
|
|
101
117
|
if (value === "~") {
|
|
102
118
|
return homeDirectory;
|
|
103
119
|
}
|
|
104
120
|
if (/^~[\\/]/u.test(value)) {
|
|
105
|
-
return
|
|
121
|
+
return paths.join(homeDirectory, value.slice(2));
|
|
106
122
|
}
|
|
107
123
|
return value;
|
|
108
124
|
}
|
|
109
|
-
function isInsideRoot(candidate, root) {
|
|
110
|
-
const relative =
|
|
125
|
+
function isInsideRoot(candidate, root, paths) {
|
|
126
|
+
const relative = paths.relative(root, candidate);
|
|
111
127
|
return (relative === "" ||
|
|
112
128
|
(relative !== ".." &&
|
|
113
|
-
!relative.startsWith(`..${
|
|
114
|
-
!
|
|
129
|
+
!relative.startsWith(`..${paths.sep}`) &&
|
|
130
|
+
!paths.isAbsolute(relative)));
|
|
115
131
|
}
|
|
116
|
-
function requireInsideAnyRoot(candidate, roots) {
|
|
117
|
-
if (!roots.some((root) => isInsideRoot(candidate, root))) {
|
|
132
|
+
function requireInsideAnyRoot(candidate, roots, paths) {
|
|
133
|
+
if (!roots.some((root) => isInsideRoot(candidate, root, paths))) {
|
|
118
134
|
throw bridgeError("PATH_NOT_ALLOWED", "Move the file into the current workspace or add its parent directory to OMNI_ALLOWED_ROOTS.", false);
|
|
119
135
|
}
|
|
120
136
|
}
|
|
@@ -148,8 +164,8 @@ function redactedSourceFingerprint(fileStat) {
|
|
|
148
164
|
].map((value) => value.toString()).join(":");
|
|
149
165
|
return `sha256:${createHash("sha256").update(identity, "utf8").digest("hex")}`;
|
|
150
166
|
}
|
|
151
|
-
function safeFileType(resolvedPath) {
|
|
152
|
-
const safeExtension =
|
|
167
|
+
function safeFileType(resolvedPath, paths) {
|
|
168
|
+
const safeExtension = paths.extname(resolvedPath).toLowerCase();
|
|
153
169
|
if (!/^\.[a-z0-9]{1,10}$/u.test(safeExtension)) {
|
|
154
170
|
throw bridgeError("UNSUPPORTED_MEDIA_TYPE", "The source media type is not supported.", false, { supported_extensions: SUPPORTED_EXTENSIONS });
|
|
155
171
|
}
|
|
@@ -175,19 +191,20 @@ function fileAccessError(error) {
|
|
|
175
191
|
}
|
|
176
192
|
return bridgeError("FILE_NOT_READABLE", "Omni cannot read the local file. Check its permissions and try again.", false);
|
|
177
193
|
}
|
|
178
|
-
async function resolveAllowedRoots(options, fileSystem, homeDirectory) {
|
|
179
|
-
|
|
180
|
-
const
|
|
194
|
+
async function resolveAllowedRoots(options, fileSystem, homeDirectory, platform, paths) {
|
|
195
|
+
const workspace = normalizedPath(options.workspace, platform);
|
|
196
|
+
const expandedWorkspace = expandHomeOnly(workspace, homeDirectory, paths);
|
|
197
|
+
const workspaceInput = paths.resolve(normalizedPath(expandedWorkspace, platform));
|
|
181
198
|
const requestedRoots = [
|
|
182
199
|
workspaceInput,
|
|
183
200
|
...(options.extraRoots ?? [])
|
|
184
201
|
.filter((root) => root.length > 0)
|
|
185
202
|
.map((root) => {
|
|
186
|
-
|
|
187
|
-
const expanded = expandHomeOnly(
|
|
188
|
-
return
|
|
203
|
+
const normalizedRoot = normalizedPath(root, platform);
|
|
204
|
+
const expanded = normalizedPath(expandHomeOnly(normalizedRoot, homeDirectory, paths), platform);
|
|
205
|
+
return paths.isAbsolute(expanded)
|
|
189
206
|
? expanded
|
|
190
|
-
:
|
|
207
|
+
: paths.resolve(workspaceInput, expanded);
|
|
191
208
|
}),
|
|
192
209
|
];
|
|
193
210
|
try {
|
|
@@ -199,7 +216,7 @@ async function resolveAllowedRoots(options, fileSystem, homeDirectory) {
|
|
|
199
216
|
}
|
|
200
217
|
return resolved;
|
|
201
218
|
}));
|
|
202
|
-
return [...new Set(roots)];
|
|
219
|
+
return { roots: [...new Set(roots)], workspaceInput };
|
|
203
220
|
}
|
|
204
221
|
catch (error) {
|
|
205
222
|
if (error instanceof OmniBridgeError) {
|
|
@@ -208,21 +225,25 @@ async function resolveAllowedRoots(options, fileSystem, homeDirectory) {
|
|
|
208
225
|
throw bridgeError("INVALID_ALLOWED_ROOT", "The workspace or an OMNI_ALLOWED_ROOTS entry is unavailable.", false);
|
|
209
226
|
}
|
|
210
227
|
}
|
|
211
|
-
export function splitAllowedRoots(value) {
|
|
228
|
+
export function splitAllowedRoots(value, platform = process.platform) {
|
|
212
229
|
if (value === undefined || value.length === 0) {
|
|
213
230
|
return [];
|
|
214
231
|
}
|
|
215
|
-
return value
|
|
232
|
+
return value
|
|
233
|
+
.split(pathsFor(platform).delimiter)
|
|
234
|
+
.filter((root) => root.length > 0);
|
|
216
235
|
}
|
|
217
236
|
export async function openAllowedFile(input, options) {
|
|
218
|
-
|
|
237
|
+
const platform = options.platform ?? process.platform;
|
|
238
|
+
const paths = pathsFor(platform);
|
|
219
239
|
const fileSystem = options.fileSystem ?? NODE_FILE_SYSTEM;
|
|
220
240
|
const homeDirectory = options.homeDirectory ?? homedir();
|
|
221
|
-
const
|
|
222
|
-
const expanded = expandHomeOnly(
|
|
223
|
-
const
|
|
241
|
+
const normalizedInput = normalizedPath(input, platform);
|
|
242
|
+
const expanded = normalizedPath(expandHomeOnly(normalizedInput, homeDirectory, paths), platform);
|
|
243
|
+
const { roots, workspaceInput } = await resolveAllowedRoots(options, fileSystem, homeDirectory, platform, paths);
|
|
244
|
+
const candidate = paths.isAbsolute(expanded)
|
|
224
245
|
? expanded
|
|
225
|
-
:
|
|
246
|
+
: paths.resolve(workspaceInput, expanded);
|
|
226
247
|
let resolved;
|
|
227
248
|
try {
|
|
228
249
|
resolved = await fileSystem.realpath(candidate);
|
|
@@ -230,7 +251,7 @@ export async function openAllowedFile(input, options) {
|
|
|
230
251
|
catch (error) {
|
|
231
252
|
throw fileAccessError(error);
|
|
232
253
|
}
|
|
233
|
-
requireInsideAnyRoot(resolved, roots);
|
|
254
|
+
requireInsideAnyRoot(resolved, roots, paths);
|
|
234
255
|
let handle;
|
|
235
256
|
try {
|
|
236
257
|
const pathStat = await fileSystem.stat(resolved);
|
|
@@ -244,11 +265,11 @@ export async function openAllowedFile(input, options) {
|
|
|
244
265
|
requireSameFile(pathStat, before);
|
|
245
266
|
const size = requireAllowedSize(before);
|
|
246
267
|
const afterPath = await fileSystem.realpath(resolved);
|
|
247
|
-
requireInsideAnyRoot(afterPath, roots);
|
|
268
|
+
requireInsideAnyRoot(afterPath, roots, paths);
|
|
248
269
|
const after = await fileSystem.stat(afterPath);
|
|
249
270
|
requireRegularFile(after);
|
|
250
271
|
requireSameFile(before, after);
|
|
251
|
-
const { safeExtension, contentType } = safeFileType(afterPath);
|
|
272
|
+
const { safeExtension, contentType } = safeFileType(afterPath, paths);
|
|
252
273
|
const opened = new DescriptorBackedFile(handle, size, safeExtension, contentType, redactedSourceFingerprint(before));
|
|
253
274
|
handle = undefined;
|
|
254
275
|
return opened;
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const LOCAL_BRIDGE_PROTOCOL_VERSION = "omni.local_bridge_tools.
|
|
3
|
-
export declare const OPERATION_JOURNAL_VERSION =
|
|
2
|
+
export declare const LOCAL_BRIDGE_PROTOCOL_VERSION = "omni.local_bridge_tools.v5";
|
|
3
|
+
export declare const OPERATION_JOURNAL_VERSION = 5;
|
|
4
4
|
export declare const BUNDLE_CURSOR_VERSION = 2;
|
|
5
5
|
export declare const RESULT_BUNDLE_PROTOCOL_VERSION = "omni.result_bundle.v1";
|
|
6
6
|
export declare const GROUNDING_SCHEMA_VERSION = "omni.grounding.v1";
|
|
7
|
+
export type ResultDelivery = "auto" | "artifact";
|
|
7
8
|
export interface RepresentationIntent {
|
|
8
9
|
readonly detail: "text" | "grounded" | "layout";
|
|
9
10
|
readonly groundingSchemaVersion: "none" | "omni.grounding.v1";
|
|
@@ -15,31 +16,38 @@ export declare const parseSchemaShape: {
|
|
|
15
16
|
source: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
16
17
|
url: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
17
18
|
detail: z.ZodOptional<z.ZodEnum<["text", "grounded", "layout"]>>;
|
|
19
|
+
result_delivery: z.ZodOptional<z.ZodEnum<["auto", "artifact"]>>;
|
|
18
20
|
};
|
|
19
21
|
export declare const parseSchema: z.ZodEffects<z.ZodObject<{
|
|
20
22
|
source: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
21
23
|
url: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
22
24
|
detail: z.ZodOptional<z.ZodEnum<["text", "grounded", "layout"]>>;
|
|
25
|
+
result_delivery: z.ZodOptional<z.ZodEnum<["auto", "artifact"]>>;
|
|
23
26
|
}, "strict", z.ZodTypeAny, {
|
|
24
27
|
source?: string | undefined;
|
|
25
28
|
url?: string | undefined;
|
|
26
29
|
detail?: "grounded" | "layout" | "text" | undefined;
|
|
30
|
+
result_delivery?: "auto" | "artifact" | undefined;
|
|
27
31
|
}, {
|
|
28
32
|
source?: string | undefined;
|
|
29
33
|
url?: string | undefined;
|
|
30
34
|
detail?: "grounded" | "layout" | "text" | undefined;
|
|
35
|
+
result_delivery?: "auto" | "artifact" | undefined;
|
|
31
36
|
}>, {
|
|
32
37
|
source?: string | undefined;
|
|
33
38
|
url?: string | undefined;
|
|
34
39
|
detail?: "grounded" | "layout" | "text" | undefined;
|
|
40
|
+
result_delivery?: "auto" | "artifact" | undefined;
|
|
35
41
|
}, {
|
|
36
42
|
source?: string | undefined;
|
|
37
43
|
url?: string | undefined;
|
|
38
44
|
detail?: "grounded" | "layout" | "text" | undefined;
|
|
45
|
+
result_delivery?: "auto" | "artifact" | undefined;
|
|
39
46
|
}>;
|
|
40
47
|
export interface NormalizedParseArguments {
|
|
41
48
|
readonly source: string;
|
|
42
49
|
readonly detail?: "text" | "grounded" | "layout";
|
|
50
|
+
readonly resultDelivery: ResultDelivery;
|
|
43
51
|
}
|
|
44
52
|
export declare function normalizeParseArguments(args: ParseArguments): NormalizedParseArguments;
|
|
45
53
|
export declare const getParseStatusSchema: z.ZodObject<{
|
package/dist/protocol.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { RESULT_CHUNK_MAX_BYTES, STATUS_LONG_POLL_MAX_MS } from "./constants.js";
|
|
3
|
-
export const LOCAL_BRIDGE_PROTOCOL_VERSION = "omni.local_bridge_tools.
|
|
4
|
-
|
|
5
|
-
// The journal record version and the bundle cursor version are bumped
|
|
6
|
-
// together with the tool contract; legacy v2 journal records still recover
|
|
7
|
-
// text operations unchanged and are never auto-upgraded.
|
|
8
|
-
export const OPERATION_JOURNAL_VERSION = 3;
|
|
3
|
+
export const LOCAL_BRIDGE_PROTOCOL_VERSION = "omni.local_bridge_tools.v5";
|
|
4
|
+
export const OPERATION_JOURNAL_VERSION = 5;
|
|
9
5
|
export const BUNDLE_CURSOR_VERSION = 2;
|
|
10
6
|
// Canonical bundle/grounding literals carried by non-text representations.
|
|
11
7
|
export const RESULT_BUNDLE_PROTOCOL_VERSION = "omni.result_bundle.v1";
|
|
@@ -25,6 +21,7 @@ export function normalizeRepresentation(detail) {
|
|
|
25
21
|
};
|
|
26
22
|
}
|
|
27
23
|
export const MACHINE_INSTRUCTIONS = [
|
|
24
|
+
"Use parse as the only first call for both HTTP(S) URLs and local paths; do not ask the user to choose a local, remote, upload, or URL mode.",
|
|
28
25
|
"Pass the user-provided source string directly to parse.",
|
|
29
26
|
"Treat only HTTP(S) as URL; ordinary paths require the local Bridge.",
|
|
30
27
|
"Never read, attach, base64-encode, or insert local source content before calling Omni.",
|
|
@@ -36,6 +33,20 @@ export const MACHINE_INSTRUCTIONS = [
|
|
|
36
33
|
"Do not promise background notification when the client lacks task support.",
|
|
37
34
|
"Do not claim deletion before cleanup is confirmed.",
|
|
38
35
|
"Report authoritative unit progress when present; never treat partial output as final.",
|
|
36
|
+
"Choose continuation tools from the structured result; do not present the Bridge tool menu to the user.",
|
|
37
|
+
"Text output is Markdown and may retain headings, lists, GFM tables, or raw HTML tables; it lacks grounding/layout sidecars, not all structure.",
|
|
38
|
+
"An empty outline means no recognized headings, not that the text has no structure.",
|
|
39
|
+
"Answer directly → use inline text when present; otherwise read_result",
|
|
40
|
+
"Find one section → read_outline, then pass its cursor to read_result",
|
|
41
|
+
"Read all content → read_result until next_cursor is absent",
|
|
42
|
+
"Deliver a file → save_result",
|
|
43
|
+
"Outline navigation does not require save_result.",
|
|
44
|
+
"Use result_delivery=artifact for saving, section navigation, multiple documents, or strict context control.",
|
|
45
|
+
"Use bounded concurrent independent parse calls for multiple sources; there is no batch_parse tool.",
|
|
46
|
+
"Discover MCP Tasks, MCP Roots, host tool timeout, and process cwd versus active workspace; do not guess client capabilities.",
|
|
47
|
+
"Tasks unknown → use ordinary parse and get_parse_status polling.",
|
|
48
|
+
"Roots unknown → use process cwd and explicitly configured roots only.",
|
|
49
|
+
"Host timeout unknown → retain the bounded 20-second status wait.",
|
|
39
50
|
"After parsing, continue the user's original task.",
|
|
40
51
|
].join("\n");
|
|
41
52
|
const operationIdSchema = z.string().regex(/^op_[A-Za-z0-9_-]{16,64}$/u);
|
|
@@ -60,6 +71,7 @@ const parseSchemaObject = z
|
|
|
60
71
|
.refine((value) => !value.includes("\0"))
|
|
61
72
|
.optional(),
|
|
62
73
|
detail: z.enum(["text", "grounded", "layout"]).optional(),
|
|
74
|
+
result_delivery: z.enum(["auto", "artifact"]).optional(),
|
|
63
75
|
})
|
|
64
76
|
.strict();
|
|
65
77
|
export const parseSchemaShape = parseSchemaObject.shape;
|
|
@@ -71,7 +83,11 @@ export function normalizeParseArguments(args) {
|
|
|
71
83
|
// schema-validated input and guards misuse of the exported helper.
|
|
72
84
|
throw new Error("parse arguments require exactly one of source or url");
|
|
73
85
|
}
|
|
74
|
-
return {
|
|
86
|
+
return {
|
|
87
|
+
source,
|
|
88
|
+
detail: args.detail,
|
|
89
|
+
resultDelivery: args.result_delivery ?? "auto",
|
|
90
|
+
};
|
|
75
91
|
}
|
|
76
92
|
export const getParseStatusSchema = z
|
|
77
93
|
.object({
|
package/dist/remote-client.js
CHANGED
|
@@ -2,7 +2,7 @@ import { LATEST_PROTOCOL_VERSION } from "@modelcontextprotocol/sdk/types.js";
|
|
|
2
2
|
import { parseReaderCapabilities, selectUrlProfile, } from "./capabilities.js";
|
|
3
3
|
import { BRIDGE_RELEASE_VERSION, REMOTE_CAPABILITIES_CUSTOM_FIELD, REMOTE_OMNI_MCP_URL, } from "./constants.js";
|
|
4
4
|
import { API_KEY_URL } from "./onboarding-policy.js";
|
|
5
|
-
import { OmniBridgeError } from "./errors.js";
|
|
5
|
+
import { OmniBridgeError, unsupportedDetailError } from "./errors.js";
|
|
6
6
|
import { parseResultSchema } from "./result-contract.js";
|
|
7
7
|
import { classifySource } from "./source.js";
|
|
8
8
|
const INITIALIZE_REQUEST_ID = "initialize";
|
|
@@ -108,16 +108,6 @@ function protocolError() {
|
|
|
108
108
|
retryable: false,
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
-
function unsupportedDetail() {
|
|
112
|
-
return remoteError({
|
|
113
|
-
code: "UNSUPPORTED_DETAIL",
|
|
114
|
-
message: "This remote Omni service does not support the requested output detail.",
|
|
115
|
-
failureScope: "service",
|
|
116
|
-
userAction: "Use plain Markdown output for this source.",
|
|
117
|
-
operationCreated: false,
|
|
118
|
-
retryable: false,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
111
|
// Extracts exactly `result.capabilities.experimental["cue.omni-reader"]` from
|
|
122
112
|
// an MCP initialize envelope; returns undefined when the exact custom field is
|
|
123
113
|
// absent (server did not declare the capability), throws on contract
|
|
@@ -351,7 +341,7 @@ export class HttpRemoteOmniClient {
|
|
|
351
341
|
}
|
|
352
342
|
const custom = initializeCustomCapability(envelope, INITIALIZE_REQUEST_ID);
|
|
353
343
|
if (custom === undefined) {
|
|
354
|
-
throw
|
|
344
|
+
throw unsupportedDetailError("url");
|
|
355
345
|
}
|
|
356
346
|
let capabilities;
|
|
357
347
|
try {
|
|
@@ -388,7 +378,7 @@ export class HttpRemoteOmniClient {
|
|
|
388
378
|
// non-text v3 call; a missing/mismatched profile fails closed with
|
|
389
379
|
// UNSUPPORTED_DETAIL and zero tools/call requests.
|
|
390
380
|
const capabilities = await this.initializeCapabilities(signal);
|
|
391
|
-
selectUrlProfile(capabilities, detail);
|
|
381
|
+
selectUrlProfile(capabilities, detail, "url");
|
|
392
382
|
args = { source: classified.source, detail, wait: false };
|
|
393
383
|
}
|
|
394
384
|
return this.#call("parse", args, clientRequestId, signal);
|