@runpod/mcp-server 4.10.1 → 4.11.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/CHANGELOG.md +11 -0
- package/dist/{chunk-FQJFKWUV.mjs → chunk-24UOECYY.mjs} +19 -1
- package/dist/chunk-24UOECYY.mjs.map +1 -0
- package/dist/{chunk-AKX5ZMCL.mjs → chunk-4M7QDHK4.mjs} +312 -28
- package/dist/chunk-4M7QDHK4.mjs.map +1 -0
- package/dist/hosted.cjs +326 -26
- package/dist/hosted.cjs.map +1 -1
- package/dist/hosted.mjs +2 -2
- package/dist/http.cjs +326 -26
- package/dist/http.cjs.map +1 -1
- package/dist/http.mjs +2 -2
- package/dist/specgen/profile.cjs +19 -0
- package/dist/specgen/profile.cjs.map +1 -1
- package/dist/specgen/profile.d.cts +6 -3
- package/dist/specgen/profile.d.ts +6 -3
- package/dist/specgen/profile.mjs +3 -1
- package/dist/stdio.cjs +324 -25
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.mjs +324 -25
- package/dist/stdio.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-AKX5ZMCL.mjs.map +0 -1
- package/dist/chunk-FQJFKWUV.mjs.map +0 -1
package/dist/hosted.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
handleMcpRequest,
|
|
11
11
|
parseSearchRequest,
|
|
12
12
|
searchKnowledge
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-4M7QDHK4.mjs";
|
|
14
14
|
import {
|
|
15
15
|
ALP_REFERRAL_SOURCES,
|
|
16
16
|
ALP_REFERRAL_USE_CASES,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./chunk-577IYCJT.mjs";
|
|
21
21
|
import {
|
|
22
22
|
DIRECTORY_PATH
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-24UOECYY.mjs";
|
|
24
24
|
|
|
25
25
|
// src/alp/ingest.ts
|
|
26
26
|
var MAX_CONTENT_CHARS = 2e4;
|
package/dist/http.cjs
CHANGED
|
@@ -333,25 +333,16 @@ async function dispatchGeneratedTool(client, tool, args) {
|
|
|
333
333
|
const value = args[param.name];
|
|
334
334
|
query[param.name] = param.explode === false && Array.isArray(value) ? value.join(",") : value;
|
|
335
335
|
}
|
|
336
|
-
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
if (tool.hasBody && requestBody !== void 0) {
|
|
351
|
-
const properties = tool.inputSchema.properties ?? {};
|
|
352
|
-
const defs = tool.inputSchema.$defs ?? {};
|
|
353
|
-
requestBody = coerceScalars(requestBody, properties.body, defs);
|
|
354
|
-
}
|
|
336
|
+
const sent = tool.hasBody ? bodyAsSent(tool, args.body) : { body: args.body };
|
|
337
|
+
if (!sent)
|
|
338
|
+
return {
|
|
339
|
+
ok: false,
|
|
340
|
+
status: 400,
|
|
341
|
+
payload: {
|
|
342
|
+
error: "The body argument arrived as a string that is not valid JSON. Send body as an object."
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
const requestBody = sent.body;
|
|
355
346
|
const verbs = client;
|
|
356
347
|
const { data, error, response } = await verbs[tool.method](tool.path, {
|
|
357
348
|
params: { path: pathParams, query },
|
|
@@ -364,6 +355,32 @@ async function dispatchGeneratedTool(client, tool, args) {
|
|
|
364
355
|
payload: data ?? { status: response.status }
|
|
365
356
|
};
|
|
366
357
|
}
|
|
358
|
+
function bodyAsSent(tool, body) {
|
|
359
|
+
let parsed = body;
|
|
360
|
+
if (typeof parsed === "string") {
|
|
361
|
+
try {
|
|
362
|
+
parsed = JSON.parse(parsed);
|
|
363
|
+
} catch {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (parsed === void 0) return { body: parsed };
|
|
368
|
+
const properties = tool.inputSchema.properties ?? {};
|
|
369
|
+
const defs = tool.inputSchema.$defs ?? {};
|
|
370
|
+
return { body: coerceScalars(parsed, properties.body, defs) };
|
|
371
|
+
}
|
|
372
|
+
function argsAsSent(tool, args) {
|
|
373
|
+
if (!tool.hasBody || args.body === void 0) return args;
|
|
374
|
+
const sent = bodyAsSent(tool, args.body);
|
|
375
|
+
return sent ? { ...args, body: sent.body } : null;
|
|
376
|
+
}
|
|
377
|
+
function omittedEmptyQueryArg(tool) {
|
|
378
|
+
const required = new Set(tool.inputSchema.required ?? []);
|
|
379
|
+
const query = new Set(
|
|
380
|
+
tool.params.filter((p) => p.location === "query").map((p) => p.name)
|
|
381
|
+
);
|
|
382
|
+
return (name, value) => query.has(name) && !required.has(name) && isEmptyValue(value);
|
|
383
|
+
}
|
|
367
384
|
function isEmptyValue(value) {
|
|
368
385
|
return value === null || value === "" || Array.isArray(value) && !value.length;
|
|
369
386
|
}
|
|
@@ -2800,6 +2817,109 @@ var generatedTools = [
|
|
|
2800
2817
|
}
|
|
2801
2818
|
}
|
|
2802
2819
|
},
|
|
2820
|
+
{
|
|
2821
|
+
name: "exec-pod",
|
|
2822
|
+
title: "Run a command in a Pod",
|
|
2823
|
+
operationId: "execPod",
|
|
2824
|
+
description: `Run one command inside a running Pod's container and get stdout, stderr and the exit code back. No SSH key, public IP or exposed port is needed. command is an argv array run without a shell: pass ["sh", "-c", "..."] for pipes, redirects, globs or &&. One call waits at most timeoutSeconds (1-25, default 20). timedOut true means the call stopped waiting, NOT that the command stopped: it keeps running in the container. For anything longer (model downloads, pip installs, builds), start it in the background and log to a file, e.g. ["sh", "-c", "nohup wget -c -O /workspace/m.safetensors URL > /tmp/dl.log 2>&1 &"], then check progress with later calls (ls -la, du -h, tail /tmp/dl.log). stdout and stderr are each capped at 1 MiB (truncated true). Right after a create, the Pod can answer 404 "Pod not found" for about 10 seconds even with the right id, then 409 while its container starts: retry in about 10 seconds, a few times at most. A Pod that is not running answers 409. A host not yet updated for exec answers 503. Reaches only Pods owned by the API key's own account. Commands can change or delete data in the Pod: run write commands only for what the user asked.`,
|
|
2825
|
+
directoryDescription: "Run one command inside a running Pod's container and return stdout, stderr and the exit code. The command is an argv array run without a shell. One call waits at most timeoutSeconds (1-25, default 20); a command still running then keeps running in the container, and the result says timedOut. stdout and stderr are each capped at 1 MiB. A Pod that is not running answers 409, and a host not yet updated for exec answers 503. Reaches only Pods owned by the caller's own account. The command can change or delete data in the Pod.",
|
|
2826
|
+
method: "POST",
|
|
2827
|
+
path: "/v2/pods/{id}/exec",
|
|
2828
|
+
params: [
|
|
2829
|
+
{
|
|
2830
|
+
name: "id",
|
|
2831
|
+
location: "path"
|
|
2832
|
+
}
|
|
2833
|
+
],
|
|
2834
|
+
hasBody: true,
|
|
2835
|
+
annotations: {
|
|
2836
|
+
readOnlyHint: false,
|
|
2837
|
+
destructiveHint: true,
|
|
2838
|
+
idempotentHint: false,
|
|
2839
|
+
openWorldHint: true
|
|
2840
|
+
},
|
|
2841
|
+
inputSchema: {
|
|
2842
|
+
type: "object",
|
|
2843
|
+
properties: {
|
|
2844
|
+
id: {
|
|
2845
|
+
type: "string",
|
|
2846
|
+
description: "Pod identifier"
|
|
2847
|
+
},
|
|
2848
|
+
body: {
|
|
2849
|
+
$ref: "#/$defs/PodExecRequest",
|
|
2850
|
+
type: "object"
|
|
2851
|
+
}
|
|
2852
|
+
},
|
|
2853
|
+
required: ["id", "body"],
|
|
2854
|
+
$defs: {
|
|
2855
|
+
PodExecRequest: {
|
|
2856
|
+
type: "object",
|
|
2857
|
+
additionalProperties: false,
|
|
2858
|
+
required: ["command"],
|
|
2859
|
+
properties: {
|
|
2860
|
+
command: {
|
|
2861
|
+
type: "array",
|
|
2862
|
+
minItems: 1,
|
|
2863
|
+
maxItems: 256,
|
|
2864
|
+
prefixItems: [
|
|
2865
|
+
{
|
|
2866
|
+
type: "string",
|
|
2867
|
+
minLength: 1,
|
|
2868
|
+
maxLength: 4096,
|
|
2869
|
+
pattern: "^[^\\x00]*[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\\x00][^\\x00]*$"
|
|
2870
|
+
}
|
|
2871
|
+
],
|
|
2872
|
+
items: {
|
|
2873
|
+
type: "string",
|
|
2874
|
+
maxLength: 4096,
|
|
2875
|
+
pattern: "^[^\\x00]*$"
|
|
2876
|
+
},
|
|
2877
|
+
description: 'Command to run, as an argv array of 1-256 arguments of at most 4096 characters each. It is run directly, never through a shell; for pipes, redirects or globbing pass `["sh", "-c", "..."]`.',
|
|
2878
|
+
examples: [
|
|
2879
|
+
["nvidia-smi", "--query-gpu=name,memory.used", "--format=csv"]
|
|
2880
|
+
]
|
|
2881
|
+
},
|
|
2882
|
+
timeoutSeconds: {
|
|
2883
|
+
type: "integer",
|
|
2884
|
+
minimum: 1,
|
|
2885
|
+
maximum: 25,
|
|
2886
|
+
default: 20,
|
|
2887
|
+
description: "How long the call waits for the command to finish, in seconds. A command still running at this point returns with `timedOut: true`.",
|
|
2888
|
+
examples: [10]
|
|
2889
|
+
},
|
|
2890
|
+
cwd: {
|
|
2891
|
+
type: "string",
|
|
2892
|
+
pattern: "^/[^\\x00-\\x1f\\x7f]*$",
|
|
2893
|
+
maxLength: 1024,
|
|
2894
|
+
description: "Absolute working directory for the command, at most 1024 characters and without control characters. Defaults to the image's `WORKDIR`.",
|
|
2895
|
+
examples: ["/workspace"]
|
|
2896
|
+
},
|
|
2897
|
+
env: {
|
|
2898
|
+
type: "object",
|
|
2899
|
+
maxProperties: 64,
|
|
2900
|
+
propertyNames: {
|
|
2901
|
+
type: "string",
|
|
2902
|
+
minLength: 1,
|
|
2903
|
+
maxLength: 256,
|
|
2904
|
+
pattern: "^[^=\\x00]+$"
|
|
2905
|
+
},
|
|
2906
|
+
additionalProperties: {
|
|
2907
|
+
type: "string",
|
|
2908
|
+
maxLength: 16384,
|
|
2909
|
+
pattern: "^[^\\x00]*$"
|
|
2910
|
+
},
|
|
2911
|
+
description: "Up to 64 environment variables added to the container's environment for this command only. A name is 1-256 characters and must not contain `=` or a NUL character; a value is at most 16384 characters and must not contain a NUL character.",
|
|
2912
|
+
examples: [
|
|
2913
|
+
{
|
|
2914
|
+
HF_HOME: "/workspace/hf"
|
|
2915
|
+
}
|
|
2916
|
+
]
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
},
|
|
2803
2923
|
{
|
|
2804
2924
|
name: "get-cluster",
|
|
2805
2925
|
title: "Get cluster",
|
|
@@ -6862,6 +6982,122 @@ var generatedTools = [
|
|
|
6862
6982
|
}
|
|
6863
6983
|
];
|
|
6864
6984
|
|
|
6985
|
+
// src/specgen/validate.ts
|
|
6986
|
+
var import__ = require("ajv/dist/2020.js");
|
|
6987
|
+
function schemaValidationMode(value = process.env.MCP_SCHEMA_VALIDATION) {
|
|
6988
|
+
const mode = value?.trim().toLowerCase();
|
|
6989
|
+
return mode === "off" || mode === "enforce" ? mode : "shadow";
|
|
6990
|
+
}
|
|
6991
|
+
var ajv = new import__.Ajv2020({
|
|
6992
|
+
strict: false,
|
|
6993
|
+
allErrors: true,
|
|
6994
|
+
validateFormats: false
|
|
6995
|
+
});
|
|
6996
|
+
var compiled = /* @__PURE__ */ new WeakMap();
|
|
6997
|
+
function validatorFor(schema) {
|
|
6998
|
+
let validate = compiled.get(schema);
|
|
6999
|
+
if (!validate) {
|
|
7000
|
+
validate = ajv.compile(structuredClone(schema));
|
|
7001
|
+
compiled.set(schema, validate);
|
|
7002
|
+
}
|
|
7003
|
+
return validate;
|
|
7004
|
+
}
|
|
7005
|
+
var MAX_NULL_PASSES = 8;
|
|
7006
|
+
function isNullTypeError(error, data) {
|
|
7007
|
+
return error.keyword === "type" && error.instancePath !== "" && valueAt(data, error.instancePath) === null;
|
|
7008
|
+
}
|
|
7009
|
+
function pointerSegments(pointer) {
|
|
7010
|
+
return pointer.split("/").slice(1).map((s) => s.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
7011
|
+
}
|
|
7012
|
+
function valueAt(data, pointer) {
|
|
7013
|
+
let node = data;
|
|
7014
|
+
for (const key of pointerSegments(pointer)) {
|
|
7015
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
7016
|
+
node = node[key];
|
|
7017
|
+
}
|
|
7018
|
+
return node;
|
|
7019
|
+
}
|
|
7020
|
+
function removeAt(data, pointer) {
|
|
7021
|
+
const segments = pointerSegments(pointer);
|
|
7022
|
+
const last = segments.pop();
|
|
7023
|
+
const parent = valueAt(data, segments.length ? `/${segments.join("/")}` : "");
|
|
7024
|
+
if (last === void 0 || parent === null || typeof parent !== "object")
|
|
7025
|
+
return false;
|
|
7026
|
+
if (Array.isArray(parent)) return false;
|
|
7027
|
+
delete parent[last];
|
|
7028
|
+
return true;
|
|
7029
|
+
}
|
|
7030
|
+
var WRAPPER_KEYWORDS = /* @__PURE__ */ new Set(["if"]);
|
|
7031
|
+
function toViolation(error) {
|
|
7032
|
+
const base = pointerSegments(error.instancePath);
|
|
7033
|
+
let path = base.join(".");
|
|
7034
|
+
let message = error.message ?? "is invalid";
|
|
7035
|
+
const params = error.params;
|
|
7036
|
+
if (error.keyword === "required" && typeof params.missingProperty === "string") {
|
|
7037
|
+
path = [...base, params.missingProperty].join(".");
|
|
7038
|
+
message = "is required";
|
|
7039
|
+
} else if (error.keyword === "additionalProperties" && typeof params.additionalProperty === "string") {
|
|
7040
|
+
path = [...base, params.additionalProperty].join(".");
|
|
7041
|
+
message = "is not an accepted argument here";
|
|
7042
|
+
} else if (error.keyword === "pattern") {
|
|
7043
|
+
message = "is not in an accepted format";
|
|
7044
|
+
}
|
|
7045
|
+
const allowed = error.keyword === "enum" ? params.allowedValues : error.keyword === "const" ? [params.allowedValue] : void 0;
|
|
7046
|
+
return {
|
|
7047
|
+
path,
|
|
7048
|
+
keyword: error.keyword,
|
|
7049
|
+
message,
|
|
7050
|
+
...allowed ? { allowed } : {},
|
|
7051
|
+
schemaPath: error.schemaPath
|
|
7052
|
+
};
|
|
7053
|
+
}
|
|
7054
|
+
function schemaViolations(schema, args, omitted = () => false) {
|
|
7055
|
+
const validate = validatorFor(schema);
|
|
7056
|
+
const data = structuredClone(
|
|
7057
|
+
Object.fromEntries(
|
|
7058
|
+
Object.entries(args).filter(([name, value]) => !omitted(name, value))
|
|
7059
|
+
)
|
|
7060
|
+
);
|
|
7061
|
+
for (let pass = 0; ; pass++) {
|
|
7062
|
+
if (validate(data)) return [];
|
|
7063
|
+
const errors = validate.errors ?? [];
|
|
7064
|
+
let removed = false;
|
|
7065
|
+
if (pass < MAX_NULL_PASSES) {
|
|
7066
|
+
for (const error of errors.filter((e) => isNullTypeError(e, data)))
|
|
7067
|
+
removed = removeAt(data, error.instancePath) || removed;
|
|
7068
|
+
}
|
|
7069
|
+
if (!removed) {
|
|
7070
|
+
return errors.filter((e) => !WRAPPER_KEYWORDS.has(e.keyword)).map(toViolation);
|
|
7071
|
+
}
|
|
7072
|
+
}
|
|
7073
|
+
}
|
|
7074
|
+
var INVALID_ARGUMENTS_HINT = "Fix the listed fields and call again.";
|
|
7075
|
+
function invalidArgumentsPayload(violations) {
|
|
7076
|
+
return {
|
|
7077
|
+
error: "Invalid arguments",
|
|
7078
|
+
code: "invalid_arguments",
|
|
7079
|
+
fields: violations.map(({ path, message, allowed }) => ({
|
|
7080
|
+
path,
|
|
7081
|
+
problem: message,
|
|
7082
|
+
...allowed ? { allowed } : {}
|
|
7083
|
+
})),
|
|
7084
|
+
hint: INVALID_ARGUMENTS_HINT
|
|
7085
|
+
};
|
|
7086
|
+
}
|
|
7087
|
+
function logSchemaViolations(tool, mode, violations) {
|
|
7088
|
+
console.error(
|
|
7089
|
+
"schema_violation",
|
|
7090
|
+
JSON.stringify({
|
|
7091
|
+
tool,
|
|
7092
|
+
mode,
|
|
7093
|
+
violations: violations.map(({ keyword, schemaPath }) => ({
|
|
7094
|
+
keyword,
|
|
7095
|
+
schemaPath
|
|
7096
|
+
}))
|
|
7097
|
+
})
|
|
7098
|
+
);
|
|
7099
|
+
}
|
|
7100
|
+
|
|
6865
7101
|
// src/specgen/tools/annotations.ts
|
|
6866
7102
|
var readOnly = {
|
|
6867
7103
|
readOnlyHint: true,
|
|
@@ -7076,6 +7312,8 @@ var DIRECTORY_TOOLS = {
|
|
|
7076
7312
|
"deploy-hub-repo": IN,
|
|
7077
7313
|
"detach-cost-center-resource": IN,
|
|
7078
7314
|
"endpoint-health": IN,
|
|
7315
|
+
// env can carry tokens (HF_TOKEN for a model download), so the directory omits it.
|
|
7316
|
+
"exec-pod": { include: true, omitInputs: ["body.env"] },
|
|
7079
7317
|
"get-capacity": IN,
|
|
7080
7318
|
"get-cluster": IN,
|
|
7081
7319
|
"get-cost-center": IN,
|
|
@@ -7195,6 +7433,21 @@ function directoryOmittedInputs(name) {
|
|
|
7195
7433
|
const decision = DIRECTORY_TOOLS[name];
|
|
7196
7434
|
return decision?.include ? decision.omitInputs ?? [] : [];
|
|
7197
7435
|
}
|
|
7436
|
+
function omittedInputsIn(omit, args) {
|
|
7437
|
+
return omit.filter((key) => {
|
|
7438
|
+
const [parent, child] = key.split(".");
|
|
7439
|
+
if (child === void 0) return parent in args;
|
|
7440
|
+
let value = args[parent];
|
|
7441
|
+
if (typeof value === "string") {
|
|
7442
|
+
try {
|
|
7443
|
+
value = JSON.parse(value);
|
|
7444
|
+
} catch {
|
|
7445
|
+
return false;
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
return !!value && typeof value === "object" && child in value;
|
|
7449
|
+
});
|
|
7450
|
+
}
|
|
7198
7451
|
function profileForPath(pathname) {
|
|
7199
7452
|
return pathname.replace(/\/+$/, "") === DIRECTORY_PATH ? "directory" : "default";
|
|
7200
7453
|
}
|
|
@@ -10784,13 +11037,40 @@ function withoutCredentialExamples(schema) {
|
|
|
10784
11037
|
};
|
|
10785
11038
|
return strip(schema);
|
|
10786
11039
|
}
|
|
10787
|
-
function
|
|
10788
|
-
if (!omit.length) return schema;
|
|
11040
|
+
function withoutKeys(schema, omit) {
|
|
10789
11041
|
const properties = { ...schema.properties ?? {} };
|
|
10790
11042
|
for (const key of omit) delete properties[key];
|
|
10791
11043
|
const required = Array.isArray(schema.required) ? schema.required.filter((key) => !omit.includes(key)) : schema.required;
|
|
10792
11044
|
return { ...schema, properties, ...required ? { required } : {} };
|
|
10793
11045
|
}
|
|
11046
|
+
function withoutInputs(schema, omit) {
|
|
11047
|
+
if (!omit.length) return schema;
|
|
11048
|
+
let out = withoutKeys(
|
|
11049
|
+
schema,
|
|
11050
|
+
omit.filter((key) => !key.includes("."))
|
|
11051
|
+
);
|
|
11052
|
+
for (const key of omit.filter((k) => k.includes("."))) {
|
|
11053
|
+
const [parent, child] = key.split(".");
|
|
11054
|
+
const properties = out.properties ?? {};
|
|
11055
|
+
const node = properties[parent];
|
|
11056
|
+
if (!node) continue;
|
|
11057
|
+
const ref = typeof node.$ref === "string" ? node.$ref : void 0;
|
|
11058
|
+
const defName = ref?.startsWith("#/$defs/") ? ref.slice(8) : void 0;
|
|
11059
|
+
const defs = out.$defs ?? {};
|
|
11060
|
+
if (defName && defs[defName]) {
|
|
11061
|
+
out = {
|
|
11062
|
+
...out,
|
|
11063
|
+
$defs: { ...defs, [defName]: withoutKeys(defs[defName], [child]) }
|
|
11064
|
+
};
|
|
11065
|
+
} else {
|
|
11066
|
+
out = {
|
|
11067
|
+
...out,
|
|
11068
|
+
properties: { ...properties, [parent]: withoutKeys(node, [child]) }
|
|
11069
|
+
};
|
|
11070
|
+
}
|
|
11071
|
+
}
|
|
11072
|
+
return out;
|
|
11073
|
+
}
|
|
10794
11074
|
function callShape(schema) {
|
|
10795
11075
|
const defs = schema.$defs ?? {};
|
|
10796
11076
|
const resolve = (node) => {
|
|
@@ -10892,7 +11172,7 @@ function words2(name) {
|
|
|
10892
11172
|
|
|
10893
11173
|
// src/server.ts
|
|
10894
11174
|
var SERVER_NAME = "Runpod API Server";
|
|
10895
|
-
var SERVER_VERSION = true ? "4.
|
|
11175
|
+
var SERVER_VERSION = true ? "4.11.0" : "dev";
|
|
10896
11176
|
|
|
10897
11177
|
// src/specgen/analytics.ts
|
|
10898
11178
|
var import_node_crypto = require("crypto");
|
|
@@ -11513,6 +11793,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
11513
11793
|
const caller = callerId(ctx.apiKey);
|
|
11514
11794
|
const profile = opts.profile ?? "default";
|
|
11515
11795
|
const directory = profile === "directory";
|
|
11796
|
+
const schemaMode = schemaValidationMode();
|
|
11516
11797
|
const alp = directory ? void 0 : opts.alp;
|
|
11517
11798
|
const servedGeneratedTools = directory ? generatedTools.filter((tool) => directoryIncludes(tool.name)) : generatedTools;
|
|
11518
11799
|
const servedCuratedTools = [
|
|
@@ -11619,7 +11900,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
11619
11900
|
(tool) => tool.name === request.params.name
|
|
11620
11901
|
);
|
|
11621
11902
|
const curatedArgs = curated ? withoutNullOptionals(curated.inputSchema, args) : args;
|
|
11622
|
-
const omitted = directory ? directoryOmittedInputs(request.params.name)
|
|
11903
|
+
const omitted = directory ? omittedInputsIn(directoryOmittedInputs(request.params.name), args) : [];
|
|
11623
11904
|
const rejected = omitted.length ? {
|
|
11624
11905
|
ok: false,
|
|
11625
11906
|
status: 400,
|
|
@@ -11629,8 +11910,26 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
11629
11910
|
} : curated && !curated.lenientArguments ? validateArguments(
|
|
11630
11911
|
curated.inputSchema,
|
|
11631
11912
|
curatedArgs
|
|
11632
|
-
) : null;
|
|
11633
|
-
|
|
11913
|
+
) : generated ? validateArguments(generated.inputSchema, args) : null;
|
|
11914
|
+
let schemaRejected = null;
|
|
11915
|
+
if (!rejected && schemaMode !== "off") {
|
|
11916
|
+
const sent = generated ? argsAsSent(generated, args) : null;
|
|
11917
|
+
const violations = curated ? curated.lenientArguments ? [] : schemaViolations(curated.inputSchema, curatedArgs) : generated && sent ? schemaViolations(
|
|
11918
|
+
generated.inputSchema,
|
|
11919
|
+
sent,
|
|
11920
|
+
omittedEmptyQueryArg(generated)
|
|
11921
|
+
) : [];
|
|
11922
|
+
if (violations.length) {
|
|
11923
|
+
logSchemaViolations(request.params.name, schemaMode, violations);
|
|
11924
|
+
if (schemaMode === "enforce")
|
|
11925
|
+
schemaRejected = {
|
|
11926
|
+
ok: false,
|
|
11927
|
+
status: 400,
|
|
11928
|
+
payload: invalidArgumentsPayload(violations)
|
|
11929
|
+
};
|
|
11930
|
+
}
|
|
11931
|
+
}
|
|
11932
|
+
const result = rejected ?? schemaRejected ?? await runTool(
|
|
11634
11933
|
() => curated ? curated.handler(ctx, curatedArgs) : dispatchTool(generated, request.params.name, args)
|
|
11635
11934
|
);
|
|
11636
11935
|
logToolCall({
|
|
@@ -11969,6 +12268,7 @@ function createToolContext(options = {}) {
|
|
|
11969
12268
|
|
|
11970
12269
|
// src/specgen/not-found-limiter.ts
|
|
11971
12270
|
var SINK_TIMEOUT_MS = 3e3;
|
|
12271
|
+
var LOOP_LIMITED_TOOLS = /* @__PURE__ */ new Set(["get-pod"]);
|
|
11972
12272
|
var NOT_FOUND_LOOP = "not_found_loop";
|
|
11973
12273
|
var blocked = /* @__PURE__ */ new Map();
|
|
11974
12274
|
function notFoundSinkUrl(submitUrl) {
|
|
@@ -11993,7 +12293,7 @@ function createNotFoundLimiter(opts) {
|
|
|
11993
12293
|
};
|
|
11994
12294
|
},
|
|
11995
12295
|
onToolResult: (tool, status) => {
|
|
11996
|
-
if (status !== 404) return;
|
|
12296
|
+
if (status !== 404 || !LOOP_LIMITED_TOOLS.has(tool)) return;
|
|
11997
12297
|
const pair = `${opts.key}|${tool}`;
|
|
11998
12298
|
void fetchImpl(opts.sinkUrl, {
|
|
11999
12299
|
method: "POST",
|