@runtypelabs/sdk 10.5.3 → 10.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +31 -7
- package/dist/index.d.cts +97 -5
- package/dist/index.d.ts +97 -5
- package/dist/index.mjs +31 -7
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2352,12 +2352,13 @@ const DEFAULT_BLOCKED_CODE_PATTERNS = [
|
|
|
2352
2352
|
/\bsubprocess\b/i,
|
|
2353
2353
|
/\bos\.system\s*\(/i
|
|
2354
2354
|
];
|
|
2355
|
-
const
|
|
2355
|
+
const CUSTOM_TOOL_SANDBOX_PROVIDERS = [
|
|
2356
2356
|
"quickjs",
|
|
2357
2357
|
"daytona",
|
|
2358
2358
|
"cloudflare-worker",
|
|
2359
|
-
"
|
|
2359
|
+
"runtype-sandbox"
|
|
2360
2360
|
];
|
|
2361
|
+
const DEFAULT_ALLOWED_SANDBOX_PROVIDERS = [...CUSTOM_TOOL_SANDBOX_PROVIDERS, "cloudflare-sandbox"];
|
|
2361
2362
|
const DEFAULT_ALLOWED_LANGUAGES = [
|
|
2362
2363
|
"javascript",
|
|
2363
2364
|
"typescript",
|
|
@@ -2379,7 +2380,21 @@ function isLanguage(value) {
|
|
|
2379
2380
|
return value === "javascript" || value === "typescript" || value === "python";
|
|
2380
2381
|
}
|
|
2381
2382
|
function isSandboxProvider(value) {
|
|
2382
|
-
return value
|
|
2383
|
+
return CUSTOM_TOOL_SANDBOX_PROVIDERS.includes(value);
|
|
2384
|
+
}
|
|
2385
|
+
function isNetworkAccess(value) {
|
|
2386
|
+
if (value === "off" || value === "on") return true;
|
|
2387
|
+
if (!isObject(value) || !Array.isArray(value.allowedHostnames)) return false;
|
|
2388
|
+
const hosts = value.allowedHostnames;
|
|
2389
|
+
return hosts.length > 0 && hosts.every((host) => typeof host === "string" && host.length > 0);
|
|
2390
|
+
}
|
|
2391
|
+
/** Why the requested posture exceeds what the caller allowed, or null when it fits. */
|
|
2392
|
+
function networkAccessViolation(requested, allowed) {
|
|
2393
|
+
if (requested === void 0 || requested === "off" || allowed === true) return null;
|
|
2394
|
+
if (!allowed) return "Generated tool requests network access, which this gate does not allow";
|
|
2395
|
+
if (requested === "on") return "Generated tool requests unrestricted network access; only an allowedHostnames list is allowed";
|
|
2396
|
+
const outside = requested.allowedHostnames.filter((host) => !allowed.allowedHostnames.includes(host));
|
|
2397
|
+
return outside.length > 0 ? `Generated tool requests hosts outside the allowed list: ${outside.join(", ")}` : null;
|
|
2383
2398
|
}
|
|
2384
2399
|
function isJSONSchema(value) {
|
|
2385
2400
|
if (!isObject(value)) return false;
|
|
@@ -2426,6 +2441,12 @@ function normalizeGeneratedProposal(proposal, violations) {
|
|
|
2426
2441
|
const sandboxProviderRaw = config.sandboxProvider;
|
|
2427
2442
|
const languageRaw = config.language;
|
|
2428
2443
|
const timeoutRaw = config.timeout;
|
|
2444
|
+
const sandboxProvider = isSandboxProvider(sandboxProviderRaw) ? sandboxProviderRaw : "cloudflare-worker";
|
|
2445
|
+
const language = isLanguage(languageRaw) ? languageRaw : "javascript";
|
|
2446
|
+
const timeout = asNumber(timeoutRaw);
|
|
2447
|
+
if (Array.isArray(config.secrets) && config.secrets.length > 0) violations.push("Generated tools cannot declare config.secrets (managed credentials)");
|
|
2448
|
+
const networkAccess = config.networkAccess;
|
|
2449
|
+
if (networkAccess !== void 0 && !isNetworkAccess(networkAccess)) violations.push("config.networkAccess must be 'off', 'on', or { allowedHostnames: string[] }");
|
|
2429
2450
|
return {
|
|
2430
2451
|
name,
|
|
2431
2452
|
description,
|
|
@@ -2433,9 +2454,10 @@ function normalizeGeneratedProposal(proposal, violations) {
|
|
|
2433
2454
|
parametersSchema,
|
|
2434
2455
|
config: {
|
|
2435
2456
|
code,
|
|
2436
|
-
sandboxProvider
|
|
2437
|
-
language
|
|
2438
|
-
timeout
|
|
2457
|
+
sandboxProvider,
|
|
2458
|
+
language,
|
|
2459
|
+
timeout,
|
|
2460
|
+
...isNetworkAccess(networkAccess) ? { networkAccess } : {}
|
|
2439
2461
|
}
|
|
2440
2462
|
};
|
|
2441
2463
|
}
|
|
@@ -2488,6 +2510,8 @@ function evaluateGeneratedRuntimeToolProposal(proposal, options = {}) {
|
|
|
2488
2510
|
violations.push(`Generated code matched blocked pattern: ${pattern}`);
|
|
2489
2511
|
break;
|
|
2490
2512
|
}
|
|
2513
|
+
const networkViolation = networkAccessViolation(normalized.config.networkAccess, options.allowNetworkAccess);
|
|
2514
|
+
if (networkViolation) violations.push(networkViolation);
|
|
2491
2515
|
}
|
|
2492
2516
|
const tool = {
|
|
2493
2517
|
name: normalized.name,
|
|
@@ -13457,7 +13481,7 @@ function transformQueryParams(params) {
|
|
|
13457
13481
|
}
|
|
13458
13482
|
//#endregion
|
|
13459
13483
|
//#region src/version.ts
|
|
13460
|
-
const SDK_VERSION = "10.
|
|
13484
|
+
const SDK_VERSION = "10.6.0";
|
|
13461
13485
|
/**
|
|
13462
13486
|
* Canonical client identity the API uses for attribution
|
|
13463
13487
|
* (`detectActorSource` in apps/api/src/lib/audit-log.ts keys `'sdk'` off the
|
package/dist/index.d.cts
CHANGED
|
@@ -117,6 +117,45 @@ interface ContextErrorHandling {
|
|
|
117
117
|
* Do not make direct changes to the file.
|
|
118
118
|
*/
|
|
119
119
|
interface paths {
|
|
120
|
+
"/.well-known/jwks.json": {
|
|
121
|
+
parameters: {
|
|
122
|
+
query?: never;
|
|
123
|
+
header?: never;
|
|
124
|
+
path?: never;
|
|
125
|
+
cookie?: never;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Identity assertion signing keys (JWKS)
|
|
129
|
+
* @description Public keys that verify the Runtype-signed `{{_identity.token}}` a tool call carries. Verify offline: check the ES256 signature against the key whose `kid` matches the token header, then `iss` (pin it to the one Runtype organization you trust: `<API origin>/orgs/<organizationId>`), `aud` (your host), `exp`, and the per-scope assurance in the `runtype` claim. Cache the response for up to five minutes; re-fetch when a token names an unknown `kid`.
|
|
130
|
+
*/
|
|
131
|
+
get: {
|
|
132
|
+
parameters: {
|
|
133
|
+
query?: never;
|
|
134
|
+
header?: never;
|
|
135
|
+
path?: never;
|
|
136
|
+
cookie?: never;
|
|
137
|
+
};
|
|
138
|
+
requestBody?: never;
|
|
139
|
+
responses: {
|
|
140
|
+
/** @description The published key set. Empty when this environment has no signing key configured. */
|
|
141
|
+
200: {
|
|
142
|
+
headers: {
|
|
143
|
+
[name: string]: unknown;
|
|
144
|
+
};
|
|
145
|
+
content: {
|
|
146
|
+
"application/json": components["schemas"]["IdentityAssertionJwks"];
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
put?: never;
|
|
152
|
+
post?: never;
|
|
153
|
+
delete?: never;
|
|
154
|
+
options?: never;
|
|
155
|
+
head?: never;
|
|
156
|
+
patch?: never;
|
|
157
|
+
trace?: never;
|
|
158
|
+
};
|
|
120
159
|
"/v1/agent-aliases": {
|
|
121
160
|
parameters: {
|
|
122
161
|
query?: never;
|
|
@@ -40582,6 +40621,15 @@ interface paths {
|
|
|
40582
40621
|
"application/json": components["schemas"]["Error"];
|
|
40583
40622
|
};
|
|
40584
40623
|
};
|
|
40624
|
+
/** @description A target record changed while the edit was applied (`record_conflict`); nothing was written, retry the edit */
|
|
40625
|
+
409: {
|
|
40626
|
+
headers: {
|
|
40627
|
+
[name: string]: unknown;
|
|
40628
|
+
};
|
|
40629
|
+
content: {
|
|
40630
|
+
"application/json": components["schemas"]["Error"];
|
|
40631
|
+
};
|
|
40632
|
+
};
|
|
40585
40633
|
/** @description A record's post-merge metadata violates its type's collection schema (enforce mode); the whole edit is rejected */
|
|
40586
40634
|
422: {
|
|
40587
40635
|
headers: {
|
|
@@ -41215,7 +41263,7 @@ interface paths {
|
|
|
41215
41263
|
/** @enum {string} */
|
|
41216
41264
|
role: "user" | "assistant";
|
|
41217
41265
|
}[] | null;
|
|
41218
|
-
/** @
|
|
41266
|
+
/** @description Replaces the whole metadata object. Omit to leave metadata unchanged. */
|
|
41219
41267
|
metadata?: {
|
|
41220
41268
|
[key: string]: unknown;
|
|
41221
41269
|
};
|
|
@@ -41306,7 +41354,7 @@ interface paths {
|
|
|
41306
41354
|
"application/json": components["schemas"]["Error"];
|
|
41307
41355
|
};
|
|
41308
41356
|
};
|
|
41309
|
-
/** @description Duplicate record */
|
|
41357
|
+
/** @description Duplicate record (`duplicate_record`), or the record changed while this update was applied (`record_conflict`; re-read and retry) */
|
|
41310
41358
|
409: {
|
|
41311
41359
|
headers: {
|
|
41312
41360
|
[name: string]: unknown;
|
|
@@ -53230,6 +53278,24 @@ interface components {
|
|
|
53230
53278
|
valid: boolean;
|
|
53231
53279
|
warnings: components["schemas"]["FlowValidationIssue"][];
|
|
53232
53280
|
};
|
|
53281
|
+
IdentityAssertionJwks: {
|
|
53282
|
+
/** @description Every key that may have signed a live assertion: the active key first, then verify-only keys kept for rotation. */
|
|
53283
|
+
keys: components["schemas"]["IdentityAssertionPublicJwk"][];
|
|
53284
|
+
};
|
|
53285
|
+
IdentityAssertionPublicJwk: {
|
|
53286
|
+
/** @description Always `ES256`. */
|
|
53287
|
+
alg: string;
|
|
53288
|
+
/** @description Curve; always `P-256`. */
|
|
53289
|
+
crv: string;
|
|
53290
|
+
/** @description Key id, matched against the token header `kid`. */
|
|
53291
|
+
kid: string;
|
|
53292
|
+
/** @description Key type; always `EC`. */
|
|
53293
|
+
kty: string;
|
|
53294
|
+
/** @description Always `sig`. */
|
|
53295
|
+
use: string;
|
|
53296
|
+
x: string;
|
|
53297
|
+
y: string;
|
|
53298
|
+
};
|
|
53233
53299
|
InputDeliveryReceipt: {
|
|
53234
53300
|
deliveryId: string;
|
|
53235
53301
|
executionId: string;
|
|
@@ -56763,8 +56829,23 @@ export interface RuntimeFlowToolConfig {
|
|
|
56763
56829
|
export interface RuntimeCustomToolConfig {
|
|
56764
56830
|
code: string;
|
|
56765
56831
|
language?: 'javascript' | 'typescript' | 'python';
|
|
56766
|
-
sandboxProvider?: 'quickjs' | 'daytona' | 'cloudflare-worker';
|
|
56832
|
+
sandboxProvider?: 'quickjs' | 'daytona' | 'cloudflare-worker' | 'runtype-sandbox';
|
|
56767
56833
|
timeout?: number;
|
|
56834
|
+
/** Egress posture for the code. Omitted means `'off'`; prefer an `allowedHostnames` list. */
|
|
56835
|
+
networkAccess?: 'off' | 'on' | {
|
|
56836
|
+
allowedHostnames: string[];
|
|
56837
|
+
};
|
|
56838
|
+
/** Managed secrets the code may send, read as phantom tokens from `secrets.<key>`. Requires SECRETS:READ. */
|
|
56839
|
+
secrets?: RuntimeCustomToolSecret[];
|
|
56840
|
+
}
|
|
56841
|
+
/** One managed secret a custom tool may send; the egress proxy injects it only for the matching host and path. */
|
|
56842
|
+
export interface RuntimeCustomToolSecret {
|
|
56843
|
+
/** Bare managed secret name, e.g. `GITHUB_TOKEN`. */
|
|
56844
|
+
key: string;
|
|
56845
|
+
hostnamePattern: string;
|
|
56846
|
+
pathPattern?: string;
|
|
56847
|
+
injectionMode: 'bearer_header' | 'api_key_header' | 'query_param' | 'basic_auth';
|
|
56848
|
+
injectionConfig?: Record<string, JsonValue>;
|
|
56768
56849
|
}
|
|
56769
56850
|
export interface RuntimeExternalToolConfig {
|
|
56770
56851
|
url: string;
|
|
@@ -62538,14 +62619,16 @@ interface ApiKeyRequestListParams {
|
|
|
62538
62619
|
}
|
|
62539
62620
|
//#endregion
|
|
62540
62621
|
//#region src/generated-tool-gate.d.ts
|
|
62622
|
+
declare const CUSTOM_TOOL_SANDBOX_PROVIDERS: readonly ["quickjs", "daytona", "cloudflare-worker", "runtype-sandbox"];
|
|
62623
|
+
type GateSandboxProvider = (typeof CUSTOM_TOOL_SANDBOX_PROVIDERS)[number] | 'cloudflare-sandbox';
|
|
62541
62624
|
interface GeneratedRuntimeToolGateOptions {
|
|
62542
62625
|
/**
|
|
62543
62626
|
* Allowed runtime tool types.
|
|
62544
62627
|
* Defaults to ['custom'] because this gate is intended for generated code tools.
|
|
62545
62628
|
*/
|
|
62546
62629
|
allowedToolTypes?: Array<'custom' | 'external' | 'flow' | 'local'>;
|
|
62547
|
-
/** Allowed sandbox providers for generated custom tools. Defaults to
|
|
62548
|
-
allowedSandboxProviders?:
|
|
62630
|
+
/** Allowed sandbox providers for generated custom tools. Defaults to every provider, including runtype-sandbox and its cloudflare-sandbox alias. */
|
|
62631
|
+
allowedSandboxProviders?: GateSandboxProvider[];
|
|
62549
62632
|
/** Allowed languages for generated custom tools. Defaults to JS/TS/Python. */
|
|
62550
62633
|
allowedLanguages?: Array<'javascript' | 'typescript' | 'python'>;
|
|
62551
62634
|
/** Maximum allowed code size in characters (default 12000). */
|
|
@@ -62561,6 +62644,15 @@ interface GeneratedRuntimeToolGateOptions {
|
|
|
62561
62644
|
blockedCodePatterns?: RegExp[];
|
|
62562
62645
|
/** Optional custom validator for additional policy checks. Return a violation message to reject. */
|
|
62563
62646
|
customValidator?: (tool: RuntimeTool) => string | null;
|
|
62647
|
+
/**
|
|
62648
|
+
* Network egress a generated custom tool may request via `config.networkAccess`. Off by default:
|
|
62649
|
+
* a proposal asking for anything but `'off'` is rejected. `true` passes the requested posture
|
|
62650
|
+
* through; `{ allowedHostnames }` accepts only an allowlist within those hosts. A generated tool
|
|
62651
|
+
* can never declare `config.secrets`: managed credentials are always rejected by this gate.
|
|
62652
|
+
*/
|
|
62653
|
+
allowNetworkAccess?: boolean | {
|
|
62654
|
+
allowedHostnames: string[];
|
|
62655
|
+
};
|
|
62564
62656
|
}
|
|
62565
62657
|
interface GeneratedRuntimeToolGateDecision {
|
|
62566
62658
|
approved: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,45 @@ interface ContextErrorHandling {
|
|
|
117
117
|
* Do not make direct changes to the file.
|
|
118
118
|
*/
|
|
119
119
|
interface paths {
|
|
120
|
+
"/.well-known/jwks.json": {
|
|
121
|
+
parameters: {
|
|
122
|
+
query?: never;
|
|
123
|
+
header?: never;
|
|
124
|
+
path?: never;
|
|
125
|
+
cookie?: never;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Identity assertion signing keys (JWKS)
|
|
129
|
+
* @description Public keys that verify the Runtype-signed `{{_identity.token}}` a tool call carries. Verify offline: check the ES256 signature against the key whose `kid` matches the token header, then `iss` (pin it to the one Runtype organization you trust: `<API origin>/orgs/<organizationId>`), `aud` (your host), `exp`, and the per-scope assurance in the `runtype` claim. Cache the response for up to five minutes; re-fetch when a token names an unknown `kid`.
|
|
130
|
+
*/
|
|
131
|
+
get: {
|
|
132
|
+
parameters: {
|
|
133
|
+
query?: never;
|
|
134
|
+
header?: never;
|
|
135
|
+
path?: never;
|
|
136
|
+
cookie?: never;
|
|
137
|
+
};
|
|
138
|
+
requestBody?: never;
|
|
139
|
+
responses: {
|
|
140
|
+
/** @description The published key set. Empty when this environment has no signing key configured. */
|
|
141
|
+
200: {
|
|
142
|
+
headers: {
|
|
143
|
+
[name: string]: unknown;
|
|
144
|
+
};
|
|
145
|
+
content: {
|
|
146
|
+
"application/json": components["schemas"]["IdentityAssertionJwks"];
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
put?: never;
|
|
152
|
+
post?: never;
|
|
153
|
+
delete?: never;
|
|
154
|
+
options?: never;
|
|
155
|
+
head?: never;
|
|
156
|
+
patch?: never;
|
|
157
|
+
trace?: never;
|
|
158
|
+
};
|
|
120
159
|
"/v1/agent-aliases": {
|
|
121
160
|
parameters: {
|
|
122
161
|
query?: never;
|
|
@@ -40582,6 +40621,15 @@ interface paths {
|
|
|
40582
40621
|
"application/json": components["schemas"]["Error"];
|
|
40583
40622
|
};
|
|
40584
40623
|
};
|
|
40624
|
+
/** @description A target record changed while the edit was applied (`record_conflict`); nothing was written, retry the edit */
|
|
40625
|
+
409: {
|
|
40626
|
+
headers: {
|
|
40627
|
+
[name: string]: unknown;
|
|
40628
|
+
};
|
|
40629
|
+
content: {
|
|
40630
|
+
"application/json": components["schemas"]["Error"];
|
|
40631
|
+
};
|
|
40632
|
+
};
|
|
40585
40633
|
/** @description A record's post-merge metadata violates its type's collection schema (enforce mode); the whole edit is rejected */
|
|
40586
40634
|
422: {
|
|
40587
40635
|
headers: {
|
|
@@ -41215,7 +41263,7 @@ interface paths {
|
|
|
41215
41263
|
/** @enum {string} */
|
|
41216
41264
|
role: "user" | "assistant";
|
|
41217
41265
|
}[] | null;
|
|
41218
|
-
/** @
|
|
41266
|
+
/** @description Replaces the whole metadata object. Omit to leave metadata unchanged. */
|
|
41219
41267
|
metadata?: {
|
|
41220
41268
|
[key: string]: unknown;
|
|
41221
41269
|
};
|
|
@@ -41306,7 +41354,7 @@ interface paths {
|
|
|
41306
41354
|
"application/json": components["schemas"]["Error"];
|
|
41307
41355
|
};
|
|
41308
41356
|
};
|
|
41309
|
-
/** @description Duplicate record */
|
|
41357
|
+
/** @description Duplicate record (`duplicate_record`), or the record changed while this update was applied (`record_conflict`; re-read and retry) */
|
|
41310
41358
|
409: {
|
|
41311
41359
|
headers: {
|
|
41312
41360
|
[name: string]: unknown;
|
|
@@ -53230,6 +53278,24 @@ interface components {
|
|
|
53230
53278
|
valid: boolean;
|
|
53231
53279
|
warnings: components["schemas"]["FlowValidationIssue"][];
|
|
53232
53280
|
};
|
|
53281
|
+
IdentityAssertionJwks: {
|
|
53282
|
+
/** @description Every key that may have signed a live assertion: the active key first, then verify-only keys kept for rotation. */
|
|
53283
|
+
keys: components["schemas"]["IdentityAssertionPublicJwk"][];
|
|
53284
|
+
};
|
|
53285
|
+
IdentityAssertionPublicJwk: {
|
|
53286
|
+
/** @description Always `ES256`. */
|
|
53287
|
+
alg: string;
|
|
53288
|
+
/** @description Curve; always `P-256`. */
|
|
53289
|
+
crv: string;
|
|
53290
|
+
/** @description Key id, matched against the token header `kid`. */
|
|
53291
|
+
kid: string;
|
|
53292
|
+
/** @description Key type; always `EC`. */
|
|
53293
|
+
kty: string;
|
|
53294
|
+
/** @description Always `sig`. */
|
|
53295
|
+
use: string;
|
|
53296
|
+
x: string;
|
|
53297
|
+
y: string;
|
|
53298
|
+
};
|
|
53233
53299
|
InputDeliveryReceipt: {
|
|
53234
53300
|
deliveryId: string;
|
|
53235
53301
|
executionId: string;
|
|
@@ -56763,8 +56829,23 @@ export interface RuntimeFlowToolConfig {
|
|
|
56763
56829
|
export interface RuntimeCustomToolConfig {
|
|
56764
56830
|
code: string;
|
|
56765
56831
|
language?: 'javascript' | 'typescript' | 'python';
|
|
56766
|
-
sandboxProvider?: 'quickjs' | 'daytona' | 'cloudflare-worker';
|
|
56832
|
+
sandboxProvider?: 'quickjs' | 'daytona' | 'cloudflare-worker' | 'runtype-sandbox';
|
|
56767
56833
|
timeout?: number;
|
|
56834
|
+
/** Egress posture for the code. Omitted means `'off'`; prefer an `allowedHostnames` list. */
|
|
56835
|
+
networkAccess?: 'off' | 'on' | {
|
|
56836
|
+
allowedHostnames: string[];
|
|
56837
|
+
};
|
|
56838
|
+
/** Managed secrets the code may send, read as phantom tokens from `secrets.<key>`. Requires SECRETS:READ. */
|
|
56839
|
+
secrets?: RuntimeCustomToolSecret[];
|
|
56840
|
+
}
|
|
56841
|
+
/** One managed secret a custom tool may send; the egress proxy injects it only for the matching host and path. */
|
|
56842
|
+
export interface RuntimeCustomToolSecret {
|
|
56843
|
+
/** Bare managed secret name, e.g. `GITHUB_TOKEN`. */
|
|
56844
|
+
key: string;
|
|
56845
|
+
hostnamePattern: string;
|
|
56846
|
+
pathPattern?: string;
|
|
56847
|
+
injectionMode: 'bearer_header' | 'api_key_header' | 'query_param' | 'basic_auth';
|
|
56848
|
+
injectionConfig?: Record<string, JsonValue>;
|
|
56768
56849
|
}
|
|
56769
56850
|
export interface RuntimeExternalToolConfig {
|
|
56770
56851
|
url: string;
|
|
@@ -62538,14 +62619,16 @@ interface ApiKeyRequestListParams {
|
|
|
62538
62619
|
}
|
|
62539
62620
|
//#endregion
|
|
62540
62621
|
//#region src/generated-tool-gate.d.ts
|
|
62622
|
+
declare const CUSTOM_TOOL_SANDBOX_PROVIDERS: readonly ["quickjs", "daytona", "cloudflare-worker", "runtype-sandbox"];
|
|
62623
|
+
type GateSandboxProvider = (typeof CUSTOM_TOOL_SANDBOX_PROVIDERS)[number] | 'cloudflare-sandbox';
|
|
62541
62624
|
interface GeneratedRuntimeToolGateOptions {
|
|
62542
62625
|
/**
|
|
62543
62626
|
* Allowed runtime tool types.
|
|
62544
62627
|
* Defaults to ['custom'] because this gate is intended for generated code tools.
|
|
62545
62628
|
*/
|
|
62546
62629
|
allowedToolTypes?: Array<'custom' | 'external' | 'flow' | 'local'>;
|
|
62547
|
-
/** Allowed sandbox providers for generated custom tools. Defaults to
|
|
62548
|
-
allowedSandboxProviders?:
|
|
62630
|
+
/** Allowed sandbox providers for generated custom tools. Defaults to every provider, including runtype-sandbox and its cloudflare-sandbox alias. */
|
|
62631
|
+
allowedSandboxProviders?: GateSandboxProvider[];
|
|
62549
62632
|
/** Allowed languages for generated custom tools. Defaults to JS/TS/Python. */
|
|
62550
62633
|
allowedLanguages?: Array<'javascript' | 'typescript' | 'python'>;
|
|
62551
62634
|
/** Maximum allowed code size in characters (default 12000). */
|
|
@@ -62561,6 +62644,15 @@ interface GeneratedRuntimeToolGateOptions {
|
|
|
62561
62644
|
blockedCodePatterns?: RegExp[];
|
|
62562
62645
|
/** Optional custom validator for additional policy checks. Return a violation message to reject. */
|
|
62563
62646
|
customValidator?: (tool: RuntimeTool) => string | null;
|
|
62647
|
+
/**
|
|
62648
|
+
* Network egress a generated custom tool may request via `config.networkAccess`. Off by default:
|
|
62649
|
+
* a proposal asking for anything but `'off'` is rejected. `true` passes the requested posture
|
|
62650
|
+
* through; `{ allowedHostnames }` accepts only an allowlist within those hosts. A generated tool
|
|
62651
|
+
* can never declare `config.secrets`: managed credentials are always rejected by this gate.
|
|
62652
|
+
*/
|
|
62653
|
+
allowNetworkAccess?: boolean | {
|
|
62654
|
+
allowedHostnames: string[];
|
|
62655
|
+
};
|
|
62564
62656
|
}
|
|
62565
62657
|
interface GeneratedRuntimeToolGateDecision {
|
|
62566
62658
|
approved: boolean;
|
package/dist/index.mjs
CHANGED
|
@@ -2351,12 +2351,13 @@ const DEFAULT_BLOCKED_CODE_PATTERNS = [
|
|
|
2351
2351
|
/\bsubprocess\b/i,
|
|
2352
2352
|
/\bos\.system\s*\(/i
|
|
2353
2353
|
];
|
|
2354
|
-
const
|
|
2354
|
+
const CUSTOM_TOOL_SANDBOX_PROVIDERS = [
|
|
2355
2355
|
"quickjs",
|
|
2356
2356
|
"daytona",
|
|
2357
2357
|
"cloudflare-worker",
|
|
2358
|
-
"
|
|
2358
|
+
"runtype-sandbox"
|
|
2359
2359
|
];
|
|
2360
|
+
const DEFAULT_ALLOWED_SANDBOX_PROVIDERS = [...CUSTOM_TOOL_SANDBOX_PROVIDERS, "cloudflare-sandbox"];
|
|
2360
2361
|
const DEFAULT_ALLOWED_LANGUAGES = [
|
|
2361
2362
|
"javascript",
|
|
2362
2363
|
"typescript",
|
|
@@ -2378,7 +2379,21 @@ function isLanguage(value) {
|
|
|
2378
2379
|
return value === "javascript" || value === "typescript" || value === "python";
|
|
2379
2380
|
}
|
|
2380
2381
|
function isSandboxProvider(value) {
|
|
2381
|
-
return value
|
|
2382
|
+
return CUSTOM_TOOL_SANDBOX_PROVIDERS.includes(value);
|
|
2383
|
+
}
|
|
2384
|
+
function isNetworkAccess(value) {
|
|
2385
|
+
if (value === "off" || value === "on") return true;
|
|
2386
|
+
if (!isObject(value) || !Array.isArray(value.allowedHostnames)) return false;
|
|
2387
|
+
const hosts = value.allowedHostnames;
|
|
2388
|
+
return hosts.length > 0 && hosts.every((host) => typeof host === "string" && host.length > 0);
|
|
2389
|
+
}
|
|
2390
|
+
/** Why the requested posture exceeds what the caller allowed, or null when it fits. */
|
|
2391
|
+
function networkAccessViolation(requested, allowed) {
|
|
2392
|
+
if (requested === void 0 || requested === "off" || allowed === true) return null;
|
|
2393
|
+
if (!allowed) return "Generated tool requests network access, which this gate does not allow";
|
|
2394
|
+
if (requested === "on") return "Generated tool requests unrestricted network access; only an allowedHostnames list is allowed";
|
|
2395
|
+
const outside = requested.allowedHostnames.filter((host) => !allowed.allowedHostnames.includes(host));
|
|
2396
|
+
return outside.length > 0 ? `Generated tool requests hosts outside the allowed list: ${outside.join(", ")}` : null;
|
|
2382
2397
|
}
|
|
2383
2398
|
function isJSONSchema(value) {
|
|
2384
2399
|
if (!isObject(value)) return false;
|
|
@@ -2425,6 +2440,12 @@ function normalizeGeneratedProposal(proposal, violations) {
|
|
|
2425
2440
|
const sandboxProviderRaw = config.sandboxProvider;
|
|
2426
2441
|
const languageRaw = config.language;
|
|
2427
2442
|
const timeoutRaw = config.timeout;
|
|
2443
|
+
const sandboxProvider = isSandboxProvider(sandboxProviderRaw) ? sandboxProviderRaw : "cloudflare-worker";
|
|
2444
|
+
const language = isLanguage(languageRaw) ? languageRaw : "javascript";
|
|
2445
|
+
const timeout = asNumber(timeoutRaw);
|
|
2446
|
+
if (Array.isArray(config.secrets) && config.secrets.length > 0) violations.push("Generated tools cannot declare config.secrets (managed credentials)");
|
|
2447
|
+
const networkAccess = config.networkAccess;
|
|
2448
|
+
if (networkAccess !== void 0 && !isNetworkAccess(networkAccess)) violations.push("config.networkAccess must be 'off', 'on', or { allowedHostnames: string[] }");
|
|
2428
2449
|
return {
|
|
2429
2450
|
name,
|
|
2430
2451
|
description,
|
|
@@ -2432,9 +2453,10 @@ function normalizeGeneratedProposal(proposal, violations) {
|
|
|
2432
2453
|
parametersSchema,
|
|
2433
2454
|
config: {
|
|
2434
2455
|
code,
|
|
2435
|
-
sandboxProvider
|
|
2436
|
-
language
|
|
2437
|
-
timeout
|
|
2456
|
+
sandboxProvider,
|
|
2457
|
+
language,
|
|
2458
|
+
timeout,
|
|
2459
|
+
...isNetworkAccess(networkAccess) ? { networkAccess } : {}
|
|
2438
2460
|
}
|
|
2439
2461
|
};
|
|
2440
2462
|
}
|
|
@@ -2487,6 +2509,8 @@ function evaluateGeneratedRuntimeToolProposal(proposal, options = {}) {
|
|
|
2487
2509
|
violations.push(`Generated code matched blocked pattern: ${pattern}`);
|
|
2488
2510
|
break;
|
|
2489
2511
|
}
|
|
2512
|
+
const networkViolation = networkAccessViolation(normalized.config.networkAccess, options.allowNetworkAccess);
|
|
2513
|
+
if (networkViolation) violations.push(networkViolation);
|
|
2490
2514
|
}
|
|
2491
2515
|
const tool = {
|
|
2492
2516
|
name: normalized.name,
|
|
@@ -13456,7 +13480,7 @@ function transformQueryParams(params) {
|
|
|
13456
13480
|
}
|
|
13457
13481
|
//#endregion
|
|
13458
13482
|
//#region src/version.ts
|
|
13459
|
-
const SDK_VERSION = "10.
|
|
13483
|
+
const SDK_VERSION = "10.6.0";
|
|
13460
13484
|
/**
|
|
13461
13485
|
* Canonical client identity the API uses for attribution
|
|
13462
13486
|
* (`detectActorSource` in apps/api/src/lib/audit-log.ts keys `'sdk'` off the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/sdk",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "TypeScript SDK for the Runtype API with fluent methods. Use it to quickly realize AI products, agents, and workflows.",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@runtypelabs/shared": "3.
|
|
27
|
+
"@runtypelabs/shared": "3.67.0",
|
|
28
28
|
"openapi-typescript": "^7.13.0",
|
|
29
29
|
"tsdown": "^0.23.0",
|
|
30
30
|
"typescript": "^6.0.3",
|