@relvo/mcp 0.1.2 → 0.1.3
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/README.md +90 -5
- package/bin/relvo-mcp.mjs +1 -1
- package/dist/client/agent-run.js +681 -0
- package/dist/client/browser.js +650 -0
- package/dist/client/evm-wallet.js +214 -0
- package/dist/client/index.js +3 -360
- package/dist/client/local-input.js +18 -11
- package/dist/client/local-profile.js +22 -110
- package/dist/client/local-setup.js +0 -1
- package/dist/client/tool-name-hints.js +48 -0
- package/dist/client/wallet-access.js +207 -0
- package/dist/mcp/agent-server.js +237 -0
- package/dist/mcp/context.js +3 -2
- package/dist/mcp/host-schema.js +47 -0
- package/dist/mcp/instructions.js +12 -2
- package/dist/mcp/local-upload.js +12 -4
- package/dist/mcp/operations.js +30 -0
- package/dist/mcp/runtime.js +25 -5
- package/dist/mcp/server.js +191 -37
- package/dist/mcp/version.js +1 -0
- package/dist/schema/accountRequestMethods.js +1 -0
- package/dist/schema/cronValidator.js +150 -0
- package/dist/schema/platformApiKey.js +5 -5
- package/dist/schema/platformBillingConstants.js +3 -0
- package/dist/schema/platformCapabilityFamilies.js +217 -0
- package/dist/schema/platformConnectionCatalog.js +20 -3
- package/dist/schema/platformConnectionPolicy.js +26 -0
- package/dist/schema/platformCustomTools.js +113 -0
- package/dist/schema/platformFunding.js +9 -0
- package/dist/schema/platformHttpConstraints.js +7 -0
- package/dist/schema/platformMcpTools.js +7 -0
- package/dist/schema/platformMetaTools.js +8 -6
- package/dist/schema/platformMonitorSchedule.js +123 -0
- package/dist/schema/platformMonitors.js +159 -0
- package/dist/schema/platformOAuth.js +7 -0
- package/dist/schema/platformPublicExecution.js +53 -15
- package/dist/schema/platformRoutes.js +61 -1
- package/dist/schema/platformSkills.js +1 -1
- package/dist/schema/platformTeamSecretName.js +3 -0
- package/dist/schema/platformTeamSkills.js +49 -0
- package/dist/schema/platformToolAccess.js +13 -0
- package/dist/schema/platformTriggers.js +152 -0
- package/dist/schema/platformWorkflows.js +100 -0
- package/dist/schema/scheduleTimeZone.js +15 -0
- package/dist/schema/toolDiscovery.js +20 -3
- package/dist/schema/toolInputRepair.js +110 -0
- package/dist/schema/toolResultContext.js +1 -1
- package/package.json +1 -1
- package/dist/schema/amazonAds.js +0 -13
- package/dist/schema/oauth2.js +0 -64
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { projectScopeSchema, platformJsonObjectSchema, platformMicrosSchema } from "./platformPublicExecution.js";
|
|
3
|
+
import { platformMonitorCronSchema, platformMonitorIntervalSchema, platformMonitorTimeZoneSchema } from "./platformMonitorSchedule.js";
|
|
4
|
+
export { PLATFORM_MONITOR_INTERVALS, platformMonitorIntervalSchema } from "./platformMonitorSchedule.js";
|
|
5
|
+
export const PLATFORM_MONITOR_LIMITS = {
|
|
6
|
+
perProject: 25,
|
|
7
|
+
nameChars: 80,
|
|
8
|
+
eventsPage: 100,
|
|
9
|
+
eventItemBytes: 8_192,
|
|
10
|
+
snapshotItems: 500,
|
|
11
|
+
retentionDays: 30,
|
|
12
|
+
popularMinimumOrganizations: 3,
|
|
13
|
+
popularPage: 50,
|
|
14
|
+
};
|
|
15
|
+
export const PLATFORM_MONITOR_DESTINATION_LIMITS = {
|
|
16
|
+
perMonitor: 5,
|
|
17
|
+
emailRecipients: 5,
|
|
18
|
+
labelChars: 80,
|
|
19
|
+
urlChars: 512,
|
|
20
|
+
digestEvents: 10,
|
|
21
|
+
};
|
|
22
|
+
export const PLATFORM_MONITOR_EMAIL_PRICE_MICROS = 900;
|
|
23
|
+
export const platformMonitorDestinationKindSchema = z.enum(["webhook", "slack", "discord", "email"]);
|
|
24
|
+
const httpsUrl = (value) => {
|
|
25
|
+
try {
|
|
26
|
+
const url = new URL(value);
|
|
27
|
+
return url.protocol === "https:" && !url.username && !url.password && url.hash === "" ? url : null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export const isPlatformWebhookUrl = (value) => {
|
|
34
|
+
const url = httpsUrl(value);
|
|
35
|
+
return Boolean(url && url.port === "");
|
|
36
|
+
};
|
|
37
|
+
export const isPlatformSlackWebhookUrl = (value) => {
|
|
38
|
+
const url = httpsUrl(value);
|
|
39
|
+
return Boolean(url && url.hostname === "hooks.slack.com" && url.port === "" && url.search === "" && /^\/services\/[A-Za-z0-9]+\/[A-Za-z0-9]+\/[A-Za-z0-9]+$/.test(url.pathname));
|
|
40
|
+
};
|
|
41
|
+
export const isPlatformDiscordWebhookUrl = (value) => {
|
|
42
|
+
const url = httpsUrl(value);
|
|
43
|
+
return Boolean(url && ["discord.com", "discordapp.com"].includes(url.hostname) && url.port === "" && url.search === "" &&
|
|
44
|
+
/^\/api(\/v\d{1,2})?\/webhooks\/\d{1,25}\/[A-Za-z0-9_-]{1,200}$/.test(url.pathname));
|
|
45
|
+
};
|
|
46
|
+
const destinationUrl = z.string().trim().max(PLATFORM_MONITOR_DESTINATION_LIMITS.urlChars);
|
|
47
|
+
const destinationLabel = z.string().trim().max(PLATFORM_MONITOR_DESTINATION_LIMITS.labelChars).default("");
|
|
48
|
+
const memberId = z.string().min(1).max(64);
|
|
49
|
+
export const platformMonitorDestinationInputSchema = z.discriminatedUnion("kind", [
|
|
50
|
+
z.object({ kind: z.literal("webhook"), label: destinationLabel, url: destinationUrl.refine(isPlatformWebhookUrl, "platform_monitor_destination_url_invalid") }).strict(),
|
|
51
|
+
z.object({ kind: z.literal("slack"), label: destinationLabel, url: destinationUrl.refine(isPlatformSlackWebhookUrl, "platform_monitor_destination_url_invalid") }).strict(),
|
|
52
|
+
z.object({ kind: z.literal("discord"), label: destinationLabel, url: destinationUrl.refine(isPlatformDiscordWebhookUrl, "platform_monitor_destination_url_invalid") }).strict(),
|
|
53
|
+
z.object({ kind: z.literal("email"), label: destinationLabel,
|
|
54
|
+
memberIds: z.array(memberId).min(1).max(PLATFORM_MONITOR_DESTINATION_LIMITS.emailRecipients) }).strict(),
|
|
55
|
+
]);
|
|
56
|
+
export const platformMonitorDestinationSchema = z.object({
|
|
57
|
+
id: z.string().regex(/^dst_[A-Za-z0-9_-]{1,100}$/),
|
|
58
|
+
kind: platformMonitorDestinationKindSchema,
|
|
59
|
+
label: z.string(),
|
|
60
|
+
target: z.string(),
|
|
61
|
+
memberIds: z.array(z.string()),
|
|
62
|
+
createdAt: z.string(),
|
|
63
|
+
lastDeliveredAt: z.string().nullable(),
|
|
64
|
+
lastStatus: z.enum(["ok", "failed"]).nullable(),
|
|
65
|
+
lastError: z.string().nullable(),
|
|
66
|
+
signingSecret: z.string().optional(),
|
|
67
|
+
});
|
|
68
|
+
export const platformMonitorRecipientSchema = z.object({ memberId, email: z.string(), name: z.string() });
|
|
69
|
+
const toolName = z.string().regex(/^[a-z][a-z0-9_]{1,63}$/);
|
|
70
|
+
export const PLATFORM_MONITOR_ID = /^mon_[A-Za-z0-9_-]{1,100}$/;
|
|
71
|
+
const monitorId = z.string().regex(PLATFORM_MONITOR_ID);
|
|
72
|
+
export const platformMonitorCreateSchema = z.object({
|
|
73
|
+
tool: toolName,
|
|
74
|
+
arguments: platformJsonObjectSchema.default({}),
|
|
75
|
+
provider: z.string().trim().max(64).default(""),
|
|
76
|
+
interval: platformMonitorIntervalSchema.optional().describe("Run every 15m, 1h (default) or 1d. Omit when using cron."),
|
|
77
|
+
cron: platformMonitorCronSchema.optional().describe("5-field cron for fixed times, at least 15 minutes between runs, for example '0 9 * * 1-5' (weekdays 09:00). Omit when using interval."),
|
|
78
|
+
timeZone: platformMonitorTimeZoneSchema.optional().describe("IANA time zone the cron is read in, for example Asia/Tokyo; UTC when omitted. Only with cron."),
|
|
79
|
+
name: z.string().trim().max(PLATFORM_MONITOR_LIMITS.nameChars).default(""),
|
|
80
|
+
maximumChargeMicrosPerRun: platformMicrosSchema.default(0),
|
|
81
|
+
destinations: z.array(platformMonitorDestinationInputSchema).max(PLATFORM_MONITOR_DESTINATION_LIMITS.perMonitor).default([]),
|
|
82
|
+
}).strict();
|
|
83
|
+
export const platformMonitorPoolSchema = z.object({
|
|
84
|
+
chargeCeilingMicros: platformMicrosSchema,
|
|
85
|
+
members: z.number().int().min(0),
|
|
86
|
+
shareMicros: platformMicrosSchema,
|
|
87
|
+
});
|
|
88
|
+
export const platformMonitorQuoteSchema = platformMonitorCreateSchema.pick({ tool: true, arguments: true, provider: true, interval: true, cron: true, timeZone: true }).strict();
|
|
89
|
+
export const platformMonitorQuoteResultSchema = platformMonitorPoolSchema.extend({
|
|
90
|
+
joined: z.boolean(),
|
|
91
|
+
payers: z.number().int().min(1),
|
|
92
|
+
});
|
|
93
|
+
export const platformMonitorResumeSchema = z.object({ maximumChargeMicrosPerRun: platformMicrosSchema.optional() }).strict();
|
|
94
|
+
export const platformMonitorSchema = z.object({
|
|
95
|
+
id: monitorId,
|
|
96
|
+
name: z.string(),
|
|
97
|
+
tool: toolName,
|
|
98
|
+
provider: z.string(),
|
|
99
|
+
arguments: platformJsonObjectSchema,
|
|
100
|
+
interval: platformMonitorIntervalSchema.nullable(),
|
|
101
|
+
cron: z.string().nullable().default(null),
|
|
102
|
+
timeZone: z.string().nullable().default(null),
|
|
103
|
+
subscribers: z.number().int().min(1),
|
|
104
|
+
lastCheckedAt: z.string().nullable(),
|
|
105
|
+
lastChangedAt: z.string().nullable(),
|
|
106
|
+
nextCheckAt: z.string().nullable(),
|
|
107
|
+
lastError: z.string().nullable(),
|
|
108
|
+
createdAt: z.string(),
|
|
109
|
+
maximumChargeMicrosPerRun: platformMicrosSchema,
|
|
110
|
+
pool: platformMonitorPoolSchema,
|
|
111
|
+
status: z.enum(["active", "suspended"]),
|
|
112
|
+
suspendedReason: z.string().nullable(),
|
|
113
|
+
destinations: z.array(platformMonitorDestinationSchema).default([]),
|
|
114
|
+
});
|
|
115
|
+
const changeValue = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
116
|
+
export const platformMonitorEventSchema = z.object({
|
|
117
|
+
id: z.string().regex(/^\d{1,20}$/),
|
|
118
|
+
monitorId: monitorId,
|
|
119
|
+
kind: z.enum(["added", "changed", "removed"]),
|
|
120
|
+
itemKey: z.string(),
|
|
121
|
+
title: z.string(),
|
|
122
|
+
url: z.string(),
|
|
123
|
+
item: platformJsonObjectSchema,
|
|
124
|
+
changes: z.array(z.object({ field: z.string(), before: changeValue, after: changeValue })),
|
|
125
|
+
detectedAt: z.string(),
|
|
126
|
+
});
|
|
127
|
+
export const platformMonitorEventsQuerySchema = z.object({
|
|
128
|
+
after: z.string().regex(/^\d{1,20}$/).optional(),
|
|
129
|
+
limit: z.coerce.number().int().min(1).max(PLATFORM_MONITOR_LIMITS.eventsPage).default(50),
|
|
130
|
+
}).strict();
|
|
131
|
+
export const platformMonitorEventsSchema = z.object({ events: z.array(platformMonitorEventSchema), nextAfter: z.string().nullable() });
|
|
132
|
+
export const platformPopularMonitorSchema = z.object({
|
|
133
|
+
tool: toolName, provider: z.string(), arguments: platformJsonObjectSchema,
|
|
134
|
+
interval: platformMonitorIntervalSchema.nullable(), cron: z.string().nullable().default(null), timeZone: z.string().nullable().default(null),
|
|
135
|
+
organizations: z.number().int().min(1),
|
|
136
|
+
chargeCeilingMicros: platformMicrosSchema,
|
|
137
|
+
});
|
|
138
|
+
export const platformMonitorableToolSchema = z.object({ name: toolName, provider: z.string(), chargeCeilingMicros: platformMicrosSchema });
|
|
139
|
+
export function platformMonitorWire(monitor) {
|
|
140
|
+
const { cron, timeZone, destinations, ...rest } = monitor;
|
|
141
|
+
return { ...rest, ...(cron == null ? {} : { cron }), ...(timeZone == null ? {} : { timeZone }), ...(destinations?.length ? { destinations } : {}) };
|
|
142
|
+
}
|
|
143
|
+
export const platformMonitorContracts = {
|
|
144
|
+
listDeveloperMonitors: { input: projectScopeSchema.strict(), output: z.object({ monitors: z.array(platformMonitorSchema) }).strict() },
|
|
145
|
+
createDeveloperMonitor: { input: projectScopeSchema.extend({ monitor: platformMonitorCreateSchema }).strict(), output: z.object({ monitor: platformMonitorSchema }).strict() },
|
|
146
|
+
deleteDeveloperMonitor: { input: projectScopeSchema.extend({ monitorId }).strict(), output: z.object({ success: z.literal(true) }).strict() },
|
|
147
|
+
quoteDeveloperMonitor: { input: projectScopeSchema.extend({ monitor: platformMonitorQuoteSchema }).strict(), output: z.object({ quote: platformMonitorQuoteResultSchema }).strict() },
|
|
148
|
+
resumeDeveloperMonitor: { input: projectScopeSchema.extend({ monitorId }).merge(platformMonitorResumeSchema).strict(), output: z.object({ monitor: platformMonitorSchema }).strict() },
|
|
149
|
+
listDeveloperMonitorEvents: {
|
|
150
|
+
input: projectScopeSchema.extend({ monitorId: monitorId.optional(), after: platformMonitorEventsQuerySchema.shape.after,
|
|
151
|
+
limit: z.number().int().min(1).max(PLATFORM_MONITOR_LIMITS.eventsPage).default(50) }).strict(),
|
|
152
|
+
output: platformMonitorEventsSchema,
|
|
153
|
+
},
|
|
154
|
+
addDeveloperMonitorDestination: { input: projectScopeSchema.extend({ monitorId, destination: platformMonitorDestinationInputSchema }).strict(), output: z.object({ monitor: platformMonitorSchema }).strict() },
|
|
155
|
+
removeDeveloperMonitorDestination: { input: projectScopeSchema.extend({ monitorId, destinationId: platformMonitorDestinationSchema.shape.id }).strict(), output: z.object({ monitor: platformMonitorSchema }).strict() },
|
|
156
|
+
listDeveloperMonitorRecipients: { input: projectScopeSchema.strict(), output: z.object({ recipients: z.array(platformMonitorRecipientSchema) }).strict() },
|
|
157
|
+
listPopularMonitors: { input: projectScopeSchema.strict(), output: z.object({ monitors: z.array(platformPopularMonitorSchema) }).strict() },
|
|
158
|
+
listMonitorableTools: { input: projectScopeSchema.strict(), output: z.object({ tools: z.array(platformMonitorableToolSchema) }).strict() },
|
|
159
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const platformOAuthScopeAlternativesSchema = z.array(z.array(z.string().min(1).max(256)).max(128)).min(1).max(128);
|
|
3
|
+
export const platformOAuthPermissionSchema = z.object({
|
|
4
|
+
status: z.enum(["available", "missing_scopes", "unknown_grant", "unknown_requirements", "not_applicable"]),
|
|
5
|
+
required: platformOAuthScopeAlternativesSchema.optional(),
|
|
6
|
+
missing: z.array(z.string()).optional(),
|
|
7
|
+
});
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { fitToolResultPage, TOOL_RESULT_CONTEXT_MAX_BYTES, toolResultContextSchema, toolResultPageSchema } from "./toolResultContext.js";
|
|
3
|
+
import { platformOAuthPermissionSchema } from "./platformOAuth.js";
|
|
3
4
|
export const PLATFORM_EXECUTION_MAX_STEPS = 20;
|
|
4
5
|
export const PLATFORM_EXECUTION_MAX_WAIT_SECONDS = 25;
|
|
5
6
|
export const PLATFORM_STEP_OUTPUT_MAX_BYTES = 1_048_576;
|
|
6
7
|
export const PLATFORM_EXECUTION_RESPONSE_MAX_BYTES = PLATFORM_EXECUTION_MAX_STEPS * PLATFORM_STEP_OUTPUT_MAX_BYTES + 65_536;
|
|
7
8
|
export const platformJsonObjectSchema = z.record(z.string(), z.json());
|
|
9
|
+
export const organizationScopeSchema = z.object({ developerOrganizationId: z.string().min(1).max(128) });
|
|
10
|
+
export const projectScopeSchema = organizationScopeSchema.extend({ developerProjectId: z.string().min(1).max(128) });
|
|
8
11
|
export const developerKeyScopeSchema = z.enum(["project:read", "usage:read", "tools:read", "tools:execute", "executions:read"]);
|
|
12
|
+
export const developerKeyAnyScopeSchema = z.enum([...developerKeyScopeSchema.options, "access:write"]);
|
|
9
13
|
export const PLATFORM_INPUT_MAX_BYTES = 12 * 1024 * 1024;
|
|
14
|
+
export const PLATFORM_FILE_CHUNK_MAX_BYTES = 32 * 1024 * 1024;
|
|
10
15
|
export const PLATFORM_UPLOAD_MAX_BYTES = 16 * 1024 * 1024 + 4096;
|
|
11
16
|
export const platformInputFileIdSchema = z.string().regex(/^f_[a-f0-9]{64}$/);
|
|
12
17
|
export const platformInputMimeSchema = z.enum(["image/jpeg", "image/png", "image/webp", "audio/wav", "audio/mpeg", "video/mp4", "video/quicktime"]);
|
|
13
|
-
export const
|
|
14
|
-
export const
|
|
18
|
+
export const platformInputFileMimeSchema = z.string().max(255).regex(/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/);
|
|
19
|
+
export const platformInputUploadSchema = z.object({ mimeType: platformInputFileMimeSchema, data: z.string().min(4).max(16 * 1024 * 1024),
|
|
20
|
+
purpose: z.literal("file").optional().describe("file stores opaque bytes for provider uploads, including GIF, documents, archives and local upload chunks. Omit for validated AI media.") }).strict();
|
|
21
|
+
export const platformInputFileSchema = z.object({ id: platformInputFileIdSchema, mimeType: platformInputFileMimeSchema,
|
|
15
22
|
sizeBytes: z.number().int().positive().max(PLATFORM_INPUT_MAX_BYTES), sha256: z.string().regex(/^[a-f0-9]{64}$/), expiresAt: z.iso.datetime() });
|
|
16
23
|
export const platformMicrosSchema = z.number().int().min(0).max(1_000_000_000_000);
|
|
17
24
|
export const platformToolNameSchema = z.string().regex(/^[a-z][a-z0-9_]{1,63}$/);
|
|
@@ -22,34 +29,55 @@ export const PLATFORM_SANDBOX_LIMITS = { code: 64000, sourceExecutions: 10, time
|
|
|
22
29
|
export const platformProviderChoiceSchema = z.string().trim().regex(/^(?:[a-z][a-z0-9_]{0,63})?$/)
|
|
23
30
|
.transform(value => value === "" || value === "auto" ? undefined : value).optional()
|
|
24
31
|
.describe("Omit, use auto, or use an empty string for automatic routing. A catalog provider ID strictly selects that compatible provider; no other provider is substituted.");
|
|
32
|
+
export const platformRelevanceCheckSchema = z.enum(["", "auto", "light"])
|
|
33
|
+
.transform(value => value === "light" ? "light" : undefined).optional()
|
|
34
|
+
.describe("Auto result filtering: auto (default) or light, a cheaper check that keeps rows it cannot decide.");
|
|
35
|
+
export const platformInvalidArgumentFieldsSchema = z.array(z.string().max(200).regex(/^[\w.-]*$/)).max(50);
|
|
25
36
|
export const PLATFORM_REQUEST_INTENT_MAX_CHARS = 1000;
|
|
26
37
|
export const platformRequestIntentSchema = z.string().trim().max(PLATFORM_REQUEST_INTENT_MAX_CHARS).transform(value => value || undefined).optional()
|
|
27
38
|
.describe("Brief user goal without secrets or private content. Empty means omitted.");
|
|
28
39
|
export const platformExecutionStatusSchema = z.enum(["queued", "running", "waiting", "succeeded", "failed", "cancelled", "needs_review"]);
|
|
29
|
-
export const platformFundingSchema = z.enum(["relvo", "
|
|
30
|
-
|
|
31
|
-
const platformModelFundingSchema = z.enum(["relvo", "toolhub", "provider"])
|
|
32
|
-
.transform(value => value === "toolhub" ? "relvo" : value);
|
|
40
|
+
export const platformFundingSchema = z.enum(["relvo", "provider", "mixed"]);
|
|
41
|
+
const platformModelFundingSchema = z.enum(["relvo", "provider"]);
|
|
33
42
|
const workspaceArgumentNames = new Set(["workspaceid", "workspaceids", "teamid", "provideraccountid", "provideraccountids", "datasetid", "datasetids", "knowledgebaseid", "sessionid", "skillid"]);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
export function validatePlatformArgumentIdentifiers(tool, input, context, field = "arguments") {
|
|
44
|
+
if (tool?.startsWith("custom__"))
|
|
45
|
+
return;
|
|
46
|
+
const nativeFields = tool?.startsWith("tikhub_") ? ["session_id"]
|
|
47
|
+
: tool?.startsWith("brightdata_") ? ["dataset_id"]
|
|
48
|
+
: tool?.startsWith("firecrawl_") ? ["dataset_id", "session_id", "team_id"] : [];
|
|
49
|
+
for (const key of Object.keys(input))
|
|
50
|
+
if (workspaceArgumentNames.has(key.replaceAll("_", "").toLowerCase()) && !nativeFields.includes(key)) {
|
|
51
|
+
context.addIssue({ code: "custom", path: [field, key], message: "Workspace-owned data is unavailable on the standalone Platform." });
|
|
38
52
|
}
|
|
39
|
-
}
|
|
53
|
+
}
|
|
54
|
+
const standaloneArgumentsSchema = z.record(z.string(), z.unknown()).pipe(platformJsonObjectSchema)
|
|
55
|
+
.describe("Self-contained tool arguments: prompts, public URLs or public account identifiers. Web workspace identifiers are not supported.");
|
|
40
56
|
export const platformToolInputSchema = z.object({ tool: platformToolNameSchema.describe("Tool name from the standalone Platform catalog."), arguments: standaloneArgumentsSchema,
|
|
41
57
|
provider: platformProviderChoiceSchema,
|
|
58
|
+
relevanceCheck: platformRelevanceCheckSchema,
|
|
42
59
|
intent: platformRequestIntentSchema,
|
|
43
|
-
sessionId: platformOptionalToolSessionIdSchema.describe("Relvo tool session returned by platform_search_tools. Omit or use an empty string for standalone executions.") }).strict()
|
|
60
|
+
sessionId: platformOptionalToolSessionIdSchema.describe("Relvo tool session returned by platform_search_tools. Omit or use an empty string for standalone executions.") }).strict()
|
|
61
|
+
.superRefine((value, context) => validatePlatformArgumentIdentifiers(value.tool, value.arguments, context));
|
|
62
|
+
export const platformQuoteRequestSchema = platformToolInputSchema.extend({
|
|
63
|
+
maximumChargeMicros: platformMicrosSchema.optional()
|
|
64
|
+
.describe("Optional cap: an Auto quote above it returns the best plan within it as plan; execute with plan's fields."),
|
|
65
|
+
}).strict();
|
|
66
|
+
export const platformRunRequestHashSchema = z.string().regex(/^[a-f0-9]{64}$/);
|
|
67
|
+
export const platformRecoverExecutionSchema = z.object({ idempotencyKey: z.string().regex(/^[A-Za-z0-9._:-]{8,128}$/),
|
|
68
|
+
requestHash: platformRunRequestHashSchema.optional() }).strict();
|
|
44
69
|
export const platformCreateExecutionSchema = platformToolInputSchema.extend({
|
|
45
70
|
maximumChargeMicros: platformMicrosSchema,
|
|
46
71
|
priceVersion: z.string().min(1).max(100),
|
|
72
|
+
runRequestHash: platformRunRequestHashSchema.optional(),
|
|
47
73
|
}).strict();
|
|
48
74
|
export const platformQuoteSchema = z.object({
|
|
49
75
|
tool: platformToolNameSchema, priceVersion: z.string(), currency: z.literal("usd"),
|
|
50
76
|
minimumChargeMicros: platformMicrosSchema, maximumChargeMicros: platformMicrosSchema,
|
|
77
|
+
lowestChargeMicros: platformMicrosSchema.optional(),
|
|
51
78
|
expiresAt: z.string(),
|
|
52
79
|
funding: platformFundingSchema.optional(), externalBillingProviders: z.array(z.string()).optional(),
|
|
80
|
+
plan: z.object({ provider: z.string().optional(), relevanceCheck: z.literal("light").optional() }).strict().optional(),
|
|
53
81
|
});
|
|
54
82
|
export const platformExecutionSchema = z.object({
|
|
55
83
|
id: platformExecutionIdSchema, tool: platformToolNameSchema, status: platformExecutionStatusSchema, cancelRequested: z.boolean(),
|
|
@@ -121,16 +149,26 @@ export const platformArtifactSchema = z.object({
|
|
|
121
149
|
generation: z.string().regex(/^\d{1,30}$/), expiresAt: z.iso.datetime(),
|
|
122
150
|
});
|
|
123
151
|
export const platformArtifactDownloadSchema = z.object({ url: z.url().refine((value) => { const url = new URL(value); return url.protocol === "https:" && !url.username && !url.password; }), expiresAt: z.iso.datetime() });
|
|
152
|
+
export const platformUnavailableReasonSchema = z.enum(["setup", "own_key", "connection", "permission", "retired"]);
|
|
124
153
|
export const platformCatalogToolSchema = z.object({
|
|
125
154
|
name: platformToolNameSchema, title: z.string().optional(), description: z.string(), category: z.enum(["research", "seo", "social", "generation", "enrichment", "finance", "news"]),
|
|
126
|
-
available: z.boolean(), inputSchema: platformJsonObjectSchema, example: platformJsonObjectSchema,
|
|
127
|
-
|
|
155
|
+
available: z.boolean(), unavailable: platformUnavailableReasonSchema.optional(), inputSchema: platformJsonObjectSchema, example: platformJsonObjectSchema,
|
|
156
|
+
permission: platformOAuthPermissionSchema.optional(),
|
|
157
|
+
providers: z.array(z.object({ id: z.string(), name: z.string(), available: z.boolean(), unavailable: platformUnavailableReasonSchema.optional(),
|
|
128
158
|
role: z.enum(["primary", "fallback", "alternative"]), condition: z.string().optional() })).optional(),
|
|
129
|
-
models: z.array(z.object({ id: z.string(), available: z.boolean(), example: platformJsonObjectSchema, priceDescription: z.string(), funding: platformModelFundingSchema.optional() })).optional(),
|
|
159
|
+
models: z.array(z.object({ id: z.string(), available: z.boolean(), unavailable: platformUnavailableReasonSchema.optional(), example: platformJsonObjectSchema, priceDescription: z.string(), funding: platformModelFundingSchema.optional() })).optional(),
|
|
130
160
|
price: z.object({ minimumChargeMicros: platformMicrosSchema, unit: z.string(), unitPriceMicros: platformMicrosSchema.nullable(), unitPriceCeilingMicros: platformMicrosSchema.optional(), description: z.string(),
|
|
161
|
+
unitsPerRequest: z.object({ minimum: z.number().int().positive(), maximum: z.number().int().positive() }).refine(range => range.minimum <= range.maximum).optional(),
|
|
131
162
|
funding: platformFundingSchema.optional(), externalBillingProviders: z.array(z.string()).optional() }),
|
|
132
163
|
});
|
|
133
164
|
const platformCatalogHeader = { priceVersion: z.string(), currency: z.literal("usd"), executionEnabled: z.boolean() };
|
|
134
165
|
export const platformCatalogSchema = z.object({ ...platformCatalogHeader, tools: z.array(platformCatalogToolSchema) });
|
|
166
|
+
export const PLATFORM_CATALOG_PAGE_MAX = 50;
|
|
167
|
+
export const PLATFORM_READ_UNIT_BYTES = 262_144;
|
|
168
|
+
export const platformCatalogPageQuerySchema = z.object({
|
|
169
|
+
offset: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER).default(0),
|
|
170
|
+
limit: z.number().int().min(1).max(PLATFORM_CATALOG_PAGE_MAX).default(PLATFORM_CATALOG_PAGE_MAX),
|
|
171
|
+
}).strict();
|
|
172
|
+
export const platformCatalogPageSchema = platformCatalogSchema.extend({ total: z.number().int().min(0), nextOffset: z.number().int().min(0).nullable() });
|
|
135
173
|
export const platformCatalogSummarySchema = z.object({ ...platformCatalogHeader, tools: z.array(platformCatalogToolSchema.omit({ inputSchema: true })) });
|
|
136
174
|
export const platformCatalogToolDetailSchema = z.object({ ...platformCatalogHeader, tool: platformCatalogToolSchema });
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
const TOOL = "[a-z][a-z0-9_]{1,63}";
|
|
2
2
|
const EXECUTION = "[A-Za-z0-9_-]{1,128}";
|
|
3
3
|
const ARTIFACT = "a_[A-Za-z0-9_-]{1,100}";
|
|
4
|
+
const MONITOR = "mon_[A-Za-z0-9_-]{1,100}";
|
|
5
|
+
const CUSTOM_TOOL = "custom__[a-z][a-z0-9_]{1,39}";
|
|
6
|
+
const TEAM_SKILL = "[a-z][a-z0-9_]{1,39}";
|
|
7
|
+
const WORKFLOW = "[a-z][a-z0-9_]{1,39}";
|
|
8
|
+
const WORKFLOW_RUN = "wfr_[A-Za-z0-9_-]{1,100}";
|
|
9
|
+
const TRIGGER = "trg_[A-Za-z0-9_-]{1,100}";
|
|
10
|
+
const MEMBER = "[A-Za-z0-9-]{1,128}";
|
|
4
11
|
export const PLATFORM_ROUTES = {
|
|
5
12
|
tools: "/v1/tools",
|
|
6
13
|
connections: "/v1/connections",
|
|
@@ -8,11 +15,56 @@ export const PLATFORM_ROUTES = {
|
|
|
8
15
|
project: "/v1/project",
|
|
9
16
|
usage: "/v1/usage",
|
|
10
17
|
executions: "/v1/executions",
|
|
18
|
+
executionRecovery: "/v1/executions/recover",
|
|
11
19
|
execution: `/v1/executions/:id{${EXECUTION}}`,
|
|
12
20
|
executionContext: `/v1/executions/:id{${EXECUTION}}/context`,
|
|
13
21
|
executionResult: `/v1/executions/:id{${EXECUTION}}/result`,
|
|
14
22
|
executionCancel: `/v1/executions/:id{${EXECUTION}}/cancel`,
|
|
15
23
|
artifactDownload: `/v1/executions/:id{${EXECUTION}}/artifacts/:artifact{${ARTIFACT}}/download`,
|
|
24
|
+
monitors: "/v1/monitors",
|
|
25
|
+
monitorTools: "/v1/monitors/tools",
|
|
26
|
+
monitorsPopular: "/v1/monitors/popular",
|
|
27
|
+
monitorQuote: "/v1/monitors/quote",
|
|
28
|
+
monitorResume: `/v1/monitors/:id{${MONITOR}}/resume`,
|
|
29
|
+
monitor: `/v1/monitors/:id{${MONITOR}}`,
|
|
30
|
+
monitorDelete: `/v1/monitors/:id{${MONITOR}}/delete`,
|
|
31
|
+
monitorEvents: `/v1/monitors/:id{${MONITOR}}/events`,
|
|
32
|
+
monitorDestinations: `/v1/monitors/:id{${MONITOR}}/destinations`,
|
|
33
|
+
monitorDestinationDelete: `/v1/monitors/:id{${MONITOR}}/destinations/:destinationId{dst_[A-Za-z0-9_-]{1,100}}/delete`,
|
|
34
|
+
monitorRecipients: "/v1/monitor-recipients",
|
|
35
|
+
monitorFeed: "/v1/monitor-events",
|
|
36
|
+
customTools: "/v1/custom-tools",
|
|
37
|
+
customTool: `/v1/custom-tools/:name{${CUSTOM_TOOL}}`,
|
|
38
|
+
customToolUpdate: `/v1/custom-tools/:name{${CUSTOM_TOOL}}/update`,
|
|
39
|
+
customToolDelete: `/v1/custom-tools/:name{${CUSTOM_TOOL}}/delete`,
|
|
40
|
+
customToolVersions: `/v1/custom-tools/:name{${CUSTOM_TOOL}}/versions`,
|
|
41
|
+
customToolRestore: `/v1/custom-tools/:name{${CUSTOM_TOOL}}/restore`,
|
|
42
|
+
teamSkills: "/v1/team-skills",
|
|
43
|
+
teamSkill: `/v1/team-skills/:slug{${TEAM_SKILL}}`,
|
|
44
|
+
teamSkillUpdate: `/v1/team-skills/:slug{${TEAM_SKILL}}/update`,
|
|
45
|
+
teamSkillDelete: `/v1/team-skills/:slug{${TEAM_SKILL}}/delete`,
|
|
46
|
+
teamSkillVersions: `/v1/team-skills/:slug{${TEAM_SKILL}}/versions`,
|
|
47
|
+
teamSkillRestore: `/v1/team-skills/:slug{${TEAM_SKILL}}/restore`,
|
|
48
|
+
workflows: "/v1/workflows",
|
|
49
|
+
workflow: `/v1/workflows/:slug{${WORKFLOW}}`,
|
|
50
|
+
workflowUpdate: `/v1/workflows/:slug{${WORKFLOW}}/update`,
|
|
51
|
+
workflowDelete: `/v1/workflows/:slug{${WORKFLOW}}/delete`,
|
|
52
|
+
workflowVersions: `/v1/workflows/:slug{${WORKFLOW}}/versions`,
|
|
53
|
+
workflowRuns: `/v1/workflows/:slug{${WORKFLOW}}/runs`,
|
|
54
|
+
workflowRun: `/v1/workflow-runs/:id{${WORKFLOW_RUN}}`,
|
|
55
|
+
workflowRunCancel: `/v1/workflow-runs/:id{${WORKFLOW_RUN}}/cancel`,
|
|
56
|
+
triggers: "/v1/triggers",
|
|
57
|
+
trigger: `/v1/triggers/:id{${TRIGGER}}`,
|
|
58
|
+
triggerUpdate: `/v1/triggers/:id{${TRIGGER}}/update`,
|
|
59
|
+
triggerDelete: `/v1/triggers/:id{${TRIGGER}}/delete`,
|
|
60
|
+
triggerEvents: `/v1/triggers/:id{${TRIGGER}}/events`,
|
|
61
|
+
triggerDestinations: `/v1/triggers/:id{${TRIGGER}}/destinations`,
|
|
62
|
+
triggerDestinationDelete: `/v1/triggers/:id{${TRIGGER}}/destinations/:destinationId{dst_[A-Za-z0-9_-]{1,100}}/delete`,
|
|
63
|
+
triggerFeed: "/v1/trigger-events",
|
|
64
|
+
triggerTypes: "/v1/trigger-types",
|
|
65
|
+
suggestions: "/v1/suggestions",
|
|
66
|
+
access: "/v1/access",
|
|
67
|
+
memberAccess: `/v1/access/members/:id{${MEMBER}}/update`,
|
|
16
68
|
definition: `/tools/definition/:name{${TOOL}}`,
|
|
17
69
|
tool: `/tools/:tool{${TOOL}}`,
|
|
18
70
|
discover: "/tools/discover",
|
|
@@ -25,11 +77,19 @@ export const PLATFORM_ROUTES = {
|
|
|
25
77
|
metaWorkbench: "/tools/meta/workbench",
|
|
26
78
|
metaBash: "/tools/meta/bash",
|
|
27
79
|
};
|
|
80
|
+
export const PLATFORM_TRIGGER_INGRESS_ROUTES = {
|
|
81
|
+
endpoint: "/v1/trigger-ingress/:endpoint{tep_[a-f0-9]{32}}",
|
|
82
|
+
app: "/v1/trigger-ingress/app/:app{[a-z0-9][a-z0-9_]{0,63}}",
|
|
83
|
+
};
|
|
84
|
+
export const PLATFORM_WALLET_ROUTES = {
|
|
85
|
+
signIn: "/v1/wallet/sign-in",
|
|
86
|
+
topUp: "/v1/wallet/top-up",
|
|
87
|
+
};
|
|
28
88
|
export const PLATFORM_META_ROUTES = [PLATFORM_ROUTES.metaSearch, PLATFORM_ROUTES.metaSchemas, PLATFORM_ROUTES.metaConnections,
|
|
29
89
|
PLATFORM_ROUTES.metaExecute, PLATFORM_ROUTES.metaWorkbench, PLATFORM_ROUTES.metaBash];
|
|
30
90
|
export const PLATFORM_BRIDGE_ROUTES = [
|
|
31
91
|
PLATFORM_ROUTES.tools, PLATFORM_ROUTES.connections, PLATFORM_ROUTES.quote, PLATFORM_ROUTES.project, PLATFORM_ROUTES.usage,
|
|
32
|
-
PLATFORM_ROUTES.executions, PLATFORM_ROUTES.execution, PLATFORM_ROUTES.executionContext, PLATFORM_ROUTES.executionResult,
|
|
92
|
+
PLATFORM_ROUTES.executions, PLATFORM_ROUTES.executionRecovery, PLATFORM_ROUTES.execution, PLATFORM_ROUTES.executionContext, PLATFORM_ROUTES.executionResult,
|
|
33
93
|
PLATFORM_ROUTES.executionCancel, PLATFORM_ROUTES.artifactDownload, PLATFORM_ROUTES.definition, PLATFORM_ROUTES.tool,
|
|
34
94
|
];
|
|
35
95
|
const ALIASED = "(?:project|usage|quote|executions|connections)(?:\\/|$)";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const PLATFORM_SKILLS_MAX_BYTES = 1_048_576;
|
|
3
3
|
export const PLATFORM_SKILL_MAX_BYTES = 65_536;
|
|
4
|
-
export const platformSkillSchema = z.object({ name: z.string().regex(/^
|
|
4
|
+
export const platformSkillSchema = z.object({ name: z.string().regex(/^relvo(?:-[a-z0-9]+)*$/).max(64),
|
|
5
5
|
description: z.string().min(1).max(1000), sha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
6
6
|
content: z.string().min(1).max(PLATFORM_SKILL_MAX_BYTES).refine(value => new TextEncoder().encode(value).byteLength <= PLATFORM_SKILL_MAX_BYTES) }).strict();
|
|
7
7
|
export const platformSkillsBundleSchema = z.object({ version: z.string().regex(/^[a-f0-9]{64}$/),
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const PLATFORM_TEAM_SECRET_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,63}$/;
|
|
3
|
+
export const platformTeamSecretNameSchema = z.string().regex(PLATFORM_TEAM_SECRET_NAME).describe("Letters, digits and underscores, not starting with a digit, e.g. STRIPE_API_KEY.");
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { projectScopeSchema } from "./platformPublicExecution.js";
|
|
3
|
+
import { PLATFORM_CUSTOM_TOOL_LIMITS, platformVersionAuthorSchema } from "./platformCustomTools.js";
|
|
4
|
+
export const PLATFORM_TEAM_SKILL_LIMITS = {
|
|
5
|
+
perProject: 200,
|
|
6
|
+
versions: 50,
|
|
7
|
+
titleChars: 80,
|
|
8
|
+
descriptionChars: 500,
|
|
9
|
+
contentBytes: 32_768,
|
|
10
|
+
};
|
|
11
|
+
export const PLATFORM_TEAM_SKILL_SLUG = /^[a-z][a-z0-9_]{1,39}$/;
|
|
12
|
+
export const platformTeamSkillSlugSchema = z.string().regex(PLATFORM_TEAM_SKILL_SLUG).describe("Lowercase letters, digits and underscores, starting with a letter.");
|
|
13
|
+
export const platformTeamSkillDefinitionSchema = z.object({
|
|
14
|
+
title: z.string().trim().min(1).max(PLATFORM_TEAM_SKILL_LIMITS.titleChars),
|
|
15
|
+
description: z.string().trim().min(1).max(PLATFORM_TEAM_SKILL_LIMITS.descriptionChars).describe("When an agent should follow this skill; agents choose skills by it."),
|
|
16
|
+
content: z.string().trim().min(1).refine(value => new TextEncoder().encode(value).byteLength <= PLATFORM_TEAM_SKILL_LIMITS.contentBytes, "The content is too long")
|
|
17
|
+
.describe("Markdown: the steps, the tools to use (by name) and what to check. No secrets."),
|
|
18
|
+
}).strict();
|
|
19
|
+
export const platformTeamSkillCreateSchema = platformTeamSkillDefinitionSchema.extend({ slug: platformTeamSkillSlugSchema }).strict();
|
|
20
|
+
export const platformTeamSkillUpdateSchema = platformTeamSkillDefinitionSchema.extend({ expectedVersion: z.number().int().min(1) }).strict();
|
|
21
|
+
export const platformTeamSkillRestoreSchema = z.object({ version: z.number().int().min(1), expectedVersion: z.number().int().min(1) }).strict();
|
|
22
|
+
export const platformTeamSkillSchema = z.object({ slug: platformTeamSkillSlugSchema, title: z.string(), description: z.string(), content: z.string(),
|
|
23
|
+
version: z.number().int().min(1), createdAt: z.string(), updatedAt: z.string() });
|
|
24
|
+
export const platformTeamSkillSummarySchema = platformTeamSkillSchema.omit({ content: true });
|
|
25
|
+
export const platformTeamSkillVersionSchema = z.object({ version: z.number().int().min(1), title: z.string(), createdAt: z.string() });
|
|
26
|
+
export const platformSuggestionSchema = z.discriminatedUnion("kind", [
|
|
27
|
+
z.object({ kind: z.literal("custom_tool"), occurrences: z.number().int().min(2), lastSeenAt: z.string(),
|
|
28
|
+
executions: z.array(z.string()).min(1).max(3),
|
|
29
|
+
code: z.string().min(1).max(PLATFORM_CUSTOM_TOOL_LIMITS.codeChars) }),
|
|
30
|
+
z.object({ kind: z.literal("skill"), occurrences: z.number().int().min(2), lastSeenAt: z.string(), tools: z.array(z.string()).min(2).max(3) }),
|
|
31
|
+
]);
|
|
32
|
+
export const platformSuggestionsSchema = z.object({ suggestions: z.array(platformSuggestionSchema).max(20), since: z.string() });
|
|
33
|
+
export const platformTeamSkillHistorySchema = platformTeamSkillVersionSchema.extend({ author: platformVersionAuthorSchema });
|
|
34
|
+
export const platformTeamSkillVersionDetailSchema = platformTeamSkillSchema.pick({ title: true, description: true, content: true })
|
|
35
|
+
.extend({ version: z.number().int().min(1), createdAt: z.string(), author: platformVersionAuthorSchema });
|
|
36
|
+
const skillInput = projectScopeSchema.extend({ slug: platformTeamSkillSlugSchema });
|
|
37
|
+
const skillResult = z.object({ skill: platformTeamSkillSchema }).strict();
|
|
38
|
+
export const platformTeamSkillContracts = {
|
|
39
|
+
listDeveloperTeamSkills: { input: projectScopeSchema.strict(), output: z.object({ skills: z.array(platformTeamSkillSummarySchema.extend({ canEdit: z.boolean(), canDelete: z.boolean() })),
|
|
40
|
+
canCreate: z.boolean() }).strict() },
|
|
41
|
+
getDeveloperTeamSkill: { input: skillInput.strict(), output: skillResult },
|
|
42
|
+
createDeveloperTeamSkill: { input: projectScopeSchema.extend({ skill: platformTeamSkillCreateSchema }).strict(), output: skillResult },
|
|
43
|
+
updateDeveloperTeamSkill: { input: skillInput.extend({ skill: platformTeamSkillUpdateSchema }).strict(), output: skillResult },
|
|
44
|
+
restoreDeveloperTeamSkill: { input: skillInput.merge(platformTeamSkillRestoreSchema).strict(), output: skillResult },
|
|
45
|
+
deleteDeveloperTeamSkill: { input: skillInput.strict(), output: z.object({ success: z.literal(true) }).strict() },
|
|
46
|
+
listDeveloperTeamSkillVersions: { input: skillInput.strict(), output: z.object({ versions: z.array(platformTeamSkillHistorySchema) }).strict() },
|
|
47
|
+
getDeveloperTeamSkillVersion: { input: skillInput.extend({ version: z.number().int().min(1) }).strict(), output: z.object({ version: platformTeamSkillVersionDetailSchema }).strict() },
|
|
48
|
+
listDeveloperSuggestions: { input: projectScopeSchema.strict(), output: platformSuggestionsSchema },
|
|
49
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { platformCustomToolNameSchema } from "./platformCustomTools.js";
|
|
3
|
+
const connectionId = z.string().regex(/^[A-Za-z0-9-]{1,64}$/);
|
|
4
|
+
export const platformConnectionGrantSchema = z.templateLiteral(["connection:", connectionId]);
|
|
5
|
+
export const platformConnectionOperationGrantSchema = z.templateLiteral(["connection:", connectionId, "/", z.string().regex(/^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/)]);
|
|
6
|
+
export const memberToolAccessSchema = z.array(z.union([platformCustomToolNameSchema, platformConnectionGrantSchema, platformConnectionOperationGrantSchema])).max(20_000).nullable();
|
|
7
|
+
export const keyToolAccessSchema = memberToolAccessSchema;
|
|
8
|
+
export const platformTeamAccessSchema = z.object({
|
|
9
|
+
members: z.array(z.object({ memberId: z.string(), email: z.string(), name: z.string().nullable(), role: z.string(), toolAccess: memberToolAccessSchema }).loose()),
|
|
10
|
+
invitations: z.array(z.object({ id: z.string(), email: z.string(), role: z.string(), expiresAt: z.string(), toolAccess: memberToolAccessSchema }).loose()),
|
|
11
|
+
});
|
|
12
|
+
export const platformMemberAccessUpdateSchema = z.object({ toolAccess: memberToolAccessSchema }).strict();
|
|
13
|
+
export const memberTeamSkillAccessSchema = z.enum(["EDIT", "OWN", "READ"]);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { projectScopeSchema, platformJsonObjectSchema, platformMicrosSchema } from "./platformPublicExecution.js";
|
|
3
|
+
import { platformMonitorDestinationInputSchema, platformMonitorDestinationSchema, platformMonitorRecipientSchema, PLATFORM_MONITOR_DESTINATION_LIMITS } from "./platformMonitors.js";
|
|
4
|
+
import { platformWorkflowSlugSchema } from "./platformWorkflows.js";
|
|
5
|
+
import { PLATFORM_FREE_TOOL_OVERAGE_MICROS } from "./platformBillingConstants.js";
|
|
6
|
+
export const PLATFORM_TRIGGER_LIMITS = {
|
|
7
|
+
perProject: 50,
|
|
8
|
+
perTeam: 100,
|
|
9
|
+
nameChars: 80,
|
|
10
|
+
eventsPage: 100,
|
|
11
|
+
eventDataBytes: 65_536,
|
|
12
|
+
ingressBodyBytes: 1_048_576,
|
|
13
|
+
retentionDays: 30,
|
|
14
|
+
keptEvents: 10_000,
|
|
15
|
+
eventsPerBatch: 100,
|
|
16
|
+
typesPage: 100,
|
|
17
|
+
};
|
|
18
|
+
export const PLATFORM_TRIGGER_INTERVALS = { "1m": 60, "5m": 300, "15m": 900, "1h": 3_600 };
|
|
19
|
+
export const platformTriggerIntervalSchema = z.enum(["1m", "5m", "15m", "1h"]);
|
|
20
|
+
export const PLATFORM_TRIGGER_DEFAULT_MAXIMUM_CHARGE_MICROS_PER_POLL = PLATFORM_FREE_TOOL_OVERAGE_MICROS;
|
|
21
|
+
export const PLATFORM_TRIGGER_ID = /^trg_[A-Za-z0-9_-]{1,100}$/;
|
|
22
|
+
export const platformTriggerIdSchema = z.string().regex(PLATFORM_TRIGGER_ID);
|
|
23
|
+
export const PLATFORM_TRIGGER_TYPE = /^[a-z0-9][a-z0-9_]{0,63}\.[a-z0-9][a-z0-9_.]{0,79}$/;
|
|
24
|
+
export const platformTriggerTypeIdSchema = z.string().regex(PLATFORM_TRIGGER_TYPE);
|
|
25
|
+
const toolName = z.string().regex(/^[a-z][a-z0-9_]{1,127}$/);
|
|
26
|
+
const connectionId = z.string().min(1).max(128);
|
|
27
|
+
const pointer = z.string().max(200).regex(/^(\/[^/]*)*$/);
|
|
28
|
+
export const platformTriggerDestinationKindSchema = z.enum(["webhook", "slack", "discord", "email", "workflow"]);
|
|
29
|
+
const workflowDestination = z.object({
|
|
30
|
+
kind: z.literal("workflow"),
|
|
31
|
+
label: z.string().trim().max(PLATFORM_MONITOR_DESTINATION_LIMITS.labelChars).default(""),
|
|
32
|
+
workflow: platformWorkflowSlugSchema,
|
|
33
|
+
input: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]{0,63}$/).default("event").describe("The workflow input that receives the event object."),
|
|
34
|
+
maximumChargeMicros: platformMicrosSchema,
|
|
35
|
+
}).strict();
|
|
36
|
+
export const platformTriggerDestinationInputSchema = z.union([platformMonitorDestinationInputSchema, workflowDestination]);
|
|
37
|
+
export const platformTriggerDestinationSchema = platformMonitorDestinationSchema.extend({
|
|
38
|
+
kind: platformTriggerDestinationKindSchema,
|
|
39
|
+
workflow: z.object({ slug: platformWorkflowSlugSchema, input: z.string(), maximumChargeMicros: platformMicrosSchema }).nullable().default(null),
|
|
40
|
+
});
|
|
41
|
+
const common = {
|
|
42
|
+
name: z.string().trim().max(PLATFORM_TRIGGER_LIMITS.nameChars).default("").describe("Empty names the trigger after its type or operation."),
|
|
43
|
+
connectionId: connectionId.describe("The connection of the app, from /tools/connections."),
|
|
44
|
+
destinations: z.array(platformTriggerDestinationInputSchema).max(PLATFORM_MONITOR_DESTINATION_LIMITS.perMonitor).default([]),
|
|
45
|
+
};
|
|
46
|
+
export const platformTriggerCreateSchema = z.discriminatedUnion("kind", [
|
|
47
|
+
z.object({
|
|
48
|
+
kind: z.literal("poll"),
|
|
49
|
+
tool: toolName.describe("A read operation of the connected app, for example github__issues_list_for_repo."),
|
|
50
|
+
arguments: platformJsonObjectSchema.default({}).describe("The operation's arguments without connectionId."),
|
|
51
|
+
interval: platformTriggerIntervalSchema.default("5m"),
|
|
52
|
+
itemsPath: pointer.optional().describe("Where the list of items is in the response body. Omit to use the largest list."),
|
|
53
|
+
maximumChargeMicrosPerPoll: platformMicrosSchema.default(PLATFORM_TRIGGER_DEFAULT_MAXIMUM_CHARGE_MICROS_PER_POLL),
|
|
54
|
+
...common,
|
|
55
|
+
}).strict(),
|
|
56
|
+
z.object({
|
|
57
|
+
kind: z.literal("webhook"),
|
|
58
|
+
type: platformTriggerTypeIdSchema.describe("A trigger type from /trigger-types, for example github.push."),
|
|
59
|
+
config: platformJsonObjectSchema.default({}).describe("The type's settings, valid against its configSchema."),
|
|
60
|
+
...common,
|
|
61
|
+
}).strict(),
|
|
62
|
+
]);
|
|
63
|
+
export const platformTriggerUpdateSchema = z.object({
|
|
64
|
+
enabled: z.boolean().optional(),
|
|
65
|
+
name: z.string().trim().max(PLATFORM_TRIGGER_LIMITS.nameChars).optional().describe("Empty or omitted keeps the name."),
|
|
66
|
+
}).strict();
|
|
67
|
+
export const platformTriggerStatusSchema = z.enum(["active", "disabled", "failed"]);
|
|
68
|
+
export const platformTriggerSchema = z.object({
|
|
69
|
+
id: platformTriggerIdSchema,
|
|
70
|
+
name: z.string(),
|
|
71
|
+
kind: z.enum(["poll", "webhook"]),
|
|
72
|
+
app: z.string(),
|
|
73
|
+
connectionId: z.string(),
|
|
74
|
+
status: platformTriggerStatusSchema,
|
|
75
|
+
statusReason: z.string().nullable(),
|
|
76
|
+
tool: z.string().nullable(),
|
|
77
|
+
arguments: platformJsonObjectSchema.nullable(),
|
|
78
|
+
interval: platformTriggerIntervalSchema.nullable(),
|
|
79
|
+
itemsPath: z.string().nullable(),
|
|
80
|
+
maximumChargeMicrosPerPoll: platformMicrosSchema.nullable(),
|
|
81
|
+
type: z.string().nullable(),
|
|
82
|
+
config: platformJsonObjectSchema.nullable(),
|
|
83
|
+
apiKeyId: z.string(),
|
|
84
|
+
lastCheckedAt: z.string().nullable(),
|
|
85
|
+
lastEventAt: z.string().nullable(),
|
|
86
|
+
nextCheckAt: z.string().nullable(),
|
|
87
|
+
lastError: z.string().nullable(),
|
|
88
|
+
createdAt: z.string(),
|
|
89
|
+
destinations: z.array(platformTriggerDestinationSchema),
|
|
90
|
+
});
|
|
91
|
+
export const platformTriggerEventSchema = z.object({
|
|
92
|
+
id: z.string().regex(/^\d{1,20}$/),
|
|
93
|
+
triggerId: platformTriggerIdSchema,
|
|
94
|
+
type: z.string(),
|
|
95
|
+
key: z.string(),
|
|
96
|
+
title: z.string(),
|
|
97
|
+
url: z.string(),
|
|
98
|
+
data: platformJsonObjectSchema,
|
|
99
|
+
receivedAt: z.string(),
|
|
100
|
+
});
|
|
101
|
+
export const platformTriggerEventsQuerySchema = z.object({
|
|
102
|
+
after: z.string().regex(/^\d{1,20}$/).optional(),
|
|
103
|
+
limit: z.coerce.number().int().min(1).max(PLATFORM_TRIGGER_LIMITS.eventsPage).default(50),
|
|
104
|
+
}).strict();
|
|
105
|
+
export const platformTriggerEventsSchema = z.object({ events: z.array(platformTriggerEventSchema), nextAfter: z.string().nullable() });
|
|
106
|
+
export const platformTriggerTypeSchema = z.object({
|
|
107
|
+
type: platformTriggerTypeIdSchema,
|
|
108
|
+
app: z.string(),
|
|
109
|
+
name: z.string(),
|
|
110
|
+
description: z.string(),
|
|
111
|
+
configSchema: platformJsonObjectSchema,
|
|
112
|
+
setup: z.enum(["automatic", "app"]),
|
|
113
|
+
available: z.boolean(),
|
|
114
|
+
unavailableReason: z.string().nullable(),
|
|
115
|
+
});
|
|
116
|
+
export const platformTriggerOperationSchema = z.object({ tool: toolName, app: z.string(), description: z.string(), inputSchema: platformJsonObjectSchema });
|
|
117
|
+
export const platformTriggerTypesQuerySchema = z.object({
|
|
118
|
+
app: z.string().regex(/^[a-z0-9][a-z0-9_]{0,63}$/),
|
|
119
|
+
connectionId: z.string().max(128).optional(),
|
|
120
|
+
query: z.string().trim().max(100).default(""),
|
|
121
|
+
offset: z.coerce.number().int().min(0).max(100_000).default(0),
|
|
122
|
+
limit: z.coerce.number().int().min(1).max(PLATFORM_TRIGGER_LIMITS.typesPage).default(50),
|
|
123
|
+
}).strict();
|
|
124
|
+
export const platformTriggerTypesSchema = z.object({
|
|
125
|
+
types: z.array(platformTriggerTypeSchema),
|
|
126
|
+
operations: z.array(platformTriggerOperationSchema),
|
|
127
|
+
total: z.number().int().min(0),
|
|
128
|
+
});
|
|
129
|
+
export const platformTriggerDeliverySchema = z.object({
|
|
130
|
+
version: z.literal(1),
|
|
131
|
+
type: z.literal("trigger.event"),
|
|
132
|
+
deliveryId: z.string(),
|
|
133
|
+
trigger: z.object({ id: platformTriggerIdSchema, name: z.string(), kind: z.enum(["poll", "webhook"]), app: z.string(), source: z.string(), connectionId: z.string() }).strict(),
|
|
134
|
+
event: platformTriggerEventSchema.omit({ triggerId: true }),
|
|
135
|
+
}).strict();
|
|
136
|
+
const projectTrigger = projectScopeSchema.extend({ triggerId: platformTriggerIdSchema });
|
|
137
|
+
export const platformTriggerContracts = {
|
|
138
|
+
listDeveloperTriggers: { input: projectScopeSchema.strict(), output: z.object({ triggers: z.array(platformTriggerSchema) }).strict() },
|
|
139
|
+
createDeveloperTrigger: { input: projectScopeSchema.extend({ apiKeyId: z.string().min(1).max(128), trigger: platformTriggerCreateSchema }).strict(),
|
|
140
|
+
output: z.object({ trigger: platformTriggerSchema }).strict() },
|
|
141
|
+
updateDeveloperTrigger: { input: projectTrigger.merge(platformTriggerUpdateSchema).strict(), output: z.object({ trigger: platformTriggerSchema }).strict() },
|
|
142
|
+
deleteDeveloperTrigger: { input: projectTrigger.strict(), output: z.object({ success: z.literal(true) }).strict() },
|
|
143
|
+
listDeveloperTriggerEvents: {
|
|
144
|
+
input: projectScopeSchema.extend({ triggerId: platformTriggerIdSchema.optional(), after: platformTriggerEventsQuerySchema.shape.after,
|
|
145
|
+
limit: z.number().int().min(1).max(PLATFORM_TRIGGER_LIMITS.eventsPage).default(50) }).strict(),
|
|
146
|
+
output: platformTriggerEventsSchema,
|
|
147
|
+
},
|
|
148
|
+
listDeveloperTriggerTypes: { input: projectScopeSchema.merge(platformTriggerTypesQuerySchema).strict(), output: platformTriggerTypesSchema },
|
|
149
|
+
addDeveloperTriggerDestination: { input: projectTrigger.extend({ destination: platformTriggerDestinationInputSchema }).strict(), output: z.object({ trigger: platformTriggerSchema }).strict() },
|
|
150
|
+
removeDeveloperTriggerDestination: { input: projectTrigger.extend({ destinationId: platformTriggerDestinationSchema.shape.id }).strict(), output: z.object({ trigger: platformTriggerSchema }).strict() },
|
|
151
|
+
listDeveloperTriggerRecipients: { input: projectScopeSchema.strict(), output: z.object({ recipients: z.array(platformMonitorRecipientSchema) }).strict() },
|
|
152
|
+
};
|