@rudderhq/cli 0.7.23-canary.2 → 0.7.23-canary.4
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/dist/index.js +154 -132
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28219,6 +28219,122 @@ function formatAgentCliCapabilitiesHumanReadable(capabilities = getAgentCliCapab
|
|
|
28219
28219
|
return lines.join("\n").trimEnd();
|
|
28220
28220
|
}
|
|
28221
28221
|
|
|
28222
|
+
// src/agent-v1-mcp-validation.ts
|
|
28223
|
+
function validateMcpToolArguments(toolName, input) {
|
|
28224
|
+
const tool2 = buildAgentV1McpToolsManifest("agent-v1", { surface: "all" }).tools.find((entry) => entry.name === toolName);
|
|
28225
|
+
if (!tool2) return;
|
|
28226
|
+
const schema = tool2.inputSchema;
|
|
28227
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
28228
|
+
for (const key of required) {
|
|
28229
|
+
const property = String(key);
|
|
28230
|
+
if (!Object.prototype.hasOwnProperty.call(input, property) || input[property] === void 0) {
|
|
28231
|
+
throwInvalidMcpArgument(toolName, property, "is required");
|
|
28232
|
+
}
|
|
28233
|
+
}
|
|
28234
|
+
if (Array.isArray(schema.anyOf)) {
|
|
28235
|
+
const matches = schema.anyOf.some((candidate) => {
|
|
28236
|
+
if (!isRecord2(candidate) || !Array.isArray(candidate.required)) return false;
|
|
28237
|
+
return candidate.required.every((key) => {
|
|
28238
|
+
const property = String(key);
|
|
28239
|
+
return Object.prototype.hasOwnProperty.call(input, property) && input[property] !== void 0;
|
|
28240
|
+
});
|
|
28241
|
+
});
|
|
28242
|
+
if (!matches) {
|
|
28243
|
+
const alternatives = schema.anyOf.flatMap((candidate) => isRecord2(candidate) && Array.isArray(candidate.required) ? candidate.required : []).map(String);
|
|
28244
|
+
throwInvalidMcpArgument(toolName, alternatives.join(" or "), "is required");
|
|
28245
|
+
}
|
|
28246
|
+
}
|
|
28247
|
+
const properties = isRecord2(schema.properties) ? schema.properties : {};
|
|
28248
|
+
for (const [key, value] of Object.entries(input)) {
|
|
28249
|
+
const property = properties[key];
|
|
28250
|
+
if (!isRecord2(property) || value === void 0) continue;
|
|
28251
|
+
const violation = jsonSchemaViolation(value, property);
|
|
28252
|
+
if (violation) throwInvalidMcpArgument(toolName, key, violation);
|
|
28253
|
+
}
|
|
28254
|
+
}
|
|
28255
|
+
function jsonSchemaViolation(value, schema) {
|
|
28256
|
+
if (Array.isArray(schema.anyOf)) {
|
|
28257
|
+
const matches = schema.anyOf.some(
|
|
28258
|
+
(candidate) => isRecord2(candidate) && jsonSchemaViolation(value, candidate) === null
|
|
28259
|
+
);
|
|
28260
|
+
if (!matches) return "does not match any allowed shape";
|
|
28261
|
+
}
|
|
28262
|
+
if (Array.isArray(schema.oneOf)) {
|
|
28263
|
+
const matchingBranches = schema.oneOf.filter(
|
|
28264
|
+
(candidate) => isRecord2(candidate) && jsonSchemaViolation(value, candidate) === null
|
|
28265
|
+
).length;
|
|
28266
|
+
if (matchingBranches !== 1) return "does not match exactly one allowed shape";
|
|
28267
|
+
}
|
|
28268
|
+
const types = Array.isArray(schema.type) ? schema.type : schema.type === void 0 ? [] : [schema.type];
|
|
28269
|
+
if (types.length > 0) {
|
|
28270
|
+
const validType = types.some((type) => type === "string" ? typeof value === "string" : type === "number" ? typeof value === "number" && Number.isFinite(value) : type === "integer" ? typeof value === "number" && Number.isInteger(value) : type === "boolean" ? typeof value === "boolean" : type === "array" ? Array.isArray(value) : type === "object" ? isRecord2(value) : type === "null" ? value === null : false);
|
|
28271
|
+
if (!validType) return `must be ${types.join(" or ")}`;
|
|
28272
|
+
}
|
|
28273
|
+
if (typeof value === "string") {
|
|
28274
|
+
const characterLength = Array.from(value).length;
|
|
28275
|
+
if (typeof schema.minLength === "number" && characterLength < schema.minLength) {
|
|
28276
|
+
return `must contain at least ${schema.minLength} character(s)`;
|
|
28277
|
+
}
|
|
28278
|
+
if (typeof schema.maxLength === "number" && characterLength > schema.maxLength) {
|
|
28279
|
+
return `must contain at most ${schema.maxLength} characters`;
|
|
28280
|
+
}
|
|
28281
|
+
if (Array.isArray(schema.enum) && !schema.enum.includes(value)) {
|
|
28282
|
+
return `must be one of: ${schema.enum.join(", ")}`;
|
|
28283
|
+
}
|
|
28284
|
+
}
|
|
28285
|
+
if (typeof value === "number") {
|
|
28286
|
+
if (typeof schema.minimum === "number" && value < schema.minimum) {
|
|
28287
|
+
return `must be at least ${schema.minimum}`;
|
|
28288
|
+
}
|
|
28289
|
+
if (typeof schema.maximum === "number" && value > schema.maximum) {
|
|
28290
|
+
return `must be at most ${schema.maximum}`;
|
|
28291
|
+
}
|
|
28292
|
+
}
|
|
28293
|
+
if (Array.isArray(value)) {
|
|
28294
|
+
if (typeof schema.minItems === "number" && value.length < schema.minItems) {
|
|
28295
|
+
return `must contain at least ${schema.minItems} items`;
|
|
28296
|
+
}
|
|
28297
|
+
if (typeof schema.maxItems === "number" && value.length > schema.maxItems) {
|
|
28298
|
+
return `must contain at most ${schema.maxItems} items`;
|
|
28299
|
+
}
|
|
28300
|
+
if (isRecord2(schema.items)) {
|
|
28301
|
+
for (const [index, item] of value.entries()) {
|
|
28302
|
+
const violation = jsonSchemaViolation(item, schema.items);
|
|
28303
|
+
if (violation) return `item ${index} ${violation}`;
|
|
28304
|
+
}
|
|
28305
|
+
}
|
|
28306
|
+
}
|
|
28307
|
+
if (isRecord2(value)) {
|
|
28308
|
+
const properties = isRecord2(schema.properties) ? schema.properties : {};
|
|
28309
|
+
if (typeof schema.minProperties === "number" && Object.keys(value).length < schema.minProperties) {
|
|
28310
|
+
return `must contain at least ${schema.minProperties} propert${schema.minProperties === 1 ? "y" : "ies"}`;
|
|
28311
|
+
}
|
|
28312
|
+
const required = Array.isArray(schema.required) ? schema.required.map(String) : [];
|
|
28313
|
+
for (const key of required) {
|
|
28314
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) return `field ${key} is required`;
|
|
28315
|
+
}
|
|
28316
|
+
if (schema.additionalProperties === false) {
|
|
28317
|
+
const unsupported = Object.keys(value).filter((key) => !(key in properties));
|
|
28318
|
+
if (unsupported.length > 0) return `contains unsupported field(s): ${unsupported.sort().join(", ")}`;
|
|
28319
|
+
}
|
|
28320
|
+
for (const [key, child] of Object.entries(value)) {
|
|
28321
|
+
const childSchema = properties[key];
|
|
28322
|
+
if (!isRecord2(childSchema)) continue;
|
|
28323
|
+
const violation = jsonSchemaViolation(child, childSchema);
|
|
28324
|
+
if (violation) return `field ${key} ${violation}`;
|
|
28325
|
+
}
|
|
28326
|
+
}
|
|
28327
|
+
return null;
|
|
28328
|
+
}
|
|
28329
|
+
function throwInvalidMcpArgument(toolName, key, reason) {
|
|
28330
|
+
const err = new Error(`Invalid argument for ${toolName}: ${key} ${reason}. Consult tools/list for the exact schema.`);
|
|
28331
|
+
err.code = "rudder_mcp_invalid_arguments";
|
|
28332
|
+
throw err;
|
|
28333
|
+
}
|
|
28334
|
+
function isRecord2(value) {
|
|
28335
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28336
|
+
}
|
|
28337
|
+
|
|
28222
28338
|
// src/client/http.ts
|
|
28223
28339
|
import { URL as URL3 } from "node:url";
|
|
28224
28340
|
|
|
@@ -28665,7 +28781,7 @@ function issueTransportUnavailable(state, now, requestScope = state) {
|
|
|
28665
28781
|
function attachTransportDiagnostic(error, state, now, requestScope = state) {
|
|
28666
28782
|
const upstreamDetails = error.details;
|
|
28667
28783
|
error.details = {
|
|
28668
|
-
...
|
|
28784
|
+
...isRecord3(upstreamDetails) ? upstreamDetails : upstreamDetails === void 0 ? {} : { upstreamDetails },
|
|
28669
28785
|
issueTransport: transportDiagnostic(state, now, requestScope)
|
|
28670
28786
|
};
|
|
28671
28787
|
}
|
|
@@ -28822,7 +28938,7 @@ async function writeState(filePath, state) {
|
|
|
28822
28938
|
}
|
|
28823
28939
|
}
|
|
28824
28940
|
function normalizeIssueTransportState(value) {
|
|
28825
|
-
if (!
|
|
28941
|
+
if (!isRecord3(value)) return null;
|
|
28826
28942
|
const operation = typeof value.operation === "string" ? value.operation.trim() : "";
|
|
28827
28943
|
const issueId = typeof value.issueId === "string" ? value.issueId.trim() : "";
|
|
28828
28944
|
const scopeKey = typeof value.scopeKey === "string" && value.scopeKey.trim().length > 0 ? value.scopeKey.trim() : issueId ? `issue:${issueId}` : "";
|
|
@@ -28893,7 +29009,7 @@ function issueCommentPayload(value) {
|
|
|
28893
29009
|
} catch {
|
|
28894
29010
|
return null;
|
|
28895
29011
|
}
|
|
28896
|
-
if (!
|
|
29012
|
+
if (!isRecord3(parsed) || typeof parsed.body !== "string" || parsed.body.length === 0) return null;
|
|
28897
29013
|
return { body: parsed.body, reopen: parsed.reopen === true };
|
|
28898
29014
|
}
|
|
28899
29015
|
async function retireExpiredState(stateFilePath, state, now) {
|
|
@@ -28953,7 +29069,7 @@ function issueTransportStorageUnavailable(scope, surface) {
|
|
|
28953
29069
|
);
|
|
28954
29070
|
}
|
|
28955
29071
|
function normalizeFingerprint(value) {
|
|
28956
|
-
if (!
|
|
29072
|
+
if (!isRecord3(value) || typeof value.fingerprint !== "string" || typeof value.status !== "number" || typeof value.code !== "string" || typeof value.normalizedMessage !== "string") {
|
|
28957
29073
|
return void 0;
|
|
28958
29074
|
}
|
|
28959
29075
|
return {
|
|
@@ -28986,14 +29102,14 @@ function normalizeScopeValue(value) {
|
|
|
28986
29102
|
function transportSurfaceFromEnv() {
|
|
28987
29103
|
return process.env.RUDDER_TOOL_TRANSPORT_SURFACE === "mcp" ? "mcp" : "cli";
|
|
28988
29104
|
}
|
|
28989
|
-
function
|
|
29105
|
+
function isRecord3(value) {
|
|
28990
29106
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28991
29107
|
}
|
|
28992
29108
|
function isAlreadyExists(error) {
|
|
28993
|
-
return
|
|
29109
|
+
return isRecord3(error) && error.code === "EEXIST";
|
|
28994
29110
|
}
|
|
28995
29111
|
function isNotFound(error) {
|
|
28996
|
-
return
|
|
29112
|
+
return isRecord3(error) && error.code === "ENOENT";
|
|
28997
29113
|
}
|
|
28998
29114
|
|
|
28999
29115
|
// src/client/http.ts
|
|
@@ -29923,10 +30039,10 @@ function buildAgentV1ToolCallPlan(toolName, rawArgs, env = buildMcpServerEnv())
|
|
|
29923
30039
|
if (!capabilityId) {
|
|
29924
30040
|
throw new Error(`Unknown Rudder MCP tool: ${toolName}`);
|
|
29925
30041
|
}
|
|
29926
|
-
if (rawArgs !== void 0 && rawArgs !== null && !
|
|
30042
|
+
if (rawArgs !== void 0 && rawArgs !== null && !isRecord4(rawArgs)) {
|
|
29927
30043
|
throwInvalidMcpArgument(toolName, "arguments", "must be object");
|
|
29928
30044
|
}
|
|
29929
|
-
const input = normalizeLegacyToolArguments(capabilityId,
|
|
30045
|
+
const input = normalizeLegacyToolArguments(capabilityId, isRecord4(rawArgs) ? rawArgs : {});
|
|
29930
30046
|
const capability = getAgentCliCapabilityById(capabilityId);
|
|
29931
30047
|
rejectModelProvidedRuntimeIdentity(input);
|
|
29932
30048
|
rejectUnsupportedToolArguments(toolName, input);
|
|
@@ -30036,7 +30152,7 @@ async function runAgentV1McpJsonRpcMessage(message, env = buildMcpServerEnv(), s
|
|
|
30036
30152
|
case "tools/list": {
|
|
30037
30153
|
const tools = surface === "computer" ? computerCapabilityEnabled(env) ? COMPUTER_USE_MCP_TOOLS : [] : surface === "browser" && !browserCapabilityEnabled(env) ? [] : buildAgentV1McpToolsManifest("agent-v1", { surface }).tools.map(toMcpToolListEntry);
|
|
30038
30154
|
if (isModernMcpRequest(message.params)) {
|
|
30039
|
-
const cursor =
|
|
30155
|
+
const cursor = isRecord4(message.params) ? message.params.cursor : void 0;
|
|
30040
30156
|
if (typeof cursor === "string" && parseMcpToolCursor(cursor) === null) {
|
|
30041
30157
|
return rpcError(id, -32602, "Invalid tools/list cursor");
|
|
30042
30158
|
}
|
|
@@ -30190,7 +30306,7 @@ async function callToolSafely(params, env, surface, signal) {
|
|
|
30190
30306
|
const details = errorDetails(err);
|
|
30191
30307
|
const payload = {
|
|
30192
30308
|
status: "error",
|
|
30193
|
-
code:
|
|
30309
|
+
code: isRecord4(details) && typeof details.code === "string" ? details.code : "rudder_mcp_tool_error",
|
|
30194
30310
|
message: errorMessage(err),
|
|
30195
30311
|
details: details ?? null
|
|
30196
30312
|
};
|
|
@@ -30205,7 +30321,7 @@ async function callToolSafely(params, env, surface, signal) {
|
|
|
30205
30321
|
}
|
|
30206
30322
|
}
|
|
30207
30323
|
async function callTool(params, env, surface, signal) {
|
|
30208
|
-
const record =
|
|
30324
|
+
const record = isRecord4(params) ? params : {};
|
|
30209
30325
|
const toolName = typeof record.name === "string" ? record.name : "";
|
|
30210
30326
|
if (surface === "computer") {
|
|
30211
30327
|
if (!computerCapabilityEnabled(env)) {
|
|
@@ -30220,7 +30336,7 @@ async function callTool(params, env, surface, signal) {
|
|
|
30220
30336
|
error.code = "rudder_mcp_tool_not_available";
|
|
30221
30337
|
throw error;
|
|
30222
30338
|
}
|
|
30223
|
-
const rawArgs2 =
|
|
30339
|
+
const rawArgs2 = isRecord4(record.arguments) ? record.arguments : {};
|
|
30224
30340
|
rejectModelProvidedRuntimeIdentity(rawArgs2);
|
|
30225
30341
|
const parsed = computerUseActionSchemas[action].safeParse(rawArgs2);
|
|
30226
30342
|
if (!parsed.success) {
|
|
@@ -30239,7 +30355,7 @@ async function callTool(params, env, surface, signal) {
|
|
|
30239
30355
|
throw err;
|
|
30240
30356
|
}
|
|
30241
30357
|
const rawArgs = record.arguments;
|
|
30242
|
-
const args =
|
|
30358
|
+
const args = isRecord4(rawArgs) ? normalizeLegacyToolArguments(toolNameToCapabilityId(toolName) ?? "", rawArgs) : rawArgs;
|
|
30243
30359
|
const plan = buildAgentV1ToolCallPlan(toolName, args, env);
|
|
30244
30360
|
const directResult = await callToolDirectlyIfSupported(toolName, args, env, signal);
|
|
30245
30361
|
if (directResult) return directResult;
|
|
@@ -30283,7 +30399,7 @@ async function callTool(params, env, surface, signal) {
|
|
|
30283
30399
|
async function callToolDirectlyIfSupported(toolName, rawArgs, env, signal) {
|
|
30284
30400
|
const capabilityId = toolNameToCapabilityId(toolName);
|
|
30285
30401
|
if (!capabilityId) return null;
|
|
30286
|
-
const input =
|
|
30402
|
+
const input = isRecord4(rawArgs) ? rawArgs : {};
|
|
30287
30403
|
if (hasLocalImageInputs(input.images)) return null;
|
|
30288
30404
|
const api = mcpApiClient(env, signal);
|
|
30289
30405
|
const success = (data) => mcpSuccess(
|
|
@@ -30641,7 +30757,7 @@ function mcpApiClient(env, signal) {
|
|
|
30641
30757
|
});
|
|
30642
30758
|
}
|
|
30643
30759
|
function mcpSuccess(data, maxResultBytes = RUDDER_MCP_MAX_TOOL_RESULT_BYTES) {
|
|
30644
|
-
if (
|
|
30760
|
+
if (isRecord4(data) && (data.mimeType === "image/png" || data.mimeType === "image/jpeg") && typeof data.base64 === "string" && data.base64.length > 0) {
|
|
30645
30761
|
const { base64, ...metadata } = data;
|
|
30646
30762
|
return {
|
|
30647
30763
|
content: [{ type: "image", data: base64, mimeType: data.mimeType }],
|
|
@@ -30652,9 +30768,9 @@ function mcpSuccess(data, maxResultBytes = RUDDER_MCP_MAX_TOOL_RESULT_BYTES) {
|
|
|
30652
30768
|
return mcpSuccessFromJsonText(JSON.stringify(data ?? {}), maxResultBytes);
|
|
30653
30769
|
}
|
|
30654
30770
|
function mcpSuccessWithImages(data, maxResultBytes) {
|
|
30655
|
-
if (!
|
|
30771
|
+
if (!isRecord4(data) || !Array.isArray(data.images)) return mcpSuccess(data, maxResultBytes);
|
|
30656
30772
|
const images = data.images.filter(
|
|
30657
|
-
(entry) =>
|
|
30773
|
+
(entry) => isRecord4(entry) && (entry.mimeType === "image/png" || entry.mimeType === "image/jpeg") && typeof entry.base64 === "string" && entry.base64.length > 0
|
|
30658
30774
|
);
|
|
30659
30775
|
if (images.length === 0) return mcpSuccess(data, maxResultBytes);
|
|
30660
30776
|
const metadata = { ...data };
|
|
@@ -30899,7 +31015,7 @@ function cliArgsForCapability(capabilityId, input, tempFiles, env) {
|
|
|
30899
31015
|
}
|
|
30900
31016
|
case "issue.comment": {
|
|
30901
31017
|
const args = ["issue", "comment", requiredAnyString(input, ["issue", "issueId"])];
|
|
30902
|
-
pushBodyFile(args, "--body-file", input
|
|
31018
|
+
pushBodyFile(args, "--body-file", firstNonBlankString(input, ["body", "comment"]), tempFiles);
|
|
30903
31019
|
pushImages(args, input.images);
|
|
30904
31020
|
if (input.reopen === true) args.push("--reopen");
|
|
30905
31021
|
return args;
|
|
@@ -30925,15 +31041,16 @@ function cliArgsForCapability(capabilityId, input, tempFiles, env) {
|
|
|
30925
31041
|
pushOptional(args, "--request-depth", input.requestDepth);
|
|
30926
31042
|
pushOptional(args, "--billing-code", input.billingCode);
|
|
30927
31043
|
pushOptional(args, "--hidden-at", input.hiddenAt);
|
|
30928
|
-
|
|
30929
|
-
|
|
31044
|
+
const comment = firstNonBlankString(input, ["comment", "body"]);
|
|
31045
|
+
if (comment) {
|
|
31046
|
+
pushBodyFile(args, "--comment-file", comment, tempFiles);
|
|
30930
31047
|
}
|
|
30931
31048
|
pushImages(args, input.images);
|
|
30932
31049
|
return args;
|
|
30933
31050
|
}
|
|
30934
31051
|
case "issue.review": {
|
|
30935
31052
|
const args = ["issue", "review", requiredAnyString(input, ["issue", "issueId"]), "--decision", requiredString(input, "decision")];
|
|
30936
|
-
pushBodyFile(args, "--comment-file", input
|
|
31053
|
+
pushBodyFile(args, "--comment-file", firstNonBlankString(input, ["comment", "body"]), tempFiles);
|
|
30937
31054
|
return args;
|
|
30938
31055
|
}
|
|
30939
31056
|
case "issue.commit": {
|
|
@@ -30946,13 +31063,13 @@ function cliArgsForCapability(capabilityId, input, tempFiles, env) {
|
|
|
30946
31063
|
}
|
|
30947
31064
|
case "issue.done": {
|
|
30948
31065
|
const args = ["issue", "done", requiredAnyString(input, ["issue", "issueId"])];
|
|
30949
|
-
pushBodyFile(args, "--comment-file", input
|
|
31066
|
+
pushBodyFile(args, "--comment-file", firstNonBlankString(input, ["comment", "body"]), tempFiles);
|
|
30950
31067
|
pushImages(args, input.images);
|
|
30951
31068
|
return args;
|
|
30952
31069
|
}
|
|
30953
31070
|
case "issue.block": {
|
|
30954
31071
|
const args = ["issue", "block", requiredAnyString(input, ["issue", "issueId"])];
|
|
30955
|
-
pushBodyFile(args, "--comment-file", input
|
|
31072
|
+
pushBodyFile(args, "--comment-file", firstNonBlankString(input, ["comment", "body"]), tempFiles);
|
|
30956
31073
|
pushImages(args, input.images);
|
|
30957
31074
|
return args;
|
|
30958
31075
|
}
|
|
@@ -31016,7 +31133,7 @@ function cliArgsForCapability(capabilityId, input, tempFiles, env) {
|
|
|
31016
31133
|
return ["approval", "issues", requiredAnyString(input, ["approval", "approvalId"])];
|
|
31017
31134
|
case "approval.comment": {
|
|
31018
31135
|
const args = ["approval", "comment", requiredAnyString(input, ["approval", "approvalId"])];
|
|
31019
|
-
pushBodyFile(args, "--body-file", input
|
|
31136
|
+
pushBodyFile(args, "--body-file", firstNonBlankString(input, ["body", "comment"]), tempFiles);
|
|
31020
31137
|
return args;
|
|
31021
31138
|
}
|
|
31022
31139
|
case "skill.list":
|
|
@@ -31352,7 +31469,7 @@ function modernOrLegacyResult(params, result, options) {
|
|
|
31352
31469
|
}
|
|
31353
31470
|
function paginateMcpTools(tools, params) {
|
|
31354
31471
|
if (!isModernMcpRequest(params)) return { tools };
|
|
31355
|
-
const record =
|
|
31472
|
+
const record = isRecord4(params) ? params : {};
|
|
31356
31473
|
const cursor = typeof record.cursor === "string" ? record.cursor : null;
|
|
31357
31474
|
const offset = cursor === null ? 0 : parseMcpToolCursor(cursor) ?? 0;
|
|
31358
31475
|
const page = tools.slice(offset, offset + RUDDER_MCP_TOOL_PAGE_SIZE);
|
|
@@ -31375,7 +31492,7 @@ function parseMcpToolCursor(cursor) {
|
|
|
31375
31492
|
return null;
|
|
31376
31493
|
}
|
|
31377
31494
|
function requestedProtocolVersion(params) {
|
|
31378
|
-
if (!
|
|
31495
|
+
if (!isRecord4(params)) return null;
|
|
31379
31496
|
return typeof params.protocolVersion === "string" && params.protocolVersion.trim().length > 0 ? params.protocolVersion.trim() : null;
|
|
31380
31497
|
}
|
|
31381
31498
|
function toolNameToCapabilityId(toolName) {
|
|
@@ -31389,11 +31506,16 @@ function requiredString(input, key) {
|
|
|
31389
31506
|
throw new Error(`Missing required argument: ${key}`);
|
|
31390
31507
|
}
|
|
31391
31508
|
function requiredAnyString(input, keys) {
|
|
31509
|
+
const value = firstNonBlankString(input, keys);
|
|
31510
|
+
if (value) return value;
|
|
31511
|
+
throw new Error(`Missing required argument: ${keys[0]}`);
|
|
31512
|
+
}
|
|
31513
|
+
function firstNonBlankString(input, keys) {
|
|
31392
31514
|
for (const key of keys) {
|
|
31393
31515
|
const value = optionalString(input[key]);
|
|
31394
31516
|
if (value) return value;
|
|
31395
31517
|
}
|
|
31396
|
-
|
|
31518
|
+
return null;
|
|
31397
31519
|
}
|
|
31398
31520
|
function optionalString(value) {
|
|
31399
31521
|
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
@@ -31420,7 +31542,7 @@ function pushJson(args, flag, value) {
|
|
|
31420
31542
|
args.push(flag, value.trim());
|
|
31421
31543
|
return;
|
|
31422
31544
|
}
|
|
31423
|
-
if (
|
|
31545
|
+
if (isRecord4(value) || Array.isArray(value)) {
|
|
31424
31546
|
args.push(flag, JSON.stringify(value));
|
|
31425
31547
|
}
|
|
31426
31548
|
}
|
|
@@ -31477,106 +31599,6 @@ function rejectUnsupportedToolArguments(toolName, input) {
|
|
|
31477
31599
|
err.code = "rudder_mcp_invalid_arguments";
|
|
31478
31600
|
throw err;
|
|
31479
31601
|
}
|
|
31480
|
-
function validateMcpToolArguments(toolName, input) {
|
|
31481
|
-
const tool2 = buildAgentV1McpToolsManifest("agent-v1", { surface: "all" }).tools.find((entry) => entry.name === toolName);
|
|
31482
|
-
if (!tool2) return;
|
|
31483
|
-
const schema = tool2.inputSchema;
|
|
31484
|
-
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
31485
|
-
for (const key of required) {
|
|
31486
|
-
const value = input[key];
|
|
31487
|
-
const missing = value === void 0 || value === null || typeof value === "string" && value.trim().length === 0 || Array.isArray(value) && value.length === 0;
|
|
31488
|
-
if (missing) throwInvalidMcpArgument(toolName, key, "is required");
|
|
31489
|
-
}
|
|
31490
|
-
if (Array.isArray(schema.anyOf)) {
|
|
31491
|
-
const matches = schema.anyOf.some((candidate) => {
|
|
31492
|
-
if (!isRecord3(candidate) || !Array.isArray(candidate.required)) return false;
|
|
31493
|
-
return candidate.required.every((key) => {
|
|
31494
|
-
const value = input[String(key)];
|
|
31495
|
-
return value !== void 0 && value !== null && !(typeof value === "string" && value.trim().length === 0) && !(Array.isArray(value) && value.length === 0);
|
|
31496
|
-
});
|
|
31497
|
-
});
|
|
31498
|
-
if (!matches) {
|
|
31499
|
-
const alternatives = schema.anyOf.flatMap((candidate) => isRecord3(candidate) && Array.isArray(candidate.required) ? candidate.required : []).map(String);
|
|
31500
|
-
throwInvalidMcpArgument(toolName, alternatives.join(" or "), "is required");
|
|
31501
|
-
}
|
|
31502
|
-
}
|
|
31503
|
-
for (const [key, value] of Object.entries(input)) {
|
|
31504
|
-
const property = schema.properties[key];
|
|
31505
|
-
if (!isRecord3(property) || value === void 0) continue;
|
|
31506
|
-
const violation = jsonSchemaViolation(value, property);
|
|
31507
|
-
if (violation) throwInvalidMcpArgument(toolName, key, violation);
|
|
31508
|
-
}
|
|
31509
|
-
}
|
|
31510
|
-
function jsonSchemaViolation(value, schema) {
|
|
31511
|
-
if (Array.isArray(schema.oneOf)) {
|
|
31512
|
-
const matches = schema.oneOf.some(
|
|
31513
|
-
(candidate) => isRecord3(candidate) && jsonSchemaViolation(value, candidate) === null
|
|
31514
|
-
);
|
|
31515
|
-
if (!matches) return "does not match any allowed shape";
|
|
31516
|
-
}
|
|
31517
|
-
const types = Array.isArray(schema.type) ? schema.type : schema.type === void 0 ? [] : [schema.type];
|
|
31518
|
-
if (types.length > 0) {
|
|
31519
|
-
const validType = types.some((type) => type === "string" ? typeof value === "string" : type === "number" ? typeof value === "number" && Number.isFinite(value) : type === "boolean" ? typeof value === "boolean" : type === "array" ? Array.isArray(value) : type === "object" ? isRecord3(value) : false);
|
|
31520
|
-
if (!validType) return `must be ${types.join(" or ")}`;
|
|
31521
|
-
}
|
|
31522
|
-
if (typeof value === "string") {
|
|
31523
|
-
const characterLength = Array.from(value).length;
|
|
31524
|
-
if (typeof schema.minLength === "number" && characterLength < schema.minLength) {
|
|
31525
|
-
return `must contain at least ${schema.minLength} character(s)`;
|
|
31526
|
-
}
|
|
31527
|
-
if (typeof schema.maxLength === "number" && characterLength > schema.maxLength) {
|
|
31528
|
-
return `must contain at most ${schema.maxLength} characters`;
|
|
31529
|
-
}
|
|
31530
|
-
if (Array.isArray(schema.enum) && !schema.enum.includes(value)) {
|
|
31531
|
-
return `must be one of: ${schema.enum.join(", ")}`;
|
|
31532
|
-
}
|
|
31533
|
-
}
|
|
31534
|
-
if (typeof value === "number") {
|
|
31535
|
-
if (typeof schema.minimum === "number" && value < schema.minimum) {
|
|
31536
|
-
return `must be at least ${schema.minimum}`;
|
|
31537
|
-
}
|
|
31538
|
-
if (typeof schema.maximum === "number" && value > schema.maximum) {
|
|
31539
|
-
return `must be at most ${schema.maximum}`;
|
|
31540
|
-
}
|
|
31541
|
-
}
|
|
31542
|
-
if (Array.isArray(value)) {
|
|
31543
|
-
if (typeof schema.minItems === "number" && value.length < schema.minItems) {
|
|
31544
|
-
return `must contain at least ${schema.minItems} items`;
|
|
31545
|
-
}
|
|
31546
|
-
if (typeof schema.maxItems === "number" && value.length > schema.maxItems) {
|
|
31547
|
-
return `must contain at most ${schema.maxItems} items`;
|
|
31548
|
-
}
|
|
31549
|
-
if (isRecord3(schema.items)) {
|
|
31550
|
-
for (const [index, item] of value.entries()) {
|
|
31551
|
-
const violation = jsonSchemaViolation(item, schema.items);
|
|
31552
|
-
if (violation) return `item ${index} ${violation}`;
|
|
31553
|
-
}
|
|
31554
|
-
}
|
|
31555
|
-
}
|
|
31556
|
-
if (isRecord3(value) && schema.type === "object") {
|
|
31557
|
-
const properties = isRecord3(schema.properties) ? schema.properties : {};
|
|
31558
|
-
const required = Array.isArray(schema.required) ? schema.required.map(String) : [];
|
|
31559
|
-
for (const key of required) {
|
|
31560
|
-
if (!(key in value)) return `field ${key} is required`;
|
|
31561
|
-
}
|
|
31562
|
-
if (schema.additionalProperties === false) {
|
|
31563
|
-
const unsupported = Object.keys(value).filter((key) => !(key in properties));
|
|
31564
|
-
if (unsupported.length > 0) return `contains unsupported field(s): ${unsupported.sort().join(", ")}`;
|
|
31565
|
-
}
|
|
31566
|
-
for (const [key, child] of Object.entries(value)) {
|
|
31567
|
-
const childSchema = properties[key];
|
|
31568
|
-
if (!isRecord3(childSchema)) continue;
|
|
31569
|
-
const violation = jsonSchemaViolation(child, childSchema);
|
|
31570
|
-
if (violation) return `field ${key} ${violation}`;
|
|
31571
|
-
}
|
|
31572
|
-
}
|
|
31573
|
-
return null;
|
|
31574
|
-
}
|
|
31575
|
-
function throwInvalidMcpArgument(toolName, key, reason) {
|
|
31576
|
-
const err = new Error(`Invalid argument for ${toolName}: ${key} ${reason}. Consult tools/list for the exact schema.`);
|
|
31577
|
-
err.code = "rudder_mcp_invalid_arguments";
|
|
31578
|
-
throw err;
|
|
31579
|
-
}
|
|
31580
31602
|
var READ_ONLY_BROWSER_LOCATOR_ACTIONS = /* @__PURE__ */ new Set([
|
|
31581
31603
|
"count",
|
|
31582
31604
|
"allTextContents",
|
|
@@ -31627,7 +31649,7 @@ function assertBrowserCapabilityEnabled(capabilityId, env) {
|
|
|
31627
31649
|
function structuredContentFromJsonText(text6) {
|
|
31628
31650
|
try {
|
|
31629
31651
|
const parsed = JSON.parse(text6);
|
|
31630
|
-
if (
|
|
31652
|
+
if (isRecord4(parsed)) return { structuredContent: parsed };
|
|
31631
31653
|
return { structuredContent: { result: parsed } };
|
|
31632
31654
|
} catch {
|
|
31633
31655
|
return {};
|
|
@@ -31716,7 +31738,7 @@ function errorMessage(err) {
|
|
|
31716
31738
|
function errorDetails(err) {
|
|
31717
31739
|
if (!(err instanceof Error)) return void 0;
|
|
31718
31740
|
if (err instanceof ApiRequestError) {
|
|
31719
|
-
const details =
|
|
31741
|
+
const details = isRecord4(err.details) ? err.details : err.details === void 0 ? {} : { upstreamDetails: err.details };
|
|
31720
31742
|
return {
|
|
31721
31743
|
code: err.code ?? "api_request_error",
|
|
31722
31744
|
status: err.status,
|
|
@@ -31726,7 +31748,7 @@ function errorDetails(err) {
|
|
|
31726
31748
|
const code = err.code;
|
|
31727
31749
|
return code ? { code } : void 0;
|
|
31728
31750
|
}
|
|
31729
|
-
function
|
|
31751
|
+
function isRecord4(value) {
|
|
31730
31752
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31731
31753
|
}
|
|
31732
31754
|
|