@runtypelabs/cli 2.35.0 → 2.35.2

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.
Files changed (2) hide show
  1. package/dist/index.js +881 -484
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -15212,7 +15212,7 @@ var CANONICAL_LOG_COLUMN_SET = {
15212
15212
  };
15213
15213
  var CANONICAL_LOG_COLUMNS = Object.keys(CANONICAL_LOG_COLUMN_SET);
15214
15214
 
15215
- // ../shared/dist/chunk-2GMXBACL.mjs
15215
+ // ../shared/dist/chunk-Q5ZS77L4.mjs
15216
15216
  var MODEL_FAMILY_PROVIDER_IDS = {
15217
15217
  "claude-fable-5": {
15218
15218
  "anthropic": "claude-fable-5",
@@ -15498,6 +15498,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
15498
15498
  "glm-5-3": {
15499
15499
  "vercel": "zai/glm-5.3"
15500
15500
  },
15501
+ "glm-5-3-flash": {
15502
+ "vercel": "zai/glm-5.3-flash"
15503
+ },
15501
15504
  "glm-5.2": {
15502
15505
  "mixlayer": "z-ai/glm-5.2",
15503
15506
  "vercel": "zai/glm-5.2"
@@ -15508,6 +15511,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
15508
15511
  "glm-5.3": {
15509
15512
  "vercel": "zai/glm-5.3"
15510
15513
  },
15514
+ "glm-5.3-flash": {
15515
+ "vercel": "zai/glm-5.3-flash"
15516
+ },
15511
15517
  "gpt-4-1": {
15512
15518
  "openai": "gpt-4.1",
15513
15519
  "vercel": "openai/gpt-4.1"
@@ -15564,12 +15570,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
15564
15570
  "gpt-4o-mini-fast": {
15565
15571
  "vercel": "openai/gpt-4o-mini-fast"
15566
15572
  },
15567
- "gpt-4o-mini-search": {
15568
- "vercel": "openai/gpt-4o-mini-search-preview"
15569
- },
15570
- "gpt-4o-mini-search-preview": {
15571
- "vercel": "openai/gpt-4o-mini-search-preview"
15572
- },
15573
15573
  "gpt-5": {
15574
15574
  "openai": "gpt-5",
15575
15575
  "vercel": "openai/gpt-5"
@@ -15796,6 +15796,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
15796
15796
  "gpt-image-1.5": {
15797
15797
  "openai": "gpt-image-1.5"
15798
15798
  },
15799
+ "gpt-oss-safeguard-120b": {
15800
+ "vercel": "openai/gpt-oss-safeguard-120b"
15801
+ },
15799
15802
  "grok-4-20-0309-non-reasoning": {
15800
15803
  "xai": "grok-4.20-0309-non-reasoning"
15801
15804
  },
@@ -15996,12 +15999,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
15996
15999
  "lyria-3-pro-preview": {
15997
16000
  "google": "lyria-3-pro-preview"
15998
16001
  },
15999
- "magistral-medium": {
16000
- "vercel": "mistral/magistral-medium"
16001
- },
16002
- "magistral-small": {
16003
- "vercel": "mistral/magistral-small"
16004
- },
16005
16002
  "mercury-2": {
16006
16003
  "vercel": "inception/mercury-2"
16007
16004
  },
@@ -16023,18 +16020,27 @@ var MODEL_FAMILY_PROVIDER_IDS = {
16023
16020
  "minimax-m2-7": {
16024
16021
  "vercel": "minimax/minimax-m2.7"
16025
16022
  },
16023
+ "minimax-m2-7-free": {
16024
+ "vercel": "minimax/minimax-m2.7-free"
16025
+ },
16026
16026
  "minimax-m2-7-highspeed": {
16027
16027
  "vercel": "minimax/minimax-m2.7-highspeed"
16028
16028
  },
16029
16029
  "minimax-m2.7": {
16030
16030
  "vercel": "minimax/minimax-m2.7"
16031
16031
  },
16032
+ "minimax-m2.7-free": {
16033
+ "vercel": "minimax/minimax-m2.7-free"
16034
+ },
16032
16035
  "minimax-m2.7-highspeed": {
16033
16036
  "vercel": "minimax/minimax-m2.7-highspeed"
16034
16037
  },
16035
16038
  "minimax-m3": {
16036
16039
  "vercel": "minimax/minimax-m3"
16037
16040
  },
16041
+ "minimax-m3-free": {
16042
+ "vercel": "minimax/minimax-m3-free"
16043
+ },
16038
16044
  "ministral-14b": {
16039
16045
  "vercel": "mistral/ministral-14b"
16040
16046
  },
@@ -16089,9 +16095,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
16089
16095
  "nemotron-3-5-lightning": {
16090
16096
  "vercel": "nvidia/nemotron-3.5-lightning"
16091
16097
  },
16092
- "nemotron-3-5-lightning-free": {
16093
- "vercel": "nvidia/nemotron-3.5-lightning-free"
16094
- },
16095
16098
  "nemotron-3-nano-30b-a3b": {
16096
16099
  "vercel": "nvidia/nemotron-3-nano-30b-a3b"
16097
16100
  },
@@ -16104,9 +16107,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
16104
16107
  "nemotron-3.5-lightning": {
16105
16108
  "vercel": "nvidia/nemotron-3.5-lightning"
16106
16109
  },
16107
- "nemotron-3.5-lightning-free": {
16108
- "vercel": "nvidia/nemotron-3.5-lightning-free"
16109
- },
16110
16110
  "nemotron-nano-12b-v2-vl": {
16111
16111
  "vercel": "nvidia/nemotron-nano-12b-v2-vl"
16112
16112
  },
@@ -16204,6 +16204,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
16204
16204
  "qwen3-8-27b": {
16205
16205
  "vercel": "alibaba/qwen3.8-27b"
16206
16206
  },
16207
+ "qwen3-8-flash": {
16208
+ "vercel": "alibaba/qwen3.8-flash"
16209
+ },
16207
16210
  "qwen3-8-max": {
16208
16211
  "vercel": "alibaba/qwen3.8-max"
16209
16212
  },
@@ -16295,6 +16298,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
16295
16298
  "qwen3.8-27b": {
16296
16299
  "vercel": "alibaba/qwen3.8-27b"
16297
16300
  },
16301
+ "qwen3.8-flash": {
16302
+ "vercel": "alibaba/qwen3.8-flash"
16303
+ },
16298
16304
  "qwen3.8-max": {
16299
16305
  "vercel": "alibaba/qwen3.8-max"
16300
16306
  },
@@ -16357,9 +16363,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
16357
16363
  },
16358
16364
  "trinity-large-thinking": {
16359
16365
  "vercel": "arcee-ai/trinity-large-thinking"
16360
- },
16361
- "trinity-mini": {
16362
- "vercel": "arcee-ai/trinity-mini"
16363
16366
  }
16364
16367
  };
16365
16368
  var PLATFORM_KEY_PROVIDER_MAP = {
@@ -16387,6 +16390,333 @@ var PLATFORM_KEY_PROVIDER_MAP = {
16387
16390
  var PLATFORM_KEY_PROVIDERS = new Set(
16388
16391
  Object.entries(PLATFORM_KEY_PROVIDER_MAP).filter(([, v2]) => v2).map(([k2]) => k2)
16389
16392
  );
16393
+ function workersAiPrimary(ids, fallback = ["vercel"]) {
16394
+ const config3 = {
16395
+ providers: [{ provider: "workers-ai", weight: 100 }],
16396
+ fallback
16397
+ };
16398
+ return Object.fromEntries(ids.map((id) => [id, config3]));
16399
+ }
16400
+ function workersAiAliases(cfId, ids) {
16401
+ return Object.fromEntries(
16402
+ ids.map((id) => [
16403
+ id,
16404
+ id.includes("/") ? { "workers-ai": cfId, vercel: id } : { "workers-ai": cfId }
16405
+ ])
16406
+ );
16407
+ }
16408
+ var DEEPSEEK_V4_FLASH_IDS = [
16409
+ "deepseek-v4-flash",
16410
+ "deepseek-v4-flash-0731",
16411
+ "deepseek/deepseek-v4-flash",
16412
+ "deepseek/deepseek-v4-flash-0731"
16413
+ ];
16414
+ var GLM_5_3_FLASH_IDS = ["glm-5.3-flash", "glm-5-3-flash", "zai/glm-5.3-flash"];
16415
+ var PROVIDER_ROUTING_CONFIG = {
16416
+ // Claude 4.5 Sonnet - Route through Vercel AI Gateway
16417
+ "claude-sonnet-4-5": {
16418
+ providers: [
16419
+ { provider: "vercel", weight: 100 }
16420
+ ],
16421
+ fallback: ["anthropic"]
16422
+ },
16423
+ // Claude 4.5 Haiku - Route through Vercel AI Gateway
16424
+ "claude-haiku-4-5": {
16425
+ providers: [
16426
+ { provider: "vercel", weight: 100 }
16427
+ ],
16428
+ fallback: ["anthropic"]
16429
+ },
16430
+ // Claude 4.5 Opus - Route through Vercel AI Gateway
16431
+ "claude-opus-4-5": {
16432
+ providers: [
16433
+ { provider: "vercel", weight: 100 }
16434
+ ],
16435
+ fallback: ["anthropic"]
16436
+ },
16437
+ // Claude Fable 5 - Route through Vercel AI Gateway
16438
+ "claude-fable-5": {
16439
+ providers: [
16440
+ { provider: "vercel", weight: 100 }
16441
+ ],
16442
+ fallback: ["anthropic"]
16443
+ },
16444
+ // GPT-5.4 Nano - CF Gateway primary for testing, Vercel + OpenAI as fallback
16445
+ "gpt-5.4-nano": {
16446
+ providers: [
16447
+ { provider: "cloudflare", weight: 100 }
16448
+ ],
16449
+ fallback: ["vercel", "openai"]
16450
+ },
16451
+ "gpt-5-4-nano": {
16452
+ providers: [
16453
+ { provider: "cloudflare", weight: 100 }
16454
+ ],
16455
+ fallback: ["vercel", "openai"]
16456
+ },
16457
+ // Gemini 2.5 Pro - Route through Vercel AI Gateway
16458
+ "gemini-2.5-pro": {
16459
+ providers: [
16460
+ { provider: "vercel", weight: 100 }
16461
+ ],
16462
+ fallback: ["google"]
16463
+ },
16464
+ // Gemini 2.5 Flash - Route through Vercel AI Gateway
16465
+ "gemini-2.5-flash": {
16466
+ providers: [
16467
+ { provider: "vercel", weight: 100 }
16468
+ ],
16469
+ fallback: ["google"]
16470
+ },
16471
+ // Gemini 2.5 Flash Image - Route through Vercel AI Gateway only
16472
+ // Note: No Google fallback - this image model is only available via Vercel gateway
16473
+ "gemini-2.5-flash-image": {
16474
+ providers: [
16475
+ { provider: "vercel", weight: 100 }
16476
+ ],
16477
+ fallback: []
16478
+ },
16479
+ // Gemini 3 Flash - the Vercel gateway alias is advertised but fails live
16480
+ // dispatch. Route the family through Google's still-live preview id instead.
16481
+ "gemini-3-flash": {
16482
+ providers: [
16483
+ { provider: "google", weight: 100 }
16484
+ ],
16485
+ fallback: []
16486
+ },
16487
+ // Gemini 3.1 Flash-Lite - Vercel AI Gateway (3.1 generation fast text).
16488
+ // Google fallback mirrors gemini-3-flash: the model exists on the google
16489
+ // provider, so a missing/unavailable gateway key degrades to direct Google
16490
+ // instead of a guaranteed dispatch failure (also what makes local dev work
16491
+ // with only PLATFORM_GOOGLE_KEY set).
16492
+ "gemini-3-1-flash-lite": {
16493
+ providers: [
16494
+ { provider: "vercel", weight: 100 }
16495
+ ],
16496
+ fallback: ["google"]
16497
+ },
16498
+ // Gemini 3 Pro Image - Route through Vercel AI Gateway only
16499
+ // Note: No Google fallback - this image model is only available via Vercel gateway
16500
+ "gemini-3-pro-image": {
16501
+ providers: [
16502
+ { provider: "vercel", weight: 100 }
16503
+ ],
16504
+ fallback: []
16505
+ },
16506
+ // Gemini 3.1 Flash Image - Vercel AI Gateway only
16507
+ "gemini-3-1-flash-image": {
16508
+ providers: [
16509
+ { provider: "vercel", weight: 100 }
16510
+ ],
16511
+ fallback: []
16512
+ },
16513
+ // Gemini 3 Pro Preview - Deprecated March 9, 2026. Aliased to gemini-3.1-pro in router.
16514
+ "gemini-3-pro-preview": {
16515
+ providers: [
16516
+ { provider: "vercel", weight: 100 }
16517
+ ],
16518
+ fallback: ["google"]
16519
+ },
16520
+ // Gemini 3.1 Pro - Route through Vercel AI Gateway (successor to gemini-3-pro-preview)
16521
+ "gemini-3.1-pro": {
16522
+ providers: [
16523
+ { provider: "vercel", weight: 100 }
16524
+ ],
16525
+ fallback: ["google"]
16526
+ },
16527
+ // Grok 4 legacy alias - route to the current Grok 4.3 successor.
16528
+ "grok-4": {
16529
+ providers: [
16530
+ { provider: "vercel", weight: 100 }
16531
+ ],
16532
+ fallback: ["xai"]
16533
+ },
16534
+ // Grok 4.3 - Route through Vercel AI Gateway with xAI fallback
16535
+ "grok-4.3": {
16536
+ providers: [
16537
+ { provider: "vercel", weight: 100 }
16538
+ ],
16539
+ fallback: ["xai"]
16540
+ },
16541
+ // Grok 4 Fast legacy aliases - route to the live 4.20 non-reasoning
16542
+ // successor; Vercel still advertises the 4.1 ids but rejects dispatch.
16543
+ "grok-4-fast": {
16544
+ providers: [
16545
+ { provider: "vercel", weight: 100 }
16546
+ ],
16547
+ fallback: []
16548
+ },
16549
+ "grok-4.1-fast-non-reasoning": {
16550
+ providers: [
16551
+ { provider: "vercel", weight: 100 }
16552
+ ],
16553
+ fallback: []
16554
+ },
16555
+ // GPT 5.1 Codex Max - Route through Vercel AI Gateway
16556
+ "gpt-5.1-codex-max": {
16557
+ providers: [
16558
+ { provider: "vercel", weight: 100 }
16559
+ ],
16560
+ fallback: ["openai"]
16561
+ },
16562
+ // Kimi K2.5 is RETIRED — see EXCLUDED_MODELS in scripts/update-models.ts.
16563
+ // Cloudflare deprecated it on 2026-05-30 and silently served K2.6 in its
16564
+ // place, so the id no longer meant what it said. `resolveModelAlias` maps
16565
+ // kimi-k2.5 → kimi-k2.6 for any stored reference that outlives migration 0120.
16566
+ // Kimi K2.6 - Route through Cloudflare Workers AI
16567
+ "kimi-k2.6": {
16568
+ providers: [
16569
+ { provider: "workers-ai", weight: 100 }
16570
+ ],
16571
+ fallback: ["vercel"]
16572
+ },
16573
+ // Kimi K2.7 Code - Route through Mixlayer, fall back to Cloudflare Workers AI.
16574
+ // Vercel renamed its listing to `moonshotai/kimi-k2.7-code-highspeed`, so the
16575
+ // bare `kimi-k2.7-code` base model no longer resolves to a Vercel gateway id;
16576
+ // Mixlayer (a platform-key provider) serves `moonshotai/kimi-k2.7-code`.
16577
+ // Workers AI (`@cf/moonshotai/kimi-k2.7-code`) was the original primary but
16578
+ // was removed from models.dev upstream in 2026-08, so its pricing data no
16579
+ // longer flows into the generated config — moved to fallback.
16580
+ "kimi-k2.7-code": {
16581
+ providers: [
16582
+ { provider: "mixlayer", weight: 100 }
16583
+ ],
16584
+ fallback: ["workers-ai"]
16585
+ },
16586
+ // NVIDIA Nemotron-3 120B - Route through Cloudflare Workers AI (no Vercel equivalent)
16587
+ "nemotron-3-120b-a12b": {
16588
+ providers: [
16589
+ { provider: "workers-ai", weight: 100 }
16590
+ ]
16591
+ },
16592
+ // Google Gemma 4 26B - Route through Cloudflare Workers AI
16593
+ "gemma-4-26b-a4b-it": {
16594
+ providers: [
16595
+ { provider: "workers-ai", weight: 100 }
16596
+ ],
16597
+ fallback: ["vercel"]
16598
+ },
16599
+ // OpenAI GPT OSS 120B - Route through Tinfoil, fall back to Workers AI.
16600
+ // Workers AI (`@cf/openai/gpt-oss-120b`) was the original primary but was
16601
+ // removed from models.dev upstream in 2026-08, so its pricing data no longer
16602
+ // flows into the generated config — moved to fallback.
16603
+ "gpt-oss-120b": {
16604
+ providers: [
16605
+ { provider: "tinfoil", weight: 100 }
16606
+ ],
16607
+ fallback: ["workers-ai"]
16608
+ },
16609
+ // Z.ai GLM-5.2 - Route through Cloudflare Workers AI, then Mixlayer, then the
16610
+ // Vercel AI Gateway. All three serve the same base model, so a Workers AI
16611
+ // rate-limit / capacity failure fast-fails to the next provider on the SAME
16612
+ // model rather than erroring the run (see `getPlatformDefaultStallFallback`,
16613
+ // which derives its same-model failover chain from this ordered list).
16614
+ // Mixlayer sits in the middle because it is the most reliable GLM host we
16615
+ // measured; Vercel is the last-resort gateway.
16616
+ //
16617
+ // This route is curated independently of generated upstream listings. The
16618
+ // Workers AI variant disappeared from models.dev in 2026-08, but the binding
16619
+ // endpoint remains executable and its pricing is preserved in the static
16620
+ // WORKERS_AI_MODEL_MAPPINGS table in @runtypelabs/model-execution.
16621
+ //
16622
+ // `providers` is the selection-time primary (Workers AI); `fallback` is the
16623
+ // ORDERED remaining-provider chain, used both for selection-time key
16624
+ // fallback AND as the runtime same-model failover order.
16625
+ //
16626
+ // All three id forms of this model resolve to the same route:
16627
+ // - `glm-5.2` — bare routed family (this entry)
16628
+ // - `glm-5-2` — dashed alias form
16629
+ // - `zai/glm-5.2` — gateway/catalog id (what surfaces like Persona pin);
16630
+ // the explicit entry overrides the static catalog provider (`vercel`) via
16631
+ // the PROVIDER_ROUTING_CONFIG-wins branch in resolveRoutedFamily.
16632
+ "glm-5.2": {
16633
+ providers: [
16634
+ { provider: "workers-ai", weight: 100 }
16635
+ ],
16636
+ fallback: ["mixlayer", "vercel"]
16637
+ },
16638
+ "glm-5-2": {
16639
+ providers: [
16640
+ { provider: "workers-ai", weight: 100 }
16641
+ ],
16642
+ fallback: ["mixlayer", "vercel"]
16643
+ },
16644
+ "zai/glm-5.2": {
16645
+ providers: [
16646
+ { provider: "workers-ai", weight: 100 }
16647
+ ],
16648
+ fallback: ["mixlayer", "vercel"]
16649
+ },
16650
+ // DeepSeek V4 Pro - Route through Cloudflare Workers AI, fall back to the
16651
+ // Vercel AI Gateway. Cloudflare serves the date-pinned build
16652
+ // (`@cf/deepseek-ai/deepseek-v4-pro-0813`) as its only V4 Pro variant, so every
16653
+ // id form maps onto it; the Vercel listing is the ordered fallback, used both
16654
+ // for selection-time key/binding fallback and as the runtime same-model
16655
+ // failover rung (`getPlatformDefaultStallFallback`).
16656
+ //
16657
+ // All four id forms of this model resolve to the same Workers-AI-primary route:
16658
+ // - `deepseek-v4-pro` — bare routed family
16659
+ // - `deepseek-v4-pro-0813` — date-pinned family
16660
+ // - `deepseek/deepseek-v4-pro` — catalog/gateway id (what surfaces pin)
16661
+ // - `deepseek/deepseek-v4-pro-0813`— date-pinned catalog id
16662
+ //
16663
+ // The two slash forms are the interesting case: `deepseek` is a DIRECT
16664
+ // provider, so they parse as direct access and resolve through
16665
+ // `resolveDirectAccessModel`, which short-circuits slash-form catalog ids to
16666
+ // their catalog provider (`vercel`). An explicit entry here now wins over that
16667
+ // short-circuit — the same PROVIDER_ROUTING_CONFIG-wins precedence
16668
+ // `resolveRoutedFamily` already applies. The COLON form
16669
+ // (`deepseek:deepseek-v4-pro`) stays explicit direct-access by design.
16670
+ "deepseek-v4-pro": {
16671
+ providers: [
16672
+ { provider: "workers-ai", weight: 100 }
16673
+ ],
16674
+ fallback: ["vercel"]
16675
+ },
16676
+ "deepseek-v4-pro-0813": {
16677
+ providers: [
16678
+ { provider: "workers-ai", weight: 100 }
16679
+ ],
16680
+ fallback: ["vercel"]
16681
+ },
16682
+ "deepseek/deepseek-v4-pro": {
16683
+ providers: [
16684
+ { provider: "workers-ai", weight: 100 }
16685
+ ],
16686
+ fallback: ["vercel"]
16687
+ },
16688
+ "deepseek/deepseek-v4-pro-0813": {
16689
+ providers: [
16690
+ { provider: "workers-ai", weight: 100 }
16691
+ ],
16692
+ fallback: ["vercel"]
16693
+ },
16694
+ // DeepSeek V4 Flash - Route through Cloudflare Workers AI, fall back to the
16695
+ // Vercel AI Gateway. Same shape as V4 Pro above: Cloudflare serves the
16696
+ // date-pinned `@cf/deepseek-ai/deepseek-v4-flash-0731` build as its only V4
16697
+ // Flash variant, so every id form maps onto it and each slash form falls back
16698
+ // to its OWN Vercel listing (`deepseek` is a DIRECT provider, so the slash
16699
+ // forms need an explicit entry to escape `resolveDirectAccessModel`'s catalog
16700
+ // short-circuit).
16701
+ ...workersAiPrimary(DEEPSEEK_V4_FLASH_IDS),
16702
+ // Qwen 3.8 27B is deliberately NOT routed to Workers AI: Cloudflare's build
16703
+ // accepts 262,144 tokens against the Vercel listing's 1,000,000, and the
16704
+ // fallback rung only engages when the AI binding is absent, so a long prompt
16705
+ // that succeeds on Vercel would fail outright. It stays on the generated
16706
+ // Vercel route.
16707
+ // Z.ai GLM-5.3 Flash - Route through Cloudflare Workers AI
16708
+ // (`@cf/zai-org/glm-5.3-flash`), fall back to the Vercel AI Gateway listing
16709
+ // (`zai/glm-5.3-flash`). Three id forms: bare family, dashed alias, and the
16710
+ // `zai/` gateway/catalog id surfaces pin.
16711
+ ...workersAiPrimary(GLM_5_3_FLASH_IDS),
16712
+ // MiniMax M2.7 - Route exclusively through the Vercel AI Gateway.
16713
+ "minimax-m2.7": {
16714
+ providers: [
16715
+ { provider: "vercel", weight: 100 }
16716
+ ],
16717
+ fallback: []
16718
+ }
16719
+ };
16390
16720
  var MANUAL_PROVIDER_MAP_OVERRIDES = {
16391
16721
  // Bedrock uses different model ID format
16392
16722
  "claude-sonnet-4-5": {
@@ -16476,6 +16806,11 @@ var MANUAL_PROVIDER_MAP_OVERRIDES = {
16476
16806
  "workers-ai": "@cf/deepseek-ai/deepseek-v4-pro-0813",
16477
16807
  "vercel": "deepseek/deepseek-v4-pro-0813"
16478
16808
  },
16809
+ // Batch 2 of the Workers-AI-primary routes. Same rule as V4 Pro: Cloudflare
16810
+ // publishes only the date-pinned DeepSeek build, the bare families inherit
16811
+ // their `vercel` id from the generated map, and the slash forms declare it.
16812
+ ...workersAiAliases("@cf/deepseek-ai/deepseek-v4-flash-0731", DEEPSEEK_V4_FLASH_IDS),
16813
+ ...workersAiAliases("@cf/zai-org/glm-5.3-flash", GLM_5_3_FLASH_IDS),
16479
16814
  // MiniMax M2.7: Vercel's gateway-form id.
16480
16815
  "minimax-m2.7": {
16481
16816
  "vercel": "minimax/minimax-m2.7"
@@ -16601,7 +16936,7 @@ var CREATOR_TO_PROVIDER = {
16601
16936
  // Default fallback
16602
16937
  };
16603
16938
 
16604
- // ../shared/dist/chunk-E3CDLSZ6.mjs
16939
+ // ../shared/dist/chunk-V4HDWTHW.mjs
16605
16940
  var BUILTIN_TOOLS_LEAN = [
16606
16941
  { "id": "gpt-image-2", "name": "GPT Image 2", "category": "image_generation", "providers": ["multi"], "defaultConfig": { "size": "1024x1024", "quality": "low", "outputFormat": "png", "background": "auto" }, "requiresApiKey": true, "executionHint": "platform", "platformKeySupport": true },
16607
16942
  { "id": "dalle", "name": "DALL-E Image Generation", "category": "image_generation", "providers": ["multi"], "defaultConfig": { "size": "1024x1024", "quality": "standard", "style": "vivid" }, "requiresApiKey": true, "executionHint": "platform", "platformKeySupport": true, "hidden": true, "deprecated": true },
@@ -16638,8 +16973,8 @@ var BUILTIN_TOOLS_LEAN = [
16638
16973
  { "id": "search_runtype_docs", "name": "Search Runtype Docs", "category": "knowledge_retrieval", "providers": ["multi"], "requiresApiKey": false, "executionHint": "platform", "platformKeySupport": false, "experimental": true },
16639
16974
  { "id": "elevenlabs-tts", "name": "ElevenLabs Text-to-Speech", "category": "text_to_speech", "toolGroup": "voice", "providers": ["multi"], "defaultConfig": { "voice_id": "rachel", "model_id": "eleven_multilingual_v2", "stability": 0.5, "similarity_boost": 0.75 }, "requiresApiKey": true, "executionHint": "platform", "platformKeySupport": true, "marginPercent": 20, "hidden": true },
16640
16975
  { "id": "elevenlabs-stt", "name": "ElevenLabs Speech-to-Text", "category": "text_to_speech", "toolGroup": "voice", "providers": ["multi"], "defaultConfig": { "format": "wav", "model_id": "scribe_v2" }, "requiresApiKey": true, "executionHint": "platform", "platformKeySupport": true, "marginPercent": 20, "hidden": true },
16641
- { "id": "emit_artifact_markdown", "name": "Emit Artifact (Markdown)", "category": "artifact", "providers": ["multi"], "executionHint": "platform", "hidden": true },
16642
- { "id": "emit_artifact_component", "name": "Emit Artifact (Component)", "category": "artifact", "providers": ["multi"], "executionHint": "platform", "hidden": true },
16976
+ { "id": "emit_artifact_markdown", "name": "Emit Artifact (Markdown)", "category": "artifact", "providers": ["multi"], "executionHint": "platform" },
16977
+ { "id": "emit_artifact_component", "name": "Emit Artifact (Component)", "category": "artifact", "providers": ["multi"], "executionHint": "platform" },
16643
16978
  { "id": "get_current_time", "name": "Get Current Time", "category": "temporal", "toolGroup": "temporal", "providers": ["multi"], "requiresApiKey": false, "executionHint": "platform" },
16644
16979
  { "id": "convert_time", "name": "Convert Time Between Zones", "category": "temporal", "toolGroup": "temporal", "providers": ["multi"], "requiresApiKey": false, "executionHint": "platform" },
16645
16980
  { "id": "time_difference", "name": "Time Difference", "category": "temporal", "toolGroup": "temporal", "providers": ["multi"], "requiresApiKey": false, "executionHint": "platform" },
@@ -16827,7 +17162,7 @@ var BuiltInToolIdPrefix = {
16827
17162
  PLATFORM: "platform"
16828
17163
  };
16829
17164
 
16830
- // ../shared/dist/chunk-D5RN66ZS.mjs
17165
+ // ../shared/dist/chunk-3LDIAPYZ.mjs
16831
17166
  function sanitizeToolNameForAiSdk(name) {
16832
17167
  return name.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase().replace(/_+/g, "_").replace(/^_|_$/g, "");
16833
17168
  }
@@ -17216,7 +17551,7 @@ var recordCollectionSchemaSchema = external_exports.strictObject({
17216
17551
  additionalProperties: external_exports.boolean().optional()
17217
17552
  }).superRefine((schema, ctx) => addSemanticIssues(schema, ctx));
17218
17553
 
17219
- // ../shared/dist/chunk-CUYPH2YF.mjs
17554
+ // ../shared/dist/chunk-WN6ECZUE.mjs
17220
17555
  var MCPServerCategory = {
17221
17556
  COMMUNICATION: "communication",
17222
17557
  PRODUCTIVITY: "productivity",
@@ -17238,7 +17573,11 @@ var subagentExecutionConfigSchema = external_exports.object({
17238
17573
  var subagentRunHandleSchema = external_exports.object({
17239
17574
  kind: external_exports.literal("subagent_run"),
17240
17575
  runId: external_exports.string(),
17241
- agentType: external_exports.enum(["runtype", "claude_managed"]),
17576
+ /**
17577
+ * Which durable lane the child executes on. `'durable'` is the ADR 0020
17578
+ * session DO; `'runtype'` is the in-process detached-run DO.
17579
+ */
17580
+ agentType: external_exports.enum(["runtype", "claude_managed", "durable"]),
17242
17581
  status: external_exports.enum(["queued", "running"]),
17243
17582
  startedAt: external_exports.string()
17244
17583
  });
@@ -19690,7 +20029,7 @@ var GRANOLA_INTEGRATION = {
19690
20029
  ]
19691
20030
  };
19692
20031
 
19693
- // ../shared/dist/chunk-JZ6OUYPZ.mjs
20032
+ // ../shared/dist/chunk-JXGM7PL7.mjs
19694
20033
  var DEFAULT_MODELS_FOR_NEW_ACCOUNTS = [
19695
20034
  // Mixlayer models
19696
20035
  {
@@ -19769,7 +20108,8 @@ var DEFAULT_MODELS_FOR_NEW_ACCOUNTS = [
19769
20108
  strengths: "Large open-weight reasoning and tool-use flagship with a 1M context at a low price \u2014 strong analytical depth where an open model is preferred.",
19770
20109
  bestFor: ["deep-reasoning", "agentic-tools", "long-context"]
19771
20110
  },
19772
- // DeepSeek models (routed via Vercel)
20111
+ // DeepSeek V4 Flash (routed via Cloudflare Workers AI, Vercel fallback). The
20112
+ // bare routed name resolves to `@cf/deepseek-ai/deepseek-v4-flash-0731`.
19773
20113
  {
19774
20114
  provider: "runtype",
19775
20115
  modelId: "deepseek-v4-flash",
@@ -20878,7 +21218,7 @@ var UNIFIED_SSE_EVENT_TYPES = _unifiedTuple([
20878
21218
  "custom"
20879
21219
  ]);
20880
21220
 
20881
- // ../shared/dist/chunk-FYZWAHYL.mjs
21221
+ // ../shared/dist/chunk-5XPR3WY2.mjs
20882
21222
  var mediaAnnotationsSchema = external_exports.object({
20883
21223
  audience: external_exports.array(external_exports.enum(["user", "assistant"])).optional()
20884
21224
  });
@@ -20887,7 +21227,9 @@ var mediaContentPartSchema = external_exports.union([
20887
21227
  type: external_exports.literal("media"),
20888
21228
  data: external_exports.string(),
20889
21229
  mediaType: external_exports.string(),
20890
- annotations: mediaAnnotationsSchema.optional()
21230
+ annotations: mediaAnnotationsSchema.optional(),
21231
+ /** Tool-result media handle (`MediaResultRef`); present once the bytes were stored. */
21232
+ ref: external_exports.object({ uri: external_exports.string(), assetId: external_exports.string(), sizeBytes: external_exports.number() }).optional()
20891
21233
  }),
20892
21234
  external_exports.object({
20893
21235
  type: external_exports.literal("image-url"),
@@ -22005,6 +22347,10 @@ function neutralizeCsvFormula(value) {
22005
22347
  if (STRICT_NUMBER.test(value)) return value;
22006
22348
  return `'${value}`;
22007
22349
  }
22350
+ var REPLAY_FROM_START = Object.freeze({
22351
+ row: 0,
22352
+ sub: Number.POSITIVE_INFINITY
22353
+ });
22008
22354
  var agUiRoleSchema = external_exports.enum(["developer", "system", "assistant", "user", "tool"]);
22009
22355
  var runStartedEventSchema = external_exports.object({
22010
22356
  type: external_exports.literal("RUN_STARTED"),
@@ -22151,7 +22497,8 @@ var AGENT_CONTENT_CONFIG_KEYS = {
22151
22497
  temporal: true,
22152
22498
  memory: true,
22153
22499
  sandbox: true,
22154
- tenancyStrategy: true
22500
+ tenancyStrategy: true,
22501
+ durability: true
22155
22502
  };
22156
22503
  var AGENT_CONTENT_CONFIG_KEY_LIST = Object.keys(AGENT_CONTENT_CONFIG_KEYS).sort();
22157
22504
  function stripTrailingChars(value, char) {
@@ -22480,6 +22827,474 @@ var MAX_MESSAGE_CONTENT_BYTES = 1024 * 1024;
22480
22827
  var MAX_MESSAGES_TOTAL_BYTES = 32 * 1024 * 1024;
22481
22828
  var encoder = new TextEncoder();
22482
22829
  var UNEVALUATED_VERDICT = Object.freeze({ status: "unevaluated" });
22830
+ var tenancyAssuranceLevelSchema = external_exports.enum(["anonymous", "asserted", "verified"]);
22831
+ var tenancyStrategyPresetSchema = external_exports.enum([
22832
+ "internal",
22833
+ "tenant-isolated",
22834
+ "end-user-isolated"
22835
+ ]);
22836
+ var tenancyAssuranceFloorSchema = external_exports.enum(["asserted", "verified"]);
22837
+ var tenancyStrategySchema = external_exports.object({
22838
+ preset: tenancyStrategyPresetSchema,
22839
+ assuranceFloor: external_exports.object({
22840
+ tenant: tenancyAssuranceFloorSchema.optional(),
22841
+ endUser: tenancyAssuranceFloorSchema.optional()
22842
+ }).strict().optional()
22843
+ }).strict();
22844
+ var MCP_HTTP_HEADER_NAME_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
22845
+ function isValidMCPHTTPHeaderValue(value) {
22846
+ for (let index = 0; index < value.length; index += 1) {
22847
+ const code = value.charCodeAt(index);
22848
+ if (code === 9 || code >= 32 && code <= 126 || code >= 128 && code <= 255) {
22849
+ continue;
22850
+ }
22851
+ return false;
22852
+ }
22853
+ return true;
22854
+ }
22855
+ var INCOMPATIBLE_HEADERS_AUTH_FIELDS = [
22856
+ "headerName",
22857
+ "token",
22858
+ "username",
22859
+ "password",
22860
+ "tokenSecretName",
22861
+ "usernameSecretName",
22862
+ "passwordSecretName",
22863
+ "oauth2"
22864
+ ];
22865
+ function validateMCPHeadersAuth(auth) {
22866
+ if (!auth) return { valid: true };
22867
+ if (auth.type !== "headers") {
22868
+ if (auth.headers !== void 0) {
22869
+ return {
22870
+ valid: false,
22871
+ code: "headers_wrong_type",
22872
+ message: "The headers field is only valid with auth type 'headers'",
22873
+ path: ["headers"]
22874
+ };
22875
+ }
22876
+ return { valid: true };
22877
+ }
22878
+ for (const field of INCOMPATIBLE_HEADERS_AUTH_FIELDS) {
22879
+ if (auth[field] !== void 0) {
22880
+ return {
22881
+ valid: false,
22882
+ code: "incompatible_auth_field",
22883
+ message: `Auth type 'headers' cannot also set ${field}`,
22884
+ path: [field]
22885
+ };
22886
+ }
22887
+ }
22888
+ if (typeof auth.headers !== "object" || auth.headers === null || Array.isArray(auth.headers) || Object.keys(auth.headers).length === 0) {
22889
+ return {
22890
+ valid: false,
22891
+ code: "headers_required",
22892
+ message: "Auth type 'headers' requires a non-empty headers record",
22893
+ path: ["headers"]
22894
+ };
22895
+ }
22896
+ const normalizedNames = /* @__PURE__ */ new Set();
22897
+ for (const [name, value] of Object.entries(auth.headers)) {
22898
+ if (!MCP_HTTP_HEADER_NAME_PATTERN.test(name)) {
22899
+ return {
22900
+ valid: false,
22901
+ code: "invalid_header_name",
22902
+ message: `Invalid HTTP header name "${name}"`,
22903
+ path: ["headers", name]
22904
+ };
22905
+ }
22906
+ if (typeof value !== "string") {
22907
+ return {
22908
+ valid: false,
22909
+ code: "invalid_header_value",
22910
+ message: `Header "${name}" must have a string value`,
22911
+ path: ["headers", name]
22912
+ };
22913
+ }
22914
+ if (!isValidMCPHTTPHeaderValue(value)) {
22915
+ return {
22916
+ valid: false,
22917
+ code: "invalid_header_value",
22918
+ message: `Header "${name}" contains characters that are not valid in an HTTP header value`,
22919
+ path: ["headers", name]
22920
+ };
22921
+ }
22922
+ const normalizedName = name.toLowerCase();
22923
+ if (normalizedNames.has(normalizedName)) {
22924
+ return {
22925
+ valid: false,
22926
+ code: "duplicate_header_name",
22927
+ message: `Header name "${name}" is duplicated case-insensitively`,
22928
+ path: ["headers", name]
22929
+ };
22930
+ }
22931
+ normalizedNames.add(normalizedName);
22932
+ }
22933
+ return { valid: true };
22934
+ }
22935
+ var REASONING_BUDGET_BOUNDS = {
22936
+ /** Anthropic extended thinking (`thinking: { type: 'enabled', budgetTokens }`). */
22937
+ budgetTokens: { min: 1e3, max: 1e5 },
22938
+ /** Gemini 2.5 thinking budget (`thinkingConfig.thinkingBudget`). */
22939
+ thinkingBudget: { min: 1024, max: 65536 }
22940
+ };
22941
+ var reasoningConfigSchema = external_exports.union([
22942
+ external_exports.boolean(),
22943
+ external_exports.object({
22944
+ enabled: external_exports.boolean(),
22945
+ // OpenAI GPT-5 and o-series
22946
+ reasoningEffort: external_exports.enum(["minimal", "low", "medium", "high", "xhigh"]).optional(),
22947
+ reasoningSummary: external_exports.enum(["auto", "detailed"]).optional(),
22948
+ // Anthropic Claude
22949
+ budgetTokens: external_exports.number().int().min(REASONING_BUDGET_BOUNDS.budgetTokens.min).max(REASONING_BUDGET_BOUNDS.budgetTokens.max).optional(),
22950
+ // Anthropic ADAPTIVE thinking (Claude 4.6 and later, including the Claude 5 family): maps to output_config.effort.
22951
+ // Free-form because the accepted ladder is per-model catalog data
22952
+ // (`ModelReasoningOptions.effort`) and carries rungs outside the
22953
+ // `reasoningEffort` union, such as 'max'. The save-time check is the flow
22954
+ // validator's REASONING_KNOB_UNSUPPORTED advisory, not this schema: a
22955
+ // hand-kept enum here would reject a rung the model added upstream.
22956
+ effort: external_exports.string().min(1).max(32).optional(),
22957
+ // Google Gemini
22958
+ thinkingBudget: external_exports.number().int().min(REASONING_BUDGET_BOUNDS.thinkingBudget.min).max(REASONING_BUDGET_BOUNDS.thinkingBudget.max).optional(),
22959
+ // Gemini 3+ level mode; mutually exclusive with thinkingBudget per model.
22960
+ thinkingLevel: external_exports.string().min(1).max(32).optional(),
22961
+ includeThoughts: external_exports.boolean().optional()
22962
+ })
22963
+ ]);
22964
+ var samplingConfigSchema = {
22965
+ topP: external_exports.number().min(0).max(1).optional(),
22966
+ topK: external_exports.number().int().min(1).max(500).optional(),
22967
+ frequencyPenalty: external_exports.number().min(-2).max(2).optional(),
22968
+ presencePenalty: external_exports.number().min(-2).max(2).optional(),
22969
+ seed: external_exports.number().int().optional()
22970
+ };
22971
+ var errorHandlingSchema = external_exports.object({
22972
+ onError: external_exports.enum(["fail", "continue", "fallback"]),
22973
+ fallbacks: external_exports.array(
22974
+ external_exports.discriminatedUnion("type", [
22975
+ external_exports.object({
22976
+ type: external_exports.literal("retry"),
22977
+ delay: external_exports.number().int().min(0).max(6e4).optional()
22978
+ }),
22979
+ external_exports.object({
22980
+ type: external_exports.literal("model"),
22981
+ model: external_exports.string(),
22982
+ temperature: external_exports.number().min(0).max(2).optional(),
22983
+ maxTokens: external_exports.number().int().min(1).optional(),
22984
+ delay: external_exports.number().int().min(0).max(6e4).optional()
22985
+ }),
22986
+ external_exports.object({
22987
+ type: external_exports.literal("message"),
22988
+ message: external_exports.string(),
22989
+ delay: external_exports.number().int().min(0).max(6e4).optional()
22990
+ })
22991
+ ])
22992
+ ).optional(),
22993
+ // Conditions that activate the fallback chain. Mirrors PromptErrorHandling.triggers;
22994
+ // defaults to error-only when omitted.
22995
+ triggers: external_exports.array(external_exports.object({ type: external_exports.enum(["error", "empty-output"]) })).optional()
22996
+ }).optional();
22997
+ var artifactConfigSchema = external_exports.object({
22998
+ enabled: external_exports.literal(true),
22999
+ types: external_exports.array(external_exports.enum(["markdown", "component"])).min(1)
23000
+ });
23001
+ var temporalConfigSchema = external_exports.object({
23002
+ injectElapsed: external_exports.boolean().optional(),
23003
+ elapsedThresholdSeconds: external_exports.number().int().min(0).optional(),
23004
+ groundNow: external_exports.boolean().optional(),
23005
+ timezone: external_exports.string().optional()
23006
+ });
23007
+ var memoryConfigSchema = external_exports.object({
23008
+ enabled: external_exports.boolean(),
23009
+ profileTemplate: external_exports.string().optional(),
23010
+ // When omitted and `enabled` is true, treated as `true` (smart default): a
23011
+ // Markdown memory summary is woven into the agent's system prompt on each
23012
+ // turn so the agent always has the user in context — without the model having
23013
+ // to call `recall_memory` first. (The summary is cached per profile so the
23014
+ // synthesis cost is paid once, not on every turn.) Set false to skip
23015
+ // injection (focused task agents that don't benefit from a profile overview).
23016
+ // Resolved via `shouldInjectMemorySummary` so the default lives in one place.
23017
+ injectSummary: external_exports.boolean().optional()
23018
+ });
23019
+ var sandboxNetworkAccessSchema = external_exports.union([
23020
+ external_exports.enum(["none", "essentials", "open"]),
23021
+ external_exports.object({
23022
+ profile: external_exports.enum(["none", "essentials", "open"]).optional(),
23023
+ allow: external_exports.array(external_exports.string()).optional()
23024
+ })
23025
+ ]);
23026
+ var sandboxConfigSchema = external_exports.object({
23027
+ enabled: external_exports.boolean(),
23028
+ // INERT except `'runtype-sandbox'`: the agent-sandbox runtime
23029
+ // (`SandboxToolService`) REJECTS any provider other than `'runtype-sandbox'`
23030
+ // with a throw at the first sandbox tool call — `'daytona'` is NOT honored on
23031
+ // this path (Phase 3 "Daytona parity" is unshipped). Kept parseable (not
23032
+ // narrowed to `['runtype-sandbox']`) so a stored/imported `'daytona'` config
23033
+ // does not fail agent-config parse, and so this schema stays aligned with the
23034
+ // FPO public-types mirror + MCP snapshot that still list it. Selecting
23035
+ // `'daytona'` is an author-time no-op that surfaces as a runtime error.
23036
+ // (`quickjs` / `cloudflare-worker` are code-eval only, no shell — never valid.)
23037
+ provider: external_exports.enum(["runtype-sandbox", "daytona"]).optional(),
23038
+ // `'ephemeral'` and `'conversation'` (the default) are implemented.
23039
+ // `'named'` is parseable but NOT yet implemented: the runtime silently
23040
+ // degrades `'named'` to `'ephemeral'` (with a debug log) — no durable
23041
+ // cross-conversation workspace exists yet (Phase 3). Kept parseable so a
23042
+ // stored `'named'` config still loads; it just behaves as `'ephemeral'`.
23043
+ persistence: external_exports.enum(["ephemeral", "conversation", "named"]).optional(),
23044
+ // INERT on the agent sandbox path: `instanceType` is NOT honored — the agent
23045
+ // sandbox always provisions `standard-4` (the blanket default fixed by
23046
+ // apps/sandbox/wrangler.toml `[[containers]]`) regardless of this value (the
23047
+ // value is read for the transform-data/deploy sandbox billing paths, not for
23048
+ // the agent builtin tools). Kept parseable for forward-compat + mirror
23049
+ // alignment; treat it as a no-op author-time hint until the agent path wires
23050
+ // per-plan container sizing.
23051
+ instanceType: external_exports.enum(["standard-1", "standard-2", "standard-3", "standard-4"]).optional(),
23052
+ networkAccess: sandboxNetworkAccessSchema.optional(),
23053
+ ttl: external_exports.enum(["5m", "1h", "24h", "unlimited"]).optional(),
23054
+ sleepAfter: external_exports.enum(["5m", "15m", "30m", "1h"]).optional(),
23055
+ // Operator-authored bootstrap commands. The API runs this batch once after
23056
+ // enforcing the sandbox's network policy and before the first model-authored
23057
+ // sandbox verb. Commands run in order from /workspace and must be foreground,
23058
+ // self-contained, and safe to retry after an interrupted container runtime;
23059
+ // the credential-bearing exec supervisor deliberately reaps every descendant
23060
+ // before a command returns, so setup cannot launch a daemon meant to outlive
23061
+ // it. Trusted Durable Object state plus a run-scoped memo prevents the batch
23062
+ // from being repeated for the same provisioned workspace. Changing the
23063
+ // commands or managed-secret KEY bindings creates a fresh sandbox identity;
23064
+ // rotating a value under the same key does not rerun setup.
23065
+ setupCommands: external_exports.array(external_exports.string().min(1, "setup commands must not be empty")).optional(),
23066
+ // Credential environment available ONLY to the operator-authored setup batch
23067
+ // above — never to a model-authored `bash` command. Keys are env var names;
23068
+ // values are MANAGED SECRET KEYS (e.g. `GITHUB_CLONE_TOKEN`), never raw
23069
+ // credential values. The API resolves them immediately before setup and
23070
+ // delivers them out-of-band over `cloudflareSandboxExecWithSecretEnv`, so the
23071
+ // values never appear in command strings, model-facing tool schemas, logs, or
23072
+ // spill files. Like `networkAccess`, both fields are operator Definition: the
23073
+ // model cannot author setup, name a managed secret, or grant itself one.
23074
+ //
23075
+ // TRUST BOUNDARY — read before configuring this. Every process started by a
23076
+ // credentialed setup batch can read the injected values. Keep setup authored
23077
+ // and reviewed by the operator; do not run model-, attacker-, or
23078
+ // supply-chain-authored code (for example an install script) while credentials
23079
+ // are present, and never persist a raw credential into /workspace for later
23080
+ // model access. The secret supervisor freezes pre-existing processes, reaps
23081
+ // every setup descendant, and destroys the sandbox fail-closed if cleanup
23082
+ // fails, but output redaction remains defense-in-depth rather than permission
23083
+ // to echo or transform a credential.
23084
+ // Therefore:
23085
+ // - Prefer `credentialProxies` (phantom tokens, swapped at the egress
23086
+ // proxy) for any HTTP(S) protocol it supports — the real credential
23087
+ // never enters the container at all.
23088
+ // - Scope the secret as narrowly as the provider allows (read-only,
23089
+ // single-repo) and pair it with a tight `networkAccess` profile.
23090
+ // - Keep credentialed setup separate from later uncredentialed dependency
23091
+ // installation and model-authored work.
23092
+ // Name shape and the 32-entry cap mirror the sandbox worker's
23093
+ // `validateSecretEnv`; `RUNTYPE_SECRET_COMMAND` is the worker's reserved
23094
+ // control-channel variable.
23095
+ secretEnv: external_exports.record(
23096
+ external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "must be a valid environment variable name").refine((name) => name !== "RUNTYPE_SECRET_COMMAND", {
23097
+ message: "RUNTYPE_SECRET_COMMAND is reserved"
23098
+ }),
23099
+ external_exports.string().min(1, "must be a managed secret key")
23100
+ ).refine((record2) => Object.keys(record2).length <= 32, {
23101
+ message: "secretEnv supports at most 32 variables"
23102
+ }).optional()
23103
+ // NOTE: a `requireApprovalForBash` knob was forward-declared here for Phase 3
23104
+ // but never wired to any runtime gate, so it was REMOVED from the public
23105
+ // schema rather than ship a misleading, inert control (post-Fable handoff 05,
23106
+ // F3). To gate `bash` today use the generic `tools.approval` config, which
23107
+ // matches the tool by name. Re-add the dedicated knob only with its wiring.
23108
+ });
23109
+ var agentDurabilityConfigSchema = external_exports.object({
23110
+ watchLeaseMs: external_exports.number().int().min(1e4).max(18e5).nullable().optional(),
23111
+ maxBudgetMs: external_exports.number().int().min(1e3).max(864e5).nullable().optional(),
23112
+ forced: external_exports.enum(["durable", "in_process"]).optional()
23113
+ });
23114
+ var DEFAULT_TURN_MAX_BUDGET_MS = 30 * 60 * 1e3;
23115
+ var agentRuntimeConfigSchema = external_exports.object({
23116
+ model: external_exports.string().optional(),
23117
+ systemPrompt: external_exports.string().optional(),
23118
+ temperature: external_exports.number().min(0).max(2).optional(),
23119
+ // Maximum output tokens (the model call's `maxOutputTokens`). A sibling of
23120
+ // the sampling params: a static generation budget that belongs on the saved
23121
+ // agent definition. Notably load-bearing for "thinking" default models that
23122
+ // share reasoning + answer tokens in one output budget (Moonshot requires
23123
+ // `>= 16k` or the visible answer can truncate to nothing after a long
23124
+ // reasoning trace) — the Product Generator pins `24000` for exactly this.
23125
+ // `buildVirtualFlow` already maps this onto the prompt step (defaulting to
23126
+ // 16384 when unset), so saving it here is all that's required for it to take
23127
+ // effect at execution time.
23128
+ maxTokens: external_exports.number().int().min(1).optional(),
23129
+ ...samplingConfigSchema,
23130
+ // Unified tools configuration (nested under 'tools').
23131
+ //
23132
+ // This is the **createAgent / FPO-v2 create-form** projection of the canonical
23133
+ // `agentToolsConfigSchema` (`tool-types.ts`). It is kept separate on purpose —
23134
+ // it carries create-time constraints (`.int().min().max()`), a create-form
23135
+ // `runtimeTools.toolType` enum (`advisor`/`search` instead of the canonical
23136
+ // `RuntimeToolDefinition` union), and does NOT yet accept `toolSearch`.
23137
+ // Collapsing it onto the canonical leaves would change createAgent validation,
23138
+ // so the two are pinned by review + the planning doc rather than a shared
23139
+ // import. Adding `toolSearch` here (to match the canonical schema + the runtime
23140
+ // wire form) is a tracked follow-up.
23141
+ tools: external_exports.object({
23142
+ toolIds: external_exports.array(external_exports.string()).optional(),
23143
+ toolConfigs: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
23144
+ runtimeTools: external_exports.array(
23145
+ external_exports.object({
23146
+ name: external_exports.string(),
23147
+ description: external_exports.string(),
23148
+ toolType: external_exports.enum([
23149
+ "flow",
23150
+ "custom",
23151
+ "external",
23152
+ "local",
23153
+ "advisor",
23154
+ "subagent",
23155
+ "search"
23156
+ ]),
23157
+ parametersSchema: external_exports.record(external_exports.string(), external_exports.unknown()),
23158
+ config: external_exports.record(external_exports.string(), external_exports.unknown())
23159
+ })
23160
+ ).optional(),
23161
+ mcpServers: external_exports.array(
23162
+ external_exports.object({
23163
+ id: external_exports.string(),
23164
+ name: external_exports.string().optional(),
23165
+ url: external_exports.string(),
23166
+ auth: external_exports.object({
23167
+ type: external_exports.enum(["api_key", "bearer", "basic", "custom_header", "headers", "none"]),
23168
+ headerName: external_exports.string().optional(),
23169
+ token: external_exports.string().optional(),
23170
+ username: external_exports.string().optional(),
23171
+ password: external_exports.string().optional(),
23172
+ // For `type: 'headers'`: arbitrary HTTP header name → value
23173
+ // templates. The shared refinement below enforces the exclusive shape.
23174
+ headers: external_exports.record(external_exports.string(), external_exports.string()).optional()
23175
+ }).superRefine((auth, ctx) => {
23176
+ const validation = validateMCPHeadersAuth(auth);
23177
+ if (!validation.valid) {
23178
+ ctx.addIssue({
23179
+ code: "custom",
23180
+ path: validation.path,
23181
+ message: validation.message
23182
+ });
23183
+ }
23184
+ }).optional(),
23185
+ allowedTools: external_exports.array(external_exports.string()).optional(),
23186
+ timeout: external_exports.number().optional(),
23187
+ transport: external_exports.enum(["streamable_http", "rest"]).optional(),
23188
+ enabled: external_exports.boolean().optional()
23189
+ })
23190
+ ).optional(),
23191
+ maxToolCalls: external_exports.number().int().min(1).max(100).optional(),
23192
+ toolCallStrategy: external_exports.enum(["auto", "required", "none"]).optional(),
23193
+ approval: external_exports.object({
23194
+ require: external_exports.union([external_exports.array(external_exports.string()), external_exports.boolean()]),
23195
+ timeout: external_exports.number().optional(),
23196
+ /** Opt out of agent-supplied approval reasons (`_approvalReason`
23197
+ * schema injection). Default: true. Mirrors approvalConfigSchema
23198
+ * in tool-types.ts. */
23199
+ requestReason: external_exports.boolean().optional(),
23200
+ /** Persistent "always" choices offered at the approval prompt.
23201
+ * Mirrors approvalConfigSchema.choices in tool-types.ts. */
23202
+ choices: external_exports.object({
23203
+ alwaysAllow: external_exports.boolean().optional(),
23204
+ alwaysDeny: external_exports.boolean().optional()
23205
+ }).optional()
23206
+ }).optional(),
23207
+ perToolLimits: external_exports.record(
23208
+ external_exports.string(),
23209
+ external_exports.object({
23210
+ maxCalls: external_exports.number().optional(),
23211
+ required: external_exports.boolean().optional()
23212
+ })
23213
+ ).optional(),
23214
+ subagentConfig: external_exports.object({
23215
+ toolPool: external_exports.array(external_exports.string()),
23216
+ defaultMaxTurns: external_exports.number().int().min(1).max(100).optional(),
23217
+ maxTurnsLimit: external_exports.number().int().min(1).max(100).optional(),
23218
+ maxSpawnsPerRun: external_exports.number().int().min(1).max(50).optional(),
23219
+ defaultModel: external_exports.string().optional(),
23220
+ allowNesting: external_exports.boolean().optional(),
23221
+ // Max must stay <= the dispatch `options.stepTimeoutMs` cap
23222
+ // (600_000 — `api-schemas/dispatch.ts`): `resolveSubagentTimeouts`
23223
+ // (apps/api subagent dispatch) stamps the child flow's
23224
+ // `stepTimeoutMs` from the subagent's effective timeout. Keep the
23225
+ // two bounds in lockstep or 600s subagents break at the smaller cap.
23226
+ defaultTimeoutMs: external_exports.number().int().min(1e3).max(6e5).optional(),
23227
+ executionModes: external_exports.array(external_exports.enum(["attached", "detached"])).min(1).optional(),
23228
+ defaultExecutionMode: external_exports.enum(["attached", "detached"]).optional(),
23229
+ defaultNotify: external_exports.enum(["none", "narrate", "react"]).optional(),
23230
+ detachedMaxBudgetMs: external_exports.number().int().min(1e3).max(864e5).optional(),
23231
+ detachedNoProgressBudgetMs: external_exports.number().int().min(1e3).max(864e5).optional()
23232
+ }).optional(),
23233
+ codeModeConfig: external_exports.object({
23234
+ toolPool: external_exports.array(external_exports.string()),
23235
+ description: external_exports.string().optional(),
23236
+ timeoutMs: external_exports.number().int().min(1e3).max(6e5).optional()
23237
+ }).optional()
23238
+ }).optional(),
23239
+ artifacts: artifactConfigSchema.optional(),
23240
+ reasoning: reasoningConfigSchema.optional(),
23241
+ advisor: external_exports.object({
23242
+ model: external_exports.string(),
23243
+ systemPrompt: external_exports.string().optional()
23244
+ }).optional().nullable(),
23245
+ loopConfig: external_exports.object({
23246
+ maxTurns: external_exports.number().int().min(1).max(100).optional(),
23247
+ maxCost: external_exports.number().min(0).optional(),
23248
+ enableReflection: external_exports.boolean().optional(),
23249
+ reflectionInterval: external_exports.number().int().min(1).max(50).optional()
23250
+ }).optional(),
23251
+ voice: external_exports.object({
23252
+ enabled: external_exports.boolean().optional(),
23253
+ provider: external_exports.string().optional(),
23254
+ interruptionMode: external_exports.enum(["none", "cancel", "barge-in"]).optional(),
23255
+ elevenLabs: external_exports.object({
23256
+ voiceId: external_exports.string().optional(),
23257
+ modelId: external_exports.string().optional(),
23258
+ stability: external_exports.number().min(0).max(1).optional(),
23259
+ similarity: external_exports.number().min(0).max(1).optional()
23260
+ }).optional()
23261
+ }).optional(),
23262
+ errorHandling: errorHandlingSchema,
23263
+ loggingPolicy: external_exports.enum(["default", "on", "off"]).optional(),
23264
+ // Opt-in PII redaction for tail-log and telemetry payloads. `'default'`
23265
+ // defers to a lower layer (surface/product) or the resolver default (off).
23266
+ // Mirrors `loggingPolicy`.
23267
+ piiRedaction: external_exports.enum(["default", "off", "redact"]).optional(),
23268
+ // Opt-in temporal awareness. `injectElapsed` turns on the automatic
23269
+ // "time has passed" decorator (a `<temporal_context>` block prepended to
23270
+ // the user turn at dispatch, gated on turn ≥ 2 and a gap ≥
23271
+ // `elapsedThresholdSeconds`). `groundNow` additionally surfaces the current
23272
+ // datetime in that block. `timezone` is the agent's DEFAULT IANA zone —
23273
+ // the layered tool/decorator resolution overrides it per-conversation.
23274
+ temporal: temporalConfigSchema.optional(),
23275
+ // Long-term memory (Cloudflare Agent Memory). Single-sourced as
23276
+ // `memoryConfigSchema` (below) and reused by the update-agent, dispatch
23277
+ // inline-agent, and FPO agent schemas so the four surfaces never drift —
23278
+ // mirroring how `temporalConfigSchema` is shared.
23279
+ memory: memoryConfigSchema.optional(),
23280
+ // Agent Sandbox (Linux computer). When enabled, the agent gets the sandbox
23281
+ // builtin tools + system-prompt frame at dispatch. Single-sourced as
23282
+ // `sandboxConfigSchema` (above), mirroring `memory`. The live machine is agent
23283
+ // state; this block is the operator Definition that enables it.
23284
+ sandbox: sandboxConfigSchema.optional(),
23285
+ // Tenancy Strategy (ADR 0012) — per-resource opt-in to tenant/end-user
23286
+ // isolation. Part of the Definition (validated + persisted + content-hashed
23287
+ // here so `ensure` tracks it). Absent → platform-global default (no behavior
23288
+ // change); present → the execution pipeline expands it and enforces the
23289
+ // lock-down gate pre-engine. Single-sourced as `tenancyStrategySchema` in
23290
+ // `./tenancy-strategy`; the expansion + gate logic lives in apps/api.
23291
+ tenancyStrategy: tenancyStrategySchema.optional(),
23292
+ // Durable-turn knobs (ADR 0020). Single-sourced as
23293
+ // `agentDurabilityConfigSchema` (above), mirroring `memory` / `sandbox`.
23294
+ // Durability is the platform default; this block only tunes the turn and
23295
+ // carries the per-agent lane pin.
23296
+ durability: agentDurabilityConfigSchema.optional()
23297
+ }).strict();
22483
23298
  var contextFallbackSchema = external_exports.union([
22484
23299
  external_exports.object({ type: external_exports.literal("retry"), delay: external_exports.number().optional() }),
22485
23300
  external_exports.object({
@@ -23194,7 +24009,21 @@ var promptConfigSchema = external_exports.object({
23194
24009
  enabled: external_exports.literal(true),
23195
24010
  types: external_exports.array(external_exports.enum(["markdown", "component"])).min(1)
23196
24011
  }).optional(),
23197
- reasoning: external_exports.boolean().optional(),
24012
+ // The canonical `reasoningConfigSchema` from `agent-runtime-config-schema.ts`,
24013
+ // whose union already leads with `z.boolean()` — so this is the boolean-first
24014
+ // union, not a second wrapper around one.
24015
+ //
24016
+ // This field was `z.boolean().optional()` until the object form was found to
24017
+ // be unsaveable: the flow editor's reasoning dials write the full
24018
+ // `ReasoningConfig` ({enabled, reasoningEffort | effort | thinkingLevel |
24019
+ // budgetTokens | thinkingBudget | reasoningSummary | includeThoughts}), the
24020
+ // engine has always honored it (`typeof flowPrompt.reasoning === 'object'` in
24021
+ // `apps/api/src/lib/flow-execution/prompt-executor.ts`, mirrored by the
24022
+ // runtime port), and an agent has always accepted it — only flow create /
24023
+ // update rejected it, with SCHEMA_VALIDATION_FAILED "expected boolean,
24024
+ // received object". Sharing ONE schema with the agent plane is what keeps the
24025
+ // two from drifting apart again.
24026
+ reasoning: reasoningConfigSchema.optional(),
23198
24027
  previousMessages: promptPreviousMessagesSchema.optional(),
23199
24028
  streamOutput: external_exports.boolean().optional(),
23200
24029
  errorHandling: promptErrorHandlingConfigSchema.optional(),
@@ -28603,97 +29432,6 @@ var runtimeHostDependencySchema = external_exports.union([
28603
29432
  backgroundRunCoordinatorDependencySchema,
28604
29433
  unknownHostDependencySchema
28605
29434
  ]);
28606
- var MCP_HTTP_HEADER_NAME_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
28607
- function isValidMCPHTTPHeaderValue(value) {
28608
- for (let index = 0; index < value.length; index += 1) {
28609
- const code = value.charCodeAt(index);
28610
- if (code === 9 || code >= 32 && code <= 126 || code >= 128 && code <= 255) {
28611
- continue;
28612
- }
28613
- return false;
28614
- }
28615
- return true;
28616
- }
28617
- var INCOMPATIBLE_HEADERS_AUTH_FIELDS = [
28618
- "headerName",
28619
- "token",
28620
- "username",
28621
- "password",
28622
- "tokenSecretName",
28623
- "usernameSecretName",
28624
- "passwordSecretName",
28625
- "oauth2"
28626
- ];
28627
- function validateMCPHeadersAuth(auth) {
28628
- if (!auth) return { valid: true };
28629
- if (auth.type !== "headers") {
28630
- if (auth.headers !== void 0) {
28631
- return {
28632
- valid: false,
28633
- code: "headers_wrong_type",
28634
- message: "The headers field is only valid with auth type 'headers'",
28635
- path: ["headers"]
28636
- };
28637
- }
28638
- return { valid: true };
28639
- }
28640
- for (const field of INCOMPATIBLE_HEADERS_AUTH_FIELDS) {
28641
- if (auth[field] !== void 0) {
28642
- return {
28643
- valid: false,
28644
- code: "incompatible_auth_field",
28645
- message: `Auth type 'headers' cannot also set ${field}`,
28646
- path: [field]
28647
- };
28648
- }
28649
- }
28650
- if (typeof auth.headers !== "object" || auth.headers === null || Array.isArray(auth.headers) || Object.keys(auth.headers).length === 0) {
28651
- return {
28652
- valid: false,
28653
- code: "headers_required",
28654
- message: "Auth type 'headers' requires a non-empty headers record",
28655
- path: ["headers"]
28656
- };
28657
- }
28658
- const normalizedNames = /* @__PURE__ */ new Set();
28659
- for (const [name, value] of Object.entries(auth.headers)) {
28660
- if (!MCP_HTTP_HEADER_NAME_PATTERN.test(name)) {
28661
- return {
28662
- valid: false,
28663
- code: "invalid_header_name",
28664
- message: `Invalid HTTP header name "${name}"`,
28665
- path: ["headers", name]
28666
- };
28667
- }
28668
- if (typeof value !== "string") {
28669
- return {
28670
- valid: false,
28671
- code: "invalid_header_value",
28672
- message: `Header "${name}" must have a string value`,
28673
- path: ["headers", name]
28674
- };
28675
- }
28676
- if (!isValidMCPHTTPHeaderValue(value)) {
28677
- return {
28678
- valid: false,
28679
- code: "invalid_header_value",
28680
- message: `Header "${name}" contains characters that are not valid in an HTTP header value`,
28681
- path: ["headers", name]
28682
- };
28683
- }
28684
- const normalizedName = name.toLowerCase();
28685
- if (normalizedNames.has(normalizedName)) {
28686
- return {
28687
- valid: false,
28688
- code: "duplicate_header_name",
28689
- message: `Header name "${name}" is duplicated case-insensitively`,
28690
- path: ["headers", name]
28691
- };
28692
- }
28693
- normalizedNames.add(normalizedName);
28694
- }
28695
- return { valid: true };
28696
- }
28697
29435
  var SKILL_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
28698
29436
  var EMIT_ARTIFACT_MARKDOWN_TOOL_ID = "emit_artifact_markdown";
28699
29437
  var EMIT_ARTIFACT_COMPONENT_TOOL_ID = "emit_artifact_component";
@@ -29135,7 +29873,14 @@ var userProfileFeaturesSchema = external_exports.object({
29135
29873
  // marker column has been dropped. Both are kept on the wire for compatibility
29136
29874
  // with deployed SPA bundles and the published SDK.
29137
29875
  workspaceModelReady: external_exports.boolean(),
29138
- workspaceModelEligible: external_exports.boolean()
29876
+ workspaceModelEligible: external_exports.boolean(),
29877
+ // Active model credit promo factor for this account (ADR 0021): `0.5` means
29878
+ // promo-eligible models (Workers AI, Gemini) bill at 50% of nominal
29879
+ // platform-key cost; `1` means no promo. Driven by the
29880
+ // `model-credit-promo-multiplier` number flag, already clamped to `[0, 1]`.
29881
+ // The dashboard renders discount badges from it using the shared
29882
+ // `isModelCreditPromoEligible` predicate; billing never trusts the client.
29883
+ modelCreditPromoMultiplier: external_exports.number().min(0).max(1).optional()
29139
29884
  });
29140
29885
  var SLACK_REQUIRED_BOT_SCOPES = [
29141
29886
  "channels:history",
@@ -29186,356 +29931,6 @@ var SLACK_MANIFEST_BOT_SCOPES = [
29186
29931
  ...SLACK_REQUIRED_BOT_SCOPES,
29187
29932
  ...SLACK_OPTIONAL_BOT_SCOPES
29188
29933
  ];
29189
- var tenancyAssuranceLevelSchema = external_exports.enum(["anonymous", "asserted", "verified"]);
29190
- var tenancyStrategyPresetSchema = external_exports.enum([
29191
- "internal",
29192
- "tenant-isolated",
29193
- "end-user-isolated"
29194
- ]);
29195
- var tenancyAssuranceFloorSchema = external_exports.enum(["asserted", "verified"]);
29196
- var tenancyStrategySchema = external_exports.object({
29197
- preset: tenancyStrategyPresetSchema,
29198
- assuranceFloor: external_exports.object({
29199
- tenant: tenancyAssuranceFloorSchema.optional(),
29200
- endUser: tenancyAssuranceFloorSchema.optional()
29201
- }).strict().optional()
29202
- }).strict();
29203
- var reasoningConfigSchema = external_exports.union([
29204
- external_exports.boolean(),
29205
- external_exports.object({
29206
- enabled: external_exports.boolean(),
29207
- // OpenAI GPT-5 and o-series
29208
- reasoningEffort: external_exports.enum(["minimal", "low", "medium", "high", "xhigh"]).optional(),
29209
- reasoningSummary: external_exports.enum(["auto", "detailed"]).optional(),
29210
- // Anthropic Claude
29211
- budgetTokens: external_exports.number().int().min(1e3).max(1e5).optional(),
29212
- // Google Gemini
29213
- thinkingBudget: external_exports.number().int().min(1024).max(65536).optional(),
29214
- includeThoughts: external_exports.boolean().optional()
29215
- })
29216
- ]);
29217
- var samplingConfigSchema = {
29218
- topP: external_exports.number().min(0).max(1).optional(),
29219
- topK: external_exports.number().int().min(1).max(500).optional(),
29220
- frequencyPenalty: external_exports.number().min(-2).max(2).optional(),
29221
- presencePenalty: external_exports.number().min(-2).max(2).optional(),
29222
- seed: external_exports.number().int().optional()
29223
- };
29224
- var errorHandlingSchema = external_exports.object({
29225
- onError: external_exports.enum(["fail", "continue", "fallback"]),
29226
- fallbacks: external_exports.array(
29227
- external_exports.discriminatedUnion("type", [
29228
- external_exports.object({
29229
- type: external_exports.literal("retry"),
29230
- delay: external_exports.number().int().min(0).max(6e4).optional()
29231
- }),
29232
- external_exports.object({
29233
- type: external_exports.literal("model"),
29234
- model: external_exports.string(),
29235
- temperature: external_exports.number().min(0).max(2).optional(),
29236
- maxTokens: external_exports.number().int().min(1).optional(),
29237
- delay: external_exports.number().int().min(0).max(6e4).optional()
29238
- }),
29239
- external_exports.object({
29240
- type: external_exports.literal("message"),
29241
- message: external_exports.string(),
29242
- delay: external_exports.number().int().min(0).max(6e4).optional()
29243
- })
29244
- ])
29245
- ).optional(),
29246
- // Conditions that activate the fallback chain. Mirrors PromptErrorHandling.triggers;
29247
- // defaults to error-only when omitted.
29248
- triggers: external_exports.array(external_exports.object({ type: external_exports.enum(["error", "empty-output"]) })).optional()
29249
- }).optional();
29250
- var artifactConfigSchema = external_exports.object({
29251
- enabled: external_exports.literal(true),
29252
- types: external_exports.array(external_exports.enum(["markdown", "component"])).min(1)
29253
- });
29254
- var temporalConfigSchema = external_exports.object({
29255
- injectElapsed: external_exports.boolean().optional(),
29256
- elapsedThresholdSeconds: external_exports.number().int().min(0).optional(),
29257
- groundNow: external_exports.boolean().optional(),
29258
- timezone: external_exports.string().optional()
29259
- });
29260
- var memoryConfigSchema = external_exports.object({
29261
- enabled: external_exports.boolean(),
29262
- profileTemplate: external_exports.string().optional(),
29263
- // When omitted and `enabled` is true, treated as `true` (smart default): a
29264
- // Markdown memory summary is woven into the agent's system prompt on each
29265
- // turn so the agent always has the user in context — without the model having
29266
- // to call `recall_memory` first. (The summary is cached per profile so the
29267
- // synthesis cost is paid once, not on every turn.) Set false to skip
29268
- // injection (focused task agents that don't benefit from a profile overview).
29269
- // Resolved via `shouldInjectMemorySummary` so the default lives in one place.
29270
- injectSummary: external_exports.boolean().optional()
29271
- });
29272
- var sandboxNetworkAccessSchema = external_exports.union([
29273
- external_exports.enum(["none", "essentials", "open"]),
29274
- external_exports.object({
29275
- profile: external_exports.enum(["none", "essentials", "open"]).optional(),
29276
- allow: external_exports.array(external_exports.string()).optional()
29277
- })
29278
- ]);
29279
- var sandboxConfigSchema = external_exports.object({
29280
- enabled: external_exports.boolean(),
29281
- // INERT except `'runtype-sandbox'`: the agent-sandbox runtime
29282
- // (`SandboxToolService`) REJECTS any provider other than `'runtype-sandbox'`
29283
- // with a throw at the first sandbox tool call — `'daytona'` is NOT honored on
29284
- // this path (Phase 3 "Daytona parity" is unshipped). Kept parseable (not
29285
- // narrowed to `['runtype-sandbox']`) so a stored/imported `'daytona'` config
29286
- // does not fail agent-config parse, and so this schema stays aligned with the
29287
- // FPO public-types mirror + MCP snapshot that still list it. Selecting
29288
- // `'daytona'` is an author-time no-op that surfaces as a runtime error.
29289
- // (`quickjs` / `cloudflare-worker` are code-eval only, no shell — never valid.)
29290
- provider: external_exports.enum(["runtype-sandbox", "daytona"]).optional(),
29291
- // `'ephemeral'` and `'conversation'` (the default) are implemented.
29292
- // `'named'` is parseable but NOT yet implemented: the runtime silently
29293
- // degrades `'named'` to `'ephemeral'` (with a debug log) — no durable
29294
- // cross-conversation workspace exists yet (Phase 3). Kept parseable so a
29295
- // stored `'named'` config still loads; it just behaves as `'ephemeral'`.
29296
- persistence: external_exports.enum(["ephemeral", "conversation", "named"]).optional(),
29297
- // INERT on the agent sandbox path: `instanceType` is NOT honored — the agent
29298
- // sandbox always provisions `standard-1` regardless of this value (the value
29299
- // is read for the transform-data/deploy sandbox billing paths, not for the
29300
- // agent builtin tools). Kept parseable for forward-compat + mirror alignment;
29301
- // treat it as a no-op author-time hint until the agent path wires container
29302
- // sizing.
29303
- instanceType: external_exports.enum(["standard-1", "standard-2", "standard-3", "standard-4"]).optional(),
29304
- networkAccess: sandboxNetworkAccessSchema.optional(),
29305
- ttl: external_exports.enum(["5m", "1h", "24h", "unlimited"]).optional(),
29306
- sleepAfter: external_exports.enum(["5m", "15m", "30m", "1h"]).optional(),
29307
- // Operator-authored bootstrap commands. The API runs this batch once after
29308
- // enforcing the sandbox's network policy and before the first model-authored
29309
- // sandbox verb. Commands run in order from /workspace and must be foreground,
29310
- // self-contained, and safe to retry after an interrupted container runtime;
29311
- // the credential-bearing exec supervisor deliberately reaps every descendant
29312
- // before a command returns, so setup cannot launch a daemon meant to outlive
29313
- // it. Trusted Durable Object state plus a run-scoped memo prevents the batch
29314
- // from being repeated for the same provisioned workspace. Changing the
29315
- // commands or managed-secret KEY bindings creates a fresh sandbox identity;
29316
- // rotating a value under the same key does not rerun setup.
29317
- setupCommands: external_exports.array(external_exports.string().min(1, "setup commands must not be empty")).optional(),
29318
- // Credential environment available ONLY to the operator-authored setup batch
29319
- // above — never to a model-authored `bash` command. Keys are env var names;
29320
- // values are MANAGED SECRET KEYS (e.g. `GITHUB_CLONE_TOKEN`), never raw
29321
- // credential values. The API resolves them immediately before setup and
29322
- // delivers them out-of-band over `cloudflareSandboxExecWithSecretEnv`, so the
29323
- // values never appear in command strings, model-facing tool schemas, logs, or
29324
- // spill files. Like `networkAccess`, both fields are operator Definition: the
29325
- // model cannot author setup, name a managed secret, or grant itself one.
29326
- //
29327
- // TRUST BOUNDARY — read before configuring this. Every process started by a
29328
- // credentialed setup batch can read the injected values. Keep setup authored
29329
- // and reviewed by the operator; do not run model-, attacker-, or
29330
- // supply-chain-authored code (for example an install script) while credentials
29331
- // are present, and never persist a raw credential into /workspace for later
29332
- // model access. The secret supervisor freezes pre-existing processes, reaps
29333
- // every setup descendant, and destroys the sandbox fail-closed if cleanup
29334
- // fails, but output redaction remains defense-in-depth rather than permission
29335
- // to echo or transform a credential.
29336
- // Therefore:
29337
- // - Prefer `credentialProxies` (phantom tokens, swapped at the egress
29338
- // proxy) for any HTTP(S) protocol it supports — the real credential
29339
- // never enters the container at all.
29340
- // - Scope the secret as narrowly as the provider allows (read-only,
29341
- // single-repo) and pair it with a tight `networkAccess` profile.
29342
- // - Keep credentialed setup separate from later uncredentialed dependency
29343
- // installation and model-authored work.
29344
- // Name shape and the 32-entry cap mirror the sandbox worker's
29345
- // `validateSecretEnv`; `RUNTYPE_SECRET_COMMAND` is the worker's reserved
29346
- // control-channel variable.
29347
- secretEnv: external_exports.record(
29348
- external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "must be a valid environment variable name").refine((name) => name !== "RUNTYPE_SECRET_COMMAND", {
29349
- message: "RUNTYPE_SECRET_COMMAND is reserved"
29350
- }),
29351
- external_exports.string().min(1, "must be a managed secret key")
29352
- ).refine((record2) => Object.keys(record2).length <= 32, {
29353
- message: "secretEnv supports at most 32 variables"
29354
- }).optional()
29355
- // NOTE: a `requireApprovalForBash` knob was forward-declared here for Phase 3
29356
- // but never wired to any runtime gate, so it was REMOVED from the public
29357
- // schema rather than ship a misleading, inert control (post-Fable handoff 05,
29358
- // F3). To gate `bash` today use the generic `tools.approval` config, which
29359
- // matches the tool by name. Re-add the dedicated knob only with its wiring.
29360
- });
29361
- var agentRuntimeConfigSchema = external_exports.object({
29362
- model: external_exports.string().optional(),
29363
- systemPrompt: external_exports.string().optional(),
29364
- temperature: external_exports.number().min(0).max(2).optional(),
29365
- // Maximum output tokens (the model call's `maxOutputTokens`). A sibling of
29366
- // the sampling params: a static generation budget that belongs on the saved
29367
- // agent definition. Notably load-bearing for "thinking" default models that
29368
- // share reasoning + answer tokens in one output budget (Moonshot requires
29369
- // `>= 16k` or the visible answer can truncate to nothing after a long
29370
- // reasoning trace) — the Product Generator pins `24000` for exactly this.
29371
- // `buildVirtualFlow` already maps this onto the prompt step (defaulting to
29372
- // 16384 when unset), so saving it here is all that's required for it to take
29373
- // effect at execution time.
29374
- maxTokens: external_exports.number().int().min(1).optional(),
29375
- ...samplingConfigSchema,
29376
- // Unified tools configuration (nested under 'tools').
29377
- //
29378
- // This is the **createAgent / FPO-v2 create-form** projection of the canonical
29379
- // `agentToolsConfigSchema` (`tool-types.ts`). It is kept separate on purpose —
29380
- // it carries create-time constraints (`.int().min().max()`), a create-form
29381
- // `runtimeTools.toolType` enum (`advisor`/`search` instead of the canonical
29382
- // `RuntimeToolDefinition` union), and does NOT yet accept `toolSearch`.
29383
- // Collapsing it onto the canonical leaves would change createAgent validation,
29384
- // so the two are pinned by review + the planning doc rather than a shared
29385
- // import. Adding `toolSearch` here (to match the canonical schema + the runtime
29386
- // wire form) is a tracked follow-up.
29387
- tools: external_exports.object({
29388
- toolIds: external_exports.array(external_exports.string()).optional(),
29389
- toolConfigs: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
29390
- runtimeTools: external_exports.array(
29391
- external_exports.object({
29392
- name: external_exports.string(),
29393
- description: external_exports.string(),
29394
- toolType: external_exports.enum([
29395
- "flow",
29396
- "custom",
29397
- "external",
29398
- "local",
29399
- "advisor",
29400
- "subagent",
29401
- "search"
29402
- ]),
29403
- parametersSchema: external_exports.record(external_exports.string(), external_exports.unknown()),
29404
- config: external_exports.record(external_exports.string(), external_exports.unknown())
29405
- })
29406
- ).optional(),
29407
- mcpServers: external_exports.array(
29408
- external_exports.object({
29409
- id: external_exports.string(),
29410
- name: external_exports.string().optional(),
29411
- url: external_exports.string(),
29412
- auth: external_exports.object({
29413
- type: external_exports.enum(["api_key", "bearer", "basic", "custom_header", "headers", "none"]),
29414
- headerName: external_exports.string().optional(),
29415
- token: external_exports.string().optional(),
29416
- username: external_exports.string().optional(),
29417
- password: external_exports.string().optional(),
29418
- // For `type: 'headers'`: arbitrary HTTP header name → value
29419
- // templates. The shared refinement below enforces the exclusive shape.
29420
- headers: external_exports.record(external_exports.string(), external_exports.string()).optional()
29421
- }).superRefine((auth, ctx) => {
29422
- const validation = validateMCPHeadersAuth(auth);
29423
- if (!validation.valid) {
29424
- ctx.addIssue({
29425
- code: "custom",
29426
- path: validation.path,
29427
- message: validation.message
29428
- });
29429
- }
29430
- }).optional(),
29431
- allowedTools: external_exports.array(external_exports.string()).optional(),
29432
- timeout: external_exports.number().optional(),
29433
- transport: external_exports.enum(["streamable_http", "rest"]).optional(),
29434
- enabled: external_exports.boolean().optional()
29435
- })
29436
- ).optional(),
29437
- maxToolCalls: external_exports.number().int().min(1).max(100).optional(),
29438
- toolCallStrategy: external_exports.enum(["auto", "required", "none"]).optional(),
29439
- approval: external_exports.object({
29440
- require: external_exports.union([external_exports.array(external_exports.string()), external_exports.boolean()]),
29441
- timeout: external_exports.number().optional(),
29442
- /** Opt out of agent-supplied approval reasons (`_approvalReason`
29443
- * schema injection). Default: true. Mirrors approvalConfigSchema
29444
- * in tool-types.ts. */
29445
- requestReason: external_exports.boolean().optional(),
29446
- /** Persistent "always" choices offered at the approval prompt.
29447
- * Mirrors approvalConfigSchema.choices in tool-types.ts. */
29448
- choices: external_exports.object({
29449
- alwaysAllow: external_exports.boolean().optional(),
29450
- alwaysDeny: external_exports.boolean().optional()
29451
- }).optional()
29452
- }).optional(),
29453
- perToolLimits: external_exports.record(
29454
- external_exports.string(),
29455
- external_exports.object({
29456
- maxCalls: external_exports.number().optional(),
29457
- required: external_exports.boolean().optional()
29458
- })
29459
- ).optional(),
29460
- subagentConfig: external_exports.object({
29461
- toolPool: external_exports.array(external_exports.string()),
29462
- defaultMaxTurns: external_exports.number().int().min(1).max(100).optional(),
29463
- maxTurnsLimit: external_exports.number().int().min(1).max(100).optional(),
29464
- maxSpawnsPerRun: external_exports.number().int().min(1).max(50).optional(),
29465
- defaultModel: external_exports.string().optional(),
29466
- allowNesting: external_exports.boolean().optional(),
29467
- // Max must stay <= the dispatch `options.stepTimeoutMs` cap
29468
- // (600_000 — `api-schemas/dispatch.ts`): `resolveSubagentTimeouts`
29469
- // (apps/api subagent dispatch) stamps the child flow's
29470
- // `stepTimeoutMs` from the subagent's effective timeout. Keep the
29471
- // two bounds in lockstep or 600s subagents break at the smaller cap.
29472
- defaultTimeoutMs: external_exports.number().int().min(1e3).max(6e5).optional(),
29473
- executionModes: external_exports.array(external_exports.enum(["attached", "detached"])).min(1).optional(),
29474
- defaultExecutionMode: external_exports.enum(["attached", "detached"]).optional(),
29475
- defaultNotify: external_exports.enum(["none", "narrate", "react"]).optional(),
29476
- detachedMaxBudgetMs: external_exports.number().int().min(1e3).max(864e5).optional(),
29477
- detachedNoProgressBudgetMs: external_exports.number().int().min(1e3).max(864e5).optional()
29478
- }).optional(),
29479
- codeModeConfig: external_exports.object({
29480
- toolPool: external_exports.array(external_exports.string()),
29481
- description: external_exports.string().optional(),
29482
- timeoutMs: external_exports.number().int().min(1e3).max(6e5).optional()
29483
- }).optional()
29484
- }).optional(),
29485
- artifacts: artifactConfigSchema.optional(),
29486
- reasoning: reasoningConfigSchema.optional(),
29487
- advisor: external_exports.object({
29488
- model: external_exports.string(),
29489
- systemPrompt: external_exports.string().optional()
29490
- }).optional().nullable(),
29491
- loopConfig: external_exports.object({
29492
- maxTurns: external_exports.number().int().min(1).max(100).optional(),
29493
- maxCost: external_exports.number().min(0).optional(),
29494
- enableReflection: external_exports.boolean().optional(),
29495
- reflectionInterval: external_exports.number().int().min(1).max(50).optional()
29496
- }).optional(),
29497
- voice: external_exports.object({
29498
- enabled: external_exports.boolean().optional(),
29499
- provider: external_exports.string().optional(),
29500
- interruptionMode: external_exports.enum(["none", "cancel", "barge-in"]).optional(),
29501
- elevenLabs: external_exports.object({
29502
- voiceId: external_exports.string().optional(),
29503
- modelId: external_exports.string().optional(),
29504
- stability: external_exports.number().min(0).max(1).optional(),
29505
- similarity: external_exports.number().min(0).max(1).optional()
29506
- }).optional()
29507
- }).optional(),
29508
- errorHandling: errorHandlingSchema,
29509
- loggingPolicy: external_exports.enum(["default", "on", "off"]).optional(),
29510
- // Opt-in PII redaction for tail-log and telemetry payloads. `'default'`
29511
- // defers to a lower layer (surface/product) or the resolver default (off).
29512
- // Mirrors `loggingPolicy`.
29513
- piiRedaction: external_exports.enum(["default", "off", "redact"]).optional(),
29514
- // Opt-in temporal awareness. `injectElapsed` turns on the automatic
29515
- // "time has passed" decorator (a `<temporal_context>` block prepended to
29516
- // the user turn at dispatch, gated on turn ≥ 2 and a gap ≥
29517
- // `elapsedThresholdSeconds`). `groundNow` additionally surfaces the current
29518
- // datetime in that block. `timezone` is the agent's DEFAULT IANA zone —
29519
- // the layered tool/decorator resolution overrides it per-conversation.
29520
- temporal: temporalConfigSchema.optional(),
29521
- // Long-term memory (Cloudflare Agent Memory). Single-sourced as
29522
- // `memoryConfigSchema` (below) and reused by the update-agent, dispatch
29523
- // inline-agent, and FPO agent schemas so the four surfaces never drift —
29524
- // mirroring how `temporalConfigSchema` is shared.
29525
- memory: memoryConfigSchema.optional(),
29526
- // Agent Sandbox (Linux computer). When enabled, the agent gets the sandbox
29527
- // builtin tools + system-prompt frame at dispatch. Single-sourced as
29528
- // `sandboxConfigSchema` (above), mirroring `memory`. The live machine is agent
29529
- // state; this block is the operator Definition that enables it.
29530
- sandbox: sandboxConfigSchema.optional(),
29531
- // Tenancy Strategy (ADR 0012) — per-resource opt-in to tenant/end-user
29532
- // isolation. Part of the Definition (validated + persisted + content-hashed
29533
- // here so `ensure` tracks it). Absent → platform-global default (no behavior
29534
- // change); present → the execution pipeline expands it and enforces the
29535
- // lock-down gate pre-engine. Single-sourced as `tenancyStrategySchema` in
29536
- // `./tenancy-strategy`; the expansion + gate logic lives in apps/api.
29537
- tenancyStrategy: tenancyStrategySchema.optional()
29538
- }).strict();
29539
29934
  var identityAdapterKindSchema = external_exports.enum(["oidc-jwt", "session", "custom"]);
29540
29935
  var ASYMMETRIC_JWT_ALGORITHMS = [
29541
29936
  "RS256",
@@ -29769,7 +30164,12 @@ var agentReasoningConfigSchema = external_exports.object({
29769
30164
  reasoningEffort: external_exports.enum(["minimal", "low", "medium", "high", "xhigh"]).optional(),
29770
30165
  reasoningSummary: external_exports.enum(["auto", "detailed"]).optional(),
29771
30166
  budgetTokens: external_exports.number().int().min(1e3).max(1e5).optional(),
30167
+ // Anthropic adaptive thinking / Gemini 3+ level mode. Free-form for the same
30168
+ // per-model catalog-ladder reason as `reasoningConfigSchema` in
30169
+ // `agent-runtime-config-schema.ts`; kept in lockstep with it.
30170
+ effort: external_exports.string().min(1).max(32).optional(),
29772
30171
  thinkingBudget: external_exports.number().int().min(1024).max(65536).optional(),
30172
+ thinkingLevel: external_exports.string().min(1).max(32).optional(),
29773
30173
  includeThoughts: external_exports.boolean().optional()
29774
30174
  });
29775
30175
  var agentVoiceConfigSchema = external_exports.object({
@@ -32111,7 +32511,7 @@ var DispatchRequestEnvelopeSchema = external_exports.object({
32111
32511
  */
32112
32512
  clientToolsPolicy: ClientToolsPolicySchema.optional(),
32113
32513
  secrets: external_exports.record(external_exports.string(), external_exports.string()).optional().describe(
32114
- "Per-request credentials for agent/external-tool execution. Ignored when `flow` is the hosted target; FLOW credentials must use managed {{secret:NAME}} references."
32514
+ "Retired. A NON-EMPTY map on an agent dispatch is rejected with 400 RUNTIME_AGENT_TRANSIENT_SECRETS_UNSUPPORTED, unless the deprecated `options.useRuntimePackage: false` opt-out routes the run to the legacy engine, which still honors it for single-turn (non-loop) agents until that engine is removed. An empty map is accepted and does nothing. Ignored on flow dispatches. Store credentials as managed secrets and reference them as {{secret:NAME}}. The field is kept on the wire for compatibility only."
32115
32515
  ),
32116
32516
  credentialProxies: external_exports.array(credentialProxyConfigSchema).max(10).optional(),
32117
32517
  inputs: external_exports.record(external_exports.string(), external_exports.any()).optional().refine(
@@ -32154,7 +32554,7 @@ var DispatchRequestEnvelopeSchema = external_exports.object({
32154
32554
  debugMode: external_exports.boolean().optional().default(false),
32155
32555
  loggingPolicy: external_exports.enum(["default", "on", "off"]).optional(),
32156
32556
  useRuntimePackage: external_exports.boolean().optional().describe(
32157
- "Compatibility execution-lane OPT-OUT. For FLOW dispatches the field is accepted but ignored: eligible flows always use the @runtypelabs/runtime lane, while ineligible flows still fold to legacy silently. For AGENT dispatches, an eligible agent now uses the @runtypelabs/runtime lane by DEFAULT when this field is omitted; only an explicit `false` forces the legacy engine. Definitions the runtime lane cannot execute faithfully still fold to legacy on their own."
32557
+ "Execution-lane selector. `false` is DEPRECATED: the legacy agent engine is being retired, an agent dispatch that sends `false` still runs on it today with RFC 9745 `Deprecation` + `X-API-Deprecation-Warning` response headers, and a later release rejects it. Omitted (the default) runs an eligible agent on the @runtypelabs/runtime lane and folds a definition the lane cannot execute faithfully to legacy on its own; `true` is the strict opt-in that turns such a fold into a 400 instead. For FLOW dispatches the field is accepted but ignored: eligible flows always use the runtime lane, while ineligible flows still fold to legacy silently."
32158
32558
  ),
32159
32559
  /** Route prompt model calls through an attached dashboard browser. */
32160
32560
  localInference: LocalInferenceSelectionSchema.optional(),
@@ -53006,18 +53406,15 @@ agentsCommand.command("execute <id>").description("Execute an agent").requiredOp
53006
53406
  const apiKey = await ensureAuth();
53007
53407
  if (!apiKey) return;
53008
53408
  const client = createCliClient(apiKey);
53409
+ const messages = [{ role: "user", content: options.message }];
53009
53410
  const payload = {
53010
- messages: [{ role: "user", content: options.message }],
53411
+ messages,
53011
53412
  streamResponse: options.stream
53012
53413
  };
53013
53414
  if (options.stream) {
53014
53415
  console.log(chalk25.gray("Starting agent..."));
53015
53416
  try {
53016
- const response = await client.requestStream(`/agents/${id}/execute`, {
53017
- method: "POST",
53018
- body: JSON.stringify(payload),
53019
- headers: { Accept: "text/event-stream" }
53020
- });
53417
+ const response = await client.agents.executeStream(id, { messages });
53021
53418
  const callbacks = {
53022
53419
  onStepDelta: (chunk) => {
53023
53420
  process.stdout.write(chunk);