@runpod/mcp-server 4.9.1 → 4.10.1
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 +35 -0
- package/README.md +2 -11
- package/dist/alp.cjs +21 -2
- package/dist/alp.cjs.map +1 -1
- package/dist/alp.d.cts +2 -1
- package/dist/alp.d.ts +2 -1
- package/dist/alp.mjs +3 -1
- package/dist/{chunk-N4OSRS4A.mjs → chunk-AKX5ZMCL.mjs} +1931 -221
- package/dist/chunk-AKX5ZMCL.mjs.map +1 -0
- package/dist/{chunk-6IETGSON.mjs → chunk-FQJFKWUV.mjs} +32 -1
- package/dist/chunk-FQJFKWUV.mjs.map +1 -0
- package/dist/{chunk-H3NZYQIB.mjs → chunk-WWXM5EES.mjs} +20 -3
- package/dist/chunk-WWXM5EES.mjs.map +1 -0
- package/dist/hosted.cjs +1986 -217
- package/dist/hosted.cjs.map +1 -1
- package/dist/hosted.mjs +16 -5
- package/dist/hosted.mjs.map +1 -1
- package/dist/http.cjs +1960 -219
- package/dist/http.cjs.map +1 -1
- package/dist/http.mjs +2 -2
- package/dist/specgen/profile.cjs +31 -0
- package/dist/specgen/profile.cjs.map +1 -1
- package/dist/specgen/profile.mjs +1 -1
- package/dist/stdio.cjs +1960 -219
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.mjs +1960 -219
- package/dist/stdio.mjs.map +1 -1
- package/package.json +4 -3
- package/dist/chunk-6IETGSON.mjs.map +0 -1
- package/dist/chunk-H3NZYQIB.mjs.map +0 -1
- package/dist/chunk-N4OSRS4A.mjs.map +0 -1
package/dist/hosted.cjs
CHANGED
|
@@ -312,6 +312,14 @@ function validateArguments(inputSchema, args) {
|
|
|
312
312
|
}
|
|
313
313
|
return null;
|
|
314
314
|
}
|
|
315
|
+
function withoutNullOptionals(inputSchema, args) {
|
|
316
|
+
const required = new Set(inputSchema.required ?? []);
|
|
317
|
+
return Object.fromEntries(
|
|
318
|
+
Object.entries(args).filter(
|
|
319
|
+
([name, value]) => value !== null || required.has(name)
|
|
320
|
+
)
|
|
321
|
+
);
|
|
322
|
+
}
|
|
315
323
|
async function dispatchGeneratedTool(client, tool, args) {
|
|
316
324
|
const rejected = validateArguments(tool.inputSchema, args);
|
|
317
325
|
if (rejected) return rejected;
|
|
@@ -436,6 +444,104 @@ function coerceScalars(value, schema, defs, depth = 0) {
|
|
|
436
444
|
|
|
437
445
|
// src/specgen/generated/tools.gen.ts
|
|
438
446
|
var generatedTools = [
|
|
447
|
+
{
|
|
448
|
+
name: "add-organization-group-member",
|
|
449
|
+
title: "Add organization group member",
|
|
450
|
+
operationId: "addOrganizationGroupMember",
|
|
451
|
+
description: "Add a member to a group. Adds the organization member to the group. The group and user must belong to the current organization. Adding an existing member is idempotent and returns the same no-content response.",
|
|
452
|
+
method: "PUT",
|
|
453
|
+
path: "/v2/organization/groups/{id}/members/{userId}",
|
|
454
|
+
params: [
|
|
455
|
+
{
|
|
456
|
+
name: "id",
|
|
457
|
+
location: "path"
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
name: "userId",
|
|
461
|
+
location: "path"
|
|
462
|
+
}
|
|
463
|
+
],
|
|
464
|
+
hasBody: false,
|
|
465
|
+
annotations: {
|
|
466
|
+
readOnlyHint: false,
|
|
467
|
+
destructiveHint: false,
|
|
468
|
+
idempotentHint: true,
|
|
469
|
+
openWorldHint: true
|
|
470
|
+
},
|
|
471
|
+
inputSchema: {
|
|
472
|
+
type: "object",
|
|
473
|
+
properties: {
|
|
474
|
+
id: {
|
|
475
|
+
type: "string",
|
|
476
|
+
minLength: 1,
|
|
477
|
+
description: "Group ID."
|
|
478
|
+
},
|
|
479
|
+
userId: {
|
|
480
|
+
type: "string",
|
|
481
|
+
minLength: 1,
|
|
482
|
+
description: "Organization member user ID."
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
required: ["id", "userId"]
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "attach-cost-center-resource",
|
|
490
|
+
title: "Attach cost center resource",
|
|
491
|
+
operationId: "attachCostCenterResource",
|
|
492
|
+
description: "Attribute a resource to a cost center. Attributes a resource to a cost center. Repeating the request is a no-op. A resource belongs to at most one cost center; one already attributed elsewhere is rejected with 409 rather than moved.",
|
|
493
|
+
method: "PUT",
|
|
494
|
+
path: "/v2/cost-centers/{id}/{resourceType}/{resourceId}",
|
|
495
|
+
params: [
|
|
496
|
+
{
|
|
497
|
+
name: "id",
|
|
498
|
+
location: "path"
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
name: "resourceType",
|
|
502
|
+
location: "path"
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: "resourceId",
|
|
506
|
+
location: "path"
|
|
507
|
+
}
|
|
508
|
+
],
|
|
509
|
+
hasBody: false,
|
|
510
|
+
annotations: {
|
|
511
|
+
readOnlyHint: false,
|
|
512
|
+
destructiveHint: false,
|
|
513
|
+
idempotentHint: true,
|
|
514
|
+
openWorldHint: true
|
|
515
|
+
},
|
|
516
|
+
inputSchema: {
|
|
517
|
+
type: "object",
|
|
518
|
+
properties: {
|
|
519
|
+
id: {
|
|
520
|
+
type: "string",
|
|
521
|
+
minLength: 1,
|
|
522
|
+
description: "Cost center identifier."
|
|
523
|
+
},
|
|
524
|
+
resourceType: {
|
|
525
|
+
$ref: "#/$defs/ResourceType",
|
|
526
|
+
description: "Kind of resource.",
|
|
527
|
+
type: "string"
|
|
528
|
+
},
|
|
529
|
+
resourceId: {
|
|
530
|
+
type: "string",
|
|
531
|
+
minLength: 1,
|
|
532
|
+
description: "Resource identifier."
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
required: ["id", "resourceType", "resourceId"],
|
|
536
|
+
$defs: {
|
|
537
|
+
ResourceType: {
|
|
538
|
+
type: "string",
|
|
539
|
+
description: "Kind of resource a cost center or tag can be attached to.",
|
|
540
|
+
enum: ["POD", "CLUSTER", "SERVERLESS_ENDPOINT", "NETWORK_VOLUME"]
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
},
|
|
439
545
|
{
|
|
440
546
|
name: "create-cluster",
|
|
441
547
|
title: "Create cluster",
|
|
@@ -534,7 +640,6 @@ var generatedTools = [
|
|
|
534
640
|
},
|
|
535
641
|
network: {
|
|
536
642
|
type: "array",
|
|
537
|
-
maxItems: 1,
|
|
538
643
|
items: {
|
|
539
644
|
$ref: "#/$defs/NetworkMount"
|
|
540
645
|
}
|
|
@@ -556,7 +661,7 @@ var generatedTools = [
|
|
|
556
661
|
gpuCountPerPod: {
|
|
557
662
|
type: "integer",
|
|
558
663
|
minimum: 1,
|
|
559
|
-
description: "Number of GPUs on each pod. Bounded above by the GPU type's per-cloud maximum (GpuType.maxCount);
|
|
664
|
+
description: "Number of GPUs on each pod. Bounded above by the GPU type's per-cloud maximum (GpuType.maxCount); values beyond it are rejected.",
|
|
560
665
|
examples: [8]
|
|
561
666
|
},
|
|
562
667
|
podCount: {
|
|
@@ -569,7 +674,7 @@ var generatedTools = [
|
|
|
569
674
|
}
|
|
570
675
|
},
|
|
571
676
|
ClusterMounts: {
|
|
572
|
-
description: "Storage mounts for a cluster create: `persistent` or `network
|
|
677
|
+
description: "Storage mounts for a cluster create: `persistent` or one `network` volume, not both. Clusters cannot mount global volumes, so `global` is rejected.",
|
|
573
678
|
"x-go-type": "BaseMounts",
|
|
574
679
|
allOf: [
|
|
575
680
|
{
|
|
@@ -589,6 +694,7 @@ var generatedTools = [
|
|
|
589
694
|
},
|
|
590
695
|
network: {
|
|
591
696
|
type: "array",
|
|
697
|
+
maxItems: 1,
|
|
592
698
|
items: {
|
|
593
699
|
type: "object",
|
|
594
700
|
properties: {
|
|
@@ -667,7 +773,7 @@ var generatedTools = [
|
|
|
667
773
|
type: "object",
|
|
668
774
|
required: ["volumeId", "path"],
|
|
669
775
|
additionalProperties: false,
|
|
670
|
-
description: "Reference to a NetworkVolume. Custom paths are honored at runtime on both GPU and CPU pods.
|
|
776
|
+
description: "Reference to a NetworkVolume. Custom paths are honored at runtime on both GPU and CPU pods. On a pod, the volume can be mounted, moved, or unmounted after creation (see `UpdatePodMounts`).",
|
|
671
777
|
properties: {
|
|
672
778
|
volumeId: {
|
|
673
779
|
type: "string",
|
|
@@ -690,7 +796,7 @@ var generatedTools = [
|
|
|
690
796
|
size: {
|
|
691
797
|
type: "integer",
|
|
692
798
|
minimum: 10,
|
|
693
|
-
description: "Host-local persistent storage in GB.
|
|
799
|
+
description: "Host-local persistent storage in GB. Minimum 10 GB.",
|
|
694
800
|
examples: [20]
|
|
695
801
|
},
|
|
696
802
|
path: {
|
|
@@ -703,6 +809,77 @@ var generatedTools = [
|
|
|
703
809
|
}
|
|
704
810
|
}
|
|
705
811
|
},
|
|
812
|
+
{
|
|
813
|
+
name: "create-cost-center",
|
|
814
|
+
title: "Create cost center",
|
|
815
|
+
operationId: "createCostCenter",
|
|
816
|
+
description: "Create a cost center. Creates a cost center \u2014 a named label that groups resource spend so it can be broken out in billing. Pass `resources` to attribute resources at creation time; attaching is all-or-nothing, and a resource that already belongs to another cost center is rejected rather than moved.",
|
|
817
|
+
method: "POST",
|
|
818
|
+
path: "/v2/cost-centers",
|
|
819
|
+
params: [],
|
|
820
|
+
hasBody: true,
|
|
821
|
+
annotations: {
|
|
822
|
+
readOnlyHint: false,
|
|
823
|
+
destructiveHint: false,
|
|
824
|
+
idempotentHint: false,
|
|
825
|
+
openWorldHint: true
|
|
826
|
+
},
|
|
827
|
+
inputSchema: {
|
|
828
|
+
type: "object",
|
|
829
|
+
properties: {
|
|
830
|
+
body: {
|
|
831
|
+
$ref: "#/$defs/CreateCostCenterRequest",
|
|
832
|
+
type: "object"
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
required: ["body"],
|
|
836
|
+
$defs: {
|
|
837
|
+
CostCenterResource: {
|
|
838
|
+
type: "object",
|
|
839
|
+
additionalProperties: false,
|
|
840
|
+
required: ["id", "type"],
|
|
841
|
+
properties: {
|
|
842
|
+
id: {
|
|
843
|
+
type: "string",
|
|
844
|
+
minLength: 1,
|
|
845
|
+
examples: ["p9k2m4n6q8"]
|
|
846
|
+
},
|
|
847
|
+
type: {
|
|
848
|
+
$ref: "#/$defs/ResourceType"
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
},
|
|
852
|
+
CreateCostCenterRequest: {
|
|
853
|
+
type: "object",
|
|
854
|
+
additionalProperties: false,
|
|
855
|
+
required: ["value"],
|
|
856
|
+
properties: {
|
|
857
|
+
value: {
|
|
858
|
+
type: "string",
|
|
859
|
+
minLength: 1,
|
|
860
|
+
maxLength: 50,
|
|
861
|
+
pattern: "^\\s*\\S",
|
|
862
|
+
description: "Leading and trailing whitespace is trimmed.",
|
|
863
|
+
examples: ["team-ml"]
|
|
864
|
+
},
|
|
865
|
+
resources: {
|
|
866
|
+
type: "array",
|
|
867
|
+
description: "Resources to attribute to the new cost center.",
|
|
868
|
+
maxItems: 100,
|
|
869
|
+
items: {
|
|
870
|
+
$ref: "#/$defs/CostCenterResource"
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
ResourceType: {
|
|
876
|
+
type: "string",
|
|
877
|
+
description: "Kind of resource a cost center or tag can be attached to.",
|
|
878
|
+
enum: ["POD", "CLUSTER", "SERVERLESS_ENDPOINT", "NETWORK_VOLUME"]
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
},
|
|
706
883
|
{
|
|
707
884
|
name: "create-delegation",
|
|
708
885
|
title: "Create ECR delegation",
|
|
@@ -1231,6 +1408,7 @@ var generatedTools = [
|
|
|
1231
1408
|
type: "string",
|
|
1232
1409
|
minLength: 1,
|
|
1233
1410
|
maxLength: 191,
|
|
1411
|
+
pattern: "[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]",
|
|
1234
1412
|
description: "Human-readable name, 1\u2013191 characters with at least one non-whitespace character. Leading and trailing whitespace is trimmed.",
|
|
1235
1413
|
examples: ["training-data"]
|
|
1236
1414
|
}
|
|
@@ -1306,6 +1484,169 @@ var generatedTools = [
|
|
|
1306
1484
|
}
|
|
1307
1485
|
}
|
|
1308
1486
|
},
|
|
1487
|
+
{
|
|
1488
|
+
name: "create-organization-group",
|
|
1489
|
+
title: "Create organization group",
|
|
1490
|
+
operationId: "createOrganizationGroup",
|
|
1491
|
+
description: "Create a group in your current organization",
|
|
1492
|
+
method: "POST",
|
|
1493
|
+
path: "/v2/organization/groups",
|
|
1494
|
+
params: [],
|
|
1495
|
+
hasBody: true,
|
|
1496
|
+
annotations: {
|
|
1497
|
+
readOnlyHint: false,
|
|
1498
|
+
destructiveHint: false,
|
|
1499
|
+
idempotentHint: false,
|
|
1500
|
+
openWorldHint: true
|
|
1501
|
+
},
|
|
1502
|
+
inputSchema: {
|
|
1503
|
+
type: "object",
|
|
1504
|
+
properties: {
|
|
1505
|
+
body: {
|
|
1506
|
+
$ref: "#/$defs/CreateOrganizationGroupRequest",
|
|
1507
|
+
type: "object"
|
|
1508
|
+
}
|
|
1509
|
+
},
|
|
1510
|
+
required: ["body"],
|
|
1511
|
+
$defs: {
|
|
1512
|
+
CreateOrganizationGroupRequest: {
|
|
1513
|
+
type: "object",
|
|
1514
|
+
additionalProperties: false,
|
|
1515
|
+
required: ["name"],
|
|
1516
|
+
properties: {
|
|
1517
|
+
name: {
|
|
1518
|
+
type: "string",
|
|
1519
|
+
minLength: 1,
|
|
1520
|
+
maxLength: 191,
|
|
1521
|
+
pattern: "[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]",
|
|
1522
|
+
description: "Group name with at least one non-whitespace character; surrounding whitespace is trimmed.",
|
|
1523
|
+
examples: ["Engineering"]
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
name: "create-organization-invite",
|
|
1532
|
+
title: "Create organization invite",
|
|
1533
|
+
operationId: "createOrganizationInvite",
|
|
1534
|
+
description: "Invite a user to your organization. Sends an invitation to join the authenticated caller's organization and returns the pending invite; `expiresAt` is when it lapses. The invitee receives an email carrying the acceptance link, which is never returned here. Returns 409 when the address already belongs to a member or to a pending invite, or when the organization has reached its pending-invite limit; 404 when the role is unknown to the organization; and 403 when the caller does not hold every capability the role grants. Inviting requires the organization's invite-management capability, which the built-in admin role holds; other members, and callers outside an organization, receive 403, as does a caller for whom organizations are unavailable.",
|
|
1535
|
+
method: "POST",
|
|
1536
|
+
path: "/v2/organization/invites",
|
|
1537
|
+
params: [],
|
|
1538
|
+
hasBody: true,
|
|
1539
|
+
annotations: {
|
|
1540
|
+
readOnlyHint: false,
|
|
1541
|
+
destructiveHint: false,
|
|
1542
|
+
idempotentHint: false,
|
|
1543
|
+
openWorldHint: true
|
|
1544
|
+
},
|
|
1545
|
+
inputSchema: {
|
|
1546
|
+
type: "object",
|
|
1547
|
+
properties: {
|
|
1548
|
+
body: {
|
|
1549
|
+
$ref: "#/$defs/CreateOrganizationInviteRequest",
|
|
1550
|
+
type: "object"
|
|
1551
|
+
}
|
|
1552
|
+
},
|
|
1553
|
+
required: ["body"],
|
|
1554
|
+
$defs: {
|
|
1555
|
+
CreateOrganizationInviteRequest: {
|
|
1556
|
+
type: "object",
|
|
1557
|
+
additionalProperties: false,
|
|
1558
|
+
required: ["email", "role"],
|
|
1559
|
+
properties: {
|
|
1560
|
+
email: {
|
|
1561
|
+
type: "string",
|
|
1562
|
+
format: "email",
|
|
1563
|
+
minLength: 1,
|
|
1564
|
+
maxLength: 254,
|
|
1565
|
+
description: "Address to invite, stored lowercased. The invitee accepts by signing in with a verified account on this address.",
|
|
1566
|
+
examples: ["new-member@example.com"]
|
|
1567
|
+
},
|
|
1568
|
+
role: {
|
|
1569
|
+
$ref: "#/$defs/OrganizationRoleInput"
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
},
|
|
1573
|
+
OrganizationRoleInput: {
|
|
1574
|
+
type: "object",
|
|
1575
|
+
description: "An organization role to assign, by ID.",
|
|
1576
|
+
additionalProperties: false,
|
|
1577
|
+
required: ["id"],
|
|
1578
|
+
properties: {
|
|
1579
|
+
id: {
|
|
1580
|
+
type: "string",
|
|
1581
|
+
minLength: 1,
|
|
1582
|
+
description: "Role ID, as reported on a member or an invite: `builtin:admin`, `builtin:dev`, `builtin:billing`, `builtin:basic`, or a custom role's own ID.",
|
|
1583
|
+
examples: ["builtin:dev"]
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
name: "create-organization-role",
|
|
1592
|
+
title: "Create organization role",
|
|
1593
|
+
operationId: "createOrganizationRole",
|
|
1594
|
+
description: "Create a custom organization role. Creates a custom role in the authenticated caller's organization and returns it. Returns 409 when the organization already has a role with this name or has reached its custom-role limit; 422 when a capability is unknown or the name is reserved; and 403 when the caller does not hold every capability the role grants. Creating roles requires the organization's role-management capability, which the built-in admin role holds; other members, and callers outside an organization, receive 403, as does a caller for whom organizations are unavailable.",
|
|
1595
|
+
method: "POST",
|
|
1596
|
+
path: "/v2/organization/roles",
|
|
1597
|
+
params: [],
|
|
1598
|
+
hasBody: true,
|
|
1599
|
+
annotations: {
|
|
1600
|
+
readOnlyHint: false,
|
|
1601
|
+
destructiveHint: false,
|
|
1602
|
+
idempotentHint: false,
|
|
1603
|
+
openWorldHint: true
|
|
1604
|
+
},
|
|
1605
|
+
inputSchema: {
|
|
1606
|
+
type: "object",
|
|
1607
|
+
properties: {
|
|
1608
|
+
body: {
|
|
1609
|
+
$ref: "#/$defs/CreateOrganizationRoleRequest",
|
|
1610
|
+
type: "object"
|
|
1611
|
+
}
|
|
1612
|
+
},
|
|
1613
|
+
required: ["body"],
|
|
1614
|
+
$defs: {
|
|
1615
|
+
CreateOrganizationRoleRequest: {
|
|
1616
|
+
type: "object",
|
|
1617
|
+
additionalProperties: false,
|
|
1618
|
+
required: ["name", "capabilities"],
|
|
1619
|
+
properties: {
|
|
1620
|
+
name: {
|
|
1621
|
+
$ref: "#/$defs/OrganizationRoleName"
|
|
1622
|
+
},
|
|
1623
|
+
capabilities: {
|
|
1624
|
+
$ref: "#/$defs/OrganizationRoleCapabilitiesInput"
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
},
|
|
1628
|
+
OrganizationRoleCapabilitiesInput: {
|
|
1629
|
+
type: "array",
|
|
1630
|
+
description: "What the role grants, as `FAMILY:VERB` capabilities from `get-organization-role-capabilities`. The caller must hold every capability it lists.",
|
|
1631
|
+
minItems: 1,
|
|
1632
|
+
uniqueItems: true,
|
|
1633
|
+
items: {
|
|
1634
|
+
type: "string",
|
|
1635
|
+
pattern: "^[A-Z0-9_]+:[A-Z0-9_]+$"
|
|
1636
|
+
},
|
|
1637
|
+
examples: [["POD:VIEW"]]
|
|
1638
|
+
},
|
|
1639
|
+
OrganizationRoleName: {
|
|
1640
|
+
type: "string",
|
|
1641
|
+
minLength: 1,
|
|
1642
|
+
maxLength: 191,
|
|
1643
|
+
pattern: "[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]",
|
|
1644
|
+
description: "Display name, 1\u2013191 characters with at least one non-whitespace character. Leading and trailing whitespace is trimmed. It must be unique within the organization and cannot be a built-in role's name.",
|
|
1645
|
+
examples: ["Pod viewer"]
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
},
|
|
1309
1650
|
{
|
|
1310
1651
|
name: "create-pod",
|
|
1311
1652
|
title: "Create Pod",
|
|
@@ -1426,6 +1767,7 @@ var generatedTools = [
|
|
|
1426
1767
|
count: {
|
|
1427
1768
|
type: "integer",
|
|
1428
1769
|
minimum: 1,
|
|
1770
|
+
maximum: 1024,
|
|
1429
1771
|
default: 1,
|
|
1430
1772
|
description: "Number of GPUs",
|
|
1431
1773
|
examples: [1]
|
|
@@ -1440,7 +1782,6 @@ var generatedTools = [
|
|
|
1440
1782
|
},
|
|
1441
1783
|
network: {
|
|
1442
1784
|
type: "array",
|
|
1443
|
-
maxItems: 1,
|
|
1444
1785
|
items: {
|
|
1445
1786
|
$ref: "#/$defs/NetworkMount"
|
|
1446
1787
|
}
|
|
@@ -1504,12 +1845,14 @@ var generatedTools = [
|
|
|
1504
1845
|
minRamPerGpu: {
|
|
1505
1846
|
type: "integer",
|
|
1506
1847
|
minimum: 1,
|
|
1848
|
+
maximum: 65536,
|
|
1507
1849
|
description: "Minimum host system RAM in GB per requested GPU. This is a placement filter, not a resource request. The actual total allocated system RAM may be higher and is returned in gpu.memory.",
|
|
1508
1850
|
examples: [8]
|
|
1509
1851
|
},
|
|
1510
1852
|
minVcpuCountPerGpu: {
|
|
1511
1853
|
type: "integer",
|
|
1512
1854
|
minimum: 1,
|
|
1855
|
+
maximum: 4096,
|
|
1513
1856
|
description: "Minimum host vCPU count per requested GPU. This is a placement filter, not a resource request. The actual total allocated vCPU count may be higher and is returned in gpu.vcpuCount.",
|
|
1514
1857
|
examples: [2]
|
|
1515
1858
|
}
|
|
@@ -1600,7 +1943,7 @@ var generatedTools = [
|
|
|
1600
1943
|
type: "object",
|
|
1601
1944
|
required: ["volumeId"],
|
|
1602
1945
|
additionalProperties: false,
|
|
1603
|
-
description: "Reference to a GlobalVolume. Usage-billed, so it has no size.
|
|
1946
|
+
description: "Reference to a GlobalVolume. Usage-billed, so it has no size. On a pod, the volume can be mounted, moved, or unmounted after creation (see `UpdatePodMounts`).",
|
|
1604
1947
|
properties: {
|
|
1605
1948
|
volumeId: {
|
|
1606
1949
|
type: "string",
|
|
@@ -1609,7 +1952,7 @@ var generatedTools = [
|
|
|
1609
1952
|
},
|
|
1610
1953
|
path: {
|
|
1611
1954
|
type: "string",
|
|
1612
|
-
description: "Mount path inside the container. Optional
|
|
1955
|
+
description: "Mount path inside the container. Optional; a default is chosen for you when omitted.",
|
|
1613
1956
|
examples: ["/data"]
|
|
1614
1957
|
}
|
|
1615
1958
|
}
|
|
@@ -1623,10 +1966,18 @@ var generatedTools = [
|
|
|
1623
1966
|
{
|
|
1624
1967
|
type: "object",
|
|
1625
1968
|
properties: {
|
|
1969
|
+
network: {
|
|
1970
|
+
type: "array",
|
|
1971
|
+
maxItems: 4,
|
|
1972
|
+
description: "Up to 4 network volumes, all in the pod's data center.",
|
|
1973
|
+
items: {
|
|
1974
|
+
$ref: "#/$defs/NetworkMount"
|
|
1975
|
+
}
|
|
1976
|
+
},
|
|
1626
1977
|
global: {
|
|
1627
1978
|
type: "array",
|
|
1628
1979
|
maxItems: 1,
|
|
1629
|
-
description: "At most one global volume, on GPU and CPU pods, with no data center constraint. Combinable with `network` but not with `persistent` (rejected):
|
|
1980
|
+
description: "At most one global volume, on GPU and CPU pods, with no data center constraint. Combinable with `network` but not with `persistent` (rejected): a persistent disk is dropped whenever a volume is attached. Same PATCH rules as `network`.",
|
|
1630
1981
|
items: {
|
|
1631
1982
|
$ref: "#/$defs/GlobalMount"
|
|
1632
1983
|
}
|
|
@@ -1640,7 +1991,7 @@ var generatedTools = [
|
|
|
1640
1991
|
type: "object",
|
|
1641
1992
|
required: ["volumeId", "path"],
|
|
1642
1993
|
additionalProperties: false,
|
|
1643
|
-
description: "Reference to a NetworkVolume. Custom paths are honored at runtime on both GPU and CPU pods.
|
|
1994
|
+
description: "Reference to a NetworkVolume. Custom paths are honored at runtime on both GPU and CPU pods. On a pod, the volume can be mounted, moved, or unmounted after creation (see `UpdatePodMounts`).",
|
|
1644
1995
|
properties: {
|
|
1645
1996
|
volumeId: {
|
|
1646
1997
|
type: "string",
|
|
@@ -1663,7 +2014,7 @@ var generatedTools = [
|
|
|
1663
2014
|
size: {
|
|
1664
2015
|
type: "integer",
|
|
1665
2016
|
minimum: 10,
|
|
1666
|
-
description: "Host-local persistent storage in GB.
|
|
2017
|
+
description: "Host-local persistent storage in GB. Minimum 10 GB.",
|
|
1667
2018
|
examples: [20]
|
|
1668
2019
|
},
|
|
1669
2020
|
path: {
|
|
@@ -1960,7 +2311,7 @@ var generatedTools = [
|
|
|
1960
2311
|
size: {
|
|
1961
2312
|
type: "integer",
|
|
1962
2313
|
minimum: 10,
|
|
1963
|
-
description: "Host-local persistent storage in GB.
|
|
2314
|
+
description: "Host-local persistent storage in GB. Minimum 10 GB.",
|
|
1964
2315
|
examples: [20]
|
|
1965
2316
|
},
|
|
1966
2317
|
path: {
|
|
@@ -2021,13 +2372,12 @@ var generatedTools = [
|
|
|
2021
2372
|
}
|
|
2022
2373
|
},
|
|
2023
2374
|
{
|
|
2024
|
-
name: "delete-
|
|
2025
|
-
title: "Delete
|
|
2026
|
-
operationId: "
|
|
2027
|
-
description: "Delete a
|
|
2028
|
-
directoryDescription: "Delete a Serverless endpoint permanently and immediately.",
|
|
2375
|
+
name: "delete-cost-center",
|
|
2376
|
+
title: "Delete cost center",
|
|
2377
|
+
operationId: "deleteCostCenter",
|
|
2378
|
+
description: "Delete a cost center. Deletes a cost center. The delete fails with 409 while any resource is still attributed to the cost center; detach those resources first.",
|
|
2029
2379
|
method: "DELETE",
|
|
2030
|
-
path: "/v2/
|
|
2380
|
+
path: "/v2/cost-centers/{id}",
|
|
2031
2381
|
params: [
|
|
2032
2382
|
{
|
|
2033
2383
|
name: "id",
|
|
@@ -2046,17 +2396,50 @@ var generatedTools = [
|
|
|
2046
2396
|
properties: {
|
|
2047
2397
|
id: {
|
|
2048
2398
|
type: "string",
|
|
2049
|
-
|
|
2399
|
+
minLength: 1,
|
|
2400
|
+
description: "Cost center identifier."
|
|
2050
2401
|
}
|
|
2051
2402
|
},
|
|
2052
2403
|
required: ["id"]
|
|
2053
2404
|
}
|
|
2054
2405
|
},
|
|
2055
2406
|
{
|
|
2056
|
-
name: "delete-
|
|
2057
|
-
title: "Delete
|
|
2058
|
-
operationId: "
|
|
2059
|
-
description: "Delete a
|
|
2407
|
+
name: "delete-endpoint",
|
|
2408
|
+
title: "Delete endpoint",
|
|
2409
|
+
operationId: "deleteEndpoint",
|
|
2410
|
+
description: "Delete a serverless endpoint permanently and immediately. Verify the id belongs to the intended endpoint (get-endpoint) before deleting; delete only endpoints your own tool calls created in this conversation, or the one the user asked you to delete by id \u2014 a name found by listing is not attribution.",
|
|
2411
|
+
directoryDescription: "Delete a Serverless endpoint permanently and immediately.",
|
|
2412
|
+
method: "DELETE",
|
|
2413
|
+
path: "/v2/serverless/{id}",
|
|
2414
|
+
params: [
|
|
2415
|
+
{
|
|
2416
|
+
name: "id",
|
|
2417
|
+
location: "path"
|
|
2418
|
+
}
|
|
2419
|
+
],
|
|
2420
|
+
hasBody: false,
|
|
2421
|
+
annotations: {
|
|
2422
|
+
readOnlyHint: false,
|
|
2423
|
+
destructiveHint: true,
|
|
2424
|
+
idempotentHint: true,
|
|
2425
|
+
openWorldHint: true
|
|
2426
|
+
},
|
|
2427
|
+
inputSchema: {
|
|
2428
|
+
type: "object",
|
|
2429
|
+
properties: {
|
|
2430
|
+
id: {
|
|
2431
|
+
type: "string",
|
|
2432
|
+
description: "Serverless endpoint identifier"
|
|
2433
|
+
}
|
|
2434
|
+
},
|
|
2435
|
+
required: ["id"]
|
|
2436
|
+
}
|
|
2437
|
+
},
|
|
2438
|
+
{
|
|
2439
|
+
name: "delete-global-volume",
|
|
2440
|
+
title: "Delete global volume",
|
|
2441
|
+
operationId: "deleteGlobalVolume",
|
|
2442
|
+
description: "Delete a global volume. Permanently deletes a global volume and its stored data. Fails with `409` while the volume is still mounted: terminate every pod that mounts it (stopped pods count) and detach it from every serverless endpoint first. Nothing is detached or terminated on your behalf.",
|
|
2060
2443
|
method: "DELETE",
|
|
2061
2444
|
path: "/v2/global-volumes/{id}",
|
|
2062
2445
|
params: [
|
|
@@ -2114,6 +2497,131 @@ var generatedTools = [
|
|
|
2114
2497
|
required: ["id"]
|
|
2115
2498
|
}
|
|
2116
2499
|
},
|
|
2500
|
+
{
|
|
2501
|
+
name: "delete-organization-group",
|
|
2502
|
+
title: "Delete organization group",
|
|
2503
|
+
operationId: "deleteOrganizationGroup",
|
|
2504
|
+
description: "Delete a group in your current organization. Permanently deletes the group and its group memberships. Organization members are not removed. Returns 404 when the group does not exist in your current organization, including when it has already been deleted.",
|
|
2505
|
+
method: "DELETE",
|
|
2506
|
+
path: "/v2/organization/groups/{id}",
|
|
2507
|
+
params: [
|
|
2508
|
+
{
|
|
2509
|
+
name: "id",
|
|
2510
|
+
location: "path"
|
|
2511
|
+
}
|
|
2512
|
+
],
|
|
2513
|
+
hasBody: false,
|
|
2514
|
+
annotations: {
|
|
2515
|
+
readOnlyHint: false,
|
|
2516
|
+
destructiveHint: true,
|
|
2517
|
+
idempotentHint: true,
|
|
2518
|
+
openWorldHint: true
|
|
2519
|
+
},
|
|
2520
|
+
inputSchema: {
|
|
2521
|
+
type: "object",
|
|
2522
|
+
properties: {
|
|
2523
|
+
id: {
|
|
2524
|
+
type: "string",
|
|
2525
|
+
minLength: 1,
|
|
2526
|
+
description: "Group ID."
|
|
2527
|
+
}
|
|
2528
|
+
},
|
|
2529
|
+
required: ["id"]
|
|
2530
|
+
}
|
|
2531
|
+
},
|
|
2532
|
+
{
|
|
2533
|
+
name: "delete-organization-invite",
|
|
2534
|
+
title: "Delete organization invite",
|
|
2535
|
+
operationId: "deleteOrganizationInvite",
|
|
2536
|
+
description: "Cancel an organization invite. Cancels one invitation to the authenticated caller's organization; the invitee can no longer accept it. Returns 404 when the ID is unknown to the caller's organization: never issued, already accepted, already cancelled, or issued by another organization. An expired invite can still be cancelled. Cancelling invites requires the organization's invite-management capability, which the built-in admin role holds; other members, and callers outside an organization, receive 403, as does a caller for whom organizations are unavailable.",
|
|
2537
|
+
method: "DELETE",
|
|
2538
|
+
path: "/v2/organization/invites/{id}",
|
|
2539
|
+
params: [
|
|
2540
|
+
{
|
|
2541
|
+
name: "id",
|
|
2542
|
+
location: "path"
|
|
2543
|
+
}
|
|
2544
|
+
],
|
|
2545
|
+
hasBody: false,
|
|
2546
|
+
annotations: {
|
|
2547
|
+
readOnlyHint: false,
|
|
2548
|
+
destructiveHint: true,
|
|
2549
|
+
idempotentHint: true,
|
|
2550
|
+
openWorldHint: true
|
|
2551
|
+
},
|
|
2552
|
+
inputSchema: {
|
|
2553
|
+
type: "object",
|
|
2554
|
+
properties: {
|
|
2555
|
+
id: {
|
|
2556
|
+
type: "string",
|
|
2557
|
+
description: "Invite identifier"
|
|
2558
|
+
}
|
|
2559
|
+
},
|
|
2560
|
+
required: ["id"]
|
|
2561
|
+
}
|
|
2562
|
+
},
|
|
2563
|
+
{
|
|
2564
|
+
name: "delete-organization-role",
|
|
2565
|
+
title: "Delete organization role",
|
|
2566
|
+
operationId: "deleteOrganizationRole",
|
|
2567
|
+
description: "Delete a custom organization role. Deletes a custom role from the authenticated caller's organization. Returns 409 while a member or a pending invite holds the role: reassign those members and cancel those invites first, since deleting never changes anyone's role. Expired invites do not block deletion. Returns 400 for a built-in role, which cannot be deleted; 404 when the ID is unknown, names another organization's role, or was already deleted. Deleting roles requires the organization's role-management capability, which the built-in admin role holds; other members, and callers outside an organization, receive 403, as does a caller for whom organizations are unavailable.",
|
|
2568
|
+
method: "DELETE",
|
|
2569
|
+
path: "/v2/organization/roles/{id}",
|
|
2570
|
+
params: [
|
|
2571
|
+
{
|
|
2572
|
+
name: "id",
|
|
2573
|
+
location: "path"
|
|
2574
|
+
}
|
|
2575
|
+
],
|
|
2576
|
+
hasBody: false,
|
|
2577
|
+
annotations: {
|
|
2578
|
+
readOnlyHint: false,
|
|
2579
|
+
destructiveHint: true,
|
|
2580
|
+
idempotentHint: true,
|
|
2581
|
+
openWorldHint: true
|
|
2582
|
+
},
|
|
2583
|
+
inputSchema: {
|
|
2584
|
+
type: "object",
|
|
2585
|
+
properties: {
|
|
2586
|
+
id: {
|
|
2587
|
+
type: "string",
|
|
2588
|
+
description: "Role identifier"
|
|
2589
|
+
}
|
|
2590
|
+
},
|
|
2591
|
+
required: ["id"]
|
|
2592
|
+
}
|
|
2593
|
+
},
|
|
2594
|
+
{
|
|
2595
|
+
name: "delete-organization-user",
|
|
2596
|
+
title: "Delete organization user",
|
|
2597
|
+
operationId: "deleteOrganizationUser",
|
|
2598
|
+
description: "Remove an organization member. Removes one member from the authenticated caller's organization by user ID. Their group memberships end and the API keys attributed to them within the organization are revoked; the resources they created stay with the organization. Removing another member requires the organization's member-removal capability, which the built-in admin role holds; any member can remove themselves. The organization keeps at least one member with the built-in admin role, so removing the last one returns 409. A user who is not a member, including one from another organization, returns 404. A member without the capability removing someone else, a caller outside an organization, and a caller for whom organizations are unavailable receive 403.",
|
|
2599
|
+
method: "DELETE",
|
|
2600
|
+
path: "/v2/organization/users/{id}",
|
|
2601
|
+
params: [
|
|
2602
|
+
{
|
|
2603
|
+
name: "id",
|
|
2604
|
+
location: "path"
|
|
2605
|
+
}
|
|
2606
|
+
],
|
|
2607
|
+
hasBody: false,
|
|
2608
|
+
annotations: {
|
|
2609
|
+
readOnlyHint: false,
|
|
2610
|
+
destructiveHint: true,
|
|
2611
|
+
idempotentHint: true,
|
|
2612
|
+
openWorldHint: true
|
|
2613
|
+
},
|
|
2614
|
+
inputSchema: {
|
|
2615
|
+
type: "object",
|
|
2616
|
+
properties: {
|
|
2617
|
+
id: {
|
|
2618
|
+
type: "string",
|
|
2619
|
+
description: "User identifier"
|
|
2620
|
+
}
|
|
2621
|
+
},
|
|
2622
|
+
required: ["id"]
|
|
2623
|
+
}
|
|
2624
|
+
},
|
|
2117
2625
|
{
|
|
2118
2626
|
name: "delete-pod",
|
|
2119
2627
|
title: "Delete Pod",
|
|
@@ -2239,6 +2747,63 @@ var generatedTools = [
|
|
|
2239
2747
|
required: ["id"]
|
|
2240
2748
|
}
|
|
2241
2749
|
},
|
|
2750
|
+
{
|
|
2751
|
+
name: "detach-cost-center-resource",
|
|
2752
|
+
title: "Detach cost center resource",
|
|
2753
|
+
operationId: "detachCostCenterResource",
|
|
2754
|
+
description: "Remove a resource from a cost center. Removes a resource's attribution to a cost center. The resource itself is untouched. Returns 404 when the cost center does not exist or the resource is not attributed to it, so repeating a DELETE that succeeded returns 404.",
|
|
2755
|
+
method: "DELETE",
|
|
2756
|
+
path: "/v2/cost-centers/{id}/{resourceType}/{resourceId}",
|
|
2757
|
+
params: [
|
|
2758
|
+
{
|
|
2759
|
+
name: "id",
|
|
2760
|
+
location: "path"
|
|
2761
|
+
},
|
|
2762
|
+
{
|
|
2763
|
+
name: "resourceType",
|
|
2764
|
+
location: "path"
|
|
2765
|
+
},
|
|
2766
|
+
{
|
|
2767
|
+
name: "resourceId",
|
|
2768
|
+
location: "path"
|
|
2769
|
+
}
|
|
2770
|
+
],
|
|
2771
|
+
hasBody: false,
|
|
2772
|
+
annotations: {
|
|
2773
|
+
readOnlyHint: false,
|
|
2774
|
+
destructiveHint: true,
|
|
2775
|
+
idempotentHint: true,
|
|
2776
|
+
openWorldHint: true
|
|
2777
|
+
},
|
|
2778
|
+
inputSchema: {
|
|
2779
|
+
type: "object",
|
|
2780
|
+
properties: {
|
|
2781
|
+
id: {
|
|
2782
|
+
type: "string",
|
|
2783
|
+
minLength: 1,
|
|
2784
|
+
description: "Cost center identifier."
|
|
2785
|
+
},
|
|
2786
|
+
resourceType: {
|
|
2787
|
+
$ref: "#/$defs/ResourceType",
|
|
2788
|
+
description: "Kind of resource.",
|
|
2789
|
+
type: "string"
|
|
2790
|
+
},
|
|
2791
|
+
resourceId: {
|
|
2792
|
+
type: "string",
|
|
2793
|
+
minLength: 1,
|
|
2794
|
+
description: "Resource identifier."
|
|
2795
|
+
}
|
|
2796
|
+
},
|
|
2797
|
+
required: ["id", "resourceType", "resourceId"],
|
|
2798
|
+
$defs: {
|
|
2799
|
+
ResourceType: {
|
|
2800
|
+
type: "string",
|
|
2801
|
+
description: "Kind of resource a cost center or tag can be attached to.",
|
|
2802
|
+
enum: ["POD", "CLUSTER", "SERVERLESS_ENDPOINT", "NETWORK_VOLUME"]
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
},
|
|
2242
2807
|
{
|
|
2243
2808
|
name: "get-cluster",
|
|
2244
2809
|
title: "Get cluster",
|
|
@@ -2270,6 +2835,38 @@ var generatedTools = [
|
|
|
2270
2835
|
required: ["id"]
|
|
2271
2836
|
}
|
|
2272
2837
|
},
|
|
2838
|
+
{
|
|
2839
|
+
name: "get-cost-center",
|
|
2840
|
+
title: "Get cost center",
|
|
2841
|
+
operationId: "getCostCenter",
|
|
2842
|
+
description: "Get a cost center. Returns one cost center. Its attributed resources are listed by `GET /v2/cost-centers/{id}/resources`. Returns 404 when the cost center does not exist or is not the caller's.",
|
|
2843
|
+
method: "GET",
|
|
2844
|
+
path: "/v2/cost-centers/{id}",
|
|
2845
|
+
params: [
|
|
2846
|
+
{
|
|
2847
|
+
name: "id",
|
|
2848
|
+
location: "path"
|
|
2849
|
+
}
|
|
2850
|
+
],
|
|
2851
|
+
hasBody: false,
|
|
2852
|
+
annotations: {
|
|
2853
|
+
readOnlyHint: true,
|
|
2854
|
+
destructiveHint: false,
|
|
2855
|
+
idempotentHint: true,
|
|
2856
|
+
openWorldHint: true
|
|
2857
|
+
},
|
|
2858
|
+
inputSchema: {
|
|
2859
|
+
type: "object",
|
|
2860
|
+
properties: {
|
|
2861
|
+
id: {
|
|
2862
|
+
type: "string",
|
|
2863
|
+
minLength: 1,
|
|
2864
|
+
description: "Cost center identifier."
|
|
2865
|
+
}
|
|
2866
|
+
},
|
|
2867
|
+
required: ["id"]
|
|
2868
|
+
}
|
|
2869
|
+
},
|
|
2273
2870
|
{
|
|
2274
2871
|
name: "get-cpu-type",
|
|
2275
2872
|
title: "Get CPU type",
|
|
@@ -2467,6 +3064,261 @@ var generatedTools = [
|
|
|
2467
3064
|
required: ["id", "buildId"]
|
|
2468
3065
|
}
|
|
2469
3066
|
},
|
|
3067
|
+
{
|
|
3068
|
+
name: "get-endpoint-cold-start-metrics",
|
|
3069
|
+
title: "Get endpoint cold start metrics",
|
|
3070
|
+
operationId: "getEndpointColdStartMetrics",
|
|
3071
|
+
description: "Get serverless endpoint cold start metrics. Returns the cold start series shown on the endpoint's Metrics tab in the console. **Window.** `startTime` is inclusive and `endTime` is exclusive. Both are optional: `endTime` defaults to now and `startTime` to 24 hours before `endTime`, rounded down to the start of an `interval` bucket. An `endTime` in the future is treated as now. Metrics are kept for 90 days, so `startTime` must be within the last 90 days. **Interval.** Each record covers one `interval`-sized bucket, aligned to UTC. **Paging.** Records are oldest first, at most `limit` (default 1000) per page. Follow `pagination.nextCursor` while `pagination.hasNextPage` is true. The cursor keeps the first page's window, so `startTime`, `endTime`, and `interval` can be left out on later pages; if sent, they must match the first page or the cursor is rejected with 422. **Sparse series.** Buckets with no activity are omitted, not zero-filled, so `records` can be shorter than the number of buckets in the window, or empty. **Units.** `durationMs` is how long each cold start took, in milliseconds.",
|
|
3072
|
+
method: "GET",
|
|
3073
|
+
path: "/v2/serverless/{id}/metrics/cold-starts",
|
|
3074
|
+
params: [
|
|
3075
|
+
{
|
|
3076
|
+
name: "id",
|
|
3077
|
+
location: "path"
|
|
3078
|
+
},
|
|
3079
|
+
{
|
|
3080
|
+
name: "startTime",
|
|
3081
|
+
location: "query"
|
|
3082
|
+
},
|
|
3083
|
+
{
|
|
3084
|
+
name: "endTime",
|
|
3085
|
+
location: "query"
|
|
3086
|
+
},
|
|
3087
|
+
{
|
|
3088
|
+
name: "interval",
|
|
3089
|
+
location: "query"
|
|
3090
|
+
},
|
|
3091
|
+
{
|
|
3092
|
+
name: "cursor",
|
|
3093
|
+
location: "query"
|
|
3094
|
+
},
|
|
3095
|
+
{
|
|
3096
|
+
name: "limit",
|
|
3097
|
+
location: "query"
|
|
3098
|
+
}
|
|
3099
|
+
],
|
|
3100
|
+
hasBody: false,
|
|
3101
|
+
annotations: {
|
|
3102
|
+
readOnlyHint: true,
|
|
3103
|
+
destructiveHint: false,
|
|
3104
|
+
idempotentHint: true,
|
|
3105
|
+
openWorldHint: true
|
|
3106
|
+
},
|
|
3107
|
+
inputSchema: {
|
|
3108
|
+
type: "object",
|
|
3109
|
+
properties: {
|
|
3110
|
+
id: {
|
|
3111
|
+
type: "string",
|
|
3112
|
+
description: "Serverless endpoint identifier"
|
|
3113
|
+
},
|
|
3114
|
+
startTime: {
|
|
3115
|
+
type: "string",
|
|
3116
|
+
format: "date-time",
|
|
3117
|
+
description: "Start of the window (RFC 3339), inclusive. Defaults to 24 hours before endTime, rounded down to the start of an interval bucket. Must be within the last 90 days."
|
|
3118
|
+
},
|
|
3119
|
+
endTime: {
|
|
3120
|
+
type: "string",
|
|
3121
|
+
format: "date-time",
|
|
3122
|
+
description: "End of the window (RFC 3339), exclusive. Defaults to now; a future value is treated as now."
|
|
3123
|
+
},
|
|
3124
|
+
interval: {
|
|
3125
|
+
$ref: "#/$defs/EndpointMetricsInterval",
|
|
3126
|
+
description: "Bucket size. Defaults to 1h.",
|
|
3127
|
+
type: "string"
|
|
3128
|
+
},
|
|
3129
|
+
cursor: {
|
|
3130
|
+
type: "string",
|
|
3131
|
+
minLength: 1,
|
|
3132
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
3133
|
+
},
|
|
3134
|
+
limit: {
|
|
3135
|
+
type: "integer",
|
|
3136
|
+
minimum: 1,
|
|
3137
|
+
maximum: 1e3,
|
|
3138
|
+
description: "Page size, 1\u20131000. Defaults to 1000 when omitted."
|
|
3139
|
+
}
|
|
3140
|
+
},
|
|
3141
|
+
required: ["id"],
|
|
3142
|
+
$defs: {
|
|
3143
|
+
EndpointMetricsInterval: {
|
|
3144
|
+
type: "string",
|
|
3145
|
+
enum: ["1m", "5m", "15m", "30m", "1h", "6h", "12h", "1d"],
|
|
3146
|
+
default: "1h",
|
|
3147
|
+
description: "Bucket size for endpoint metrics."
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
},
|
|
3152
|
+
{
|
|
3153
|
+
name: "get-endpoint-request-metrics",
|
|
3154
|
+
title: "Get endpoint request metrics",
|
|
3155
|
+
operationId: "getEndpointRequestMetrics",
|
|
3156
|
+
description: "Get serverless endpoint request metrics. Returns the request series shown on the endpoint's Metrics tab in the console. **Window.** `startTime` is inclusive and `endTime` is exclusive. Both are optional: `endTime` defaults to now and `startTime` to 24 hours before `endTime`, rounded down to the start of an `interval` bucket. An `endTime` in the future is treated as now. Metrics are kept for 90 days, so `startTime` must be within the last 90 days. **Interval.** Each record covers one `interval`-sized bucket, aligned to UTC. **Paging.** Records are oldest first, at most `limit` (default 1000) per page. Follow `pagination.nextCursor` while `pagination.hasNextPage` is true. The cursor keeps the first page's window, so `startTime`, `endTime`, and `interval` can be left out on later pages; if sent, they must match the first page or the cursor is rejected with 422. **Sparse series.** Buckets with no activity are omitted, not zero-filled, so `records` can be shorter than the number of buckets in the window, or empty. **Units.** Durations are milliseconds. `executionTimeMs` is the time a worker spent running a request; `delayTimeMs` is the time a request waited in the queue before a worker picked it up.",
|
|
3157
|
+
method: "GET",
|
|
3158
|
+
path: "/v2/serverless/{id}/metrics/requests",
|
|
3159
|
+
params: [
|
|
3160
|
+
{
|
|
3161
|
+
name: "id",
|
|
3162
|
+
location: "path"
|
|
3163
|
+
},
|
|
3164
|
+
{
|
|
3165
|
+
name: "startTime",
|
|
3166
|
+
location: "query"
|
|
3167
|
+
},
|
|
3168
|
+
{
|
|
3169
|
+
name: "endTime",
|
|
3170
|
+
location: "query"
|
|
3171
|
+
},
|
|
3172
|
+
{
|
|
3173
|
+
name: "interval",
|
|
3174
|
+
location: "query"
|
|
3175
|
+
},
|
|
3176
|
+
{
|
|
3177
|
+
name: "cursor",
|
|
3178
|
+
location: "query"
|
|
3179
|
+
},
|
|
3180
|
+
{
|
|
3181
|
+
name: "limit",
|
|
3182
|
+
location: "query"
|
|
3183
|
+
}
|
|
3184
|
+
],
|
|
3185
|
+
hasBody: false,
|
|
3186
|
+
annotations: {
|
|
3187
|
+
readOnlyHint: true,
|
|
3188
|
+
destructiveHint: false,
|
|
3189
|
+
idempotentHint: true,
|
|
3190
|
+
openWorldHint: true
|
|
3191
|
+
},
|
|
3192
|
+
inputSchema: {
|
|
3193
|
+
type: "object",
|
|
3194
|
+
properties: {
|
|
3195
|
+
id: {
|
|
3196
|
+
type: "string",
|
|
3197
|
+
description: "Serverless endpoint identifier"
|
|
3198
|
+
},
|
|
3199
|
+
startTime: {
|
|
3200
|
+
type: "string",
|
|
3201
|
+
format: "date-time",
|
|
3202
|
+
description: "Start of the window (RFC 3339), inclusive. Defaults to 24 hours before endTime, rounded down to the start of an interval bucket. Must be within the last 90 days."
|
|
3203
|
+
},
|
|
3204
|
+
endTime: {
|
|
3205
|
+
type: "string",
|
|
3206
|
+
format: "date-time",
|
|
3207
|
+
description: "End of the window (RFC 3339), exclusive. Defaults to now; a future value is treated as now."
|
|
3208
|
+
},
|
|
3209
|
+
interval: {
|
|
3210
|
+
$ref: "#/$defs/EndpointMetricsInterval",
|
|
3211
|
+
description: "Bucket size. Defaults to 1h.",
|
|
3212
|
+
type: "string"
|
|
3213
|
+
},
|
|
3214
|
+
cursor: {
|
|
3215
|
+
type: "string",
|
|
3216
|
+
minLength: 1,
|
|
3217
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
3218
|
+
},
|
|
3219
|
+
limit: {
|
|
3220
|
+
type: "integer",
|
|
3221
|
+
minimum: 1,
|
|
3222
|
+
maximum: 1e3,
|
|
3223
|
+
description: "Page size, 1\u20131000. Defaults to 1000 when omitted."
|
|
3224
|
+
}
|
|
3225
|
+
},
|
|
3226
|
+
required: ["id"],
|
|
3227
|
+
$defs: {
|
|
3228
|
+
EndpointMetricsInterval: {
|
|
3229
|
+
type: "string",
|
|
3230
|
+
enum: ["1m", "5m", "15m", "30m", "1h", "6h", "12h", "1d"],
|
|
3231
|
+
default: "1h",
|
|
3232
|
+
description: "Bucket size for endpoint metrics."
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
},
|
|
3237
|
+
{
|
|
3238
|
+
name: "get-endpoint-worker-metrics",
|
|
3239
|
+
title: "Get endpoint worker metrics",
|
|
3240
|
+
operationId: "getEndpointWorkerMetrics",
|
|
3241
|
+
description: "Get serverless endpoint worker metrics. Returns the worker state series shown on the endpoint's Metrics tab in the console. For the current worker list, use `GET /v2/serverless/{id}/workers`. **Window.** `startTime` is inclusive and `endTime` is exclusive. Both are optional: `endTime` defaults to now and `startTime` to 24 hours before `endTime`, rounded down to the start of an `interval` bucket. An `endTime` in the future is treated as now. Metrics are kept for 90 days, so `startTime` must be within the last 90 days. **Interval.** Each record covers one `interval`-sized bucket, aligned to UTC. **Paging.** Records are oldest first, at most `limit` (default 1000) per page. Follow `pagination.nextCursor` while `pagination.hasNextPage` is true. The cursor keeps the first page's window, so `startTime`, `endTime`, and `interval` can be left out on later pages; if sent, they must match the first page or the cursor is rejected with 422. **Sparse series.** Buckets with no activity are omitted, not zero-filled, so `records` can be shorter than the number of buckets in the window, or empty. **Snapshots.** Each record holds the last worker-count snapshot in its bucket, as point-in-time counts.",
|
|
3242
|
+
method: "GET",
|
|
3243
|
+
path: "/v2/serverless/{id}/metrics/workers",
|
|
3244
|
+
params: [
|
|
3245
|
+
{
|
|
3246
|
+
name: "id",
|
|
3247
|
+
location: "path"
|
|
3248
|
+
},
|
|
3249
|
+
{
|
|
3250
|
+
name: "startTime",
|
|
3251
|
+
location: "query"
|
|
3252
|
+
},
|
|
3253
|
+
{
|
|
3254
|
+
name: "endTime",
|
|
3255
|
+
location: "query"
|
|
3256
|
+
},
|
|
3257
|
+
{
|
|
3258
|
+
name: "interval",
|
|
3259
|
+
location: "query"
|
|
3260
|
+
},
|
|
3261
|
+
{
|
|
3262
|
+
name: "cursor",
|
|
3263
|
+
location: "query"
|
|
3264
|
+
},
|
|
3265
|
+
{
|
|
3266
|
+
name: "limit",
|
|
3267
|
+
location: "query"
|
|
3268
|
+
}
|
|
3269
|
+
],
|
|
3270
|
+
hasBody: false,
|
|
3271
|
+
annotations: {
|
|
3272
|
+
readOnlyHint: true,
|
|
3273
|
+
destructiveHint: false,
|
|
3274
|
+
idempotentHint: true,
|
|
3275
|
+
openWorldHint: true
|
|
3276
|
+
},
|
|
3277
|
+
inputSchema: {
|
|
3278
|
+
type: "object",
|
|
3279
|
+
properties: {
|
|
3280
|
+
id: {
|
|
3281
|
+
type: "string",
|
|
3282
|
+
description: "Serverless endpoint identifier"
|
|
3283
|
+
},
|
|
3284
|
+
startTime: {
|
|
3285
|
+
type: "string",
|
|
3286
|
+
format: "date-time",
|
|
3287
|
+
description: "Start of the window (RFC 3339), inclusive. Defaults to 24 hours before endTime, rounded down to the start of an interval bucket. Must be within the last 90 days."
|
|
3288
|
+
},
|
|
3289
|
+
endTime: {
|
|
3290
|
+
type: "string",
|
|
3291
|
+
format: "date-time",
|
|
3292
|
+
description: "End of the window (RFC 3339), exclusive. Defaults to now; a future value is treated as now."
|
|
3293
|
+
},
|
|
3294
|
+
interval: {
|
|
3295
|
+
$ref: "#/$defs/EndpointMetricsInterval",
|
|
3296
|
+
description: "Bucket size. Defaults to 1h.",
|
|
3297
|
+
type: "string"
|
|
3298
|
+
},
|
|
3299
|
+
cursor: {
|
|
3300
|
+
type: "string",
|
|
3301
|
+
minLength: 1,
|
|
3302
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
3303
|
+
},
|
|
3304
|
+
limit: {
|
|
3305
|
+
type: "integer",
|
|
3306
|
+
minimum: 1,
|
|
3307
|
+
maximum: 1e3,
|
|
3308
|
+
description: "Page size, 1\u20131000. Defaults to 1000 when omitted."
|
|
3309
|
+
}
|
|
3310
|
+
},
|
|
3311
|
+
required: ["id"],
|
|
3312
|
+
$defs: {
|
|
3313
|
+
EndpointMetricsInterval: {
|
|
3314
|
+
type: "string",
|
|
3315
|
+
enum: ["1m", "5m", "15m", "30m", "1h", "6h", "12h", "1d"],
|
|
3316
|
+
default: "1h",
|
|
3317
|
+
description: "Bucket size for endpoint metrics."
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
}
|
|
3321
|
+
},
|
|
2470
3322
|
{
|
|
2471
3323
|
name: "get-global-volume",
|
|
2472
3324
|
title: "Get global volume",
|
|
@@ -2579,7 +3431,7 @@ var generatedTools = [
|
|
|
2579
3431
|
},
|
|
2580
3432
|
cloud: {
|
|
2581
3433
|
$ref: "#/$defs/GpuCloudFilter",
|
|
2582
|
-
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY.
|
|
3434
|
+
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY. Default when omitted: SECURE.",
|
|
2583
3435
|
type: "string"
|
|
2584
3436
|
},
|
|
2585
3437
|
countryCodes: {
|
|
@@ -2618,19 +3470,133 @@ var generatedTools = [
|
|
|
2618
3470
|
},
|
|
2619
3471
|
Product: {
|
|
2620
3472
|
type: "string",
|
|
2621
|
-
description: "Catalog product availability context. Availability is product-specific, so this is required whenever availability is requested.",
|
|
2622
|
-
enum: ["POD", "CLUSTER", "SERVERLESS"]
|
|
3473
|
+
description: "Catalog product availability context. Availability is product-specific, so this is required whenever availability is requested.",
|
|
3474
|
+
enum: ["POD", "CLUSTER", "SERVERLESS"]
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
},
|
|
3479
|
+
{
|
|
3480
|
+
name: "get-network-volume",
|
|
3481
|
+
title: "Get network volume",
|
|
3482
|
+
operationId: "getNetworkVolume",
|
|
3483
|
+
description: "Get a network volume. Returns a single network volume by ID.",
|
|
3484
|
+
method: "GET",
|
|
3485
|
+
path: "/v2/network-volumes/{id}",
|
|
3486
|
+
params: [
|
|
3487
|
+
{
|
|
3488
|
+
name: "id",
|
|
3489
|
+
location: "path"
|
|
3490
|
+
}
|
|
3491
|
+
],
|
|
3492
|
+
hasBody: false,
|
|
3493
|
+
annotations: {
|
|
3494
|
+
readOnlyHint: true,
|
|
3495
|
+
destructiveHint: false,
|
|
3496
|
+
idempotentHint: true,
|
|
3497
|
+
openWorldHint: true
|
|
3498
|
+
},
|
|
3499
|
+
inputSchema: {
|
|
3500
|
+
type: "object",
|
|
3501
|
+
properties: {
|
|
3502
|
+
id: {
|
|
3503
|
+
type: "string",
|
|
3504
|
+
description: "Network volume identifier"
|
|
3505
|
+
}
|
|
3506
|
+
},
|
|
3507
|
+
required: ["id"]
|
|
3508
|
+
}
|
|
3509
|
+
},
|
|
3510
|
+
{
|
|
3511
|
+
name: "get-organization",
|
|
3512
|
+
title: "Get organization",
|
|
3513
|
+
operationId: "getOrganization",
|
|
3514
|
+
description: "Get your current organization. Returns the authenticated caller's current organization. Organization context comes from the caller's membership; no organization selector is required. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
3515
|
+
method: "GET",
|
|
3516
|
+
path: "/v2/organization",
|
|
3517
|
+
params: [],
|
|
3518
|
+
hasBody: false,
|
|
3519
|
+
annotations: {
|
|
3520
|
+
readOnlyHint: true,
|
|
3521
|
+
destructiveHint: false,
|
|
3522
|
+
idempotentHint: true,
|
|
3523
|
+
openWorldHint: true
|
|
3524
|
+
},
|
|
3525
|
+
inputSchema: {
|
|
3526
|
+
type: "object",
|
|
3527
|
+
properties: {}
|
|
3528
|
+
}
|
|
3529
|
+
},
|
|
3530
|
+
{
|
|
3531
|
+
name: "get-organization-group",
|
|
3532
|
+
title: "Get organization group",
|
|
3533
|
+
operationId: "getOrganizationGroup",
|
|
3534
|
+
description: "Get a group in your current organization. Returns the group without its members. Returns 404 when the ID is unknown or belongs to another organization, or when the caller does not belong to an organization.",
|
|
3535
|
+
method: "GET",
|
|
3536
|
+
path: "/v2/organization/groups/{id}",
|
|
3537
|
+
params: [
|
|
3538
|
+
{
|
|
3539
|
+
name: "id",
|
|
3540
|
+
location: "path"
|
|
3541
|
+
}
|
|
3542
|
+
],
|
|
3543
|
+
hasBody: false,
|
|
3544
|
+
annotations: {
|
|
3545
|
+
readOnlyHint: true,
|
|
3546
|
+
destructiveHint: false,
|
|
3547
|
+
idempotentHint: true,
|
|
3548
|
+
openWorldHint: true
|
|
3549
|
+
},
|
|
3550
|
+
inputSchema: {
|
|
3551
|
+
type: "object",
|
|
3552
|
+
properties: {
|
|
3553
|
+
id: {
|
|
3554
|
+
type: "string",
|
|
3555
|
+
minLength: 1,
|
|
3556
|
+
description: "Group ID."
|
|
3557
|
+
}
|
|
3558
|
+
},
|
|
3559
|
+
required: ["id"]
|
|
3560
|
+
}
|
|
3561
|
+
},
|
|
3562
|
+
{
|
|
3563
|
+
name: "get-organization-invite",
|
|
3564
|
+
title: "Get organization invite",
|
|
3565
|
+
operationId: "getOrganizationInvite",
|
|
3566
|
+
description: "Get a pending organization invite. Returns one pending invitation to the authenticated caller's organization. Only unexpired invites are pending: an invite that has expired, been accepted or been revoked returns 404, as does an ID from another organization. Reading invites requires the organization's invite-management capability, which the built-in admin role holds; other members receive 403. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
3567
|
+
method: "GET",
|
|
3568
|
+
path: "/v2/organization/invites/{id}",
|
|
3569
|
+
params: [
|
|
3570
|
+
{
|
|
3571
|
+
name: "id",
|
|
3572
|
+
location: "path"
|
|
3573
|
+
}
|
|
3574
|
+
],
|
|
3575
|
+
hasBody: false,
|
|
3576
|
+
annotations: {
|
|
3577
|
+
readOnlyHint: true,
|
|
3578
|
+
destructiveHint: false,
|
|
3579
|
+
idempotentHint: true,
|
|
3580
|
+
openWorldHint: true
|
|
3581
|
+
},
|
|
3582
|
+
inputSchema: {
|
|
3583
|
+
type: "object",
|
|
3584
|
+
properties: {
|
|
3585
|
+
id: {
|
|
3586
|
+
type: "string",
|
|
3587
|
+
description: "Invite identifier"
|
|
2623
3588
|
}
|
|
2624
|
-
}
|
|
3589
|
+
},
|
|
3590
|
+
required: ["id"]
|
|
2625
3591
|
}
|
|
2626
3592
|
},
|
|
2627
3593
|
{
|
|
2628
|
-
name: "get-
|
|
2629
|
-
title: "Get
|
|
2630
|
-
operationId: "
|
|
2631
|
-
description: "Get
|
|
3594
|
+
name: "get-organization-role",
|
|
3595
|
+
title: "Get organization role",
|
|
3596
|
+
operationId: "getOrganizationRole",
|
|
3597
|
+
description: "Get an organization role. Returns one role a member or invite of the authenticated caller's organization can hold: a built-in role, or one of the organization's custom roles. Returns 404 when the ID is unknown or names another organization's custom role, or when the caller does not belong to an organization; 403 when the caller may not view the organization's roles or organizations are unavailable to the caller.",
|
|
2632
3598
|
method: "GET",
|
|
2633
|
-
path: "/v2/
|
|
3599
|
+
path: "/v2/organization/roles/{id}",
|
|
2634
3600
|
params: [
|
|
2635
3601
|
{
|
|
2636
3602
|
name: "id",
|
|
@@ -2649,20 +3615,31 @@ var generatedTools = [
|
|
|
2649
3615
|
properties: {
|
|
2650
3616
|
id: {
|
|
2651
3617
|
type: "string",
|
|
2652
|
-
description: "
|
|
3618
|
+
description: "Role identifier"
|
|
2653
3619
|
}
|
|
2654
3620
|
},
|
|
2655
3621
|
required: ["id"]
|
|
2656
3622
|
}
|
|
2657
3623
|
},
|
|
2658
3624
|
{
|
|
2659
|
-
name: "get-organization",
|
|
2660
|
-
title: "Get organization",
|
|
2661
|
-
operationId: "
|
|
2662
|
-
description: "
|
|
3625
|
+
name: "get-organization-role-capabilities",
|
|
3626
|
+
title: "Get organization role capabilities",
|
|
3627
|
+
operationId: "getOrganizationRoleCapabilities",
|
|
3628
|
+
description: "List grantable role capabilities. Returns the capabilities a custom role can grant, grouped by family: each capability is a family and one of its verbs, written `FAMILY:VERB`. This is the set role creation accepts, not filtered to the caller's own access; saving a role also requires the caller to hold every capability it grants. `family` and `verb` narrow the result and apply together; with neither, the whole catalog is returned. Reading the catalog requires organization membership; other callers receive 403.",
|
|
2663
3629
|
method: "GET",
|
|
2664
|
-
path: "/v2/organization",
|
|
2665
|
-
params: [
|
|
3630
|
+
path: "/v2/organization/roles/capabilities",
|
|
3631
|
+
params: [
|
|
3632
|
+
{
|
|
3633
|
+
name: "family",
|
|
3634
|
+
location: "query",
|
|
3635
|
+
explode: false
|
|
3636
|
+
},
|
|
3637
|
+
{
|
|
3638
|
+
name: "verb",
|
|
3639
|
+
location: "query",
|
|
3640
|
+
explode: false
|
|
3641
|
+
}
|
|
3642
|
+
],
|
|
2666
3643
|
hasBody: false,
|
|
2667
3644
|
annotations: {
|
|
2668
3645
|
readOnlyHint: true,
|
|
@@ -2672,7 +3649,22 @@ var generatedTools = [
|
|
|
2672
3649
|
},
|
|
2673
3650
|
inputSchema: {
|
|
2674
3651
|
type: "object",
|
|
2675
|
-
properties: {
|
|
3652
|
+
properties: {
|
|
3653
|
+
family: {
|
|
3654
|
+
type: "array",
|
|
3655
|
+
items: {
|
|
3656
|
+
type: "string"
|
|
3657
|
+
},
|
|
3658
|
+
description: "Only return these capability families, matched exactly. Comma-separated; a family matching any listed value is returned. An empty value is ignored."
|
|
3659
|
+
},
|
|
3660
|
+
verb: {
|
|
3661
|
+
type: "array",
|
|
3662
|
+
items: {
|
|
3663
|
+
type: "string"
|
|
3664
|
+
},
|
|
3665
|
+
description: "Only return these verbs, matched exactly. Comma-separated. Each family lists only the requested verbs it has, and a family with none of them is left out. An empty value is ignored."
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
2676
3668
|
}
|
|
2677
3669
|
},
|
|
2678
3670
|
{
|
|
@@ -3155,6 +4147,107 @@ var generatedTools = [
|
|
|
3155
4147
|
}
|
|
3156
4148
|
}
|
|
3157
4149
|
},
|
|
4150
|
+
{
|
|
4151
|
+
name: "list-cost-center-resources",
|
|
4152
|
+
title: "List cost center resources",
|
|
4153
|
+
operationId: "listCostCenterResources",
|
|
4154
|
+
description: "List a cost center's resources. Returns the resources attributed to one cost center, cursor-paginated; an omitted `limit` defaults to 1000. Each entry is the `{type}/{id}` pair `DELETE /v2/cost-centers/{id}/{resourceType}/{resourceId}` takes. A cost center with nothing attributed returns an empty list; one that does not exist or is not the caller's returns 404.",
|
|
4155
|
+
method: "GET",
|
|
4156
|
+
path: "/v2/cost-centers/{id}/resources",
|
|
4157
|
+
params: [
|
|
4158
|
+
{
|
|
4159
|
+
name: "id",
|
|
4160
|
+
location: "path"
|
|
4161
|
+
},
|
|
4162
|
+
{
|
|
4163
|
+
name: "cursor",
|
|
4164
|
+
location: "query"
|
|
4165
|
+
},
|
|
4166
|
+
{
|
|
4167
|
+
name: "limit",
|
|
4168
|
+
location: "query"
|
|
4169
|
+
}
|
|
4170
|
+
],
|
|
4171
|
+
hasBody: false,
|
|
4172
|
+
annotations: {
|
|
4173
|
+
readOnlyHint: true,
|
|
4174
|
+
destructiveHint: false,
|
|
4175
|
+
idempotentHint: true,
|
|
4176
|
+
openWorldHint: true
|
|
4177
|
+
},
|
|
4178
|
+
inputSchema: {
|
|
4179
|
+
type: "object",
|
|
4180
|
+
properties: {
|
|
4181
|
+
id: {
|
|
4182
|
+
type: "string",
|
|
4183
|
+
minLength: 1,
|
|
4184
|
+
description: "Cost center identifier."
|
|
4185
|
+
},
|
|
4186
|
+
cursor: {
|
|
4187
|
+
type: "string",
|
|
4188
|
+
minLength: 1,
|
|
4189
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
4190
|
+
},
|
|
4191
|
+
limit: {
|
|
4192
|
+
type: "integer",
|
|
4193
|
+
minimum: 1,
|
|
4194
|
+
maximum: 1e3,
|
|
4195
|
+
description: "Page size, 1\u20131000. Defaults to 1000 when omitted."
|
|
4196
|
+
}
|
|
4197
|
+
},
|
|
4198
|
+
required: ["id"]
|
|
4199
|
+
}
|
|
4200
|
+
},
|
|
4201
|
+
{
|
|
4202
|
+
name: "list-cost-centers",
|
|
4203
|
+
title: "List cost centers",
|
|
4204
|
+
operationId: "listCostCenters",
|
|
4205
|
+
description: "List cost centers. Returns the caller's cost centers, cursor-paginated newest-first; an omitted `limit` defaults to 1000. Follow `pagination.nextCursor` until `hasNextPage` is false.",
|
|
4206
|
+
method: "GET",
|
|
4207
|
+
path: "/v2/cost-centers",
|
|
4208
|
+
params: [
|
|
4209
|
+
{
|
|
4210
|
+
name: "search",
|
|
4211
|
+
location: "query"
|
|
4212
|
+
},
|
|
4213
|
+
{
|
|
4214
|
+
name: "cursor",
|
|
4215
|
+
location: "query"
|
|
4216
|
+
},
|
|
4217
|
+
{
|
|
4218
|
+
name: "limit",
|
|
4219
|
+
location: "query"
|
|
4220
|
+
}
|
|
4221
|
+
],
|
|
4222
|
+
hasBody: false,
|
|
4223
|
+
annotations: {
|
|
4224
|
+
readOnlyHint: true,
|
|
4225
|
+
destructiveHint: false,
|
|
4226
|
+
idempotentHint: true,
|
|
4227
|
+
openWorldHint: true
|
|
4228
|
+
},
|
|
4229
|
+
inputSchema: {
|
|
4230
|
+
type: "object",
|
|
4231
|
+
properties: {
|
|
4232
|
+
search: {
|
|
4233
|
+
type: "string",
|
|
4234
|
+
minLength: 1,
|
|
4235
|
+
description: "Case-insensitive substring match against `value`."
|
|
4236
|
+
},
|
|
4237
|
+
cursor: {
|
|
4238
|
+
type: "string",
|
|
4239
|
+
minLength: 1,
|
|
4240
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
4241
|
+
},
|
|
4242
|
+
limit: {
|
|
4243
|
+
type: "integer",
|
|
4244
|
+
minimum: 1,
|
|
4245
|
+
maximum: 1e3,
|
|
4246
|
+
description: "Page size, 1\u20131000. Defaults to 1000 when omitted."
|
|
4247
|
+
}
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
},
|
|
3158
4251
|
{
|
|
3159
4252
|
name: "list-cpu-types",
|
|
3160
4253
|
title: "List CPU types",
|
|
@@ -3685,7 +4778,7 @@ var generatedTools = [
|
|
|
3685
4778
|
},
|
|
3686
4779
|
cloud: {
|
|
3687
4780
|
$ref: "#/$defs/GpuCloudFilter",
|
|
3688
|
-
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY.
|
|
4781
|
+
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY. Default when omitted: SECURE.",
|
|
3689
4782
|
type: "string"
|
|
3690
4783
|
},
|
|
3691
4784
|
countryCodes: {
|
|
@@ -3730,31 +4823,139 @@ var generatedTools = [
|
|
|
3730
4823
|
}
|
|
3731
4824
|
},
|
|
3732
4825
|
{
|
|
3733
|
-
name: "list-network-volume-billing",
|
|
3734
|
-
title: "List network volume billing",
|
|
3735
|
-
operationId: "listNetworkVolumeBilling",
|
|
3736
|
-
description: "Get network volume billing history. Returns network volume billing history for the authenticated user, split into time buckets by startTime/endTime with bucketSize or by lastN recent buckets. Use networkVolumeId to filter to one volume; without it, records are emitted per volume per bucket. Each record includes standard storage, high-performance storage, and total amounts, while metadata reports the resolved query, distinct volume count, and totals across the returned records.",
|
|
4826
|
+
name: "list-network-volume-billing",
|
|
4827
|
+
title: "List network volume billing",
|
|
4828
|
+
operationId: "listNetworkVolumeBilling",
|
|
4829
|
+
description: "Get network volume billing history. Returns network volume billing history for the authenticated user, split into time buckets by startTime/endTime with bucketSize or by lastN recent buckets. Use networkVolumeId to filter to one volume; without it, records are emitted per volume per bucket. Each record includes standard storage, high-performance storage, and total amounts, while metadata reports the resolved query, distinct volume count, and totals across the returned records.",
|
|
4830
|
+
method: "GET",
|
|
4831
|
+
path: "/v2/billing/network-volumes",
|
|
4832
|
+
params: [
|
|
4833
|
+
{
|
|
4834
|
+
name: "startTime",
|
|
4835
|
+
location: "query"
|
|
4836
|
+
},
|
|
4837
|
+
{
|
|
4838
|
+
name: "endTime",
|
|
4839
|
+
location: "query"
|
|
4840
|
+
},
|
|
4841
|
+
{
|
|
4842
|
+
name: "bucketSize",
|
|
4843
|
+
location: "query"
|
|
4844
|
+
},
|
|
4845
|
+
{
|
|
4846
|
+
name: "lastN",
|
|
4847
|
+
location: "query"
|
|
4848
|
+
},
|
|
4849
|
+
{
|
|
4850
|
+
name: "networkVolumeId",
|
|
4851
|
+
location: "query"
|
|
4852
|
+
}
|
|
4853
|
+
],
|
|
4854
|
+
hasBody: false,
|
|
4855
|
+
annotations: {
|
|
4856
|
+
readOnlyHint: true,
|
|
4857
|
+
destructiveHint: false,
|
|
4858
|
+
idempotentHint: true,
|
|
4859
|
+
openWorldHint: true
|
|
4860
|
+
},
|
|
4861
|
+
inputSchema: {
|
|
4862
|
+
type: "object",
|
|
4863
|
+
properties: {
|
|
4864
|
+
startTime: {
|
|
4865
|
+
type: "string",
|
|
4866
|
+
format: "date-time",
|
|
4867
|
+
description: "Start of the billing period (RFC 3339). Defaults to 30 days ago."
|
|
4868
|
+
},
|
|
4869
|
+
endTime: {
|
|
4870
|
+
type: "string",
|
|
4871
|
+
format: "date-time",
|
|
4872
|
+
description: "End of the billing period (RFC 3339), exclusive. Defaults to now. Snapped up to the end of the bucketSize bucket it lands in (unless already on a boundary) so the window aligns with the returned records."
|
|
4873
|
+
},
|
|
4874
|
+
bucketSize: {
|
|
4875
|
+
$ref: "#/$defs/BillingBucketSize",
|
|
4876
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
4877
|
+
type: "string"
|
|
4878
|
+
},
|
|
4879
|
+
lastN: {
|
|
4880
|
+
type: "integer",
|
|
4881
|
+
minimum: 1,
|
|
4882
|
+
description: 'Return the last N buckets of bucketSize, ending with the current (in-progress) bucket \u2014 e.g. lastN=100 with bucketSize=day is "last 100 days".'
|
|
4883
|
+
},
|
|
4884
|
+
networkVolumeId: {
|
|
4885
|
+
type: "string",
|
|
4886
|
+
description: "Filter to a specific network volume."
|
|
4887
|
+
}
|
|
4888
|
+
},
|
|
4889
|
+
$defs: {
|
|
4890
|
+
BillingBucketSize: {
|
|
4891
|
+
type: "string",
|
|
4892
|
+
enum: ["hour", "day", "week", "month", "year"],
|
|
4893
|
+
default: "day",
|
|
4894
|
+
description: "Length of each billing time bucket.",
|
|
4895
|
+
examples: ["day"]
|
|
4896
|
+
}
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4899
|
+
},
|
|
4900
|
+
{
|
|
4901
|
+
name: "list-network-volumes",
|
|
4902
|
+
title: "List network volumes",
|
|
4903
|
+
operationId: "listNetworkVolumes",
|
|
4904
|
+
description: "List network volumes. Returns network volumes owned by the authenticated user, cursor-paginated newest-first; an omitted `limit` defaults to 1000. Follow `pagination.nextCursor` until `hasNextPage` is false.",
|
|
4905
|
+
method: "GET",
|
|
4906
|
+
path: "/v2/network-volumes",
|
|
4907
|
+
params: [
|
|
4908
|
+
{
|
|
4909
|
+
name: "cursor",
|
|
4910
|
+
location: "query"
|
|
4911
|
+
},
|
|
4912
|
+
{
|
|
4913
|
+
name: "limit",
|
|
4914
|
+
location: "query"
|
|
4915
|
+
}
|
|
4916
|
+
],
|
|
4917
|
+
hasBody: false,
|
|
4918
|
+
annotations: {
|
|
4919
|
+
readOnlyHint: true,
|
|
4920
|
+
destructiveHint: false,
|
|
4921
|
+
idempotentHint: true,
|
|
4922
|
+
openWorldHint: true
|
|
4923
|
+
},
|
|
4924
|
+
inputSchema: {
|
|
4925
|
+
type: "object",
|
|
4926
|
+
properties: {
|
|
4927
|
+
cursor: {
|
|
4928
|
+
type: "string",
|
|
4929
|
+
minLength: 1,
|
|
4930
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
4931
|
+
},
|
|
4932
|
+
limit: {
|
|
4933
|
+
type: "integer",
|
|
4934
|
+
minimum: 1,
|
|
4935
|
+
maximum: 1e3,
|
|
4936
|
+
description: "Page size, 1\u20131000. Defaults to 1000 when omitted."
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
},
|
|
4941
|
+
{
|
|
4942
|
+
name: "list-organization-group-members",
|
|
4943
|
+
title: "List organization group members",
|
|
4944
|
+
operationId: "listOrganizationGroupMembers",
|
|
4945
|
+
description: "List members of a group. Members are ordered newest first by membership creation time, with a unique upstream tie-breaker. Returns 404 when the group does not exist in the current organization, or when the caller does not belong to an organization.",
|
|
3737
4946
|
method: "GET",
|
|
3738
|
-
path: "/v2/
|
|
4947
|
+
path: "/v2/organization/groups/{id}/members",
|
|
3739
4948
|
params: [
|
|
3740
4949
|
{
|
|
3741
|
-
name: "
|
|
3742
|
-
location: "
|
|
3743
|
-
},
|
|
3744
|
-
{
|
|
3745
|
-
name: "endTime",
|
|
3746
|
-
location: "query"
|
|
3747
|
-
},
|
|
3748
|
-
{
|
|
3749
|
-
name: "bucketSize",
|
|
3750
|
-
location: "query"
|
|
4950
|
+
name: "id",
|
|
4951
|
+
location: "path"
|
|
3751
4952
|
},
|
|
3752
4953
|
{
|
|
3753
|
-
name: "
|
|
4954
|
+
name: "cursor",
|
|
3754
4955
|
location: "query"
|
|
3755
4956
|
},
|
|
3756
4957
|
{
|
|
3757
|
-
name: "
|
|
4958
|
+
name: "limit",
|
|
3758
4959
|
location: "query"
|
|
3759
4960
|
}
|
|
3760
4961
|
],
|
|
@@ -3768,50 +4969,38 @@ var generatedTools = [
|
|
|
3768
4969
|
inputSchema: {
|
|
3769
4970
|
type: "object",
|
|
3770
4971
|
properties: {
|
|
3771
|
-
|
|
4972
|
+
id: {
|
|
3772
4973
|
type: "string",
|
|
3773
|
-
|
|
3774
|
-
description: "
|
|
4974
|
+
minLength: 1,
|
|
4975
|
+
description: "Group ID."
|
|
3775
4976
|
},
|
|
3776
|
-
|
|
4977
|
+
cursor: {
|
|
3777
4978
|
type: "string",
|
|
3778
|
-
|
|
3779
|
-
description: "
|
|
3780
|
-
},
|
|
3781
|
-
bucketSize: {
|
|
3782
|
-
$ref: "#/$defs/BillingBucketSize",
|
|
3783
|
-
description: "Length of each billing time bucket. Defaults to day.",
|
|
3784
|
-
type: "string"
|
|
4979
|
+
minLength: 1,
|
|
4980
|
+
description: "Opaque resume cursor \u2014 pass the previous response's `pagination.nextCursor` through verbatim; omit for the first page. A cursor is only valid for the operation and parameters that issued it; a malformed or foreign cursor is rejected."
|
|
3785
4981
|
},
|
|
3786
|
-
|
|
4982
|
+
limit: {
|
|
3787
4983
|
type: "integer",
|
|
3788
4984
|
minimum: 1,
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
networkVolumeId: {
|
|
3792
|
-
type: "string",
|
|
3793
|
-
description: "Filter to a specific network volume."
|
|
4985
|
+
maximum: 100,
|
|
4986
|
+
description: "Page size, 1\u2013100. Defaults to 100 when omitted."
|
|
3794
4987
|
}
|
|
3795
4988
|
},
|
|
3796
|
-
|
|
3797
|
-
BillingBucketSize: {
|
|
3798
|
-
type: "string",
|
|
3799
|
-
enum: ["hour", "day", "week", "month", "year"],
|
|
3800
|
-
default: "day",
|
|
3801
|
-
description: "Length of each billing time bucket.",
|
|
3802
|
-
examples: ["day"]
|
|
3803
|
-
}
|
|
3804
|
-
}
|
|
4989
|
+
required: ["id"]
|
|
3805
4990
|
}
|
|
3806
4991
|
},
|
|
3807
4992
|
{
|
|
3808
|
-
name: "list-
|
|
3809
|
-
title: "List
|
|
3810
|
-
operationId: "
|
|
3811
|
-
description: "List
|
|
4993
|
+
name: "list-organization-groups",
|
|
4994
|
+
title: "List organization groups",
|
|
4995
|
+
operationId: "listOrganizationGroups",
|
|
4996
|
+
description: "List groups in your current organization. Returns groups without their members or roles, ordered by creation time descending and then ID descending for deterministic pagination.",
|
|
3812
4997
|
method: "GET",
|
|
3813
|
-
path: "/v2/
|
|
4998
|
+
path: "/v2/organization/groups",
|
|
3814
4999
|
params: [
|
|
5000
|
+
{
|
|
5001
|
+
name: "name",
|
|
5002
|
+
location: "query"
|
|
5003
|
+
},
|
|
3815
5004
|
{
|
|
3816
5005
|
name: "cursor",
|
|
3817
5006
|
location: "query"
|
|
@@ -3831,6 +5020,10 @@ var generatedTools = [
|
|
|
3831
5020
|
inputSchema: {
|
|
3832
5021
|
type: "object",
|
|
3833
5022
|
properties: {
|
|
5023
|
+
name: {
|
|
5024
|
+
type: "string",
|
|
5025
|
+
description: "Optional case-insensitive substring of the group name. An empty value applies no filter."
|
|
5026
|
+
},
|
|
3834
5027
|
cursor: {
|
|
3835
5028
|
type: "string",
|
|
3836
5029
|
minLength: 1,
|
|
@@ -3839,12 +5032,52 @@ var generatedTools = [
|
|
|
3839
5032
|
limit: {
|
|
3840
5033
|
type: "integer",
|
|
3841
5034
|
minimum: 1,
|
|
3842
|
-
maximum:
|
|
3843
|
-
description: "Page size, 1\
|
|
5035
|
+
maximum: 100,
|
|
5036
|
+
description: "Page size, 1\u2013100. Defaults to 100 when omitted."
|
|
3844
5037
|
}
|
|
3845
5038
|
}
|
|
3846
5039
|
}
|
|
3847
5040
|
},
|
|
5041
|
+
{
|
|
5042
|
+
name: "list-organization-invites",
|
|
5043
|
+
title: "List organization invites",
|
|
5044
|
+
operationId: "listOrganizationInvites",
|
|
5045
|
+
description: "List pending organization invites. Returns the pending invitations to the authenticated caller's organization, newest first. Only unexpired invites are pending: an invite leaves the list once it is accepted, revoked or expired. The list is complete and takes no pagination parameters, because an organization's pending invites are capped. Reading invites requires the organization's invite-management capability, which the built-in admin role holds; other members receive 403. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
5046
|
+
method: "GET",
|
|
5047
|
+
path: "/v2/organization/invites",
|
|
5048
|
+
params: [],
|
|
5049
|
+
hasBody: false,
|
|
5050
|
+
annotations: {
|
|
5051
|
+
readOnlyHint: true,
|
|
5052
|
+
destructiveHint: false,
|
|
5053
|
+
idempotentHint: true,
|
|
5054
|
+
openWorldHint: true
|
|
5055
|
+
},
|
|
5056
|
+
inputSchema: {
|
|
5057
|
+
type: "object",
|
|
5058
|
+
properties: {}
|
|
5059
|
+
}
|
|
5060
|
+
},
|
|
5061
|
+
{
|
|
5062
|
+
name: "list-organization-roles",
|
|
5063
|
+
title: "List organization roles",
|
|
5064
|
+
operationId: "listOrganizationRoles",
|
|
5065
|
+
description: "List organization roles. Returns every role a member or invite of the authenticated caller's organization can hold: Runpod's built-in roles and the organization's custom roles, oldest first. The list is complete and takes no pagination parameters, because an organization's custom roles are capped. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
5066
|
+
method: "GET",
|
|
5067
|
+
path: "/v2/organization/roles",
|
|
5068
|
+
params: [],
|
|
5069
|
+
hasBody: false,
|
|
5070
|
+
annotations: {
|
|
5071
|
+
readOnlyHint: true,
|
|
5072
|
+
destructiveHint: false,
|
|
5073
|
+
idempotentHint: true,
|
|
5074
|
+
openWorldHint: true
|
|
5075
|
+
},
|
|
5076
|
+
inputSchema: {
|
|
5077
|
+
type: "object",
|
|
5078
|
+
properties: {}
|
|
5079
|
+
}
|
|
5080
|
+
},
|
|
3848
5081
|
{
|
|
3849
5082
|
name: "list-organization-users",
|
|
3850
5083
|
title: "List organization users",
|
|
@@ -4199,6 +5432,47 @@ var generatedTools = [
|
|
|
4199
5432
|
}
|
|
4200
5433
|
}
|
|
4201
5434
|
},
|
|
5435
|
+
{
|
|
5436
|
+
name: "remove-organization-group-member",
|
|
5437
|
+
title: "Remove organization group member",
|
|
5438
|
+
operationId: "removeOrganizationGroupMember",
|
|
5439
|
+
description: "Remove a member from a group. Removes the organization member from the group. The group and user must belong to the current organization. Returns 404 when the membership is absent, including repeated deletion, or when the group is unknown or belongs to another organization.",
|
|
5440
|
+
method: "DELETE",
|
|
5441
|
+
path: "/v2/organization/groups/{id}/members/{userId}",
|
|
5442
|
+
params: [
|
|
5443
|
+
{
|
|
5444
|
+
name: "id",
|
|
5445
|
+
location: "path"
|
|
5446
|
+
},
|
|
5447
|
+
{
|
|
5448
|
+
name: "userId",
|
|
5449
|
+
location: "path"
|
|
5450
|
+
}
|
|
5451
|
+
],
|
|
5452
|
+
hasBody: false,
|
|
5453
|
+
annotations: {
|
|
5454
|
+
readOnlyHint: false,
|
|
5455
|
+
destructiveHint: true,
|
|
5456
|
+
idempotentHint: true,
|
|
5457
|
+
openWorldHint: true
|
|
5458
|
+
},
|
|
5459
|
+
inputSchema: {
|
|
5460
|
+
type: "object",
|
|
5461
|
+
properties: {
|
|
5462
|
+
id: {
|
|
5463
|
+
type: "string",
|
|
5464
|
+
minLength: 1,
|
|
5465
|
+
description: "Group ID."
|
|
5466
|
+
},
|
|
5467
|
+
userId: {
|
|
5468
|
+
type: "string",
|
|
5469
|
+
minLength: 1,
|
|
5470
|
+
description: "Organization member user ID."
|
|
5471
|
+
}
|
|
5472
|
+
},
|
|
5473
|
+
required: ["id", "userId"]
|
|
5474
|
+
}
|
|
5475
|
+
},
|
|
4202
5476
|
{
|
|
4203
5477
|
name: "revoke-delegation",
|
|
4204
5478
|
title: "Revoke ECR delegation",
|
|
@@ -4279,6 +5553,59 @@ var generatedTools = [
|
|
|
4279
5553
|
}
|
|
4280
5554
|
}
|
|
4281
5555
|
},
|
|
5556
|
+
{
|
|
5557
|
+
name: "update-cost-center",
|
|
5558
|
+
title: "Update cost center",
|
|
5559
|
+
operationId: "updateCostCenter",
|
|
5560
|
+
description: "Rename a cost center. Renames a cost center. Resources attributed to it are unaffected and follow the new name \u2014 the attribution is by identifier, not by name.",
|
|
5561
|
+
method: "PATCH",
|
|
5562
|
+
path: "/v2/cost-centers/{id}",
|
|
5563
|
+
params: [
|
|
5564
|
+
{
|
|
5565
|
+
name: "id",
|
|
5566
|
+
location: "path"
|
|
5567
|
+
}
|
|
5568
|
+
],
|
|
5569
|
+
hasBody: true,
|
|
5570
|
+
annotations: {
|
|
5571
|
+
readOnlyHint: false,
|
|
5572
|
+
destructiveHint: false,
|
|
5573
|
+
idempotentHint: true,
|
|
5574
|
+
openWorldHint: true
|
|
5575
|
+
},
|
|
5576
|
+
inputSchema: {
|
|
5577
|
+
type: "object",
|
|
5578
|
+
properties: {
|
|
5579
|
+
id: {
|
|
5580
|
+
type: "string",
|
|
5581
|
+
minLength: 1,
|
|
5582
|
+
description: "Cost center identifier."
|
|
5583
|
+
},
|
|
5584
|
+
body: {
|
|
5585
|
+
$ref: "#/$defs/UpdateCostCenterRequest",
|
|
5586
|
+
type: "object"
|
|
5587
|
+
}
|
|
5588
|
+
},
|
|
5589
|
+
required: ["id", "body"],
|
|
5590
|
+
$defs: {
|
|
5591
|
+
UpdateCostCenterRequest: {
|
|
5592
|
+
type: "object",
|
|
5593
|
+
additionalProperties: false,
|
|
5594
|
+
required: ["value"],
|
|
5595
|
+
properties: {
|
|
5596
|
+
value: {
|
|
5597
|
+
type: "string",
|
|
5598
|
+
minLength: 1,
|
|
5599
|
+
maxLength: 50,
|
|
5600
|
+
pattern: "^\\s*\\S",
|
|
5601
|
+
description: "Leading and trailing whitespace is trimmed.",
|
|
5602
|
+
examples: ["team-ml-eu"]
|
|
5603
|
+
}
|
|
5604
|
+
}
|
|
5605
|
+
}
|
|
5606
|
+
}
|
|
5607
|
+
}
|
|
5608
|
+
},
|
|
4282
5609
|
{
|
|
4283
5610
|
name: "update-endpoint",
|
|
4284
5611
|
title: "Update endpoint",
|
|
@@ -4666,19 +5993,130 @@ var generatedTools = [
|
|
|
4666
5993
|
}
|
|
4667
5994
|
}
|
|
4668
5995
|
}
|
|
4669
|
-
],
|
|
4670
|
-
unevaluatedProperties: false
|
|
5996
|
+
],
|
|
5997
|
+
unevaluatedProperties: false
|
|
5998
|
+
}
|
|
5999
|
+
}
|
|
6000
|
+
}
|
|
6001
|
+
},
|
|
6002
|
+
{
|
|
6003
|
+
name: "update-global-volume",
|
|
6004
|
+
title: "Update global volume",
|
|
6005
|
+
operationId: "updateGlobalVolume",
|
|
6006
|
+
description: "Update a global volume. Updates mutable fields on a global volume. Only provided fields are changed.",
|
|
6007
|
+
method: "PATCH",
|
|
6008
|
+
path: "/v2/global-volumes/{id}",
|
|
6009
|
+
params: [
|
|
6010
|
+
{
|
|
6011
|
+
name: "id",
|
|
6012
|
+
location: "path"
|
|
6013
|
+
}
|
|
6014
|
+
],
|
|
6015
|
+
hasBody: true,
|
|
6016
|
+
annotations: {
|
|
6017
|
+
readOnlyHint: false,
|
|
6018
|
+
destructiveHint: false,
|
|
6019
|
+
idempotentHint: true,
|
|
6020
|
+
openWorldHint: true
|
|
6021
|
+
},
|
|
6022
|
+
inputSchema: {
|
|
6023
|
+
type: "object",
|
|
6024
|
+
properties: {
|
|
6025
|
+
id: {
|
|
6026
|
+
type: "string",
|
|
6027
|
+
description: "Global volume identifier"
|
|
6028
|
+
},
|
|
6029
|
+
body: {
|
|
6030
|
+
$ref: "#/$defs/UpdateGlobalVolumeRequest",
|
|
6031
|
+
type: "object"
|
|
6032
|
+
}
|
|
6033
|
+
},
|
|
6034
|
+
required: ["id", "body"],
|
|
6035
|
+
$defs: {
|
|
6036
|
+
UpdateGlobalVolumeRequest: {
|
|
6037
|
+
type: "object",
|
|
6038
|
+
additionalProperties: false,
|
|
6039
|
+
minProperties: 1,
|
|
6040
|
+
description: "Only the provided fields are updated. At least one field must be present; an empty body is rejected.",
|
|
6041
|
+
properties: {
|
|
6042
|
+
name: {
|
|
6043
|
+
type: "string",
|
|
6044
|
+
minLength: 1,
|
|
6045
|
+
maxLength: 191,
|
|
6046
|
+
pattern: "[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]",
|
|
6047
|
+
description: "New human-readable name, 1\u2013191 characters with at least one non-whitespace character. Leading and trailing whitespace is trimmed.",
|
|
6048
|
+
examples: ["renamed-volume"]
|
|
6049
|
+
}
|
|
6050
|
+
}
|
|
6051
|
+
}
|
|
6052
|
+
}
|
|
6053
|
+
}
|
|
6054
|
+
},
|
|
6055
|
+
{
|
|
6056
|
+
name: "update-network-volume",
|
|
6057
|
+
title: "Update network volume",
|
|
6058
|
+
operationId: "updateNetworkVolume",
|
|
6059
|
+
description: "Update a network volume. Updates mutable fields on a network volume. Only provided fields are changed. Note: `size` may only increase; attempts to reduce size will be rejected.",
|
|
6060
|
+
method: "PATCH",
|
|
6061
|
+
path: "/v2/network-volumes/{id}",
|
|
6062
|
+
params: [
|
|
6063
|
+
{
|
|
6064
|
+
name: "id",
|
|
6065
|
+
location: "path"
|
|
6066
|
+
}
|
|
6067
|
+
],
|
|
6068
|
+
hasBody: true,
|
|
6069
|
+
annotations: {
|
|
6070
|
+
readOnlyHint: false,
|
|
6071
|
+
destructiveHint: false,
|
|
6072
|
+
idempotentHint: true,
|
|
6073
|
+
openWorldHint: true
|
|
6074
|
+
},
|
|
6075
|
+
inputSchema: {
|
|
6076
|
+
type: "object",
|
|
6077
|
+
properties: {
|
|
6078
|
+
id: {
|
|
6079
|
+
type: "string",
|
|
6080
|
+
description: "Network volume identifier"
|
|
6081
|
+
},
|
|
6082
|
+
body: {
|
|
6083
|
+
$ref: "#/$defs/UpdateNetworkVolumeRequest",
|
|
6084
|
+
type: "object"
|
|
6085
|
+
}
|
|
6086
|
+
},
|
|
6087
|
+
required: ["id", "body"],
|
|
6088
|
+
$defs: {
|
|
6089
|
+
UpdateNetworkVolumeRequest: {
|
|
6090
|
+
type: "object",
|
|
6091
|
+
additionalProperties: false,
|
|
6092
|
+
minProperties: 1,
|
|
6093
|
+
description: "Only the provided fields are updated. At least one field must be present; an empty body is rejected.",
|
|
6094
|
+
properties: {
|
|
6095
|
+
name: {
|
|
6096
|
+
type: "string",
|
|
6097
|
+
minLength: 1,
|
|
6098
|
+
description: "New human-readable name",
|
|
6099
|
+
examples: ["renamed-volume"]
|
|
6100
|
+
},
|
|
6101
|
+
size: {
|
|
6102
|
+
type: "integer",
|
|
6103
|
+
minimum: 10,
|
|
6104
|
+
maximum: 4096,
|
|
6105
|
+
description: "New size in GB. Must be greater than or equal to the current size \u2014 network volume storage cannot be reduced.",
|
|
6106
|
+
examples: [100]
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
4671
6109
|
}
|
|
4672
6110
|
}
|
|
4673
6111
|
}
|
|
4674
6112
|
},
|
|
4675
6113
|
{
|
|
4676
|
-
name: "update-
|
|
4677
|
-
title: "Update
|
|
4678
|
-
operationId: "
|
|
4679
|
-
description: "
|
|
6114
|
+
name: "update-organization-group",
|
|
6115
|
+
title: "Update organization group",
|
|
6116
|
+
operationId: "updateOrganizationGroup",
|
|
6117
|
+
description: "Rename a group in your current organization",
|
|
4680
6118
|
method: "PATCH",
|
|
4681
|
-
path: "/v2/
|
|
6119
|
+
path: "/v2/organization/groups/{id}",
|
|
4682
6120
|
params: [
|
|
4683
6121
|
{
|
|
4684
6122
|
name: "id",
|
|
@@ -4697,27 +6135,28 @@ var generatedTools = [
|
|
|
4697
6135
|
properties: {
|
|
4698
6136
|
id: {
|
|
4699
6137
|
type: "string",
|
|
4700
|
-
|
|
6138
|
+
minLength: 1,
|
|
6139
|
+
description: "Group ID."
|
|
4701
6140
|
},
|
|
4702
6141
|
body: {
|
|
4703
|
-
$ref: "#/$defs/
|
|
6142
|
+
$ref: "#/$defs/UpdateOrganizationGroupRequest",
|
|
4704
6143
|
type: "object"
|
|
4705
6144
|
}
|
|
4706
6145
|
},
|
|
4707
6146
|
required: ["id", "body"],
|
|
4708
6147
|
$defs: {
|
|
4709
|
-
|
|
6148
|
+
UpdateOrganizationGroupRequest: {
|
|
4710
6149
|
type: "object",
|
|
4711
6150
|
additionalProperties: false,
|
|
4712
|
-
|
|
4713
|
-
description: "Only the provided fields are updated. At least one field must be present; an empty body is rejected.",
|
|
6151
|
+
required: ["name"],
|
|
4714
6152
|
properties: {
|
|
4715
6153
|
name: {
|
|
4716
6154
|
type: "string",
|
|
4717
6155
|
minLength: 1,
|
|
4718
6156
|
maxLength: 191,
|
|
4719
|
-
|
|
4720
|
-
|
|
6157
|
+
pattern: "[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]",
|
|
6158
|
+
description: "Group name with at least one non-whitespace character; surrounding whitespace is trimmed.",
|
|
6159
|
+
examples: ["Research"]
|
|
4721
6160
|
}
|
|
4722
6161
|
}
|
|
4723
6162
|
}
|
|
@@ -4725,12 +6164,12 @@ var generatedTools = [
|
|
|
4725
6164
|
}
|
|
4726
6165
|
},
|
|
4727
6166
|
{
|
|
4728
|
-
name: "update-
|
|
4729
|
-
title: "Update
|
|
4730
|
-
operationId: "
|
|
4731
|
-
description: "Update a
|
|
6167
|
+
name: "update-organization-role",
|
|
6168
|
+
title: "Update organization role",
|
|
6169
|
+
operationId: "updateOrganizationRole",
|
|
6170
|
+
description: "Update a custom organization role. Changes a custom role's name, its capabilities, or both, and returns the role. Sent capabilities replace the whole grant set. Returns 400 for a built-in role, which cannot be changed; 404 when the ID is unknown or names another organization's role; 403 when the caller does not hold every capability the role grants, before or after the change; 409 when the organization already has a role with the new name; and 422 when a capability is unknown or the name is reserved. Updating roles requires the organization's role-management capability, which the built-in admin role holds; other members, and callers outside an organization, receive 403, as does a caller for whom organizations are unavailable.",
|
|
4732
6171
|
method: "PATCH",
|
|
4733
|
-
path: "/v2/
|
|
6172
|
+
path: "/v2/organization/roles/{id}",
|
|
4734
6173
|
params: [
|
|
4735
6174
|
{
|
|
4736
6175
|
name: "id",
|
|
@@ -4740,7 +6179,7 @@ var generatedTools = [
|
|
|
4740
6179
|
hasBody: true,
|
|
4741
6180
|
annotations: {
|
|
4742
6181
|
readOnlyHint: false,
|
|
4743
|
-
destructiveHint:
|
|
6182
|
+
destructiveHint: true,
|
|
4744
6183
|
idempotentHint: true,
|
|
4745
6184
|
openWorldHint: true
|
|
4746
6185
|
},
|
|
@@ -4749,33 +6188,129 @@ var generatedTools = [
|
|
|
4749
6188
|
properties: {
|
|
4750
6189
|
id: {
|
|
4751
6190
|
type: "string",
|
|
4752
|
-
description: "
|
|
6191
|
+
description: "Role identifier"
|
|
4753
6192
|
},
|
|
4754
6193
|
body: {
|
|
4755
|
-
$ref: "#/$defs/
|
|
6194
|
+
$ref: "#/$defs/UpdateOrganizationRoleRequest",
|
|
4756
6195
|
type: "object"
|
|
4757
6196
|
}
|
|
4758
6197
|
},
|
|
4759
6198
|
required: ["id", "body"],
|
|
4760
6199
|
$defs: {
|
|
4761
|
-
|
|
6200
|
+
OrganizationRoleCapabilitiesInput: {
|
|
6201
|
+
type: "array",
|
|
6202
|
+
description: "What the role grants, as `FAMILY:VERB` capabilities from `get-organization-role-capabilities`. The caller must hold every capability it lists.",
|
|
6203
|
+
minItems: 1,
|
|
6204
|
+
uniqueItems: true,
|
|
6205
|
+
items: {
|
|
6206
|
+
type: "string",
|
|
6207
|
+
pattern: "^[A-Z0-9_]+:[A-Z0-9_]+$"
|
|
6208
|
+
},
|
|
6209
|
+
examples: [["POD:VIEW"]]
|
|
6210
|
+
},
|
|
6211
|
+
OrganizationRoleName: {
|
|
6212
|
+
type: "string",
|
|
6213
|
+
minLength: 1,
|
|
6214
|
+
maxLength: 191,
|
|
6215
|
+
pattern: "[^\\t-\\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]",
|
|
6216
|
+
description: "Display name, 1\u2013191 characters with at least one non-whitespace character. Leading and trailing whitespace is trimmed. It must be unique within the organization and cannot be a built-in role's name.",
|
|
6217
|
+
examples: ["Pod viewer"]
|
|
6218
|
+
},
|
|
6219
|
+
UpdateOrganizationRoleRequest: {
|
|
4762
6220
|
type: "object",
|
|
4763
6221
|
additionalProperties: false,
|
|
4764
6222
|
minProperties: 1,
|
|
4765
|
-
description: "
|
|
6223
|
+
description: "The fields to change; omitted fields are unchanged. `capabilities` replaces the role's whole grant set rather than adding to it.",
|
|
4766
6224
|
properties: {
|
|
4767
6225
|
name: {
|
|
6226
|
+
$ref: "#/$defs/OrganizationRoleName"
|
|
6227
|
+
},
|
|
6228
|
+
capabilities: {
|
|
6229
|
+
$ref: "#/$defs/OrganizationRoleCapabilitiesInput"
|
|
6230
|
+
}
|
|
6231
|
+
}
|
|
6232
|
+
}
|
|
6233
|
+
}
|
|
6234
|
+
}
|
|
6235
|
+
},
|
|
6236
|
+
{
|
|
6237
|
+
name: "update-organization-user",
|
|
6238
|
+
title: "Update organization user",
|
|
6239
|
+
operationId: "updateOrganizationUser",
|
|
6240
|
+
description: "Update an organization member. Changes one member of the authenticated caller's organization by user ID: assigns a role, replaces their set of groups, or both, applied together or not at all. Send at least one field; an omitted field is left as it is, and an empty `groups` list removes the member from every group. Updating members requires the organization's member-management capability, which the built-in admin role holds; other members, and callers outside an organization, receive 403, as does a caller for whom organizations are unavailable. Returns 403 when the caller changes their own role or assigns a role granting a capability the caller lacks; 409 when the change would leave the organization without a member in the built-in admin role; and 404 when the user is not a member or the role or a group is unknown to the organization, with the detail naming which.",
|
|
6241
|
+
method: "PATCH",
|
|
6242
|
+
path: "/v2/organization/users/{id}",
|
|
6243
|
+
params: [
|
|
6244
|
+
{
|
|
6245
|
+
name: "id",
|
|
6246
|
+
location: "path"
|
|
6247
|
+
}
|
|
6248
|
+
],
|
|
6249
|
+
hasBody: true,
|
|
6250
|
+
annotations: {
|
|
6251
|
+
readOnlyHint: false,
|
|
6252
|
+
destructiveHint: true,
|
|
6253
|
+
idempotentHint: true,
|
|
6254
|
+
openWorldHint: true
|
|
6255
|
+
},
|
|
6256
|
+
inputSchema: {
|
|
6257
|
+
type: "object",
|
|
6258
|
+
properties: {
|
|
6259
|
+
id: {
|
|
6260
|
+
type: "string",
|
|
6261
|
+
description: "User identifier"
|
|
6262
|
+
},
|
|
6263
|
+
body: {
|
|
6264
|
+
$ref: "#/$defs/UpdateOrganizationUserRequest",
|
|
6265
|
+
type: "object"
|
|
6266
|
+
}
|
|
6267
|
+
},
|
|
6268
|
+
required: ["id", "body"],
|
|
6269
|
+
$defs: {
|
|
6270
|
+
OrganizationGroupInput: {
|
|
6271
|
+
type: "object",
|
|
6272
|
+
description: "An organization group, by ID.",
|
|
6273
|
+
additionalProperties: false,
|
|
6274
|
+
required: ["id"],
|
|
6275
|
+
properties: {
|
|
6276
|
+
id: {
|
|
4768
6277
|
type: "string",
|
|
4769
6278
|
minLength: 1,
|
|
4770
|
-
description: "
|
|
4771
|
-
examples: ["
|
|
6279
|
+
description: "Group ID.",
|
|
6280
|
+
examples: ["group_id_abc_123"]
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
},
|
|
6284
|
+
OrganizationRoleInput: {
|
|
6285
|
+
type: "object",
|
|
6286
|
+
description: "An organization role to assign, by ID.",
|
|
6287
|
+
additionalProperties: false,
|
|
6288
|
+
required: ["id"],
|
|
6289
|
+
properties: {
|
|
6290
|
+
id: {
|
|
6291
|
+
type: "string",
|
|
6292
|
+
minLength: 1,
|
|
6293
|
+
description: "Role ID, as reported on a member or an invite: `builtin:admin`, `builtin:dev`, `builtin:billing`, `builtin:basic`, or a custom role's own ID.",
|
|
6294
|
+
examples: ["builtin:dev"]
|
|
6295
|
+
}
|
|
6296
|
+
}
|
|
6297
|
+
},
|
|
6298
|
+
UpdateOrganizationUserRequest: {
|
|
6299
|
+
type: "object",
|
|
6300
|
+
description: "Changes to a member. Send `role`, `groups`, or both; an omitted field is left as it is.",
|
|
6301
|
+
additionalProperties: false,
|
|
6302
|
+
minProperties: 1,
|
|
6303
|
+
properties: {
|
|
6304
|
+
role: {
|
|
6305
|
+
$ref: "#/$defs/OrganizationRoleInput"
|
|
4772
6306
|
},
|
|
4773
|
-
|
|
4774
|
-
type: "
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
6307
|
+
groups: {
|
|
6308
|
+
type: "array",
|
|
6309
|
+
description: "The member's groups after the change: the whole set, by ID. An empty list removes the member from every group.",
|
|
6310
|
+
uniqueItems: true,
|
|
6311
|
+
items: {
|
|
6312
|
+
$ref: "#/$defs/OrganizationGroupInput"
|
|
6313
|
+
}
|
|
4779
6314
|
}
|
|
4780
6315
|
}
|
|
4781
6316
|
}
|
|
@@ -4786,7 +6321,7 @@ var generatedTools = [
|
|
|
4786
6321
|
name: "update-pod",
|
|
4787
6322
|
title: "Update Pod",
|
|
4788
6323
|
operationId: "updatePod",
|
|
4789
|
-
description: "Update a pod. Partially updates a pod's configuration. This is a PATCH: only the fields present in the body are changed, and omitted fields are left untouched. Use empty values only when you explicitly mean to clear a field (for example, set `registry` to `null` or set `ports` to `[]`). See `UpdatePodRequest` for the full body. Mutable fields: `name`, `image`, `args`, `disk`, `ports`, `env`, `registry`, `mounts`, `locked`, and `globalNetworking`. Some changes apply immediately while others (e.g. `globalNetworking`) take effect on the pod's next start/restart, as noted on the individual fields. Pods that belong to a Cluster cannot be updated here \u2014 manage them through `/v2/clusters/{id}`. Returns `200` with the full updated pod.",
|
|
6324
|
+
description: "Update a pod. Partially updates a pod's configuration. This is a PATCH: only the fields present in the body are changed, and omitted fields are left untouched. Use empty values only when you explicitly mean to clear a field (for example, set `registry` to `null` or set `ports` to `[]`). See `UpdatePodRequest` for the full body. Mutable fields: `name`, `image`, `args`, `disk`, `ports`, `env`, `registry`, `mounts`, `locked`, and `globalNetworking`. Some changes apply immediately while others (e.g. `globalNetworking`) take effect on the pod's next start/restart, as noted on the individual fields. Volumes can be mounted, moved, or unmounted after creation through `mounts`, one entry per volume; see `UpdatePodMounts` for the rules. Pods that belong to a Cluster cannot be updated here \u2014 manage them through `/v2/clusters/{id}`. Returns `200` with the full updated pod.",
|
|
4790
6325
|
method: "PATCH",
|
|
4791
6326
|
path: "/v2/pods/{id}",
|
|
4792
6327
|
params: [
|
|
@@ -4880,21 +6415,6 @@ var generatedTools = [
|
|
|
4880
6415
|
}
|
|
4881
6416
|
}
|
|
4882
6417
|
},
|
|
4883
|
-
BaseMounts: {
|
|
4884
|
-
type: "object",
|
|
4885
|
-
properties: {
|
|
4886
|
-
persistent: {
|
|
4887
|
-
$ref: "#/$defs/PersistentMount"
|
|
4888
|
-
},
|
|
4889
|
-
network: {
|
|
4890
|
-
type: "array",
|
|
4891
|
-
maxItems: 1,
|
|
4892
|
-
items: {
|
|
4893
|
-
$ref: "#/$defs/NetworkMount"
|
|
4894
|
-
}
|
|
4895
|
-
}
|
|
4896
|
-
}
|
|
4897
|
-
},
|
|
4898
6418
|
ContainerConfig: {
|
|
4899
6419
|
allOf: [
|
|
4900
6420
|
{
|
|
@@ -4912,11 +6432,11 @@ var generatedTools = [
|
|
|
4912
6432
|
}
|
|
4913
6433
|
]
|
|
4914
6434
|
},
|
|
4915
|
-
|
|
6435
|
+
GlobalMountPatch: {
|
|
4916
6436
|
type: "object",
|
|
4917
6437
|
required: ["volumeId"],
|
|
4918
6438
|
additionalProperties: false,
|
|
4919
|
-
description: "
|
|
6439
|
+
description: "Mounts, moves, or unmounts the pod's global volume.",
|
|
4920
6440
|
properties: {
|
|
4921
6441
|
volumeId: {
|
|
4922
6442
|
type: "string",
|
|
@@ -4925,38 +6445,21 @@ var generatedTools = [
|
|
|
4925
6445
|
},
|
|
4926
6446
|
path: {
|
|
4927
6447
|
type: "string",
|
|
4928
|
-
|
|
6448
|
+
minLength: 1,
|
|
6449
|
+
description: "Mount path inside the container. Optional; when mounting, a default is chosen for you if omitted.",
|
|
4929
6450
|
examples: ["/data"]
|
|
4930
|
-
}
|
|
4931
|
-
}
|
|
4932
|
-
},
|
|
4933
|
-
Mounts: {
|
|
4934
|
-
description: "Storage mounts for the pod: `persistent` (size + path) excludes both `network` and `global`; `network` (volumeId + path) and `global` (volumeId, optional path) take one entry each and can be combined. Every entry needs its full shape. On update, omit the field to leave the mounts as they are; the mount kind and a volume's volumeId cannot change, and mounts cannot be cleared.",
|
|
4935
|
-
allOf: [
|
|
4936
|
-
{
|
|
4937
|
-
$ref: "#/$defs/BaseMounts"
|
|
4938
6451
|
},
|
|
4939
|
-
{
|
|
4940
|
-
type: "
|
|
4941
|
-
|
|
4942
|
-
global: {
|
|
4943
|
-
type: "array",
|
|
4944
|
-
maxItems: 1,
|
|
4945
|
-
description: "At most one global volume, on GPU and CPU pods, with no data center constraint. Combinable with `network` but not with `persistent` (rejected): upstream drops a persistent disk whenever a volume is attached.",
|
|
4946
|
-
items: {
|
|
4947
|
-
$ref: "#/$defs/GlobalMount"
|
|
4948
|
-
}
|
|
4949
|
-
}
|
|
4950
|
-
}
|
|
6452
|
+
remove: {
|
|
6453
|
+
type: "boolean",
|
|
6454
|
+
description: "Unmount the volume. Cannot be combined with `path`."
|
|
4951
6455
|
}
|
|
4952
|
-
|
|
4953
|
-
unevaluatedProperties: false
|
|
6456
|
+
}
|
|
4954
6457
|
},
|
|
4955
|
-
|
|
6458
|
+
NetworkMountPatch: {
|
|
4956
6459
|
type: "object",
|
|
4957
|
-
required: ["volumeId"
|
|
6460
|
+
required: ["volumeId"],
|
|
4958
6461
|
additionalProperties: false,
|
|
4959
|
-
description: "
|
|
6462
|
+
description: "Mounts, moves, or unmounts one network volume. Mounting a volume the pod does not have requires `path`.",
|
|
4960
6463
|
properties: {
|
|
4961
6464
|
volumeId: {
|
|
4962
6465
|
type: "string",
|
|
@@ -4965,27 +6468,62 @@ var generatedTools = [
|
|
|
4965
6468
|
},
|
|
4966
6469
|
path: {
|
|
4967
6470
|
type: "string",
|
|
4968
|
-
|
|
6471
|
+
minLength: 1,
|
|
6472
|
+
description: "Mount path inside the container. Required when mounting; optional when moving a mounted volume.",
|
|
4969
6473
|
examples: ["/runpod-volume"]
|
|
6474
|
+
},
|
|
6475
|
+
remove: {
|
|
6476
|
+
type: "boolean",
|
|
6477
|
+
description: "Unmount the volume. Cannot be combined with `path`."
|
|
4970
6478
|
}
|
|
4971
6479
|
}
|
|
4972
6480
|
},
|
|
4973
|
-
|
|
6481
|
+
PersistentMountPatch: {
|
|
4974
6482
|
type: "object",
|
|
4975
|
-
required: ["size", "path"],
|
|
4976
6483
|
additionalProperties: false,
|
|
4977
|
-
description: "
|
|
6484
|
+
description: "Adds the pod's volume disk, grows it, or moves it. Adding a disk requires `size`; on a pod that already has one, omitted fields are left as they are. Not available on CPU pods.",
|
|
4978
6485
|
properties: {
|
|
4979
6486
|
size: {
|
|
4980
6487
|
type: "integer",
|
|
4981
6488
|
minimum: 10,
|
|
4982
|
-
description: "
|
|
4983
|
-
examples: [
|
|
6489
|
+
description: "Volume disk size in GB. Can only grow; a smaller size than the current one is rejected.",
|
|
6490
|
+
examples: [50]
|
|
4984
6491
|
},
|
|
4985
6492
|
path: {
|
|
4986
6493
|
type: "string",
|
|
4987
|
-
|
|
6494
|
+
minLength: 1,
|
|
6495
|
+
description: "Mount path inside the container.",
|
|
4988
6496
|
examples: ["/workspace"]
|
|
6497
|
+
},
|
|
6498
|
+
remove: {
|
|
6499
|
+
type: "boolean",
|
|
6500
|
+
description: "Removes the volume disk. Not supported yet: `remove: true` is rejected."
|
|
6501
|
+
}
|
|
6502
|
+
}
|
|
6503
|
+
},
|
|
6504
|
+
UpdatePodMounts: {
|
|
6505
|
+
type: "object",
|
|
6506
|
+
additionalProperties: false,
|
|
6507
|
+
description: "Changes to a pod's mounts. Each entry names one volume by `volumeId` and changes only that volume; volumes that are not listed, and kinds that are omitted, are left as they are. Omitting `mounts` or sending `{}` changes nothing.",
|
|
6508
|
+
properties: {
|
|
6509
|
+
persistent: {
|
|
6510
|
+
$ref: "#/$defs/PersistentMountPatch"
|
|
6511
|
+
},
|
|
6512
|
+
network: {
|
|
6513
|
+
type: "array",
|
|
6514
|
+
maxItems: 8,
|
|
6515
|
+
description: "Network volumes to mount, move, or unmount. Up to 8 entries, so a request can unmount 4 volumes and mount 4 others; the pod can still hold at most 4 afterwards.",
|
|
6516
|
+
items: {
|
|
6517
|
+
$ref: "#/$defs/NetworkMountPatch"
|
|
6518
|
+
}
|
|
6519
|
+
},
|
|
6520
|
+
global: {
|
|
6521
|
+
type: "array",
|
|
6522
|
+
maxItems: 2,
|
|
6523
|
+
description: "Global volumes to mount, move, or unmount. Up to 2 entries, so a request can swap the global volume; the pod can still hold at most 1 afterwards.",
|
|
6524
|
+
items: {
|
|
6525
|
+
$ref: "#/$defs/GlobalMountPatch"
|
|
6526
|
+
}
|
|
4989
6527
|
}
|
|
4990
6528
|
}
|
|
4991
6529
|
},
|
|
@@ -5006,7 +6544,7 @@ var generatedTools = [
|
|
|
5006
6544
|
description: "Lock the pod (true) or unlock it (false). Locked pods cannot be stopped or reset."
|
|
5007
6545
|
},
|
|
5008
6546
|
mounts: {
|
|
5009
|
-
$ref: "#/$defs/
|
|
6547
|
+
$ref: "#/$defs/UpdatePodMounts"
|
|
5010
6548
|
},
|
|
5011
6549
|
name: {
|
|
5012
6550
|
type: "string",
|
|
@@ -5253,7 +6791,7 @@ var generatedTools = [
|
|
|
5253
6791
|
size: {
|
|
5254
6792
|
type: "integer",
|
|
5255
6793
|
minimum: 10,
|
|
5256
|
-
description: "Host-local persistent storage in GB.
|
|
6794
|
+
description: "Host-local persistent storage in GB. Minimum 10 GB.",
|
|
5257
6795
|
examples: [20]
|
|
5258
6796
|
},
|
|
5259
6797
|
path: {
|
|
@@ -5514,33 +7052,53 @@ var CREDENTIAL_MANAGEMENT = "Manages stored credentials; OpenAI restricts plugin
|
|
|
5514
7052
|
var CREDENTIAL_INPUT = "Takes a secret or password as input; directories forbid collecting credentials.";
|
|
5515
7053
|
var ALP = "Collects conversation-derived data beyond the task; the directory profile never serves it.";
|
|
5516
7054
|
var DIRECTORY_TOOLS = {
|
|
7055
|
+
"add-organization-group-member": IN,
|
|
7056
|
+
"attach-cost-center-resource": IN,
|
|
5517
7057
|
"cancel-job": IN,
|
|
5518
7058
|
"create-cluster": IN,
|
|
7059
|
+
"create-cost-center": IN,
|
|
5519
7060
|
"create-delegation": IN,
|
|
5520
7061
|
"create-endpoint": IN,
|
|
5521
7062
|
"create-global-volume": IN,
|
|
5522
7063
|
"create-network-volume": IN,
|
|
7064
|
+
"create-organization-group": IN,
|
|
7065
|
+
"create-organization-invite": IN,
|
|
7066
|
+
"create-organization-role": IN,
|
|
5523
7067
|
"create-pod": IN,
|
|
5524
7068
|
"create-template": IN,
|
|
5525
7069
|
"delete-cluster": IN,
|
|
7070
|
+
"delete-cost-center": IN,
|
|
5526
7071
|
"delete-endpoint": IN,
|
|
5527
7072
|
"delete-global-volume": IN,
|
|
5528
7073
|
"delete-network-volume": IN,
|
|
7074
|
+
"delete-organization-group": IN,
|
|
7075
|
+
"delete-organization-invite": IN,
|
|
7076
|
+
"delete-organization-role": IN,
|
|
7077
|
+
"delete-organization-user": IN,
|
|
5529
7078
|
"delete-pod": IN,
|
|
5530
7079
|
"delete-template": IN,
|
|
5531
7080
|
"deploy-hub-repo": IN,
|
|
7081
|
+
"detach-cost-center-resource": IN,
|
|
5532
7082
|
"endpoint-health": IN,
|
|
5533
7083
|
"get-capacity": IN,
|
|
5534
7084
|
"get-cluster": IN,
|
|
7085
|
+
"get-cost-center": IN,
|
|
5535
7086
|
"get-cpu-type": IN,
|
|
5536
7087
|
"get-data-center": IN,
|
|
5537
7088
|
"get-endpoint": IN,
|
|
5538
7089
|
"get-endpoint-build": IN,
|
|
7090
|
+
"get-endpoint-cold-start-metrics": IN,
|
|
7091
|
+
"get-endpoint-request-metrics": IN,
|
|
7092
|
+
"get-endpoint-worker-metrics": IN,
|
|
5539
7093
|
"get-global-volume": IN,
|
|
5540
7094
|
"get-gpu-type": IN,
|
|
5541
7095
|
"get-job-status": IN,
|
|
5542
7096
|
"get-network-volume": IN,
|
|
5543
7097
|
"get-organization": IN,
|
|
7098
|
+
"get-organization-group": IN,
|
|
7099
|
+
"get-organization-invite": IN,
|
|
7100
|
+
"get-organization-role": IN,
|
|
7101
|
+
"get-organization-role-capabilities": IN,
|
|
5544
7102
|
"get-organization-user": IN,
|
|
5545
7103
|
"get-pod": IN,
|
|
5546
7104
|
"get-ssh-keys": IN,
|
|
@@ -5550,6 +7108,8 @@ var DIRECTORY_TOOLS = {
|
|
|
5550
7108
|
"list-cluster-billing": IN,
|
|
5551
7109
|
"list-cluster-pods": IN,
|
|
5552
7110
|
"list-clusters": IN,
|
|
7111
|
+
"list-cost-center-resources": IN,
|
|
7112
|
+
"list-cost-centers": IN,
|
|
5553
7113
|
"list-cpu-types": IN,
|
|
5554
7114
|
"list-data-centers": IN,
|
|
5555
7115
|
"list-delegations": IN,
|
|
@@ -5563,6 +7123,10 @@ var DIRECTORY_TOOLS = {
|
|
|
5563
7123
|
"list-hub-repos": IN,
|
|
5564
7124
|
"list-network-volume-billing": IN,
|
|
5565
7125
|
"list-network-volumes": IN,
|
|
7126
|
+
"list-organization-group-members": IN,
|
|
7127
|
+
"list-organization-groups": IN,
|
|
7128
|
+
"list-organization-invites": IN,
|
|
7129
|
+
"list-organization-roles": IN,
|
|
5566
7130
|
"list-organization-users": IN,
|
|
5567
7131
|
"list-pod-billing": IN,
|
|
5568
7132
|
"list-pods": IN,
|
|
@@ -5572,6 +7136,7 @@ var DIRECTORY_TOOLS = {
|
|
|
5572
7136
|
"list-templates": IN,
|
|
5573
7137
|
"lookup-concept": IN,
|
|
5574
7138
|
"purge-endpoint-queue": IN,
|
|
7139
|
+
"remove-organization-group-member": IN,
|
|
5575
7140
|
"retry-job": IN,
|
|
5576
7141
|
"revoke-delegation": IN,
|
|
5577
7142
|
"search-concepts": IN,
|
|
@@ -5581,9 +7146,13 @@ var DIRECTORY_TOOLS = {
|
|
|
5581
7146
|
"stream-pod-logs": IN,
|
|
5582
7147
|
"stream-worker-logs": IN,
|
|
5583
7148
|
"update-cluster": IN,
|
|
7149
|
+
"update-cost-center": IN,
|
|
5584
7150
|
"update-endpoint": IN,
|
|
5585
7151
|
"update-global-volume": IN,
|
|
5586
7152
|
"update-network-volume": IN,
|
|
7153
|
+
"update-organization-group": IN,
|
|
7154
|
+
"update-organization-role": IN,
|
|
7155
|
+
"update-organization-user": IN,
|
|
5587
7156
|
"update-pod": IN,
|
|
5588
7157
|
"update-ssh-keys": IN,
|
|
5589
7158
|
"update-template": IN,
|
|
@@ -8404,23 +9973,40 @@ function createRunpodClient(options = {}) {
|
|
|
8404
9973
|
// src/specgen/clients/sse.ts
|
|
8405
9974
|
var LOG_STREAM_DEFAULT_WAIT_MS = 5e3;
|
|
8406
9975
|
var LOG_STREAM_MAX_BYTES = 256 * 1024;
|
|
9976
|
+
var LOG_STREAM_CONNECT_TIMEOUT_MS = 1e4;
|
|
9977
|
+
var LOG_SNAPSHOT_MAX_CHARS = 32e3;
|
|
8407
9978
|
function createSseReader(options = {}) {
|
|
8408
9979
|
const apiKey = options.apiKey ?? process.env.RUNPOD_API_KEY;
|
|
8409
9980
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
9981
|
+
const connectTimeoutMs = options.connectTimeoutMs ?? LOG_STREAM_CONNECT_TIMEOUT_MS;
|
|
8410
9982
|
return async (url, opts) => {
|
|
8411
9983
|
if (!apiKey) throw missingKeyError();
|
|
8412
9984
|
const chunks = [];
|
|
8413
9985
|
let bytes = 0;
|
|
8414
9986
|
let truncated = false;
|
|
8415
9987
|
let streamEstablished = false;
|
|
9988
|
+
const connect = new AbortController();
|
|
9989
|
+
const connectTimer = setTimeout(
|
|
9990
|
+
() => connect.abort(
|
|
9991
|
+
new DOMException(
|
|
9992
|
+
`Runpod log stream sent no headers within ${connectTimeoutMs}ms`,
|
|
9993
|
+
"TimeoutError"
|
|
9994
|
+
)
|
|
9995
|
+
),
|
|
9996
|
+
connectTimeoutMs
|
|
9997
|
+
);
|
|
8416
9998
|
try {
|
|
8417
|
-
const response = await createDeadlineFetch(
|
|
9999
|
+
const response = await createDeadlineFetch(
|
|
10000
|
+
fetchImpl,
|
|
10001
|
+
connectTimeoutMs + opts.maxWaitMs
|
|
10002
|
+
)(url, {
|
|
8418
10003
|
method: "GET",
|
|
8419
10004
|
headers: {
|
|
8420
10005
|
Authorization: `Bearer ${apiKey}`,
|
|
8421
10006
|
Accept: "text/event-stream"
|
|
8422
|
-
}
|
|
8423
|
-
|
|
10007
|
+
},
|
|
10008
|
+
signal: connect.signal
|
|
10009
|
+
}).finally(() => clearTimeout(connectTimer));
|
|
8424
10010
|
if (!response.ok) {
|
|
8425
10011
|
const body = await response.text().catch(() => "");
|
|
8426
10012
|
throw new HttpError(
|
|
@@ -8431,14 +10017,31 @@ function createSseReader(options = {}) {
|
|
|
8431
10017
|
}
|
|
8432
10018
|
streamEstablished = true;
|
|
8433
10019
|
if (response.body) {
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
10020
|
+
const reader = response.body.getReader();
|
|
10021
|
+
let timer;
|
|
10022
|
+
const windowClosed = new Promise((resolve) => {
|
|
10023
|
+
timer = setTimeout(() => resolve(null), opts.maxWaitMs);
|
|
10024
|
+
});
|
|
10025
|
+
try {
|
|
10026
|
+
for (; ; ) {
|
|
10027
|
+
const read = reader.read();
|
|
10028
|
+
read.catch(() => {
|
|
10029
|
+
});
|
|
10030
|
+
const next = await Promise.race([read, windowClosed]);
|
|
10031
|
+
if (next === null || next.done) break;
|
|
10032
|
+
const boundedChunk = next.value.subarray(0, opts.maxBytes - bytes);
|
|
10033
|
+
chunks.push(boundedChunk);
|
|
10034
|
+
bytes += boundedChunk.length;
|
|
10035
|
+
if (bytes >= opts.maxBytes) {
|
|
10036
|
+
truncated = true;
|
|
10037
|
+
break;
|
|
10038
|
+
}
|
|
8441
10039
|
}
|
|
10040
|
+
} finally {
|
|
10041
|
+
clearTimeout(timer);
|
|
10042
|
+
void reader.cancel().catch(() => {
|
|
10043
|
+
});
|
|
10044
|
+
reader.releaseLock();
|
|
8442
10045
|
}
|
|
8443
10046
|
}
|
|
8444
10047
|
} catch (err) {
|
|
@@ -8464,7 +10067,80 @@ async function collectLogSnapshot(reader, logsUrl, params) {
|
|
|
8464
10067
|
for await (const event of iterateLogEvents(new Response(raw).body)) {
|
|
8465
10068
|
items.push(event.data);
|
|
8466
10069
|
}
|
|
8467
|
-
return
|
|
10070
|
+
return fitSnapshot(items, truncated);
|
|
10071
|
+
}
|
|
10072
|
+
var serializedLength = (snapshot) => JSON.stringify(snapshot, null, 2).length;
|
|
10073
|
+
var LOG_ENTRY_MAX_CHARS = 16e3;
|
|
10074
|
+
var CLIPPABLE_KEYS = ["line", "raw"];
|
|
10075
|
+
function clipText(text, keep) {
|
|
10076
|
+
const code = text.charCodeAt(keep - 1);
|
|
10077
|
+
if (keep > 0 && code >= 55296 && code <= 56319) keep--;
|
|
10078
|
+
return `${text.slice(0, keep)}\u2026 [clipped ${text.length - keep} chars]`;
|
|
10079
|
+
}
|
|
10080
|
+
function clipEntry(entry) {
|
|
10081
|
+
let clipped = false;
|
|
10082
|
+
const out = { ...entry };
|
|
10083
|
+
for (const key of CLIPPABLE_KEYS) {
|
|
10084
|
+
const text = out[key];
|
|
10085
|
+
if (typeof text === "string" && text.length > LOG_ENTRY_MAX_CHARS) {
|
|
10086
|
+
out[key] = clipText(text, LOG_ENTRY_MAX_CHARS);
|
|
10087
|
+
clipped = true;
|
|
10088
|
+
}
|
|
10089
|
+
}
|
|
10090
|
+
return { entry: out, clipped };
|
|
10091
|
+
}
|
|
10092
|
+
function fitEntry(entry, maxChars) {
|
|
10093
|
+
const size = (e) => serializedLength({ items: [e], count: 1, truncated: false });
|
|
10094
|
+
const out = { ...entry };
|
|
10095
|
+
const keys = Object.keys(out).filter((key) => key !== "ts" && typeof out[key] === "string").sort((a, b) => out[b].length - out[a].length);
|
|
10096
|
+
for (const key of keys) {
|
|
10097
|
+
if (size(out) <= maxChars) break;
|
|
10098
|
+
const text = entry[key];
|
|
10099
|
+
let lo = 0;
|
|
10100
|
+
let hi = Math.min(text.length, LOG_ENTRY_MAX_CHARS);
|
|
10101
|
+
while (lo < hi) {
|
|
10102
|
+
const mid = Math.ceil((lo + hi) / 2);
|
|
10103
|
+
if (size({ ...out, [key]: clipText(text, mid) }) <= maxChars)
|
|
10104
|
+
lo = mid;
|
|
10105
|
+
else hi = mid - 1;
|
|
10106
|
+
}
|
|
10107
|
+
out[key] = clipText(text, lo);
|
|
10108
|
+
}
|
|
10109
|
+
return out;
|
|
10110
|
+
}
|
|
10111
|
+
var entryTs = (entry) => entry?.ts;
|
|
10112
|
+
function fitSnapshot(items, truncated, maxChars = LOG_SNAPSHOT_MAX_CHARS) {
|
|
10113
|
+
let cut = truncated;
|
|
10114
|
+
const entries = items.map((item) => {
|
|
10115
|
+
const { entry, clipped } = clipEntry(item);
|
|
10116
|
+
if (clipped) cut = true;
|
|
10117
|
+
return entry;
|
|
10118
|
+
});
|
|
10119
|
+
const snapshot = (n, isCut) => ({
|
|
10120
|
+
items: entries.slice(0, n),
|
|
10121
|
+
count: n,
|
|
10122
|
+
truncated: isCut
|
|
10123
|
+
});
|
|
10124
|
+
const whole = snapshot(entries.length, cut);
|
|
10125
|
+
if (entries.length === 0 || serializedLength(whole) <= maxChars) return whole;
|
|
10126
|
+
if (serializedLength(snapshot(1, true)) > maxChars) {
|
|
10127
|
+
entries[0] = fitEntry(items[0], maxChars);
|
|
10128
|
+
if (entries.length === 1) return snapshot(1, true);
|
|
10129
|
+
}
|
|
10130
|
+
let lo = 1;
|
|
10131
|
+
let hi = entries.length - 1;
|
|
10132
|
+
while (lo < hi) {
|
|
10133
|
+
const mid = Math.ceil((lo + hi) / 2);
|
|
10134
|
+
if (serializedLength(snapshot(mid, true)) <= maxChars) lo = mid;
|
|
10135
|
+
else hi = mid - 1;
|
|
10136
|
+
}
|
|
10137
|
+
let keep = lo;
|
|
10138
|
+
const omittedTs = entryTs(entries[keep]);
|
|
10139
|
+
if (omittedTs !== void 0) {
|
|
10140
|
+
while (keep > 0 && entryTs(entries[keep - 1]) === omittedTs) keep--;
|
|
10141
|
+
if (keep === 0) keep = lo;
|
|
10142
|
+
}
|
|
10143
|
+
return snapshot(keep, true);
|
|
8468
10144
|
}
|
|
8469
10145
|
|
|
8470
10146
|
// src/specgen/tools/logs.ts
|
|
@@ -8482,13 +10158,13 @@ var logStreamProperties = {
|
|
|
8482
10158
|
},
|
|
8483
10159
|
since: {
|
|
8484
10160
|
type: "string",
|
|
8485
|
-
description: "RFC3339 timestamp to resume
|
|
10161
|
+
description: "RFC3339 timestamp to resume after (exclusive). Replays container lines only; system lines stream live from the call. When set, `tail` is ignored."
|
|
8486
10162
|
},
|
|
8487
10163
|
maxWaitMs: {
|
|
8488
10164
|
type: "integer",
|
|
8489
10165
|
minimum: 500,
|
|
8490
10166
|
maximum: 3e4,
|
|
8491
|
-
description: "How long to read the stream, in ms (default 5000, max 30000)"
|
|
10167
|
+
description: "How long to read the stream once it opens, in ms (default 5000, max 30000)"
|
|
8492
10168
|
}
|
|
8493
10169
|
};
|
|
8494
10170
|
function baseUrl() {
|
|
@@ -8514,7 +10190,7 @@ var streamPodLogs = {
|
|
|
8514
10190
|
title: "Stream Pod logs",
|
|
8515
10191
|
holdsResponse: true,
|
|
8516
10192
|
annotations: readOnly,
|
|
8517
|
-
description: "Read a bounded snapshot of a Pod's logs (container and/or system source). Holds the live stream open for maxWaitMs and returns the parsed log lines; `truncated: true` means the
|
|
10193
|
+
description: "Read a bounded snapshot of a Pod's logs (container and/or system source). Holds the live stream open for maxWaitMs and returns the parsed log lines; `truncated: true` means the size cap cut the output. For later container lines, call again with `since` set to the last container line's `ts`; `since` does not replay system lines, so for those request a smaller `tail`.",
|
|
8518
10194
|
inputSchema: {
|
|
8519
10195
|
type: "object",
|
|
8520
10196
|
properties: {
|
|
@@ -8536,10 +10212,10 @@ var streamPodLogs = {
|
|
|
8536
10212
|
var streamWorkerLogs = {
|
|
8537
10213
|
name: "stream-worker-logs",
|
|
8538
10214
|
title: "Stream worker logs",
|
|
8539
|
-
directoryDescription: "Read a bounded snapshot of a Serverless worker's logs (container, system, or both). Holds the live stream open for maxWaitMs and returns the parsed log lines; truncated: true means the
|
|
10215
|
+
directoryDescription: "Read a bounded snapshot of a Serverless worker's logs (container, system, or both). Holds the live stream open for maxWaitMs and returns the parsed log lines; truncated: true means the size cap cut the output. A worker whose container keeps failing to start can report RUNNING or THROTTLED while its logs show the failure.",
|
|
8540
10216
|
holdsResponse: true,
|
|
8541
10217
|
annotations: readOnly,
|
|
8542
|
-
description: "Read a bounded snapshot of a Serverless worker's logs (container and/or system source). Holds the live stream open for maxWaitMs and returns the parsed log lines; `truncated: true` means the
|
|
10218
|
+
description: "Read a bounded snapshot of a Serverless worker's logs (container and/or system source). Holds the live stream open for maxWaitMs and returns the parsed log lines; `truncated: true` means the size cap cut the output. For later container lines, call again with `since` set to the last container line's `ts`; `since` does not replay system lines, so for those request a smaller `tail`. Get worker IDs from list-endpoint-workers. Use this whenever a job stays IN_QUEUE while workers exist, whatever status they report \u2014 a crash-looping container often still shows RUNNING or THROTTLED with unhealthy 0, so these logs, not the worker status, are what identify a crash loop.",
|
|
8543
10219
|
inputSchema: {
|
|
8544
10220
|
type: "object",
|
|
8545
10221
|
properties: {
|
|
@@ -8683,6 +10359,24 @@ var listPublicEndpoints = {
|
|
|
8683
10359
|
// src/specgen/tools/knowledge.ts
|
|
8684
10360
|
var import_plugin_knowledge = require("@runpod/plugin-knowledge");
|
|
8685
10361
|
var knowledge = (0, import_plugin_knowledge.loadKnowledge)();
|
|
10362
|
+
var resolveGuideId = (id) => knowledge.aliases?.[id] ?? id;
|
|
10363
|
+
var hiddenRules = new Set(
|
|
10364
|
+
(process.env.KNOWLEDGE_HIDDEN_RULES ?? "").split(",").map((id) => id.trim()).filter(Boolean)
|
|
10365
|
+
);
|
|
10366
|
+
var concepts = knowledge.concepts.map((concept) => ({
|
|
10367
|
+
...concept,
|
|
10368
|
+
rules: concept.rules.filter((rule) => !hiddenRules.has(rule.id))
|
|
10369
|
+
}));
|
|
10370
|
+
for (const id of hiddenRules) {
|
|
10371
|
+
if (!knowledge.concepts.some(
|
|
10372
|
+
(concept) => concept.rules.some((rule) => rule.id === id)
|
|
10373
|
+
))
|
|
10374
|
+
console.warn("knowledge_hidden_rule_unknown", {
|
|
10375
|
+
id,
|
|
10376
|
+
plugin_version: knowledge.version
|
|
10377
|
+
});
|
|
10378
|
+
}
|
|
10379
|
+
var visibleRuleIds = (ids) => ids.filter((id) => !hiddenRules.has(id));
|
|
8686
10380
|
var GUIDE_KINDS = ["skill", "reference", "golden-path"];
|
|
8687
10381
|
var STOPWORDS = new Set(
|
|
8688
10382
|
"a an and are as at be by can do does for from how i in is it my of on or the to what when why with you your".split(
|
|
@@ -8725,7 +10419,7 @@ var guideSummary = ({
|
|
|
8725
10419
|
lanes,
|
|
8726
10420
|
mcp,
|
|
8727
10421
|
needs_shell,
|
|
8728
|
-
concepts
|
|
10422
|
+
concepts: concepts2
|
|
8729
10423
|
}) => ({
|
|
8730
10424
|
id,
|
|
8731
10425
|
kind,
|
|
@@ -8734,7 +10428,7 @@ var guideSummary = ({
|
|
|
8734
10428
|
lanes,
|
|
8735
10429
|
mcp,
|
|
8736
10430
|
needs_shell,
|
|
8737
|
-
concepts
|
|
10431
|
+
concepts: concepts2
|
|
8738
10432
|
});
|
|
8739
10433
|
function linkedGuides(conceptId) {
|
|
8740
10434
|
const byId = new Map(knowledge.guides.map((guide) => [guide.id, guide]));
|
|
@@ -8746,19 +10440,20 @@ function linkedGuides(conceptId) {
|
|
|
8746
10440
|
seen.add(link.from);
|
|
8747
10441
|
const guide = byId.get(link.from);
|
|
8748
10442
|
if (!guide) continue;
|
|
10443
|
+
const rules = link.rules && visibleRuleIds(link.rules);
|
|
8749
10444
|
if (guide.kind === "golden-path")
|
|
8750
10445
|
examples.push({ id: guide.id, title: guide.title, mcp: guide.mcp });
|
|
8751
10446
|
else
|
|
8752
10447
|
docs.push({
|
|
8753
10448
|
id: guide.id,
|
|
8754
10449
|
title: guide.title,
|
|
8755
|
-
...
|
|
10450
|
+
...rules?.length ? { rules } : {}
|
|
8756
10451
|
});
|
|
8757
10452
|
}
|
|
8758
10453
|
return { examples, docs };
|
|
8759
10454
|
}
|
|
8760
10455
|
var conceptIndex = /* @__PURE__ */ new Map();
|
|
8761
|
-
for (const concept of
|
|
10456
|
+
for (const concept of concepts) {
|
|
8762
10457
|
for (const key of [concept.id, concept.name, ...concept.aliases]) {
|
|
8763
10458
|
if (!conceptIndex.has(key.toLowerCase()))
|
|
8764
10459
|
conceptIndex.set(key.toLowerCase(), concept);
|
|
@@ -8792,7 +10487,7 @@ function resolveConcept(input) {
|
|
|
8792
10487
|
return best && !tied ? { concept: best.concept, matchedAs: best.key } : void 0;
|
|
8793
10488
|
}
|
|
8794
10489
|
var ruleIndex = /* @__PURE__ */ new Map();
|
|
8795
|
-
for (const concept of
|
|
10490
|
+
for (const concept of concepts) {
|
|
8796
10491
|
for (const rule of concept.rules) ruleIndex.set(rule.id, { rule, concept });
|
|
8797
10492
|
}
|
|
8798
10493
|
var source = {
|
|
@@ -8841,7 +10536,9 @@ var readGuide = {
|
|
|
8841
10536
|
title: "Read guide",
|
|
8842
10537
|
annotations: bundledRead,
|
|
8843
10538
|
recordedArguments: ["id"],
|
|
8844
|
-
recordedGuideKind: (args) => knowledge.guides.find(
|
|
10539
|
+
recordedGuideKind: (args) => knowledge.guides.find(
|
|
10540
|
+
(guide) => guide.id === resolveGuideId(String(args.id).trim())
|
|
10541
|
+
)?.kind,
|
|
8845
10542
|
description: 'Read one official Runpod guide in full, by the id list-guides returns (for example "runpod-usage/storage" or "golden-path/06-dev-pod").',
|
|
8846
10543
|
inputSchema: {
|
|
8847
10544
|
type: "object",
|
|
@@ -8853,7 +10550,9 @@ var readGuide = {
|
|
|
8853
10550
|
},
|
|
8854
10551
|
handler: async (_ctx, args) => {
|
|
8855
10552
|
const id = String(args.id).trim();
|
|
8856
|
-
const guide = knowledge.guides.find(
|
|
10553
|
+
const guide = knowledge.guides.find(
|
|
10554
|
+
(candidate) => candidate.id === resolveGuideId(id)
|
|
10555
|
+
);
|
|
8857
10556
|
if (!guide) {
|
|
8858
10557
|
const close = knowledge.guides.filter(
|
|
8859
10558
|
(candidate) => candidate.id.includes(id) || id.includes(candidate.id)
|
|
@@ -8911,7 +10610,7 @@ var lookupConcept = {
|
|
|
8911
10610
|
};
|
|
8912
10611
|
}
|
|
8913
10612
|
const { concept, matchedAs } = resolved;
|
|
8914
|
-
const pointedAtBy =
|
|
10613
|
+
const pointedAtBy = concepts.flatMap((other) => [
|
|
8915
10614
|
...other.is_a === concept.id ? [{ concept: other.id, type: "is_a" }] : [],
|
|
8916
10615
|
...other.part_of === concept.id ? [{ concept: other.id, type: "part_of" }] : [],
|
|
8917
10616
|
...other.relations.filter((relation) => relation.target === concept.id).map((relation) => ({ concept: other.id, type: relation.type }))
|
|
@@ -8925,6 +10624,14 @@ var lookupConcept = {
|
|
|
8925
10624
|
...source,
|
|
8926
10625
|
...matchedAs ? { matched_as: matchedAs } : {},
|
|
8927
10626
|
...concept,
|
|
10627
|
+
steps: concept.steps.map((step) => ({
|
|
10628
|
+
...step,
|
|
10629
|
+
rules: visibleRuleIds(step.rules)
|
|
10630
|
+
})),
|
|
10631
|
+
rules: concept.rules.map((rule) => ({
|
|
10632
|
+
...rule,
|
|
10633
|
+
see: visibleRuleIds(rule.see)
|
|
10634
|
+
})),
|
|
8928
10635
|
pointed_at_by: pointedAtBy,
|
|
8929
10636
|
linked_rules: linkedRules,
|
|
8930
10637
|
...linkedGuides(concept.id)
|
|
@@ -9000,6 +10707,12 @@ var guideResources = knowledge.guides.map((guide) => ({
|
|
|
9000
10707
|
mimeType: "text/markdown",
|
|
9001
10708
|
text: guide.body
|
|
9002
10709
|
}));
|
|
10710
|
+
var findGuideResource = (resources, uri) => {
|
|
10711
|
+
const id = uri.startsWith(GUIDE_URI_PREFIX) ? resolveGuideId(uri.slice(GUIDE_URI_PREFIX.length)) : void 0;
|
|
10712
|
+
return resources.find(
|
|
10713
|
+
(resource) => resource.uri === uri || resource.uri === GUIDE_URI_PREFIX + id
|
|
10714
|
+
);
|
|
10715
|
+
};
|
|
9003
10716
|
|
|
9004
10717
|
// src/specgen/prose.ts
|
|
9005
10718
|
var ABBREVIATIONS = ["e.g.", "i.e.", "etc.", "vs."];
|
|
@@ -9183,7 +10896,7 @@ function words2(name) {
|
|
|
9183
10896
|
|
|
9184
10897
|
// src/server.ts
|
|
9185
10898
|
var SERVER_NAME = "Runpod API Server";
|
|
9186
|
-
var SERVER_VERSION = true ? "4.
|
|
10899
|
+
var SERVER_VERSION = true ? "4.10.1" : "dev";
|
|
9187
10900
|
|
|
9188
10901
|
// src/specgen/analytics.ts
|
|
9189
10902
|
var import_node_crypto = require("crypto");
|
|
@@ -9251,6 +10964,7 @@ function captureToolCall(apiKey, event) {
|
|
|
9251
10964
|
server_version: event.serverVersion,
|
|
9252
10965
|
...event.clientName ? { client_name: event.clientName } : {},
|
|
9253
10966
|
...event.guideKind ? { guide_kind: event.guideKind } : {},
|
|
10967
|
+
...event.errorClass ? { error_class: event.errorClass } : {},
|
|
9254
10968
|
...event.blockedBy ? { blocked_by: event.blockedBy } : {},
|
|
9255
10969
|
...event.profile ? { profile: event.profile } : {},
|
|
9256
10970
|
...args
|
|
@@ -9874,7 +11588,7 @@ These tools manage infrastructure only. They do not do SSH sessions, file transf
|
|
|
9874
11588
|
|
|
9875
11589
|
OFFICIAL GUIDES AND FACTS. list-guides and read-guide serve the official Runpod plugin's skills, reference docs and live-verified golden paths, so you have them even without the plugin installed. For a multi-step or billable task, look for a matching golden path first. lookup-concept and search-concepts answer exact questions about how Runpod works (what a stopped pod keeps, where a volume lives) with the public source for each fact.
|
|
9876
11590
|
|
|
9877
|
-
PLAYBOOKS \u2014 READ BEFORE ACTING. Each Runpod task has a journey playbook carrying its procedure, pitfalls and report format. Before the FIRST Runpod tool call of a session, load the plugin's runpod-mcp skill if you have it, otherwise read-guide runpod-mcp (also the runpod://guides/runpod-mcp resource): it routes the request to a journey guide \u2014 deploying an endpoint reads serverless-deploy, diagnosing a broken pod reads pod-doctor, cost questions read cost-audit, and so on \u2014 and states the answer contract. A reply produced without the routed playbook loaded is out of contract.
|
|
11591
|
+
PLAYBOOKS \u2014 READ BEFORE ACTING. Each Runpod task has a journey playbook carrying its procedure, pitfalls and report format. Before the FIRST Runpod tool call of a session, load the plugin's runpod-mcp skill if you have it, otherwise read-guide runpod-mcp (also the runpod://guides/runpod-mcp resource): it routes the request to a journey guide \u2014 deploying an endpoint reads runpod-serverless-deploy, diagnosing a broken pod reads runpod-pod-doctor, cost questions read runpod-cost-audit, and so on \u2014 and states the answer contract. A reply produced without the routed playbook loaded is out of contract.
|
|
9878
11592
|
|
|
9879
11593
|
THE OFFICIAL RUNPOD PLUGIN. Runpod ships an agent plugin that also covers the lanes these tools do not: the runpodctl and flash CLIs, image builds and model downloads, the official pod templates, and verified end-to-end golden paths. Check once per session whether skills named runpod, runpod-usage, or runpodctl are available to you \u2014 read what you already have, never shell out to look. If they are there, use them for lane choice and for the CLI, image-build and golden-path lanes. For work done with these tools, the journey playbook is the procedure, wherever it is served from: the plugin's runpod-mcp skill and the journey skills it routes to when you have them, otherwise the same playbooks through read-guide here. If you do not see them, recommend the plugin to the user, and recommend updating to the latest if what they have is missing something you need. Point them at https://github.com/runpod/runpod-plugins-official \u2014 its README carries the install, update, and clone commands for each client, so read it yourself when you need the exact one rather than guessing a command. This is a recommendation, never a prerequisite: make it once, briefly, and get on with the task. Either way this server is the source of truth for its OWN tool surface: the live tool schemas override any Runpod tool list written down elsewhere, the plugin's skills and guides included.
|
|
9880
11594
|
|
|
@@ -9935,9 +11649,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9935
11649
|
resourceTemplates: []
|
|
9936
11650
|
}));
|
|
9937
11651
|
server.setRequestHandler(import_types.ReadResourceRequestSchema, async (request) => {
|
|
9938
|
-
const guide = servedGuides.
|
|
9939
|
-
(candidate) => candidate.uri === request.params.uri
|
|
9940
|
-
);
|
|
11652
|
+
const guide = findGuideResource(servedGuides, request.params.uri);
|
|
9941
11653
|
if (opts.analytics) {
|
|
9942
11654
|
captureResourceCall(ctx.apiKey, {
|
|
9943
11655
|
method: "resources/read",
|
|
@@ -9974,6 +11686,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9974
11686
|
ok: false,
|
|
9975
11687
|
status: 429,
|
|
9976
11688
|
durationMs: 0,
|
|
11689
|
+
errorClass: "rate_limited",
|
|
9977
11690
|
...verdict.reason ? { blockedBy: verdict.reason } : {},
|
|
9978
11691
|
profile,
|
|
9979
11692
|
...opts.analytics
|
|
@@ -9999,6 +11712,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9999
11712
|
const generated = servedGeneratedTools.find(
|
|
10000
11713
|
(tool) => tool.name === request.params.name
|
|
10001
11714
|
);
|
|
11715
|
+
const curatedArgs = curated ? withoutNullOptionals(curated.inputSchema, args) : args;
|
|
10002
11716
|
const omitted = directory ? directoryOmittedInputs(request.params.name).filter((key) => key in args) : [];
|
|
10003
11717
|
const rejected = omitted.length ? {
|
|
10004
11718
|
ok: false,
|
|
@@ -10008,10 +11722,10 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
10008
11722
|
}
|
|
10009
11723
|
} : curated && !curated.lenientArguments ? validateArguments(
|
|
10010
11724
|
curated.inputSchema,
|
|
10011
|
-
|
|
11725
|
+
curatedArgs
|
|
10012
11726
|
) : null;
|
|
10013
11727
|
const result = rejected ?? await runTool(
|
|
10014
|
-
() => curated ? curated.handler(ctx,
|
|
11728
|
+
() => curated ? curated.handler(ctx, curatedArgs) : dispatchTool(generated, request.params.name, args)
|
|
10015
11729
|
);
|
|
10016
11730
|
logToolCall({
|
|
10017
11731
|
tool: request.params.name,
|
|
@@ -10026,6 +11740,7 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
10026
11740
|
ok: result.ok,
|
|
10027
11741
|
status: result.status,
|
|
10028
11742
|
durationMs: Date.now() - startedAt,
|
|
11743
|
+
...result.ok ? {} : { errorClass: errorClass(result) },
|
|
10029
11744
|
// The directory profile records which tool ran, never what was asked.
|
|
10030
11745
|
...directory ? {} : {
|
|
10031
11746
|
args: recordedArgumentValues(curated?.recordedArguments, args),
|
|
@@ -10065,24 +11780,50 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
10065
11780
|
var SHAPE_HINT = "Input shape mismatch: check this tool's schema for required fields. For job payloads, the worker's release config defines the expected input object \u2014 fix the payload and retry; don't abandon the task.";
|
|
10066
11781
|
var DETAIL_HINTS = [
|
|
10067
11782
|
[
|
|
10068
|
-
/no longer any instances available|not enough free GPUs/i,
|
|
10069
|
-
"Capacity, not input: the request is valid but no machine can take it right now. Don't change the payload shape. Retry with another GPU type, data center, cloud, CUDA version or count, or try again later. For a stopped Pod, its host's GPUs are taken; that Pod can only start once they free up."
|
|
11783
|
+
/no longer any instances available|no instances currently available|not enough free GPUs/i,
|
|
11784
|
+
"Capacity, not input: the request is valid but no machine can take it right now. Don't change the payload shape. Retry with another GPU type, data center, cloud, CUDA version or count, or try again later. For a stopped Pod, its host's GPUs are taken; that Pod can only start once they free up.",
|
|
11785
|
+
"capacity"
|
|
10070
11786
|
],
|
|
10071
11787
|
[
|
|
10072
11788
|
/at least \$\d|insufficient (?:funds|balance)|\bbalance\b/i,
|
|
10073
|
-
"Account balance, not input: this operation needs funds on the account. Ask the user to add credit in the Runpod console; list-billing shows recent spend."
|
|
11789
|
+
"Account balance, not input: this operation needs funds on the account. Ask the user to add credit in the Runpod console; list-billing shows recent spend.",
|
|
11790
|
+
"balance"
|
|
10074
11791
|
],
|
|
10075
11792
|
[
|
|
10076
11793
|
/mutually exclusive|cannot be combined with/i,
|
|
10077
|
-
"Two arguments conflict: send only one of them and leave the other out entirely. Do not change anything else."
|
|
11794
|
+
"Two arguments conflict: send only one of them and leave the other out entirely. Do not change anything else.",
|
|
11795
|
+
"conflicting_args"
|
|
11796
|
+
],
|
|
11797
|
+
// A 400 with a bare "Unauthorized" detail from a write the same key can
|
|
11798
|
+
// otherwise make is upstream's answer for an unfunded account.
|
|
11799
|
+
[
|
|
11800
|
+
/^\s*unauthorized\s*$/i,
|
|
11801
|
+
"Upstream refused this write. With a key that can read, this usually means the account has no balance: ask the user to check their balance in the Runpod console before retrying.",
|
|
11802
|
+
"balance"
|
|
10078
11803
|
]
|
|
10079
11804
|
];
|
|
11805
|
+
function errorClass(result) {
|
|
11806
|
+
const { status } = result;
|
|
11807
|
+
const payload = asRecord(result.payload) ?? { error: result.payload };
|
|
11808
|
+
const detail = detailText(payload);
|
|
11809
|
+
if (status === 400 && detail) {
|
|
11810
|
+
for (const [pattern, , cls] of DETAIL_HINTS)
|
|
11811
|
+
if (pattern.test(detail)) return cls;
|
|
11812
|
+
}
|
|
11813
|
+
if (status === 400 || status === 422) return "validation";
|
|
11814
|
+
if (status === 401) return "auth";
|
|
11815
|
+
if (status === 402) return "balance";
|
|
11816
|
+
if (status === 403) return "permission";
|
|
11817
|
+
if (status === 404) return "not_found";
|
|
11818
|
+
if (status === 429) return "rate_limited";
|
|
11819
|
+
if (status === 504) return "timeout";
|
|
11820
|
+
if (status >= 500) return "server";
|
|
11821
|
+
return "other";
|
|
11822
|
+
}
|
|
10080
11823
|
function errorHint(status, detail) {
|
|
10081
11824
|
if (status === 400 && detail) {
|
|
10082
11825
|
for (const [pattern, hint] of DETAIL_HINTS)
|
|
10083
11826
|
if (pattern.test(detail)) return hint;
|
|
10084
|
-
if (/^unauthorized$/i.test(detail.trim()))
|
|
10085
|
-
return "Upstream refused this write. With a key that can read, this usually means the account has no balance: ask the user to check their balance in the Runpod console before retrying.";
|
|
10086
11827
|
}
|
|
10087
11828
|
if (status === 400 || status === 422) return SHAPE_HINT;
|
|
10088
11829
|
if (status === 401) return "The Runpod API key is missing or invalid.";
|
|
@@ -10822,7 +12563,7 @@ async function handleMcpRequest(req, res, opts = {}) {
|
|
|
10822
12563
|
}
|
|
10823
12564
|
|
|
10824
12565
|
// src/alp/scrub.ts
|
|
10825
|
-
var SCRUB_VERSION =
|
|
12566
|
+
var SCRUB_VERSION = 6;
|
|
10826
12567
|
var MARKER = /^["']?\[redacted:[a-z_]+\]["']?$/;
|
|
10827
12568
|
var CREDENTIAL_PATTERNS = [
|
|
10828
12569
|
// Runpod API keys.
|
|
@@ -11010,6 +12751,22 @@ function redactAssignments(text) {
|
|
|
11010
12751
|
out += text.slice(copiedTo);
|
|
11011
12752
|
return { text: out, redactions };
|
|
11012
12753
|
}
|
|
12754
|
+
var EMAIL = /(?<![\p{L}\p{M}\p{N}_.%+-])([\p{L}\p{M}\p{N}_.%+-]{1,64})@((?:[\p{L}\p{M}\p{N}-]{1,63}\.){1,8}[\p{L}\p{M}]{2,63})(?![\p{L}\p{M}\p{N}])/gu;
|
|
12755
|
+
var RUNPOD_SSH_HOST = "ssh.runpod.io";
|
|
12756
|
+
function redactEmails(text) {
|
|
12757
|
+
let redactions = 0;
|
|
12758
|
+
const out = text.replace(
|
|
12759
|
+
EMAIL,
|
|
12760
|
+
(address, local, domain, offset) => {
|
|
12761
|
+
const next = text[offset + address.length];
|
|
12762
|
+
if (domain.toLowerCase() === RUNPOD_SSH_HOST || local === "git" && (next === ":" || next === "/"))
|
|
12763
|
+
return address;
|
|
12764
|
+
redactions++;
|
|
12765
|
+
return "[redacted:email]";
|
|
12766
|
+
}
|
|
12767
|
+
);
|
|
12768
|
+
return { text: out, redactions };
|
|
12769
|
+
}
|
|
11013
12770
|
function scrub(text) {
|
|
11014
12771
|
let out = text;
|
|
11015
12772
|
let redactions = 0;
|
|
@@ -11017,7 +12774,8 @@ function scrub(text) {
|
|
|
11017
12774
|
redactAnchoredCredentials,
|
|
11018
12775
|
redactHeaderValues,
|
|
11019
12776
|
redactQuerySecrets,
|
|
11020
|
-
redactAssignments
|
|
12777
|
+
redactAssignments,
|
|
12778
|
+
redactEmails
|
|
11021
12779
|
]) {
|
|
11022
12780
|
const result = stage(out);
|
|
11023
12781
|
out = result.text;
|
|
@@ -11057,6 +12815,7 @@ var MAX_CONTENT_CHARS = 2e4;
|
|
|
11057
12815
|
var MAX_REFERRAL_CONTENT_CHARS = 200;
|
|
11058
12816
|
var MAX_FIELD_CHARS = 500;
|
|
11059
12817
|
var SINK_TIMEOUT_MS3 = 5e3;
|
|
12818
|
+
var TOOL_NAME = /^[A-Za-z0-9_-]{1,64}$/;
|
|
11060
12819
|
var ALP_SEVERITIES = ["blocked", "degraded", "cosmetic"];
|
|
11061
12820
|
function notRecorded(reason) {
|
|
11062
12821
|
return {
|
|
@@ -11129,7 +12888,9 @@ async function handleAlpSubmit(req, res, opts = {}) {
|
|
|
11129
12888
|
// ("critical", "high") turns a dimension back into prose, and the loss of
|
|
11130
12889
|
// one label costs less than that.
|
|
11131
12890
|
severity: !referral && ALP_SEVERITIES.includes(body.severity) ? body.severity : void 0,
|
|
11132
|
-
|
|
12891
|
+
// Same rule as severity: a free-text tool would turn a grouping key back
|
|
12892
|
+
// into prose, so only a value shaped like a tool name is kept.
|
|
12893
|
+
tool: !referral && typeof body.tool === "string" && TOOL_NAME.test(body.tool) ? body.tool : void 0,
|
|
11133
12894
|
workaround: !referral && typeof body.workaround === "string" ? body.workaround : void 0,
|
|
11134
12895
|
trigger: !referral && typeof body.trigger === "string" ? body.trigger : void 0,
|
|
11135
12896
|
// Referral-only fields. source follows the severity rule (off-enum is
|
|
@@ -11155,7 +12916,7 @@ async function handleAlpSubmit(req, res, opts = {}) {
|
|
|
11155
12916
|
intention: clean.intention?.slice(0, MAX_FIELD_CHARS),
|
|
11156
12917
|
modelType: clean.modelType?.slice(0, MAX_FIELD_CHARS),
|
|
11157
12918
|
severity: clean.severity,
|
|
11158
|
-
tool: clean.tool
|
|
12919
|
+
tool: clean.tool,
|
|
11159
12920
|
// Prose fields, so they get the content cap rather than the field cap: a
|
|
11160
12921
|
// workaround worth reading is a paragraph, not a label.
|
|
11161
12922
|
workaround: clean.workaround?.slice(0, MAX_CONTENT_CHARS),
|
|
@@ -11187,6 +12948,14 @@ async function handleAlpSubmit(req, res, opts = {}) {
|
|
|
11187
12948
|
return;
|
|
11188
12949
|
}
|
|
11189
12950
|
const sinkBody = await response.json().catch(() => null);
|
|
12951
|
+
if (sinkBody?.capped === true) {
|
|
12952
|
+
console.log(
|
|
12953
|
+
"alp_submit_capped",
|
|
12954
|
+
JSON.stringify({ route: body.route, transport: row.transport })
|
|
12955
|
+
);
|
|
12956
|
+
send(200, notRecorded("this account reached its limit for this tool"));
|
|
12957
|
+
return;
|
|
12958
|
+
}
|
|
11190
12959
|
if (sinkBody?.ok !== true || typeof sinkBody.id !== "string") {
|
|
11191
12960
|
console.warn("alp_sink_unrecognized", { status: response.status });
|
|
11192
12961
|
send(200, notRecorded("the store did not confirm the write"));
|