@runpod/mcp-server 4.7.0 → 4.8.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 +12 -0
- package/README.md +3 -0
- package/dist/chunk-6IETGSON.mjs +135 -0
- package/dist/chunk-6IETGSON.mjs.map +1 -0
- package/dist/http.cjs +115 -8
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +1 -2
- package/dist/http.d.ts +1 -2
- package/dist/http.mjs +120 -133
- package/dist/http.mjs.map +1 -1
- package/dist/specgen/profile.cjs +163 -0
- package/dist/specgen/profile.cjs.map +1 -0
- package/dist/specgen/profile.d.cts +22 -0
- package/dist/specgen/profile.d.ts +22 -0
- package/dist/specgen/profile.mjs +15 -0
- package/dist/specgen/profile.mjs.map +1 -0
- package/dist/stdio.cjs +115 -8
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.mjs +115 -8
- package/dist/stdio.mjs.map +1 -1
- package/package.json +7 -2
package/dist/http.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { ServerProfile } from './specgen/profile.cjs';
|
|
2
3
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
4
|
|
|
4
5
|
type CredentialVerdict = {
|
|
@@ -32,8 +33,6 @@ interface RpcSummary {
|
|
|
32
33
|
client?: string;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
type ServerProfile = 'default' | 'directory';
|
|
36
|
-
|
|
37
36
|
/**
|
|
38
37
|
* Extract the bearer token from an HTTP request's Authorization header.
|
|
39
38
|
* Returns null if the header is missing or malformed.
|
package/dist/http.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { ServerProfile } from './specgen/profile.js';
|
|
2
3
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
4
|
|
|
4
5
|
type CredentialVerdict = {
|
|
@@ -32,8 +33,6 @@ interface RpcSummary {
|
|
|
32
33
|
client?: string;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
type ServerProfile = 'default' | 'directory';
|
|
36
|
-
|
|
37
36
|
/**
|
|
38
37
|
* Extract the bearer token from an HTTP request's Authorization header.
|
|
39
38
|
* Returns null if the header is missing or malformed.
|
package/dist/http.mjs
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DIRECTORY_PATH,
|
|
3
|
+
directoryIncludes,
|
|
4
|
+
directoryOmittedInputs,
|
|
5
|
+
profileForPath
|
|
6
|
+
} from "./chunk-6IETGSON.mjs";
|
|
7
|
+
|
|
1
8
|
// src/http.ts
|
|
2
9
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
3
10
|
import {
|
|
@@ -543,9 +550,36 @@ var generatedTools = [
|
|
|
543
550
|
},
|
|
544
551
|
ClusterMounts: {
|
|
545
552
|
description: "Storage mounts for a cluster create: `persistent` or `network`, not both. Clusters cannot mount global volumes, so `global` is rejected.",
|
|
553
|
+
"x-go-type": "BaseMounts",
|
|
546
554
|
allOf: [
|
|
547
555
|
{
|
|
548
556
|
$ref: "#/$defs/BaseMounts"
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
type: "object",
|
|
560
|
+
properties: {
|
|
561
|
+
persistent: {
|
|
562
|
+
type: "object",
|
|
563
|
+
properties: {
|
|
564
|
+
path: {
|
|
565
|
+
type: "string",
|
|
566
|
+
minLength: 1
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
network: {
|
|
571
|
+
type: "array",
|
|
572
|
+
items: {
|
|
573
|
+
type: "object",
|
|
574
|
+
properties: {
|
|
575
|
+
path: {
|
|
576
|
+
type: "string",
|
|
577
|
+
minLength: 1
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
549
583
|
}
|
|
550
584
|
],
|
|
551
585
|
unevaluatedProperties: false
|
|
@@ -2621,6 +2655,37 @@ var generatedTools = [
|
|
|
2621
2655
|
properties: {}
|
|
2622
2656
|
}
|
|
2623
2657
|
},
|
|
2658
|
+
{
|
|
2659
|
+
name: "get-organization-user",
|
|
2660
|
+
title: "Get organization user",
|
|
2661
|
+
operationId: "getOrganizationUser",
|
|
2662
|
+
description: "Get an organization member. Returns one member of the authenticated caller's organization by user ID, with the role they hold. Any member can read it. A user who is not a member, including one from another organization, returns 404. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
2663
|
+
method: "GET",
|
|
2664
|
+
path: "/v2/organization/users/{id}",
|
|
2665
|
+
params: [
|
|
2666
|
+
{
|
|
2667
|
+
name: "id",
|
|
2668
|
+
location: "path"
|
|
2669
|
+
}
|
|
2670
|
+
],
|
|
2671
|
+
hasBody: false,
|
|
2672
|
+
annotations: {
|
|
2673
|
+
readOnlyHint: true,
|
|
2674
|
+
destructiveHint: false,
|
|
2675
|
+
idempotentHint: true,
|
|
2676
|
+
openWorldHint: true
|
|
2677
|
+
},
|
|
2678
|
+
inputSchema: {
|
|
2679
|
+
type: "object",
|
|
2680
|
+
properties: {
|
|
2681
|
+
id: {
|
|
2682
|
+
type: "string",
|
|
2683
|
+
description: "User identifier"
|
|
2684
|
+
}
|
|
2685
|
+
},
|
|
2686
|
+
required: ["id"]
|
|
2687
|
+
}
|
|
2688
|
+
},
|
|
2624
2689
|
{
|
|
2625
2690
|
name: "get-pod",
|
|
2626
2691
|
title: "Get Pod",
|
|
@@ -3760,6 +3825,26 @@ var generatedTools = [
|
|
|
3760
3825
|
}
|
|
3761
3826
|
}
|
|
3762
3827
|
},
|
|
3828
|
+
{
|
|
3829
|
+
name: "list-organization-users",
|
|
3830
|
+
title: "List organization users",
|
|
3831
|
+
operationId: "listOrganizationUsers",
|
|
3832
|
+
description: "List organization members. Returns every member of the authenticated caller's organization with the role each holds. Any member can read the roster. The list is complete and takes no pagination parameters. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
3833
|
+
method: "GET",
|
|
3834
|
+
path: "/v2/organization/users",
|
|
3835
|
+
params: [],
|
|
3836
|
+
hasBody: false,
|
|
3837
|
+
annotations: {
|
|
3838
|
+
readOnlyHint: true,
|
|
3839
|
+
destructiveHint: false,
|
|
3840
|
+
idempotentHint: true,
|
|
3841
|
+
openWorldHint: true
|
|
3842
|
+
},
|
|
3843
|
+
inputSchema: {
|
|
3844
|
+
type: "object",
|
|
3845
|
+
properties: {}
|
|
3846
|
+
}
|
|
3847
|
+
},
|
|
3763
3848
|
{
|
|
3764
3849
|
name: "list-pod-billing",
|
|
3765
3850
|
title: "List Pod billing",
|
|
@@ -5316,6 +5401,7 @@ function networkFailureResult(error) {
|
|
|
5316
5401
|
return {
|
|
5317
5402
|
ok: false,
|
|
5318
5403
|
status: unreached ? 503 : 502,
|
|
5404
|
+
requestDelivery: unreached ? "not_sent" : "uncertain",
|
|
5319
5405
|
payload: unreached ? {
|
|
5320
5406
|
error: "Could not reach the Runpod API.",
|
|
5321
5407
|
cause: code,
|
|
@@ -5342,6 +5428,7 @@ async function runTool(body) {
|
|
|
5342
5428
|
return {
|
|
5343
5429
|
ok: false,
|
|
5344
5430
|
status: 504,
|
|
5431
|
+
requestDelivery: "uncertain",
|
|
5345
5432
|
payload: {
|
|
5346
5433
|
error: "The Runpod API did not respond before the request deadline.",
|
|
5347
5434
|
hint: "Transient upstream stall: retry the same call once; if it persists, check https://uptime.runpod.io."
|
|
@@ -5400,131 +5487,6 @@ var podTransitionTools = [
|
|
|
5400
5487
|
)
|
|
5401
5488
|
];
|
|
5402
5489
|
|
|
5403
|
-
// src/specgen/profile.ts
|
|
5404
|
-
var DIRECTORY_PATH = "/directory";
|
|
5405
|
-
var IN = { include: true };
|
|
5406
|
-
var CREDENTIAL_MANAGEMENT = "Manages stored credentials; OpenAI restricts plugins that handle access credentials, so the directory leaves the whole credential family out.";
|
|
5407
|
-
var CREDENTIAL_INPUT = "Takes a secret or password as input; directories forbid collecting credentials.";
|
|
5408
|
-
var ALP = "Collects conversation-derived data beyond the task; the directory profile never serves it.";
|
|
5409
|
-
var DIRECTORY_TOOLS = {
|
|
5410
|
-
"cancel-job": IN,
|
|
5411
|
-
"create-cluster": IN,
|
|
5412
|
-
"create-delegation": IN,
|
|
5413
|
-
"create-endpoint": IN,
|
|
5414
|
-
"create-global-volume": IN,
|
|
5415
|
-
"create-network-volume": IN,
|
|
5416
|
-
"create-pod": IN,
|
|
5417
|
-
"create-template": IN,
|
|
5418
|
-
"delete-cluster": IN,
|
|
5419
|
-
"delete-endpoint": IN,
|
|
5420
|
-
"delete-global-volume": IN,
|
|
5421
|
-
"delete-network-volume": IN,
|
|
5422
|
-
"delete-pod": IN,
|
|
5423
|
-
"delete-template": IN,
|
|
5424
|
-
"deploy-hub-repo": IN,
|
|
5425
|
-
"endpoint-health": IN,
|
|
5426
|
-
"get-capacity": IN,
|
|
5427
|
-
"get-cluster": IN,
|
|
5428
|
-
"get-cpu-type": IN,
|
|
5429
|
-
"get-data-center": IN,
|
|
5430
|
-
"get-endpoint": IN,
|
|
5431
|
-
"get-endpoint-build": IN,
|
|
5432
|
-
"get-global-volume": IN,
|
|
5433
|
-
"get-gpu-type": IN,
|
|
5434
|
-
"get-job-status": IN,
|
|
5435
|
-
"get-network-volume": IN,
|
|
5436
|
-
"get-organization": IN,
|
|
5437
|
-
"get-pod": IN,
|
|
5438
|
-
"get-ssh-keys": IN,
|
|
5439
|
-
"get-template": IN,
|
|
5440
|
-
"list-audit-logs": IN,
|
|
5441
|
-
"list-billing": IN,
|
|
5442
|
-
"list-cluster-billing": IN,
|
|
5443
|
-
"list-cluster-pods": IN,
|
|
5444
|
-
"list-clusters": IN,
|
|
5445
|
-
"list-cpu-types": IN,
|
|
5446
|
-
"list-data-centers": IN,
|
|
5447
|
-
"list-delegations": IN,
|
|
5448
|
-
"list-endpoint-billing": IN,
|
|
5449
|
-
"list-endpoint-builds": IN,
|
|
5450
|
-
"list-endpoint-releases": IN,
|
|
5451
|
-
"list-endpoint-workers": IN,
|
|
5452
|
-
"list-endpoints": IN,
|
|
5453
|
-
"list-global-volumes": IN,
|
|
5454
|
-
"list-gpu-types": IN,
|
|
5455
|
-
"list-hub-repos": IN,
|
|
5456
|
-
"list-network-volume-billing": IN,
|
|
5457
|
-
"list-network-volumes": IN,
|
|
5458
|
-
"list-pod-billing": IN,
|
|
5459
|
-
"list-pods": IN,
|
|
5460
|
-
"list-public-endpoints": IN,
|
|
5461
|
-
"list-public-templates": IN,
|
|
5462
|
-
"list-serverless-billing": IN,
|
|
5463
|
-
"list-templates": IN,
|
|
5464
|
-
"lookup-concept": IN,
|
|
5465
|
-
"purge-endpoint-queue": IN,
|
|
5466
|
-
"retry-job": IN,
|
|
5467
|
-
"revoke-delegation": IN,
|
|
5468
|
-
"search-concepts": IN,
|
|
5469
|
-
"search-docs": IN,
|
|
5470
|
-
"set-endpoint-gpus": IN,
|
|
5471
|
-
"stream-job": IN,
|
|
5472
|
-
"stream-pod-logs": IN,
|
|
5473
|
-
"stream-worker-logs": IN,
|
|
5474
|
-
"update-cluster": IN,
|
|
5475
|
-
"update-endpoint": IN,
|
|
5476
|
-
"update-global-volume": IN,
|
|
5477
|
-
"update-network-volume": IN,
|
|
5478
|
-
"update-pod": IN,
|
|
5479
|
-
"update-ssh-keys": IN,
|
|
5480
|
-
"update-template": IN,
|
|
5481
|
-
"run-endpoint": { include: true, omitInputs: ["s3Config"] },
|
|
5482
|
-
"runsync-endpoint": { include: true, omitInputs: ["s3Config"] },
|
|
5483
|
-
"pod-action": {
|
|
5484
|
-
include: false,
|
|
5485
|
-
reason: "Takes the transition as an argument; OpenAI asks for one tool per operation, so the directory serves start-pod, stop-pod and restart-pod (terminate is delete-pod)."
|
|
5486
|
-
},
|
|
5487
|
-
"start-pod": IN,
|
|
5488
|
-
"stop-pod": IN,
|
|
5489
|
-
"restart-pod": IN,
|
|
5490
|
-
"list-guides": {
|
|
5491
|
-
include: false,
|
|
5492
|
-
reason: "Serves playbooks that instruct the model how to behave."
|
|
5493
|
-
},
|
|
5494
|
-
"read-guide": {
|
|
5495
|
-
include: false,
|
|
5496
|
-
reason: "Serves playbooks that instruct the model how to behave."
|
|
5497
|
-
},
|
|
5498
|
-
"describe-tool": {
|
|
5499
|
-
include: false,
|
|
5500
|
-
reason: "Fetches schemas the directory already lists in full; directories reject schema fetching."
|
|
5501
|
-
},
|
|
5502
|
-
"create-secret": { include: false, reason: CREDENTIAL_INPUT },
|
|
5503
|
-
"get-secret": { include: false, reason: CREDENTIAL_MANAGEMENT },
|
|
5504
|
-
"list-secrets": { include: false, reason: CREDENTIAL_MANAGEMENT },
|
|
5505
|
-
"delete-secret": { include: false, reason: CREDENTIAL_MANAGEMENT },
|
|
5506
|
-
"get-registry": { include: false, reason: CREDENTIAL_MANAGEMENT },
|
|
5507
|
-
"list-registries": { include: false, reason: CREDENTIAL_MANAGEMENT },
|
|
5508
|
-
"delete-registry": { include: false, reason: CREDENTIAL_MANAGEMENT },
|
|
5509
|
-
"update-secret": { include: false, reason: CREDENTIAL_INPUT },
|
|
5510
|
-
"create-registry": { include: false, reason: CREDENTIAL_INPUT },
|
|
5511
|
-
report_feedback: { include: false, reason: ALP },
|
|
5512
|
-
report_how_user_found_runpod: { include: false, reason: ALP },
|
|
5513
|
-
save_to_journal: { include: false, reason: ALP },
|
|
5514
|
-
read_journal: { include: false, reason: ALP },
|
|
5515
|
-
ask_question: { include: false, reason: ALP }
|
|
5516
|
-
};
|
|
5517
|
-
function directoryIncludes(name) {
|
|
5518
|
-
return DIRECTORY_TOOLS[name]?.include === true;
|
|
5519
|
-
}
|
|
5520
|
-
function directoryOmittedInputs(name) {
|
|
5521
|
-
const decision = DIRECTORY_TOOLS[name];
|
|
5522
|
-
return decision?.include ? decision.omitInputs ?? [] : [];
|
|
5523
|
-
}
|
|
5524
|
-
function profileForPath(pathname) {
|
|
5525
|
-
return pathname.replace(/\/+$/, "") === DIRECTORY_PATH ? "directory" : "default";
|
|
5526
|
-
}
|
|
5527
|
-
|
|
5528
5490
|
// src/specgen/redact.ts
|
|
5529
5491
|
var REDACTED = "[redacted]";
|
|
5530
5492
|
var SECRET_KEY = /pass(word|wd)?|secret|token|api_?key|private_?key|credential|auth/i;
|
|
@@ -9076,7 +9038,7 @@ function words2(name) {
|
|
|
9076
9038
|
|
|
9077
9039
|
// src/server.ts
|
|
9078
9040
|
var SERVER_NAME = "Runpod API Server";
|
|
9079
|
-
var SERVER_VERSION = true ? "4.
|
|
9041
|
+
var SERVER_VERSION = true ? "4.8.0" : "dev";
|
|
9080
9042
|
|
|
9081
9043
|
// src/specgen/analytics.ts
|
|
9082
9044
|
import { createHmac } from "crypto";
|
|
@@ -9145,6 +9107,7 @@ function captureToolCall(apiKey, event) {
|
|
|
9145
9107
|
...event.clientName ? { client_name: event.clientName } : {},
|
|
9146
9108
|
...event.guideKind ? { guide_kind: event.guideKind } : {},
|
|
9147
9109
|
...event.blockedBy ? { blocked_by: event.blockedBy } : {},
|
|
9110
|
+
...event.profile ? { profile: event.profile } : {},
|
|
9148
9111
|
...args
|
|
9149
9112
|
});
|
|
9150
9113
|
}
|
|
@@ -9777,6 +9740,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9777
9740
|
status: 429,
|
|
9778
9741
|
durationMs: 0,
|
|
9779
9742
|
...verdict.reason ? { blockedBy: verdict.reason } : {},
|
|
9743
|
+
profile,
|
|
9780
9744
|
...opts.analytics
|
|
9781
9745
|
});
|
|
9782
9746
|
}
|
|
@@ -9797,6 +9761,9 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9797
9761
|
const curated = servedCuratedTools.find(
|
|
9798
9762
|
(tool) => tool.name === request.params.name
|
|
9799
9763
|
);
|
|
9764
|
+
const generated = servedGeneratedTools.find(
|
|
9765
|
+
(tool) => tool.name === request.params.name
|
|
9766
|
+
);
|
|
9800
9767
|
const omitted = directory ? directoryOmittedInputs(request.params.name).filter((key) => key in args) : [];
|
|
9801
9768
|
const rejected = omitted.length ? {
|
|
9802
9769
|
ok: false,
|
|
@@ -9809,7 +9776,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9809
9776
|
args
|
|
9810
9777
|
) : null;
|
|
9811
9778
|
const result = rejected ?? await runTool(
|
|
9812
|
-
() => curated ? curated.handler(ctx, args) : dispatchTool(request.params.name, args)
|
|
9779
|
+
() => curated ? curated.handler(ctx, args) : dispatchTool(generated, request.params.name, args)
|
|
9813
9780
|
);
|
|
9814
9781
|
logToolCall({
|
|
9815
9782
|
tool: request.params.name,
|
|
@@ -9829,23 +9796,27 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9829
9796
|
args: recordedArgumentValues(curated?.recordedArguments, args),
|
|
9830
9797
|
guideKind: curated?.recordedGuideKind?.(args)
|
|
9831
9798
|
},
|
|
9799
|
+
profile,
|
|
9832
9800
|
...opts.analytics
|
|
9833
9801
|
});
|
|
9834
9802
|
}
|
|
9835
9803
|
opts.onToolResult?.(request.params.name, result.status);
|
|
9836
9804
|
if (!result.ok && result.status === 401) opts.onUnauthorized?.();
|
|
9805
|
+
const annotations = curated?.annotations ?? generated?.annotations;
|
|
9837
9806
|
const payload = redactSecretEnv(
|
|
9838
|
-
result.ok ? result.payload : withRecoveryHint(
|
|
9807
|
+
result.ok ? result.payload : withRecoveryHint(
|
|
9808
|
+
result,
|
|
9809
|
+
annotations?.idempotentHint === true,
|
|
9810
|
+
request.params.name,
|
|
9811
|
+
callShapeOnlyTools.has(request.params.name)
|
|
9812
|
+
)
|
|
9839
9813
|
);
|
|
9840
9814
|
return {
|
|
9841
9815
|
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
9842
9816
|
isError: !result.ok
|
|
9843
9817
|
};
|
|
9844
9818
|
});
|
|
9845
|
-
async function dispatchTool(name, args) {
|
|
9846
|
-
const tool = servedGeneratedTools.find(
|
|
9847
|
-
(candidate) => candidate.name === name
|
|
9848
|
-
);
|
|
9819
|
+
async function dispatchTool(tool, name, args) {
|
|
9849
9820
|
if (!tool)
|
|
9850
9821
|
return {
|
|
9851
9822
|
ok: false,
|
|
@@ -9893,8 +9864,24 @@ function errorHint(status, detail) {
|
|
|
9893
9864
|
return void 0;
|
|
9894
9865
|
}
|
|
9895
9866
|
var CALL_SHAPE_ONLY_HINT = `This tool lists its call shape only; ${DESCRIBE_TOOL_NAME} serves the full argument schema.`;
|
|
9896
|
-
|
|
9867
|
+
var OUTCOME_UNKNOWN_HINT = "Runpod may have completed this operation even though its response failed. Do not submit it again yet. Check the matching get- or list- tool or the Runpod console using the original request details and time. Lists can lag; if you cannot confirm the outcome, stop and ask the user to verify before retrying.";
|
|
9868
|
+
var JOB_OUTCOME_UNKNOWN_HINT = "Runpod may have submitted this Serverless job even though its response failed. Do not submit it again yet. No job-list tool is available, and get-job-status requires a job ID that this failed response may not have returned. Check the endpoint in the Runpod console or ask the user to verify the submission. If the outcome remains uncertain, stop instead of retrying.";
|
|
9869
|
+
var RETRY_JOB_OUTCOME_UNKNOWN_HINT = "Runpod may have requeued this Serverless job even though its response failed. Do not retry it again yet. Check get-job-status with the endpoint and job IDs you supplied, or check the Runpod console. If you cannot confirm the outcome, stop and ask the user to verify before retrying.";
|
|
9870
|
+
var JOB_SUBMISSION_TOOLS = /* @__PURE__ */ new Set(["run-endpoint", "runsync-endpoint"]);
|
|
9871
|
+
function withRecoveryHint(result, idempotent, toolName, listsCallShapeOnly = false) {
|
|
9897
9872
|
const payload = asRecord(result.payload) ?? { error: result.payload };
|
|
9873
|
+
if (!idempotent && result.status >= 500 && result.requestDelivery !== "not_sent") {
|
|
9874
|
+
const detail = asRecord(payload.detail);
|
|
9875
|
+
const safeDetail = detail ? { ...detail } : void 0;
|
|
9876
|
+
if (safeDetail) delete safeDetail.hint;
|
|
9877
|
+
return {
|
|
9878
|
+
...payload,
|
|
9879
|
+
...safeDetail ? { detail: safeDetail } : {},
|
|
9880
|
+
...payload.code !== void 0 ? { upstreamCode: payload.code } : {},
|
|
9881
|
+
code: "outcome_unknown",
|
|
9882
|
+
hint: toolName === "retry-job" ? RETRY_JOB_OUTCOME_UNKNOWN_HINT : JOB_SUBMISSION_TOOLS.has(toolName) ? JOB_OUTCOME_UNKNOWN_HINT : OUTCOME_UNKNOWN_HINT
|
|
9883
|
+
};
|
|
9884
|
+
}
|
|
9898
9885
|
const hint = payload.hint ?? asRecord(payload.detail)?.hint ?? errorHint(result.status, detailText(payload));
|
|
9899
9886
|
const shapeRejected = result.status === 400 || result.status === 422;
|
|
9900
9887
|
return {
|