mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 17:33:51 +02:00
Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.4.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/colinhacks/zod/releases">zod's releases</a>.</em></p> <blockquote> <h2>v4.4.3</h2> <h2>Commits:</h2> <ul> <li>4c2fa95ce3f3390fbc522324e406b4e9e89b88f9 docs: use Zernio primary wordmark for gold sponsor logo</li> <li>2aeec83eb135e3a83756e973ef44845fc5a455d2 docs: prune lapsed gold sponsors and rebalance logo sizing</li> <li>7391be88ac1ee5cd02057f5ccc012a1f5df4efd0 docs: prune lapsed silver/bronze sponsors and add active ones</li> <li>2c703322a21b4e2b12f33f49ea8430c451a68b4f docs: normalize bronze sponsor logos to github avatar pattern</li> <li>9195250cab0e7950efe39c3926d6c203b4b0a170 docs: remove Mintlify from bronze sponsors (churned)</li> <li>b8dffe9e62f17e6571e6249d05cc5102b54d94e4 docs: remove Numeric and Speakeasy (2+ missed monthly cycles)</li> <li>1cab69383fcdeae2a366d5e2a2fc4d8fc765d168 fix(v4): restore catch handling for absent object keys (<a href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>) (<a href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li> <li>c2be4f819064eed62c7c350a2d399b5faecd15f8 fix(v4): generalize optin/fallback to transform; restore preprocess on absent keys (<a href="https://redirect.github.com/colinhacks/zod/issues/5941">#5941</a>)</li> <li>f3c9ec03ba7a28ae72d25cc295f38674bee0f559 4.4.3</li> <li>1fb56a5c18c27102dbc92260a4007c7732a0ccca docs: document release procedure in AGENTS.md</li> </ul> <h2>v4.4.2</h2> <h2>Commits:</h2> <ul> <li>0c62df0ea19fd05abdf90473e9eef7eea530fab2 Clean up docs navigation and stale labels (<a href="https://redirect.github.com/colinhacks/zod/issues/5901">#5901</a>)</li> <li>20cc794895cc8604fe0c87d83a5d1c3f89fad0ac chore: add security policy and refresh tooling deps</li> <li>6fbe07b0177efdd1bf1c0b05160e70d7a0702337 fix(docs): heading anchor links now include the hash so it doesnt scoll all the way up, follows navbar logic (<a href="https://redirect.github.com/colinhacks/zod/issues/5791">#5791</a>)</li> <li>4bbed1b1c73eca4ce9e59b1189ed236aa6c8b5bd Tighten discriminated union option typing</li> <li>bbac3e567e7fccfaaf7cdc97f1ce30c295e2c908 Update PR guidance for agents</li> <li>cf0dc942a32805c292fff59ade20a7ace980735a Merge remote-tracking branch 'origin/main' into fix-discriminated-union-key-constraint</li> <li>292c894a5fd2aa42e527900b83d8d7a3009a709c docs: add Zernio gold sponsor</li> <li>1fc9f311c28dcf80d0bb5a36b177086cbc3d8eca docs: document codec inversion</li> <li>1373c85da9aeff704a9762d27bc58699618aefb7 docs: remove AI disclosure guidance</li> <li>e20d02b473c08e3a4e557bc610b1b5fac079b649 chore: ignore triage notes</li> <li>e58ea4d91b1dfe8194b73508203213cbc7e9c936 docs: test Zod Mini tab code heights</li> <li>905761a5d127e8d5dd2ebb3bc88c75cb0b8149ff docs: document preprocess input type narrowing</li> <li>bf64bac850d4dee2b7dde7e64909d5d796d32043 chore: tighten test guidance in AGENTS.md</li> <li>8ec4e73f4c4693b6361ad591be40fb41eb8a9f95 chore: update play.ts scratch</li> <li>02c2baf7d0d615872fa4528a8020603b71211702 Make z.preprocess defer optionality to inner schema (<a href="https://redirect.github.com/colinhacks/zod/issues/5929">#5929</a>)</li> <li>88015df8e25c44fb5385eb3ef28935119cd5edea fix(docs): drop deprecated <code>baseUrl</code> from tsconfig</li> <li>c59d4474e3b4cad1b323462186cf607178ce8267 4.4.2</li> </ul> <h2>v4.4.1</h2> <h2>Commits:</h2> <ul> <li>481f7be4238c83ed58183f921b2646f340a91c6a ci: gate release publishing on full test workflow</li> <li>95ccab423aec720b2523c3a64cdc7e3204537cc7 test(v3): restore optional undefined expectations</li> <li>cede2c63739a5823d6aa5093d291e9a111da943d fix(v4): reject tuple holes before required defaults (<a href="https://redirect.github.com/colinhacks/zod/issues/5900">#5900</a>)</li> <li>edd0bf0f5ada4a8dc581c259407d7bbad0a71ea7 release: 4.4.1</li> <li>180d83d1dbe6a59260710cc8637a3dea2281ee56 docs: remove Jazz featured sponsor</li> </ul> <h2>v4.4.0</h2> <h2>4.4.0</h2> <p>This is a minor release with a wide set of correctness and soundness fixes. Some fixes intentionally make Zod stricter, so code that depended on previously accepted invalid or ambiguous inputs may need small updates.</p> <h2>Potentially breaking bug fixes</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/colinhacks/zod/commit/1fb56a5c18c27102dbc92260a4007c7732a0ccca"><code>1fb56a5</code></a> docs: document release procedure in AGENTS.md</li> <li><a href="https://github.com/colinhacks/zod/commit/f3c9ec03ba7a28ae72d25cc295f38674bee0f559"><code>f3c9ec0</code></a> 4.4.3</li> <li><a href="https://github.com/colinhacks/zod/commit/c2be4f819064eed62c7c350a2d399b5faecd15f8"><code>c2be4f8</code></a> fix(v4): generalize optin/fallback to transform; restore preprocess on absent...</li> <li><a href="https://github.com/colinhacks/zod/commit/1cab69383fcdeae2a366d5e2a2fc4d8fc765d168"><code>1cab693</code></a> fix(v4): restore catch handling for absent object keys (<a href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>) (<a href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li> <li><a href="https://github.com/colinhacks/zod/commit/b8dffe9e62f17e6571e6249d05cc5102b54d94e4"><code>b8dffe9</code></a> docs: remove Numeric and Speakeasy (2+ missed monthly cycles)</li> <li><a href="https://github.com/colinhacks/zod/commit/9195250cab0e7950efe39c3926d6c203b4b0a170"><code>9195250</code></a> docs: remove Mintlify from bronze sponsors (churned)</li> <li><a href="https://github.com/colinhacks/zod/commit/2c703322a21b4e2b12f33f49ea8430c451a68b4f"><code>2c70332</code></a> docs: normalize bronze sponsor logos to github avatar pattern</li> <li><a href="https://github.com/colinhacks/zod/commit/7391be88ac1ee5cd02057f5ccc012a1f5df4efd0"><code>7391be8</code></a> docs: prune lapsed silver/bronze sponsors and add active ones</li> <li><a href="https://github.com/colinhacks/zod/commit/2aeec83eb135e3a83756e973ef44845fc5a455d2"><code>2aeec83</code></a> docs: prune lapsed gold sponsors and rebalance logo sizing</li> <li><a href="https://github.com/colinhacks/zod/commit/4c2fa95ce3f3390fbc522324e406b4e9e89b88f9"><code>4c2fa95</code></a> docs: use Zernio primary wordmark for gold sponsor logo</li> <li>Additional commits viewable in <a href="https://github.com/colinhacks/zod/compare/v3.25.76...v4.4.3">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for zod since your current version.</p> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Priya Raman <priya@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing>
817 lines
37 KiB
TypeScript
817 lines
37 KiB
TypeScript
import { z } from "zod";
|
|
import {
|
|
CONNECTION_TOKEN_ISSUANCE_PATHS,
|
|
SECRET_PROJECTION_CLASSES,
|
|
TOOL_ACTION_REQUEST_STATUSES,
|
|
TOOL_APPLICATION_STATUSES,
|
|
TOOL_APPLICATION_TYPES,
|
|
TOOL_AUDIT_EVENT_TYPES,
|
|
TOOL_AUDIT_OUTCOMES,
|
|
TOOL_CATALOG_ENTRY_KINDS,
|
|
TOOL_CATALOG_ENTRY_STATUSES,
|
|
TOOL_CONNECTION_HEALTH_STATUSES,
|
|
TOOL_CONNECTION_KINDS,
|
|
TOOL_INVOCATION_APPROVAL_STATES,
|
|
TOOL_INVOCATION_STATUSES,
|
|
TOOL_MCP_GATEWAY_CONTEXT_SCOPE_TYPES,
|
|
TOOL_MCP_GATEWAY_DEFAULT_PROFILE_MODES,
|
|
TOOL_MCP_GATEWAY_STATUSES,
|
|
TOOL_MCP_GATEWAY_TOKEN_ACTIONS,
|
|
TOOL_MCP_GATEWAY_TOKEN_SUBJECT_TYPES,
|
|
TOOL_POLICY_DECISIONS,
|
|
TOOL_POLICY_TYPES,
|
|
TOOL_PROFILE_BINDING_TARGET_TYPES,
|
|
TOOL_PROFILE_DEFAULT_ACTIONS,
|
|
TOOL_PROFILE_ENTRY_EFFECTS,
|
|
TOOL_PROFILE_ENTRY_SELECTOR_TYPES,
|
|
TOOL_PROFILE_STATUSES,
|
|
TOOL_RATE_LIMIT_WINDOW_KINDS,
|
|
TOOL_RISK_LEVELS,
|
|
TOOL_RUNTIME_KINDS,
|
|
TOOL_RUNTIME_SLOT_STATUSES,
|
|
} from "../constants.js";
|
|
import { jsonSchemaSchema } from "./plugin.js";
|
|
import { objectWithoutDefaults } from "./partial.js";
|
|
|
|
export const toolApplicationTypeSchema = z.enum(TOOL_APPLICATION_TYPES);
|
|
export const toolApplicationStatusSchema = z.enum(TOOL_APPLICATION_STATUSES);
|
|
export const toolConnectionTransportSchema = z.enum(["mcp_remote", "rest_api", "local_stdio"]);
|
|
export const toolConnectionAuthKindSchema = z.enum(["oauth", "api_key", "none"]);
|
|
export const toolConnectionOwnershipSchema = z.enum(["platform_shared", "platform_provisioned", "customer", "dcr"]);
|
|
export const connectionGrantKindSchema = z.enum(["workspace", "user"]);
|
|
export const connectionGrantStatusSchema = z.enum(["active", "revoked", "expired", "needs_reauthorization"]);
|
|
export const toolConnectionStatusSchema = z.enum(["draft", "active", "disabled", "archived"]);
|
|
export const toolConnectionInstallTargetTypeSchema = z.enum(["company", "agent"]);
|
|
export const toolCredentialPlacementSchema = z.enum(["header", "env"]);
|
|
export const toolConnectionKindSchema = z.enum(TOOL_CONNECTION_KINDS);
|
|
export const toolConnectionHealthStatusSchema = z.enum(TOOL_CONNECTION_HEALTH_STATUSES);
|
|
export const toolCatalogEntryKindSchema = z.enum(TOOL_CATALOG_ENTRY_KINDS);
|
|
export const toolCatalogEntryStatusSchema = z.enum(TOOL_CATALOG_ENTRY_STATUSES);
|
|
export const toolRiskLevelSchema = z.enum(TOOL_RISK_LEVELS);
|
|
export const toolProfileStatusSchema = z.enum(TOOL_PROFILE_STATUSES);
|
|
export const toolProfileDefaultActionSchema = z.enum(TOOL_PROFILE_DEFAULT_ACTIONS);
|
|
export const toolProfileEntrySelectorTypeSchema = z.enum(TOOL_PROFILE_ENTRY_SELECTOR_TYPES);
|
|
export const toolProfileEntryEffectSchema = z.enum(TOOL_PROFILE_ENTRY_EFFECTS);
|
|
export const toolProfileBindingTargetTypeSchema = z.enum(TOOL_PROFILE_BINDING_TARGET_TYPES);
|
|
export const toolPolicyTypeSchema = z.enum(TOOL_POLICY_TYPES);
|
|
export const toolPolicyDecisionSchema = z.enum(TOOL_POLICY_DECISIONS);
|
|
export const toolInvocationStatusSchema = z.enum(TOOL_INVOCATION_STATUSES);
|
|
export const toolInvocationApprovalStateSchema = z.enum(TOOL_INVOCATION_APPROVAL_STATES);
|
|
export const toolMcpGatewayStatusSchema = z.enum(TOOL_MCP_GATEWAY_STATUSES);
|
|
export const toolMcpGatewayDefaultProfileModeSchema = z.enum(TOOL_MCP_GATEWAY_DEFAULT_PROFILE_MODES);
|
|
export const toolMcpGatewayContextScopeTypeSchema = z.enum(TOOL_MCP_GATEWAY_CONTEXT_SCOPE_TYPES);
|
|
export const toolMcpGatewayTokenSubjectTypeSchema = z.enum(TOOL_MCP_GATEWAY_TOKEN_SUBJECT_TYPES);
|
|
export const toolMcpGatewayTokenActionSchema = z.enum(TOOL_MCP_GATEWAY_TOKEN_ACTIONS);
|
|
export const toolActionRequestStatusSchema = z.enum(TOOL_ACTION_REQUEST_STATUSES);
|
|
export const toolAuditEventTypeSchema = z.enum(TOOL_AUDIT_EVENT_TYPES);
|
|
export const toolAuditOutcomeSchema = z.enum(TOOL_AUDIT_OUTCOMES);
|
|
export const toolRuntimeKindSchema = z.enum(TOOL_RUNTIME_KINDS);
|
|
export const toolRuntimeSlotStatusSchema = z.enum(TOOL_RUNTIME_SLOT_STATUSES);
|
|
export const toolRateLimitWindowKindSchema = z.enum(TOOL_RATE_LIMIT_WINDOW_KINDS);
|
|
|
|
const safeKeyPattern = /^[a-z0-9][a-z0-9._:-]*$/i;
|
|
const sensitiveConfigKeyPattern =
|
|
/^(access[-_]?key([-_]?id)?|api[-_]?key|authorization|bearer|client[-_]?secret|credential|credentials|jwt|password|passwd|private[-_]?key|refresh[-_]?token|secret|secret[-_]?access[-_]?key|secret[-_]?key|session[-_]?token|token)$/i;
|
|
|
|
function rejectSensitiveConfigKeys(value: unknown, ctx: z.RefinementCtx, path: Array<string | number> = []) {
|
|
if (!value || typeof value !== "object") return;
|
|
if (Array.isArray(value)) {
|
|
value.forEach((entry, index) => rejectSensitiveConfigKeys(entry, ctx, [...path, index]));
|
|
return;
|
|
}
|
|
for (const [key, nested] of Object.entries(value)) {
|
|
if (sensitiveConfigKeyPattern.test(key)) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: [...path, key],
|
|
message: `Tool access config cannot persist sensitive field: ${key}. Use credentialSecretRefs instead.`,
|
|
});
|
|
}
|
|
rejectSensitiveConfigKeys(nested, ctx, [...path, key]);
|
|
}
|
|
}
|
|
|
|
export const toolCredentialSecretRefSchema = z.object({
|
|
secretId: z.string().guid(),
|
|
versionSelector: z.union([z.literal("latest"), z.number().int().positive()]).optional(),
|
|
configPath: z.string().trim().min(1).max(200),
|
|
required: z.boolean().optional(),
|
|
label: z.string().trim().max(120).optional().nullable(),
|
|
projectionClass: z.enum(SECRET_PROJECTION_CLASSES).optional(),
|
|
projectionAllowlistKey: z.string().trim().min(1).max(160).optional().nullable(),
|
|
keyScope: z.string().trim().min(1).max(160).optional(),
|
|
expiresAt: z.string().datetime({ offset: true }).optional(),
|
|
});
|
|
|
|
export const mcpConnectionCredentialRefSchema = z.object({
|
|
name: z.string().trim().min(1).max(120),
|
|
secretId: z.string().guid(),
|
|
version: z.union([z.literal("latest"), z.number().int().positive()]).optional(),
|
|
placement: toolCredentialPlacementSchema,
|
|
key: z.string().trim().min(1).max(160),
|
|
prefix: z.string().max(120).nullable().optional(),
|
|
});
|
|
|
|
export const toolTransportConfigSchema = z.record(z.string(), z.unknown()).superRefine(rejectSensitiveConfigKeys);
|
|
|
|
export const toolRedactedValueSummarySchema = z.object({
|
|
summary: z.string().max(4000),
|
|
sizeBytes: z.number().int().min(0).optional().nullable(),
|
|
sha256: z.string().trim().regex(/^[a-f0-9]{64}$/i).optional().nullable(),
|
|
redactedFields: z.array(z.string().trim().min(1).max(200)).default([]).optional(),
|
|
artifactId: z.string().guid().optional().nullable(),
|
|
});
|
|
|
|
export const createToolApplicationSchema = z.object({
|
|
applicationKey: z.string().trim().min(1).max(160).regex(safeKeyPattern).optional(),
|
|
name: z.string().trim().min(1).max(160),
|
|
description: z.string().max(4000).optional().nullable(),
|
|
type: toolApplicationTypeSchema,
|
|
status: toolApplicationStatusSchema.optional(),
|
|
pluginId: z.string().guid().optional().nullable(),
|
|
ownerAgentId: z.string().guid().optional().nullable(),
|
|
ownerUserId: z.string().optional().nullable(),
|
|
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolApplication = z.infer<typeof createToolApplicationSchema>;
|
|
|
|
export const updateToolApplicationSchema = createToolApplicationSchema.partial().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "At least one tool application field is required" },
|
|
);
|
|
|
|
export type UpdateToolApplication = z.infer<typeof updateToolApplicationSchema>;
|
|
|
|
export const createToolConnectionSchema = z.object({
|
|
applicationId: z.string().guid().optional(),
|
|
applicationName: z.string().trim().min(1).max(160).optional(),
|
|
name: z.string().trim().min(1).max(160),
|
|
transport: toolConnectionTransportSchema.optional(),
|
|
authKind: toolConnectionAuthKindSchema.default("none"),
|
|
ownership: toolConnectionOwnershipSchema.default("customer"),
|
|
status: toolConnectionStatusSchema.optional(),
|
|
connectionKind: toolConnectionKindSchema.default("managed"),
|
|
config: toolTransportConfigSchema.optional(),
|
|
transportConfig: toolTransportConfigSchema.default({}),
|
|
credentialRefs: z.array(mcpConnectionCredentialRefSchema).optional(),
|
|
credentialSecretRefs: z.array(toolCredentialSecretRefSchema).default([]),
|
|
enabled: z.boolean().optional(),
|
|
});
|
|
|
|
export type CreateToolConnection = z.infer<typeof createToolConnectionSchema>;
|
|
|
|
export const updateToolConnectionSchema = objectWithoutDefaults(createToolConnectionSchema.omit({ applicationId: true })).partial().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "At least one tool connection field is required" },
|
|
);
|
|
|
|
export type UpdateToolConnection = z.infer<typeof updateToolConnectionSchema>;
|
|
|
|
export const connectionGrantSchema = z.object({
|
|
id: z.string().guid(),
|
|
companyId: z.string().guid(),
|
|
connectionId: z.string().guid(),
|
|
kind: connectionGrantKindSchema,
|
|
subjectUserId: z.string().nullable(),
|
|
providerTenant: z.object({
|
|
name: z.string().trim().min(1).max(200).optional(),
|
|
externalId: z.string().trim().min(1).max(400).optional(),
|
|
}).nullable(),
|
|
credentialSecretRefs: z.array(toolCredentialSecretRefSchema),
|
|
status: connectionGrantStatusSchema,
|
|
isDefault: z.boolean(),
|
|
createdByAgentId: z.string().guid().nullable(),
|
|
createdByUserId: z.string().nullable(),
|
|
revokedAt: z.coerce.date().nullable(),
|
|
revokedByAgentId: z.string().guid().nullable(),
|
|
revokedByUserId: z.string().nullable(),
|
|
lastUsedAt: z.coerce.date().nullable(),
|
|
createdAt: z.coerce.date(),
|
|
updatedAt: z.coerce.date(),
|
|
}).superRefine((grant, ctx) => {
|
|
if ((grant.kind === "user") !== Boolean(grant.subjectUserId)) {
|
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["subjectUserId"], message: "User grants require a subject user; workspace grants must not have one" });
|
|
}
|
|
});
|
|
|
|
export const putToolConnectionInstallsSchema = z.object({
|
|
installs: z.array(z.object({
|
|
targetType: toolConnectionInstallTargetTypeSchema,
|
|
targetId: z.string().trim().min(1).max(200),
|
|
})).max(1000),
|
|
}).strict();
|
|
|
|
export type PutToolConnectionInstalls = z.infer<typeof putToolConnectionInstallsSchema>;
|
|
|
|
export const connectionTokenIssuancePathSchema = z.enum(CONNECTION_TOKEN_ISSUANCE_PATHS);
|
|
|
|
export const connectionTokenScopeSchema = z.union([
|
|
z.string().trim().min(1).max(500),
|
|
z.array(z.string().trim().min(1).max(240)).max(100),
|
|
]);
|
|
|
|
export const connectionTokenSubjectSchema = z.discriminatedUnion("type", [
|
|
z.object({ type: z.literal("app") }).strict(),
|
|
z.object({ type: z.literal("user"), userId: z.string().trim().min(1).max(500) }).strict(),
|
|
]);
|
|
|
|
export const connectionTokenRequestSchema = z.object({
|
|
subject: connectionTokenSubjectSchema.optional().default({ type: "app" }),
|
|
scope: connectionTokenScopeSchema.optional(),
|
|
requestedTtlSeconds: z.number().int().positive().max(86_400).optional(),
|
|
grantId: z.string().guid().optional(),
|
|
}).strict();
|
|
|
|
export const startConnectionAuthorizationSchema = z.object({
|
|
subjectUserId: z.string().trim().min(1).max(500),
|
|
scopes: z.array(z.string().trim().min(1).max(240)).max(100).optional(),
|
|
returnTo: z.string().trim().max(2000).optional(),
|
|
}).strict();
|
|
|
|
export type ConnectionTokenRequestInput = z.infer<typeof connectionTokenRequestSchema>;
|
|
|
|
const envKeyPattern = /^[A-Z_][A-Z0-9_]*$/i;
|
|
|
|
export const toolStdioTemplateToolSchema = z.object({
|
|
name: z.string().trim().min(1).max(240),
|
|
title: z.string().trim().max(240).optional().nullable(),
|
|
description: z.string().max(8000).optional().nullable(),
|
|
inputSchema: jsonSchemaSchema.optional().nullable(),
|
|
annotations: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export const createToolStdioCommandTemplateSchema = z.object({
|
|
templateId: z.string().trim().min(1).max(160).regex(safeKeyPattern),
|
|
name: z.string().trim().min(1).max(160),
|
|
description: z.string().max(4000).optional().nullable(),
|
|
command: z.string().trim().min(1).max(2000),
|
|
args: z.array(z.string().max(2000)).max(100).default([]),
|
|
envKeys: z.array(z.string().trim().min(1).max(160).regex(envKeyPattern)).max(200).default([]),
|
|
tools: z.array(toolStdioTemplateToolSchema).max(500).default([]),
|
|
});
|
|
|
|
export type CreateToolStdioCommandTemplate = z.infer<typeof createToolStdioCommandTemplateSchema>;
|
|
|
|
export const disableToolStdioCommandTemplateSchema = z.object({
|
|
reason: z.string().trim().max(1000).optional().nullable(),
|
|
});
|
|
|
|
export type DisableToolStdioCommandTemplate = z.infer<typeof disableToolStdioCommandTemplateSchema>;
|
|
|
|
export const connectToolAppSchema = z.object({
|
|
galleryKey: z.string().trim().min(1).max(120).optional(),
|
|
link: z.string().trim().url().max(2000).optional(),
|
|
name: z.string().trim().min(1).max(160).optional(),
|
|
credentialValues: z.record(z.string().trim().min(1).max(200), z.string().min(1)).optional(),
|
|
configValues: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
applicationId: z.string().guid().optional(),
|
|
}).refine(
|
|
(value) => Boolean(value.galleryKey) !== Boolean(value.link),
|
|
{ message: "Provide exactly one of galleryKey or link" },
|
|
);
|
|
|
|
export type ConnectToolApp = z.infer<typeof connectToolAppSchema>;
|
|
|
|
export const reconnectToolAppSchema = z.object({
|
|
credentialValues: z.record(z.string().trim().min(1).max(200), z.string().min(1)),
|
|
});
|
|
|
|
export type ReconnectToolApp = z.infer<typeof reconnectToolAppSchema>;
|
|
|
|
export const finishToolAppSchema = z.object({
|
|
enabledCatalogEntryIds: z.array(z.string().guid()).max(500).default([]),
|
|
askFirstCatalogEntryIds: z.array(z.string().guid()).max(500).default([]),
|
|
reviewedCatalogEntryIds: z.array(z.string().guid()).max(500).optional(),
|
|
access: z.union([
|
|
z.literal("all_agents"),
|
|
z.object({ agentIds: z.array(z.string().guid()).min(1).max(250) }),
|
|
]),
|
|
});
|
|
|
|
export type FinishToolApp = z.infer<typeof finishToolAppSchema>;
|
|
|
|
export const upsertToolCatalogEntrySchema = z.object({
|
|
applicationId: z.string().guid(),
|
|
connectionId: z.string().guid(),
|
|
entryKind: toolCatalogEntryKindSchema.default("tool"),
|
|
toolName: z.string().trim().min(1).max(240),
|
|
title: z.string().trim().max(240).optional().nullable(),
|
|
description: z.string().max(8000).optional().nullable(),
|
|
inputSchema: jsonSchemaSchema.optional().nullable(),
|
|
outputSchema: jsonSchemaSchema.optional().nullable(),
|
|
annotations: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
riskLevel: toolRiskLevelSchema.default("medium"),
|
|
isReadOnly: z.boolean().default(false),
|
|
isWrite: z.boolean().default(false),
|
|
isDestructive: z.boolean().default(false),
|
|
status: toolCatalogEntryStatusSchema.default("active"),
|
|
version: z.string().trim().max(200).optional().nullable(),
|
|
schemaHash: z.string().trim().max(128).optional().nullable(),
|
|
});
|
|
|
|
export type UpsertToolCatalogEntry = z.infer<typeof upsertToolCatalogEntrySchema>;
|
|
|
|
export const createToolProfileSchema = z.object({
|
|
profileKey: z.string().trim().min(1).max(160).regex(safeKeyPattern),
|
|
name: z.string().trim().min(1).max(160),
|
|
description: z.string().max(4000).optional().nullable(),
|
|
status: toolProfileStatusSchema.default("active"),
|
|
defaultAction: toolProfileDefaultActionSchema.default("deny"),
|
|
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolProfile = z.infer<typeof createToolProfileSchema>;
|
|
|
|
export const updateToolProfileSchema = objectWithoutDefaults(createToolProfileSchema).partial().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "At least one tool profile field is required" },
|
|
);
|
|
|
|
export type UpdateToolProfile = z.infer<typeof updateToolProfileSchema>;
|
|
|
|
export const createToolProfileEntrySchema = z.object({
|
|
profileId: z.string().guid(),
|
|
selectorType: toolProfileEntrySelectorTypeSchema,
|
|
effect: toolProfileEntryEffectSchema.default("include"),
|
|
applicationId: z.string().guid().optional().nullable(),
|
|
connectionId: z.string().guid().optional().nullable(),
|
|
catalogEntryId: z.string().guid().optional().nullable(),
|
|
toolName: z.string().trim().min(1).max(240).optional().nullable(),
|
|
riskLevel: toolRiskLevelSchema.optional().nullable(),
|
|
conditions: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolProfileEntry = z.infer<typeof createToolProfileEntrySchema>;
|
|
|
|
export const createToolProfileEntryForProfileSchema = createToolProfileEntrySchema.omit({ profileId: true });
|
|
|
|
export type CreateToolProfileEntryForProfile = z.infer<typeof createToolProfileEntryForProfileSchema>;
|
|
|
|
export const updateToolProfileEntrySchema = objectWithoutDefaults(createToolProfileEntryForProfileSchema).partial().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "At least one tool profile entry field is required" },
|
|
);
|
|
|
|
export type UpdateToolProfileEntry = z.infer<typeof updateToolProfileEntrySchema>;
|
|
|
|
export const createToolProfileWithEntriesSchema = createToolProfileSchema.extend({
|
|
entries: z.array(createToolProfileEntryForProfileSchema).max(250).optional(),
|
|
});
|
|
|
|
export type CreateToolProfileWithEntries = z.infer<typeof createToolProfileWithEntriesSchema>;
|
|
|
|
export const duplicateToolProfileSchema = z.object({
|
|
name: z.string().trim().min(1).max(160),
|
|
includeAssignments: z.boolean().default(false),
|
|
});
|
|
|
|
export type DuplicateToolProfile = z.infer<typeof duplicateToolProfileSchema>;
|
|
|
|
export const updateToolProfileWithEntriesSchema = objectWithoutDefaults(createToolProfileSchema).partial().extend({
|
|
entries: z.array(createToolProfileEntryForProfileSchema).max(250).optional(),
|
|
}).refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "At least one tool profile field is required" },
|
|
);
|
|
|
|
export type UpdateToolProfileWithEntries = z.infer<typeof updateToolProfileWithEntriesSchema>;
|
|
|
|
export const reviewToolProfileNewToolsSchema = z.object({
|
|
decisions: z.array(z.object({
|
|
catalogEntryId: z.string().guid(),
|
|
decision: z.enum(["allow", "keep_blocked"]),
|
|
})).min(1).max(250),
|
|
});
|
|
|
|
export type ReviewToolProfileNewTools = z.infer<typeof reviewToolProfileNewToolsSchema>;
|
|
|
|
export const deleteToolProfileSchema = z.object({
|
|
force: z.boolean().default(false),
|
|
reassignToProfileId: z.string().guid().optional(),
|
|
}).prefault({});
|
|
|
|
export type DeleteToolProfile = z.infer<typeof deleteToolProfileSchema>;
|
|
|
|
export const createToolProfileBindingSchema = z.object({
|
|
profileId: z.string().guid(),
|
|
targetType: toolProfileBindingTargetTypeSchema,
|
|
targetId: z.string().trim().min(1).max(200),
|
|
priority: z.number().int().min(0).max(10000).default(100),
|
|
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolProfileBinding = z.infer<typeof createToolProfileBindingSchema>;
|
|
|
|
export const createToolProfileBindingForProfileSchema = createToolProfileBindingSchema.omit({ profileId: true });
|
|
|
|
export type CreateToolProfileBindingForProfile = z.infer<typeof createToolProfileBindingForProfileSchema>;
|
|
|
|
export const unbindToolProfileBindingSchema = createToolProfileBindingForProfileSchema.pick({
|
|
targetType: true,
|
|
targetId: true,
|
|
});
|
|
|
|
export type UnbindToolProfileBinding = z.infer<typeof unbindToolProfileBindingSchema>;
|
|
|
|
const headerNameSchema = z.string().trim().min(1).max(120).regex(/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/);
|
|
|
|
export const toolMcpGatewayAuthConfigSchema = z.object({
|
|
version: z.literal(1).default(1),
|
|
bearer: z.object({
|
|
enabled: z.boolean().default(true),
|
|
tokenPrefix: z.literal("pcgw").default("pcgw"),
|
|
defaultTtlSeconds: z.number().int().positive().max(31_536_000).nullable().default(7_776_000),
|
|
requireFiniteExpiry: z.boolean().default(true),
|
|
longLivedTokenRequiresOverride: z.boolean().default(true),
|
|
}).prefault({}),
|
|
oauth: z.object({
|
|
enabled: z.literal(false).default(false),
|
|
reservedFor: z.literal("v1_5").default("v1_5"),
|
|
protectedResourceMetadataPath: z.string().trim().max(240).optional().nullable(),
|
|
dynamicClientRegistration: z.literal(false).optional(),
|
|
authorizationCodePkce: z.literal(false).optional(),
|
|
}).prefault({}),
|
|
});
|
|
|
|
export const toolMcpGatewayHeaderPolicySchema = z.object({
|
|
version: z.literal(1).default(1),
|
|
callerPassthrough: z.object({
|
|
enabled: z.boolean().default(false),
|
|
allowedHeaders: z.array(headerNameSchema).max(50).default([]),
|
|
}).prefault({}),
|
|
staticHeaders: z.array(z.object({
|
|
name: headerNameSchema,
|
|
valueRef: z.string().trim().max(240).optional().nullable(),
|
|
value: z.string().max(4000).optional().nullable(),
|
|
})).max(50).default([]),
|
|
generatedMetadata: z.object({
|
|
enabled: z.boolean().default(false),
|
|
allowedHeaders: z.array(headerNameSchema).max(20).default([]),
|
|
}).prefault({}),
|
|
responseHeaders: z.object({
|
|
forwardMcpRequiredHeaders: z.boolean().default(true),
|
|
forwardSafeCacheHeaders: z.boolean().default(true),
|
|
}).prefault({}),
|
|
});
|
|
|
|
export const toolMcpGatewayMetadataPolicySchema = z.object({
|
|
version: z.literal(1).default(1),
|
|
forwardCompanyId: z.boolean().default(false),
|
|
forwardGatewayId: z.boolean().default(false),
|
|
forwardProjectId: z.boolean().default(false),
|
|
forwardIssueId: z.boolean().default(false),
|
|
forwardAgentId: z.boolean().default(false),
|
|
forwardRunId: z.boolean().default(false),
|
|
forwardCorrelationId: z.boolean().default(true),
|
|
});
|
|
|
|
export const toolMcpGatewayOnDemandToolsConfigSchema = z.object({
|
|
enabled: z.boolean().default(false),
|
|
searchToolName: z.literal("search_tools").default("search_tools"),
|
|
runToolName: z.literal("run_tool").default("run_tool"),
|
|
});
|
|
|
|
export const createToolMcpGatewaySchema = z.object({
|
|
name: z.string().trim().min(1).max(160),
|
|
slug: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional(),
|
|
displaySlug: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional(),
|
|
description: z.string().max(4000).optional().nullable(),
|
|
profileId: z.string().guid(),
|
|
defaultProfileMode: toolMcpGatewayDefaultProfileModeSchema.default("gateway_only").optional(),
|
|
contextScopeType: toolMcpGatewayContextScopeTypeSchema.default("none").optional(),
|
|
contextScopeId: z.string().trim().min(1).max(200).optional().nullable(),
|
|
agentId: z.string().guid().optional().nullable(),
|
|
projectId: z.string().guid().optional().nullable(),
|
|
issueId: z.string().guid().optional().nullable(),
|
|
approvalIssueId: z.string().guid().optional().nullable(),
|
|
authConfig: toolMcpGatewayAuthConfigSchema.optional(),
|
|
headerPolicy: toolMcpGatewayHeaderPolicySchema.optional(),
|
|
metadataPolicy: toolMcpGatewayMetadataPolicySchema.optional(),
|
|
onDemandToolsConfig: toolMcpGatewayOnDemandToolsConfigSchema.optional(),
|
|
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolMcpGateway = z.infer<typeof createToolMcpGatewaySchema>;
|
|
|
|
export const updateToolMcpGatewaySchema = objectWithoutDefaults(createToolMcpGatewaySchema)
|
|
.partial()
|
|
.extend({ status: toolMcpGatewayStatusSchema.optional() })
|
|
.refine((value) => Object.keys(value).length > 0, { message: "At least one gateway field is required" });
|
|
|
|
export type UpdateToolMcpGateway = z.infer<typeof updateToolMcpGatewaySchema>;
|
|
|
|
export const createToolMcpGatewayTokenSchema = z.object({
|
|
name: z.string().trim().min(1).max(160),
|
|
subjectType: toolMcpGatewayTokenSubjectTypeSchema.default("gateway_client").optional(),
|
|
subjectId: z.string().trim().min(1).max(240).optional().nullable(),
|
|
clientLabel: z.string().trim().min(1).max(160),
|
|
ownerNote: z.string().trim().min(1).max(1000),
|
|
allowedActions: z.array(toolMcpGatewayTokenActionSchema).min(1).max(TOOL_MCP_GATEWAY_TOKEN_ACTIONS.length).default(["tools/list", "tools/call"]).optional(),
|
|
expiresAt: z.coerce.date().optional().nullable(),
|
|
expiryOverrideReason: z.string().trim().min(1).max(1000).optional().nullable(),
|
|
}).superRefine((value, ctx) => {
|
|
if (value.subjectType && value.subjectType !== "gateway_client") {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["subjectType"],
|
|
message: "Public V1 token minting only supports gateway_client subjects; heartbeat_run is runtime-managed, while board_user and agent are reserved for later OAuth/user-bound flows.",
|
|
});
|
|
}
|
|
if (value.expiresAt === null && !value.expiryOverrideReason) {
|
|
ctx.addIssue({
|
|
code: z.ZodIssueCode.custom,
|
|
path: ["expiryOverrideReason"],
|
|
message: "Non-expiring gateway tokens require an override reason.",
|
|
});
|
|
}
|
|
});
|
|
|
|
export type CreateToolMcpGatewayToken = z.infer<typeof createToolMcpGatewayTokenSchema>;
|
|
|
|
const argumentConditionSchema = z.object({
|
|
fieldEquals: z.record(z.string().trim().min(1).max(120), z.unknown()).optional(),
|
|
fieldNotEquals: z.record(z.string().trim().min(1).max(120), z.unknown()).optional(),
|
|
fieldIn: z.record(z.string().trim().min(1).max(120), z.array(z.unknown()).min(1).max(100)).optional(),
|
|
fieldMatches: z.record(z.string().trim().min(1).max(120), z.string().trim().min(1).max(500)).optional(),
|
|
fieldExists: z.array(z.string().trim().min(1).max(120)).max(100).optional(),
|
|
fieldAbsent: z.array(z.string().trim().min(1).max(120)).max(100).optional(),
|
|
}).strict().refine(
|
|
(value) => Object.values(value).some((nested) => Array.isArray(nested) ? nested.length > 0 : Boolean(nested && Object.keys(nested).length > 0)),
|
|
{ message: "Argument conditions must include at least one field predicate" },
|
|
);
|
|
|
|
const timeWindowConditionSchema = z.object({
|
|
startAt: z.string().trim().datetime({ offset: true }).optional(),
|
|
endAt: z.string().trim().datetime({ offset: true }).optional(),
|
|
daysOfWeekUtc: z.array(z.number().int().min(0).max(6)).max(7).optional(),
|
|
startHourUtc: z.number().int().min(0).max(23).optional(),
|
|
endHourUtc: z.number().int().min(0).max(24).optional(),
|
|
}).strict().refine(
|
|
(value) => value.startAt || value.endAt || value.daysOfWeekUtc?.length || value.startHourUtc !== undefined || value.endHourUtc !== undefined,
|
|
{ message: "timeWindow must include at least one bound" },
|
|
);
|
|
|
|
const actorConditionSchema = z.object({
|
|
actorType: z.enum(["agent", "user", "system", "plugin"]).optional(),
|
|
actorTypes: z.array(z.enum(["agent", "user", "system", "plugin"])).max(20).optional(),
|
|
agentId: z.string().guid().optional(),
|
|
agentIds: z.array(z.string().guid()).max(100).optional(),
|
|
}).strict();
|
|
|
|
const contextConditionSchema = z.object({
|
|
projectId: z.string().guid().optional(),
|
|
projectIds: z.array(z.string().guid()).max(100).optional(),
|
|
routineId: z.string().guid().optional(),
|
|
routineIds: z.array(z.string().guid()).max(100).optional(),
|
|
issueId: z.string().guid().optional(),
|
|
issueIds: z.array(z.string().guid()).max(100).optional(),
|
|
requireIssue: z.boolean().optional(),
|
|
requireProject: z.boolean().optional(),
|
|
requireRoutine: z.boolean().optional(),
|
|
}).strict();
|
|
|
|
const credentialScopeConditionSchema = z.object({
|
|
applicationId: z.string().guid().optional(),
|
|
applicationIds: z.array(z.string().guid()).max(100).optional(),
|
|
connectionId: z.string().guid().optional(),
|
|
connectionIds: z.array(z.string().guid()).max(100).optional(),
|
|
catalogEntryId: z.string().guid().optional(),
|
|
catalogEntryIds: z.array(z.string().guid()).max(100).optional(),
|
|
applicationKey: z.string().trim().min(1).max(160).optional(),
|
|
applicationKeys: z.array(z.string().trim().min(1).max(160)).max(100).optional(),
|
|
providerType: z.string().trim().min(1).max(160).optional(),
|
|
providerTypes: z.array(z.string().trim().min(1).max(160)).max(100).optional(),
|
|
}).strict();
|
|
|
|
export const toolPolicyConditionsSchema = z.object({
|
|
arguments: argumentConditionSchema.optional(),
|
|
args: argumentConditionSchema.optional(),
|
|
actor: actorConditionSchema.optional(),
|
|
context: contextConditionSchema.optional(),
|
|
risk: z.object({
|
|
levels: z.array(toolRiskLevelSchema).max(20).optional(),
|
|
max: toolRiskLevelSchema.optional(),
|
|
isWrite: z.boolean().optional(),
|
|
isDestructive: z.boolean().optional(),
|
|
}).strict().optional(),
|
|
credentialScope: credentialScopeConditionSchema.optional(),
|
|
trustBoundary: z.object({
|
|
providerType: z.string().trim().min(1).max(160).optional(),
|
|
providerTypes: z.array(z.string().trim().min(1).max(160)).max(100).optional(),
|
|
applicationKey: z.string().trim().min(1).max(160).optional(),
|
|
applicationKeys: z.array(z.string().trim().min(1).max(160)).max(100).optional(),
|
|
remoteHttpOnly: z.boolean().optional(),
|
|
paperclipSelfOnly: z.boolean().optional(),
|
|
}).strict().optional(),
|
|
timeWindow: timeWindowConditionSchema.optional(),
|
|
}).strict().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "Tool policy conditions must include at least one supported condition group" },
|
|
);
|
|
|
|
export const createToolPolicySchema = z.object({
|
|
name: z.string().trim().min(1).max(160),
|
|
description: z.string().max(4000).optional().nullable(),
|
|
policyType: toolPolicyTypeSchema,
|
|
priority: z.number().int().min(0).max(10000).default(100),
|
|
enabled: z.boolean().default(true),
|
|
selectors: z.record(z.string(), z.unknown()).default({}),
|
|
conditions: toolPolicyConditionsSchema.optional().nullable(),
|
|
config: z.record(z.string(), z.unknown()).optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolPolicy = z.infer<typeof createToolPolicySchema>;
|
|
|
|
export const updateToolPolicySchema = objectWithoutDefaults(createToolPolicySchema).partial().refine(
|
|
(value) => Object.keys(value).length > 0,
|
|
{ message: "At least one tool policy field is required" },
|
|
);
|
|
|
|
export type UpdateToolPolicy = z.infer<typeof updateToolPolicySchema>;
|
|
|
|
export const reorderToolPoliciesSchema = z.object({
|
|
policyIds: z.array(z.string().guid()).min(1).max(500),
|
|
});
|
|
|
|
export type ReorderToolPolicies = z.infer<typeof reorderToolPoliciesSchema>;
|
|
|
|
export const duplicateToolPolicySchema = z.object({
|
|
name: z.string().trim().min(1).max(160).optional(),
|
|
});
|
|
|
|
export type DuplicateToolPolicy = z.infer<typeof duplicateToolPolicySchema>;
|
|
|
|
export const createToolInvocationSchema = z.object({
|
|
idempotencyKey: z.string().trim().min(1).max(300).optional().nullable(),
|
|
issueId: z.string().guid().optional().nullable(),
|
|
runId: z.string().guid().optional().nullable(),
|
|
applicationId: z.string().guid().optional().nullable(),
|
|
connectionId: z.string().guid().optional().nullable(),
|
|
catalogEntryId: z.string().guid().optional().nullable(),
|
|
toolName: z.string().trim().min(1).max(240),
|
|
argumentsHash: z.string().trim().max(128).optional().nullable(),
|
|
argumentsSummary: toolRedactedValueSummarySchema.optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolInvocation = z.infer<typeof createToolInvocationSchema>;
|
|
|
|
export const createToolActionRequestSchema = z.object({
|
|
invocationId: z.string().guid(),
|
|
issueId: z.string().guid().optional().nullable(),
|
|
canonicalArgumentsHash: z.string().trim().min(1).max(128),
|
|
canonicalArgumentsSummary: toolRedactedValueSummarySchema,
|
|
signedArguments: z.string().trim().max(4096).optional().nullable(),
|
|
previewMarkdown: z.string().max(20_000).optional().nullable(),
|
|
expiresAt: z.coerce.date().optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolActionRequest = z.infer<typeof createToolActionRequestSchema>;
|
|
|
|
export const toolConnectionTestCallSchema = z.object({
|
|
agentId: z.string().guid(),
|
|
toolName: z.string().trim().min(1).max(240),
|
|
parameters: z.unknown().optional(),
|
|
});
|
|
|
|
export type ToolConnectionTestCallInput = z.infer<typeof toolConnectionTestCallSchema>;
|
|
|
|
export const importMcpJsonSchema = z.object({
|
|
mcpJson: z.union([z.string(), z.record(z.string(), z.unknown())]),
|
|
});
|
|
|
|
export type ImportMcpJson = z.infer<typeof importMcpJsonSchema>;
|
|
|
|
export const toolAccessSelectorSchema = z.object({
|
|
actorType: z.enum(["agent", "user", "system", "plugin"]).optional(),
|
|
agentId: z.string().guid().optional(),
|
|
agentIds: z.array(z.string().guid()).optional(),
|
|
projectId: z.string().guid().optional(),
|
|
projectIds: z.array(z.string().guid()).optional(),
|
|
routineId: z.string().guid().optional(),
|
|
routineIds: z.array(z.string().guid()).optional(),
|
|
issueId: z.string().guid().optional(),
|
|
issueIds: z.array(z.string().guid()).optional(),
|
|
gatewayId: z.string().guid().optional(),
|
|
gatewayIds: z.array(z.string().guid()).optional(),
|
|
gatewayPublicId: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional(),
|
|
gatewayPublicIds: z.array(z.string().trim().min(1).max(120).regex(safeKeyPattern)).optional(),
|
|
gatewayTokenId: z.string().guid().optional(),
|
|
gatewayTokenIds: z.array(z.string().guid()).optional(),
|
|
clientSubjectType: toolMcpGatewayTokenSubjectTypeSchema.optional(),
|
|
clientSubjectTypes: z.array(toolMcpGatewayTokenSubjectTypeSchema).optional(),
|
|
clientName: z.string().trim().min(1).max(160).optional(),
|
|
clientNames: z.array(z.string().trim().min(1).max(160)).optional(),
|
|
externalClient: z.boolean().optional(),
|
|
applicationId: z.string().guid().optional(),
|
|
applicationIds: z.array(z.string().guid()).optional(),
|
|
connectionId: z.string().guid().optional(),
|
|
connectionIds: z.array(z.string().guid()).optional(),
|
|
catalogEntryId: z.string().guid().optional(),
|
|
catalogEntryIds: z.array(z.string().guid()).optional(),
|
|
toolName: z.string().trim().min(1).max(240).optional(),
|
|
toolNames: z.array(z.string().trim().min(1).max(240)).optional(),
|
|
riskLevel: toolRiskLevelSchema.optional(),
|
|
riskLevels: z.array(toolRiskLevelSchema).optional(),
|
|
});
|
|
|
|
export const toolRateLimitRuleSchema = z.object({
|
|
limit: z.number().int().positive().max(1_000_000),
|
|
windowSeconds: z.number().int().positive().max(31_536_000),
|
|
keyBy: z.array(z.enum(["company", "agent", "application", "connection", "tool"])).optional(),
|
|
});
|
|
|
|
export const toolTrustRuleArgumentFiltersSchema = z.object({
|
|
allowAny: z.boolean().optional(),
|
|
exactHash: z.string().trim().regex(/^[a-f0-9]{64}$/i).optional().nullable(),
|
|
allowedHashes: z.array(z.string().trim().regex(/^[a-f0-9]{64}$/i)).max(100).optional(),
|
|
fieldEquals: z.record(z.string().trim().min(1).max(120), z.unknown()).optional(),
|
|
fieldNotEquals: z.record(z.string().trim().min(1).max(120), z.unknown()).optional(),
|
|
fieldIn: z.record(z.string().trim().min(1).max(120), z.array(z.unknown()).min(1).max(100)).optional(),
|
|
fieldMatches: z.record(z.string().trim().min(1).max(120), z.string().trim().min(1).max(500)).optional(),
|
|
fieldExists: z.array(z.string().trim().min(1).max(120)).max(100).optional(),
|
|
fieldAbsent: z.array(z.string().trim().min(1).max(120)).max(100).optional(),
|
|
}).refine(
|
|
(value) => value.allowAny === true
|
|
|| Boolean(value.exactHash)
|
|
|| Boolean(value.allowedHashes?.length)
|
|
|| Boolean(value.fieldEquals && Object.keys(value.fieldEquals).length > 0)
|
|
|| Boolean(value.fieldNotEquals && Object.keys(value.fieldNotEquals).length > 0)
|
|
|| Boolean(value.fieldIn && Object.keys(value.fieldIn).length > 0)
|
|
|| Boolean(value.fieldMatches && Object.keys(value.fieldMatches).length > 0)
|
|
|| Boolean(value.fieldExists?.length)
|
|
|| Boolean(value.fieldAbsent?.length),
|
|
{ message: "Trust-rule argument filters must specify allowAny, a hash filter, or a field predicate" },
|
|
);
|
|
|
|
export const toolTrustRuleScopeSchema = z.object({
|
|
includeAgent: z.boolean().optional(),
|
|
includeProject: z.boolean().optional(),
|
|
includeIssue: z.boolean().optional(),
|
|
includeApplication: z.boolean().optional(),
|
|
includeConnection: z.boolean().optional(),
|
|
includeCatalogEntry: z.boolean().optional(),
|
|
includeTool: z.boolean().optional(),
|
|
});
|
|
|
|
export const toolTrustRuleBatchApprovalSchema = z.object({
|
|
enabled: z.boolean().optional(),
|
|
maxBatchSize: z.number().int().positive().max(100).optional(),
|
|
windowSeconds: z.number().int().positive().max(31_536_000).optional(),
|
|
});
|
|
|
|
export const createToolTrustRuleFromActionRequestSchema = z.object({
|
|
name: z.string().trim().min(1).max(160).optional(),
|
|
description: z.string().max(4000).optional().nullable(),
|
|
priority: z.number().int().min(0).max(10000).default(40),
|
|
approvalThreshold: z.number().int().min(1).max(50).default(2),
|
|
selectors: toolAccessSelectorSchema.optional(),
|
|
scope: toolTrustRuleScopeSchema.optional(),
|
|
argumentFilters: toolTrustRuleArgumentFiltersSchema.optional(),
|
|
expiresAt: z.coerce.date().optional().nullable(),
|
|
batchApproval: toolTrustRuleBatchApprovalSchema.optional().nullable(),
|
|
});
|
|
|
|
export type CreateToolTrustRuleFromActionRequest = z.infer<typeof createToolTrustRuleFromActionRequestSchema>;
|
|
|
|
export const revokeToolTrustRuleSchema = z.object({
|
|
reason: z.string().trim().max(1000).optional().nullable(),
|
|
});
|
|
|
|
export type RevokeToolTrustRule = z.infer<typeof revokeToolTrustRuleSchema>;
|
|
|
|
export const toolPolicyTestRequestSchema = z.object({
|
|
companyId: z.string().guid(),
|
|
actor: z.object({
|
|
actorType: z.enum(["agent", "user", "system", "plugin"]),
|
|
actorId: z.string().trim().min(1).max(240),
|
|
agentId: z.string().guid().optional().nullable(),
|
|
}),
|
|
runContext: z.object({
|
|
heartbeatRunId: z.string().guid().optional().nullable(),
|
|
issueId: z.string().guid().optional().nullable(),
|
|
projectId: z.string().guid().optional().nullable(),
|
|
routineId: z.string().guid().optional().nullable(),
|
|
gatewayId: z.string().guid().optional().nullable(),
|
|
gatewayPublicId: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional().nullable(),
|
|
gatewayTokenId: z.string().guid().optional().nullable(),
|
|
clientSubjectType: toolMcpGatewayTokenSubjectTypeSchema.optional().nullable(),
|
|
clientSubjectId: z.string().trim().min(1).max(240).optional().nullable(),
|
|
clientName: z.string().trim().min(1).max(160).optional().nullable(),
|
|
externalClient: z.boolean().optional().nullable(),
|
|
}).optional().nullable(),
|
|
request: z.object({
|
|
applicationId: z.string().guid().optional().nullable(),
|
|
connectionId: z.string().guid().optional().nullable(),
|
|
catalogEntryId: z.string().guid().optional().nullable(),
|
|
toolName: z.string().trim().min(1).max(240),
|
|
arguments: z.unknown().optional(),
|
|
idempotencyKey: z.string().trim().min(1).max(512).optional().nullable(),
|
|
sideEffecting: z.boolean().optional(),
|
|
}),
|
|
consumeRateLimit: z.boolean().optional(),
|
|
writeAuditEvent: z.boolean().optional(),
|
|
});
|
|
|
|
export type ToolPolicyTestRequestInput = z.infer<typeof toolPolicyTestRequestSchema>;
|