@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 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 DEFAULT_ALLOWED_SANDBOX_PROVIDERS = [
2355
+ const CUSTOM_TOOL_SANDBOX_PROVIDERS = [
2356
2356
  "quickjs",
2357
2357
  "daytona",
2358
2358
  "cloudflare-worker",
2359
- "cloudflare-sandbox"
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 === "quickjs" || value === "daytona" || value === "cloudflare-worker";
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: isSandboxProvider(sandboxProviderRaw) ? sandboxProviderRaw : "cloudflare-worker",
2437
- language: isLanguage(languageRaw) ? languageRaw : "javascript",
2438
- timeout: asNumber(timeoutRaw)
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.5.3";
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
- /** @default {} */
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 ['quickjs', 'daytona', 'cloudflare-worker', 'cloudflare-sandbox']. */
62548
- allowedSandboxProviders?: Array<'quickjs' | 'daytona' | 'cloudflare-worker' | 'cloudflare-sandbox'>;
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
- /** @default {} */
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 ['quickjs', 'daytona', 'cloudflare-worker', 'cloudflare-sandbox']. */
62548
- allowedSandboxProviders?: Array<'quickjs' | 'daytona' | 'cloudflare-worker' | 'cloudflare-sandbox'>;
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 DEFAULT_ALLOWED_SANDBOX_PROVIDERS = [
2354
+ const CUSTOM_TOOL_SANDBOX_PROVIDERS = [
2355
2355
  "quickjs",
2356
2356
  "daytona",
2357
2357
  "cloudflare-worker",
2358
- "cloudflare-sandbox"
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 === "quickjs" || value === "daytona" || value === "cloudflare-worker";
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: isSandboxProvider(sandboxProviderRaw) ? sandboxProviderRaw : "cloudflare-worker",
2436
- language: isLanguage(languageRaw) ? languageRaw : "javascript",
2437
- timeout: asNumber(timeoutRaw)
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.5.3";
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.5.3",
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.66.0",
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",