@runtypelabs/cli 2.32.1 → 2.32.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +864 -500
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -619,6 +619,141 @@ import { RuntypeApiError } from "@runtypelabs/sdk";
|
|
|
619
619
|
// src/lib/sdk-client.ts
|
|
620
620
|
import { createClient } from "@runtypelabs/sdk";
|
|
621
621
|
|
|
622
|
+
// ../shared/dist/chunk-R7RM64AL.mjs
|
|
623
|
+
var DEFAULT_MODELS_FOR_NEW_ACCOUNTS = [
|
|
624
|
+
// Mixlayer models
|
|
625
|
+
{
|
|
626
|
+
provider: "runtype",
|
|
627
|
+
modelId: "qwen/qwen3.6-27b",
|
|
628
|
+
isDefault: false,
|
|
629
|
+
strengths: "Fast, low-cost open-weight workhorse with reasoning, tool-use, and vision \u2014 good for high-volume extraction, classification, and simple transforms.",
|
|
630
|
+
bestFor: ["fast-cheap", "vision"]
|
|
631
|
+
},
|
|
632
|
+
// Routed models - benefit from automatic provider optimization
|
|
633
|
+
// OpenAI models (routed via OpenAI direct, with Vercel fallback)
|
|
634
|
+
{
|
|
635
|
+
provider: "runtype",
|
|
636
|
+
modelId: "gpt-5.5",
|
|
637
|
+
isDefault: false,
|
|
638
|
+
strengths: "Top-tier general reasoning and tool-use with excellent structured-output reliability, vision, and a 1M context \u2014 a strong pick for complex, correctness-sensitive steps.",
|
|
639
|
+
bestFor: ["default", "deep-reasoning", "agentic-tools", "vision", "long-context"]
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
provider: "runtype",
|
|
643
|
+
modelId: "gpt-5.4-mini",
|
|
644
|
+
isDefault: false,
|
|
645
|
+
strengths: "Fast and affordable with dependable JSON formatting \u2014 a good fit for mid-complexity task steps.",
|
|
646
|
+
bestFor: ["fast-cheap", "default"]
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
provider: "runtype",
|
|
650
|
+
modelId: "gpt-5.4-nano",
|
|
651
|
+
isDefault: false,
|
|
652
|
+
strengths: "Cheapest and fastest GPT-5 tier \u2014 reserve for trivial deterministic transforms, routing, and classification, not complex authoring.",
|
|
653
|
+
bestFor: ["fast-cheap"]
|
|
654
|
+
},
|
|
655
|
+
// Anthropic models (routed via Anthropic direct, with Vertex/Bedrock fallback)
|
|
656
|
+
{
|
|
657
|
+
provider: "runtype",
|
|
658
|
+
modelId: "claude-haiku-4-5",
|
|
659
|
+
isDefault: false,
|
|
660
|
+
strengths: "Fast and inexpensive while retaining real reasoning, tool-use, and vision \u2014 great for high-volume task steps that still need some judgment.",
|
|
661
|
+
bestFor: ["fast-cheap", "agentic-tools", "vision"]
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
provider: "runtype",
|
|
665
|
+
modelId: "claude-sonnet-5",
|
|
666
|
+
isDefault: false,
|
|
667
|
+
strengths: "Balanced all-rounder: strong reasoning, very reliable multi-round tool loops, vision, and a 1M context \u2014 an excellent choice for agentic and structured work.",
|
|
668
|
+
bestFor: ["default", "agentic-tools", "vision", "long-context"]
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
provider: "runtype",
|
|
672
|
+
modelId: "claude-opus-4-8",
|
|
673
|
+
isDefault: false,
|
|
674
|
+
strengths: "Deepest reasoning and planning for hard analysis and multi-constraint synthesis, with vision and a 1M context \u2014 premium-priced, so reserve for genuinely difficult steps.",
|
|
675
|
+
bestFor: ["deep-reasoning", "vision", "long-context"]
|
|
676
|
+
},
|
|
677
|
+
// Google models (routed via Google direct, with Vertex/Vercel fallback)
|
|
678
|
+
{
|
|
679
|
+
provider: "runtype",
|
|
680
|
+
modelId: "gemini-3-1-flash-lite",
|
|
681
|
+
isDefault: false,
|
|
682
|
+
strengths: "Very fast and very cheap with full multimodal input (vision and audio), good structured output, and a 1M context \u2014 ideal for high-volume, simple steps.",
|
|
683
|
+
bestFor: ["fast-cheap", "vision", "long-context"]
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
provider: "runtype",
|
|
687
|
+
modelId: "gemini-3.6-flash",
|
|
688
|
+
isDefault: false,
|
|
689
|
+
strengths: "Fast, low-cost, and natively multimodal with good reasoning, tool-use, and a 1M context \u2014 a strong choice for vision and high-throughput steps.",
|
|
690
|
+
bestFor: ["default", "vision", "fast-cheap", "agentic-tools", "long-context"]
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
provider: "runtype",
|
|
694
|
+
modelId: "gemini-3-1-flash-image",
|
|
695
|
+
isDefault: false,
|
|
696
|
+
strengths: "Specialised for image generation and editing (image output) \u2014 use for steps that produce images, not text reasoning.",
|
|
697
|
+
bestFor: ["image-generation"]
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
provider: "runtype",
|
|
701
|
+
modelId: "gemini-3.1-pro",
|
|
702
|
+
isDefault: false,
|
|
703
|
+
strengths: "Google's frontier tier: strong reasoning, a 1M context, and multimodal input \u2014 for complex analytical or long-document steps.",
|
|
704
|
+
bestFor: ["deep-reasoning", "vision", "long-context"]
|
|
705
|
+
},
|
|
706
|
+
// Inception models (routed via Vercel)
|
|
707
|
+
{
|
|
708
|
+
provider: "runtype",
|
|
709
|
+
modelId: "mercury-2",
|
|
710
|
+
isDefault: false,
|
|
711
|
+
strengths: "Diffusion-based LLM optimised for very low latency \u2014 good when speed matters more than deep reasoning.",
|
|
712
|
+
bestFor: ["fast-cheap"]
|
|
713
|
+
},
|
|
714
|
+
// Moonshot models (routed via Vercel)
|
|
715
|
+
// Kimi K2.6 is the default model: a reasoning + tool-use + vision model
|
|
716
|
+
// already trusted as the product-generator default.
|
|
717
|
+
{
|
|
718
|
+
provider: "runtype",
|
|
719
|
+
modelId: "kimi-k2.6",
|
|
720
|
+
isDefault: true,
|
|
721
|
+
strengths: "Capable open agentic model with reasoning, tool-use, and vision at strong value \u2014 the current account default and a dependable general workhorse.",
|
|
722
|
+
bestFor: ["default", "agentic-tools", "vision"]
|
|
723
|
+
},
|
|
724
|
+
// NVIDIA Nemotron Ultra (reasoning + tool-use flagship, routed via Vercel)
|
|
725
|
+
{
|
|
726
|
+
provider: "runtype",
|
|
727
|
+
modelId: "nemotron-3-ultra-550b-a55b",
|
|
728
|
+
isDefault: false,
|
|
729
|
+
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.",
|
|
730
|
+
bestFor: ["deep-reasoning", "agentic-tools", "long-context"]
|
|
731
|
+
},
|
|
732
|
+
// Google models (routed via Cloudflare Workers AI)
|
|
733
|
+
{
|
|
734
|
+
provider: "runtype",
|
|
735
|
+
modelId: "gemma-4-26b-a4b-it",
|
|
736
|
+
isDefault: false,
|
|
737
|
+
strengths: "Lightweight open-weight instruct model served free on Workers AI \u2014 fine for straightforward general tasks at zero cost.",
|
|
738
|
+
bestFor: ["fast-cheap"]
|
|
739
|
+
},
|
|
740
|
+
// Z.ai GLM-5.2 (agentic coding flagship, routed via Cloudflare Workers AI,
|
|
741
|
+
// Vercel fallback). The bare routed name resolves to `@cf/zai-org/glm-5.2`.
|
|
742
|
+
{
|
|
743
|
+
provider: "runtype",
|
|
744
|
+
modelId: "glm-5.2",
|
|
745
|
+
isDefault: false,
|
|
746
|
+
strengths: "Agentic flagship \u2014 best-in-class at long, multi-round tool-call loops and coding/agent workflows, with a 1M context; well suited to tool-heavy agent steps.",
|
|
747
|
+
bestFor: ["agentic-tools", "default", "deep-reasoning", "long-context"]
|
|
748
|
+
}
|
|
749
|
+
];
|
|
750
|
+
var DEFAULT_MODEL_ID = DEFAULT_MODELS_FOR_NEW_ACCOUNTS.find((m2) => m2.isDefault)?.modelId ?? "kimi-k2.6";
|
|
751
|
+
function renderDefaultModelStrengthsGuide() {
|
|
752
|
+
return DEFAULT_MODELS_FOR_NEW_ACCOUNTS.map(
|
|
753
|
+
(m2) => `- \`${m2.modelId}\`${m2.isDefault ? " (account default)" : ""} \u2014 ${m2.strengths}`
|
|
754
|
+
).join("\n");
|
|
755
|
+
}
|
|
756
|
+
|
|
622
757
|
// ../shared/dist/chunk-72QEJTK5.mjs
|
|
623
758
|
var travrseConfig = {
|
|
624
759
|
name: "Travrse",
|
|
@@ -15260,141 +15395,6 @@ var edgeContextPayloadSchema = external_exports.object({
|
|
|
15260
15395
|
// ../shared/dist/chunk-SCJRL6LP.mjs
|
|
15261
15396
|
var MAX_DURABLE_POLL_ATTEMPTS = 1e3;
|
|
15262
15397
|
|
|
15263
|
-
// ../shared/dist/chunk-R7RM64AL.mjs
|
|
15264
|
-
var DEFAULT_MODELS_FOR_NEW_ACCOUNTS = [
|
|
15265
|
-
// Mixlayer models
|
|
15266
|
-
{
|
|
15267
|
-
provider: "runtype",
|
|
15268
|
-
modelId: "qwen/qwen3.6-27b",
|
|
15269
|
-
isDefault: false,
|
|
15270
|
-
strengths: "Fast, low-cost open-weight workhorse with reasoning, tool-use, and vision \u2014 good for high-volume extraction, classification, and simple transforms.",
|
|
15271
|
-
bestFor: ["fast-cheap", "vision"]
|
|
15272
|
-
},
|
|
15273
|
-
// Routed models - benefit from automatic provider optimization
|
|
15274
|
-
// OpenAI models (routed via OpenAI direct, with Vercel fallback)
|
|
15275
|
-
{
|
|
15276
|
-
provider: "runtype",
|
|
15277
|
-
modelId: "gpt-5.5",
|
|
15278
|
-
isDefault: false,
|
|
15279
|
-
strengths: "Top-tier general reasoning and tool-use with excellent structured-output reliability, vision, and a 1M context \u2014 a strong pick for complex, correctness-sensitive steps.",
|
|
15280
|
-
bestFor: ["default", "deep-reasoning", "agentic-tools", "vision", "long-context"]
|
|
15281
|
-
},
|
|
15282
|
-
{
|
|
15283
|
-
provider: "runtype",
|
|
15284
|
-
modelId: "gpt-5.4-mini",
|
|
15285
|
-
isDefault: false,
|
|
15286
|
-
strengths: "Fast and affordable with dependable JSON formatting \u2014 a good fit for mid-complexity task steps.",
|
|
15287
|
-
bestFor: ["fast-cheap", "default"]
|
|
15288
|
-
},
|
|
15289
|
-
{
|
|
15290
|
-
provider: "runtype",
|
|
15291
|
-
modelId: "gpt-5.4-nano",
|
|
15292
|
-
isDefault: false,
|
|
15293
|
-
strengths: "Cheapest and fastest GPT-5 tier \u2014 reserve for trivial deterministic transforms, routing, and classification, not complex authoring.",
|
|
15294
|
-
bestFor: ["fast-cheap"]
|
|
15295
|
-
},
|
|
15296
|
-
// Anthropic models (routed via Anthropic direct, with Vertex/Bedrock fallback)
|
|
15297
|
-
{
|
|
15298
|
-
provider: "runtype",
|
|
15299
|
-
modelId: "claude-haiku-4-5",
|
|
15300
|
-
isDefault: false,
|
|
15301
|
-
strengths: "Fast and inexpensive while retaining real reasoning, tool-use, and vision \u2014 great for high-volume task steps that still need some judgment.",
|
|
15302
|
-
bestFor: ["fast-cheap", "agentic-tools", "vision"]
|
|
15303
|
-
},
|
|
15304
|
-
{
|
|
15305
|
-
provider: "runtype",
|
|
15306
|
-
modelId: "claude-sonnet-5",
|
|
15307
|
-
isDefault: false,
|
|
15308
|
-
strengths: "Balanced all-rounder: strong reasoning, very reliable multi-round tool loops, vision, and a 1M context \u2014 an excellent choice for agentic and structured work.",
|
|
15309
|
-
bestFor: ["default", "agentic-tools", "vision", "long-context"]
|
|
15310
|
-
},
|
|
15311
|
-
{
|
|
15312
|
-
provider: "runtype",
|
|
15313
|
-
modelId: "claude-opus-4-8",
|
|
15314
|
-
isDefault: false,
|
|
15315
|
-
strengths: "Deepest reasoning and planning for hard analysis and multi-constraint synthesis, with vision and a 1M context \u2014 premium-priced, so reserve for genuinely difficult steps.",
|
|
15316
|
-
bestFor: ["deep-reasoning", "vision", "long-context"]
|
|
15317
|
-
},
|
|
15318
|
-
// Google models (routed via Google direct, with Vertex/Vercel fallback)
|
|
15319
|
-
{
|
|
15320
|
-
provider: "runtype",
|
|
15321
|
-
modelId: "gemini-3-1-flash-lite",
|
|
15322
|
-
isDefault: false,
|
|
15323
|
-
strengths: "Very fast and very cheap with full multimodal input (vision and audio), good structured output, and a 1M context \u2014 ideal for high-volume, simple steps.",
|
|
15324
|
-
bestFor: ["fast-cheap", "vision", "long-context"]
|
|
15325
|
-
},
|
|
15326
|
-
{
|
|
15327
|
-
provider: "runtype",
|
|
15328
|
-
modelId: "gemini-3.6-flash",
|
|
15329
|
-
isDefault: false,
|
|
15330
|
-
strengths: "Fast, low-cost, and natively multimodal with good reasoning, tool-use, and a 1M context \u2014 a strong choice for vision and high-throughput steps.",
|
|
15331
|
-
bestFor: ["default", "vision", "fast-cheap", "agentic-tools", "long-context"]
|
|
15332
|
-
},
|
|
15333
|
-
{
|
|
15334
|
-
provider: "runtype",
|
|
15335
|
-
modelId: "gemini-3-1-flash-image",
|
|
15336
|
-
isDefault: false,
|
|
15337
|
-
strengths: "Specialised for image generation and editing (image output) \u2014 use for steps that produce images, not text reasoning.",
|
|
15338
|
-
bestFor: ["image-generation"]
|
|
15339
|
-
},
|
|
15340
|
-
{
|
|
15341
|
-
provider: "runtype",
|
|
15342
|
-
modelId: "gemini-3.1-pro",
|
|
15343
|
-
isDefault: false,
|
|
15344
|
-
strengths: "Google's frontier tier: strong reasoning, a 1M context, and multimodal input \u2014 for complex analytical or long-document steps.",
|
|
15345
|
-
bestFor: ["deep-reasoning", "vision", "long-context"]
|
|
15346
|
-
},
|
|
15347
|
-
// Inception models (routed via Vercel)
|
|
15348
|
-
{
|
|
15349
|
-
provider: "runtype",
|
|
15350
|
-
modelId: "mercury-2",
|
|
15351
|
-
isDefault: false,
|
|
15352
|
-
strengths: "Diffusion-based LLM optimised for very low latency \u2014 good when speed matters more than deep reasoning.",
|
|
15353
|
-
bestFor: ["fast-cheap"]
|
|
15354
|
-
},
|
|
15355
|
-
// Moonshot models (routed via Vercel)
|
|
15356
|
-
// Kimi K2.6 is the default model: a reasoning + tool-use + vision model
|
|
15357
|
-
// already trusted as the product-generator default.
|
|
15358
|
-
{
|
|
15359
|
-
provider: "runtype",
|
|
15360
|
-
modelId: "kimi-k2.6",
|
|
15361
|
-
isDefault: true,
|
|
15362
|
-
strengths: "Capable open agentic model with reasoning, tool-use, and vision at strong value \u2014 the current account default and a dependable general workhorse.",
|
|
15363
|
-
bestFor: ["default", "agentic-tools", "vision"]
|
|
15364
|
-
},
|
|
15365
|
-
// NVIDIA Nemotron Ultra (reasoning + tool-use flagship, routed via Vercel)
|
|
15366
|
-
{
|
|
15367
|
-
provider: "runtype",
|
|
15368
|
-
modelId: "nemotron-3-ultra-550b-a55b",
|
|
15369
|
-
isDefault: false,
|
|
15370
|
-
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.",
|
|
15371
|
-
bestFor: ["deep-reasoning", "agentic-tools", "long-context"]
|
|
15372
|
-
},
|
|
15373
|
-
// Google models (routed via Cloudflare Workers AI)
|
|
15374
|
-
{
|
|
15375
|
-
provider: "runtype",
|
|
15376
|
-
modelId: "gemma-4-26b-a4b-it",
|
|
15377
|
-
isDefault: false,
|
|
15378
|
-
strengths: "Lightweight open-weight instruct model served free on Workers AI \u2014 fine for straightforward general tasks at zero cost.",
|
|
15379
|
-
bestFor: ["fast-cheap"]
|
|
15380
|
-
},
|
|
15381
|
-
// Z.ai GLM-5.2 (agentic coding flagship, routed via Cloudflare Workers AI,
|
|
15382
|
-
// Vercel fallback). The bare routed name resolves to `@cf/zai-org/glm-5.2`.
|
|
15383
|
-
{
|
|
15384
|
-
provider: "runtype",
|
|
15385
|
-
modelId: "glm-5.2",
|
|
15386
|
-
isDefault: false,
|
|
15387
|
-
strengths: "Agentic flagship \u2014 best-in-class at long, multi-round tool-call loops and coding/agent workflows, with a 1M context; well suited to tool-heavy agent steps.",
|
|
15388
|
-
bestFor: ["agentic-tools", "default", "deep-reasoning", "long-context"]
|
|
15389
|
-
}
|
|
15390
|
-
];
|
|
15391
|
-
var DEFAULT_MODEL_ID = DEFAULT_MODELS_FOR_NEW_ACCOUNTS.find((m2) => m2.isDefault)?.modelId ?? "kimi-k2.6";
|
|
15392
|
-
function renderDefaultModelStrengthsGuide() {
|
|
15393
|
-
return DEFAULT_MODELS_FOR_NEW_ACCOUNTS.map(
|
|
15394
|
-
(m2) => `- \`${m2.modelId}\`${m2.isDefault ? " (account default)" : ""} \u2014 ${m2.strengths}`
|
|
15395
|
-
).join("\n");
|
|
15396
|
-
}
|
|
15397
|
-
|
|
15398
15398
|
// ../shared/dist/chunk-UB6BK3TZ.mjs
|
|
15399
15399
|
function getNestedValue(obj, path20) {
|
|
15400
15400
|
let normalizedPath = path20;
|
|
@@ -15786,7 +15786,7 @@ function resolveFallback(parsed, context, tracking, options = {}) {
|
|
|
15786
15786
|
}
|
|
15787
15787
|
var templateEngine = new SimpleTemplateEngine();
|
|
15788
15788
|
|
|
15789
|
-
// ../shared/dist/chunk-
|
|
15789
|
+
// ../shared/dist/chunk-MN4NECP7.mjs
|
|
15790
15790
|
var tokensSchema = external_exports.object({ input: external_exports.number(), output: external_exports.number() });
|
|
15791
15791
|
var wireStopReasonSchema = external_exports.enum([
|
|
15792
15792
|
"end_turn",
|
|
@@ -16412,6 +16412,7 @@ var agentToolStartEventSchema = external_exports.object({
|
|
|
16412
16412
|
"local"
|
|
16413
16413
|
]),
|
|
16414
16414
|
parameters: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
16415
|
+
hiddenParameterNames: external_exports.array(external_exports.string()).optional(),
|
|
16415
16416
|
origin: external_exports.enum(["webmcp", "sdk"]).optional(),
|
|
16416
16417
|
pageOrigin: external_exports.string().optional()
|
|
16417
16418
|
});
|
|
@@ -17017,6 +17018,353 @@ var artifactSSEEventSchema = external_exports.discriminatedUnion("type", [
|
|
|
17017
17018
|
]);
|
|
17018
17019
|
var UNIFIED_SSE_EVENT_TYPE_SET = new Set(UNIFIED_SSE_EVENT_TYPES);
|
|
17019
17020
|
|
|
17021
|
+
// ../shared/dist/chunk-UG3J37K4.mjs
|
|
17022
|
+
function parseHTMLWithRegex(html) {
|
|
17023
|
+
if (typeof html !== "string") {
|
|
17024
|
+
throw new Error("parseHTML: input must be a string");
|
|
17025
|
+
}
|
|
17026
|
+
try {
|
|
17027
|
+
const parser = {
|
|
17028
|
+
stripTags(value) {
|
|
17029
|
+
return value.replace(/<[^>]*>/g, " ").replace(/<(\/?[a-zA-Z][^>]*)$/, "<$1").replace(/\s+/g, " ").trim();
|
|
17030
|
+
},
|
|
17031
|
+
querySelector(selector) {
|
|
17032
|
+
try {
|
|
17033
|
+
const tag = selector.replace(/[^a-zA-Z0-9-]/g, "");
|
|
17034
|
+
const match = html.match(new RegExp("<" + tag + "[^>]*>(.*?)<\\/" + tag + ">", "is"));
|
|
17035
|
+
return match ? parser.stripTags(match[1]).trim() || null : null;
|
|
17036
|
+
} catch {
|
|
17037
|
+
return null;
|
|
17038
|
+
}
|
|
17039
|
+
},
|
|
17040
|
+
querySelectorAll(selector) {
|
|
17041
|
+
try {
|
|
17042
|
+
const tag = selector.replace(/[^a-zA-Z0-9-]/g, "");
|
|
17043
|
+
const regex = new RegExp("<" + tag + "[^>]*>(.*?)<\\/" + tag + ">", "gis");
|
|
17044
|
+
const results = [];
|
|
17045
|
+
let match;
|
|
17046
|
+
while ((match = regex.exec(html)) !== null) {
|
|
17047
|
+
const value = parser.stripTags(match[1]).trim();
|
|
17048
|
+
if (value) results.push(value);
|
|
17049
|
+
}
|
|
17050
|
+
return results;
|
|
17051
|
+
} catch {
|
|
17052
|
+
return [];
|
|
17053
|
+
}
|
|
17054
|
+
}
|
|
17055
|
+
};
|
|
17056
|
+
const titleMatch = html.match(/<title[^>]*>(.*?)<\/title>/is);
|
|
17057
|
+
const title = titleMatch ? parser.stripTags(titleMatch[1]).trim() || void 0 : void 0;
|
|
17058
|
+
const headingRegex = /<h[1-6][^>]*>(.*?)<\/h[1-6]>/gis;
|
|
17059
|
+
const headings = [];
|
|
17060
|
+
let headingMatch;
|
|
17061
|
+
while ((headingMatch = headingRegex.exec(html)) !== null) {
|
|
17062
|
+
const text2 = parser.stripTags(headingMatch[1]).trim();
|
|
17063
|
+
if (text2) headings.push(text2);
|
|
17064
|
+
}
|
|
17065
|
+
const linkRegex = /<a\s[^>]*href=["']([^"']*)["'][^>]*>(.*?)<\/a>/gis;
|
|
17066
|
+
const links = [];
|
|
17067
|
+
let linkMatch;
|
|
17068
|
+
while ((linkMatch = linkRegex.exec(html)) !== null) {
|
|
17069
|
+
const href = linkMatch[1];
|
|
17070
|
+
const text2 = parser.stripTags(linkMatch[2]).trim();
|
|
17071
|
+
if (href) links.push({ href, text: text2 });
|
|
17072
|
+
}
|
|
17073
|
+
const text = parser.stripTags(html);
|
|
17074
|
+
return {
|
|
17075
|
+
title,
|
|
17076
|
+
headings,
|
|
17077
|
+
links,
|
|
17078
|
+
text,
|
|
17079
|
+
querySelector: parser.querySelector,
|
|
17080
|
+
querySelectorAll: parser.querySelectorAll
|
|
17081
|
+
};
|
|
17082
|
+
} catch (error51) {
|
|
17083
|
+
throw new Error(
|
|
17084
|
+
`parseHTML failed: ${error51 instanceof Error ? error51.message : "Unknown error"}`,
|
|
17085
|
+
{
|
|
17086
|
+
cause: error51
|
|
17087
|
+
}
|
|
17088
|
+
);
|
|
17089
|
+
}
|
|
17090
|
+
}
|
|
17091
|
+
function createPortableHelpers(parseHTML) {
|
|
17092
|
+
return {
|
|
17093
|
+
parseHTML,
|
|
17094
|
+
/**
|
|
17095
|
+
* Extract email addresses from text
|
|
17096
|
+
* @param text Text to search for emails
|
|
17097
|
+
* @returns Array of found email addresses
|
|
17098
|
+
*/
|
|
17099
|
+
extractEmails(text) {
|
|
17100
|
+
if (typeof text !== "string") {
|
|
17101
|
+
return [];
|
|
17102
|
+
}
|
|
17103
|
+
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
|
|
17104
|
+
const matches = text.match(emailRegex);
|
|
17105
|
+
return matches ? [...new Set(matches)] : [];
|
|
17106
|
+
},
|
|
17107
|
+
/**
|
|
17108
|
+
* Extract URLs from text
|
|
17109
|
+
* @param text Text to search for URLs
|
|
17110
|
+
* @returns Array of found URLs
|
|
17111
|
+
*/
|
|
17112
|
+
extractURLs(text) {
|
|
17113
|
+
if (typeof text !== "string") {
|
|
17114
|
+
return [];
|
|
17115
|
+
}
|
|
17116
|
+
const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)/g;
|
|
17117
|
+
const matches = text.match(urlRegex);
|
|
17118
|
+
return matches ? [...new Set(matches)] : [];
|
|
17119
|
+
},
|
|
17120
|
+
/**
|
|
17121
|
+
* Extract phone numbers from text
|
|
17122
|
+
* @param text Text to search for phone numbers
|
|
17123
|
+
* @returns Array of found phone numbers
|
|
17124
|
+
*/
|
|
17125
|
+
extractPhoneNumbers(text) {
|
|
17126
|
+
if (typeof text !== "string") {
|
|
17127
|
+
return [];
|
|
17128
|
+
}
|
|
17129
|
+
const phoneRegex = /(?:\+?1[-.\s]?)?(?:\([0-9]{3}\)|[0-9]{3})[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}/g;
|
|
17130
|
+
const matches = text.match(phoneRegex);
|
|
17131
|
+
return matches ? [...new Set(matches)] : [];
|
|
17132
|
+
},
|
|
17133
|
+
/**
|
|
17134
|
+
* Truncate text to specified length with ellipsis
|
|
17135
|
+
* @param text Text to truncate
|
|
17136
|
+
* @param length Maximum length
|
|
17137
|
+
* @returns Truncated text
|
|
17138
|
+
*/
|
|
17139
|
+
truncate(text, length) {
|
|
17140
|
+
if (typeof text !== "string" || typeof length !== "number") {
|
|
17141
|
+
return text || "";
|
|
17142
|
+
}
|
|
17143
|
+
if (text.length <= length) {
|
|
17144
|
+
return text;
|
|
17145
|
+
}
|
|
17146
|
+
return text.substring(0, length).trim() + "...";
|
|
17147
|
+
},
|
|
17148
|
+
/**
|
|
17149
|
+
* Create URL-friendly slug from text
|
|
17150
|
+
* @param text Text to slugify
|
|
17151
|
+
* @returns URL-friendly slug
|
|
17152
|
+
*/
|
|
17153
|
+
slugify(text) {
|
|
17154
|
+
if (typeof text !== "string") {
|
|
17155
|
+
return "";
|
|
17156
|
+
}
|
|
17157
|
+
return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
17158
|
+
},
|
|
17159
|
+
/**
|
|
17160
|
+
* Convert Markdown to HTML (basic conversion)
|
|
17161
|
+
* @param markdown Markdown text
|
|
17162
|
+
* @returns HTML string
|
|
17163
|
+
*/
|
|
17164
|
+
markdown2html(markdown) {
|
|
17165
|
+
if (typeof markdown !== "string") {
|
|
17166
|
+
return "";
|
|
17167
|
+
}
|
|
17168
|
+
return markdown.replace(/^### (.*$)/gim, "<h3>$1</h3>").replace(/^## (.*$)/gim, "<h2>$1</h2>").replace(/^# (.*$)/gim, "<h1>$1</h1>").replace(/\*\*(.*?)\*\*/gim, "<strong>$1</strong>").replace(/__(.*?)__/gim, "<strong>$1</strong>").replace(/\*(.*?)\*/gim, "<em>$1</em>").replace(/_(.*?)_/gim, "<em>$1</em>").replace(/`(.*?)`/gim, "<code>$1</code>").replace(/\[([^\]]+)\]\(([^)]+)\)/gim, '<a href="$2">$1</a>').replace(/\n\n/gim, "</p><p>").replace(/\n/gim, "<br>").replace(/^(?!<[h|u|o|l])/gim, "<p>").replace(/$/gim, "</p>").replace(/<p><\/p>/gim, "").replace(/<p>(<h[1-6]>.*<\/h[1-6]>)<\/p>/gim, "$1");
|
|
17169
|
+
},
|
|
17170
|
+
/**
|
|
17171
|
+
* Convert HTML to Markdown (basic conversion)
|
|
17172
|
+
* @param html HTML string
|
|
17173
|
+
* @returns Markdown text
|
|
17174
|
+
*/
|
|
17175
|
+
html2markdown(html) {
|
|
17176
|
+
if (typeof html !== "string") {
|
|
17177
|
+
return "";
|
|
17178
|
+
}
|
|
17179
|
+
return html.replace(/<h1[^>]*>(.*?)<\/h1>/gim, "# $1\n\n").replace(/<h2[^>]*>(.*?)<\/h2>/gim, "## $1\n\n").replace(/<h3[^>]*>(.*?)<\/h3>/gim, "### $1\n\n").replace(/<h4[^>]*>(.*?)<\/h4>/gim, "#### $1\n\n").replace(/<h5[^>]*>(.*?)<\/h5>/gim, "##### $1\n\n").replace(/<h6[^>]*>(.*?)<\/h6>/gim, "###### $1\n\n").replace(/<strong[^>]*>(.*?)<\/strong>/gim, "**$1**").replace(/<b[^>]*>(.*?)<\/b>/gim, "**$1**").replace(/<em[^>]*>(.*?)<\/em>/gim, "*$1*").replace(/<i[^>]*>(.*?)<\/i>/gim, "*$1*").replace(/<code[^>]*>(.*?)<\/code>/gim, "`$1`").replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gim, "[$2]($1)").replace(/<br[^>]*>/gim, "\n").replace(/<\/p>/gim, "\n\n").replace(/<p[^>]*>/gim, "").replace(/<li[^>]*>(.*?)<\/li>/gim, "- $1\n").replace(/<ul[^>]*>/gim, "\n").replace(/<\/ul>/gim, "\n").replace(/<ol[^>]*>/gim, "\n").replace(/<\/ol>/gim, "\n").replace(/<[^>]*>/gim, "").replace(/<(\/?[a-zA-Z][^>]*)$/, "<$1").replace(/\n\s*\n\s*\n/gim, "\n\n").trim();
|
|
17180
|
+
},
|
|
17181
|
+
/**
|
|
17182
|
+
* Parse date from various string formats
|
|
17183
|
+
* @param dateStr Date string to parse
|
|
17184
|
+
* @returns Date object or null if invalid
|
|
17185
|
+
*/
|
|
17186
|
+
parseDate(dateStr) {
|
|
17187
|
+
if (typeof dateStr !== "string") {
|
|
17188
|
+
return null;
|
|
17189
|
+
}
|
|
17190
|
+
try {
|
|
17191
|
+
const date5 = new Date(dateStr);
|
|
17192
|
+
return isNaN(date5.getTime()) ? null : date5;
|
|
17193
|
+
} catch {
|
|
17194
|
+
return null;
|
|
17195
|
+
}
|
|
17196
|
+
},
|
|
17197
|
+
/**
|
|
17198
|
+
* Format date according to specified format
|
|
17199
|
+
* @param date Date object or string
|
|
17200
|
+
* @param format Format string (simple patterns)
|
|
17201
|
+
* @returns Formatted date string
|
|
17202
|
+
*/
|
|
17203
|
+
formatDate(date5, format) {
|
|
17204
|
+
const defaultFormat = format || "YYYY-MM-DD";
|
|
17205
|
+
let dateObj;
|
|
17206
|
+
if (typeof date5 === "string") {
|
|
17207
|
+
dateObj = new Date(date5);
|
|
17208
|
+
} else if (date5 instanceof Date) {
|
|
17209
|
+
dateObj = date5;
|
|
17210
|
+
} else {
|
|
17211
|
+
return "";
|
|
17212
|
+
}
|
|
17213
|
+
if (isNaN(dateObj.getTime())) {
|
|
17214
|
+
return "";
|
|
17215
|
+
}
|
|
17216
|
+
const year = dateObj.getFullYear();
|
|
17217
|
+
const month = String(dateObj.getMonth() + 1).padStart(2, "0");
|
|
17218
|
+
const day = String(dateObj.getDate()).padStart(2, "0");
|
|
17219
|
+
const hours = String(dateObj.getHours()).padStart(2, "0");
|
|
17220
|
+
const minutes = String(dateObj.getMinutes()).padStart(2, "0");
|
|
17221
|
+
const seconds = String(dateObj.getSeconds()).padStart(2, "0");
|
|
17222
|
+
return defaultFormat.replace(/YYYY/g, String(year)).replace(/MM/g, month).replace(/DD/g, day).replace(/HH/g, hours).replace(/mm/g, minutes).replace(/ss/g, seconds);
|
|
17223
|
+
},
|
|
17224
|
+
/**
|
|
17225
|
+
* Add days to a date
|
|
17226
|
+
* @param date Date object or string
|
|
17227
|
+
* @param days Number of days to add (can be negative)
|
|
17228
|
+
* @returns New Date object
|
|
17229
|
+
*/
|
|
17230
|
+
addDays(date5, days) {
|
|
17231
|
+
let dateObj;
|
|
17232
|
+
if (typeof date5 === "string") {
|
|
17233
|
+
dateObj = new Date(date5);
|
|
17234
|
+
} else if (date5 instanceof Date) {
|
|
17235
|
+
dateObj = new Date(date5.getTime());
|
|
17236
|
+
} else {
|
|
17237
|
+
return null;
|
|
17238
|
+
}
|
|
17239
|
+
if (isNaN(dateObj.getTime()) || typeof days !== "number") {
|
|
17240
|
+
return null;
|
|
17241
|
+
}
|
|
17242
|
+
dateObj.setDate(dateObj.getDate() + days);
|
|
17243
|
+
return dateObj;
|
|
17244
|
+
},
|
|
17245
|
+
/**
|
|
17246
|
+
* Validate email address format
|
|
17247
|
+
* @param email Email address to validate
|
|
17248
|
+
* @returns True if valid email format
|
|
17249
|
+
*/
|
|
17250
|
+
isValidEmail(email3) {
|
|
17251
|
+
if (typeof email3 !== "string") {
|
|
17252
|
+
return false;
|
|
17253
|
+
}
|
|
17254
|
+
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
17255
|
+
return emailRegex.test(email3);
|
|
17256
|
+
},
|
|
17257
|
+
/**
|
|
17258
|
+
* Validate URL format
|
|
17259
|
+
* @param url URL to validate
|
|
17260
|
+
* @returns True if valid URL format
|
|
17261
|
+
*/
|
|
17262
|
+
isValidURL(url2) {
|
|
17263
|
+
if (typeof url2 !== "string") {
|
|
17264
|
+
return false;
|
|
17265
|
+
}
|
|
17266
|
+
try {
|
|
17267
|
+
new URL(url2);
|
|
17268
|
+
return true;
|
|
17269
|
+
} catch {
|
|
17270
|
+
return false;
|
|
17271
|
+
}
|
|
17272
|
+
},
|
|
17273
|
+
/**
|
|
17274
|
+
* Validate JSON string
|
|
17275
|
+
* @param str String to validate as JSON
|
|
17276
|
+
* @returns True if valid JSON
|
|
17277
|
+
*/
|
|
17278
|
+
isValidJSON(str) {
|
|
17279
|
+
if (typeof str !== "string") {
|
|
17280
|
+
return false;
|
|
17281
|
+
}
|
|
17282
|
+
try {
|
|
17283
|
+
JSON.parse(str);
|
|
17284
|
+
return true;
|
|
17285
|
+
} catch {
|
|
17286
|
+
return false;
|
|
17287
|
+
}
|
|
17288
|
+
},
|
|
17289
|
+
/**
|
|
17290
|
+
* Encode string to base64
|
|
17291
|
+
* @param str String to encode
|
|
17292
|
+
* @returns Base64 encoded string
|
|
17293
|
+
*/
|
|
17294
|
+
base64Encode(str) {
|
|
17295
|
+
if (typeof str !== "string") {
|
|
17296
|
+
return "";
|
|
17297
|
+
}
|
|
17298
|
+
try {
|
|
17299
|
+
return btoa(str);
|
|
17300
|
+
} catch {
|
|
17301
|
+
return btoa(unescape(encodeURIComponent(str)));
|
|
17302
|
+
}
|
|
17303
|
+
},
|
|
17304
|
+
/**
|
|
17305
|
+
* Decode base64 string
|
|
17306
|
+
* @param str Base64 string to decode
|
|
17307
|
+
* @returns Decoded string
|
|
17308
|
+
*/
|
|
17309
|
+
base64Decode(str) {
|
|
17310
|
+
if (typeof str !== "string") {
|
|
17311
|
+
return "";
|
|
17312
|
+
}
|
|
17313
|
+
try {
|
|
17314
|
+
return atob(str);
|
|
17315
|
+
} catch {
|
|
17316
|
+
try {
|
|
17317
|
+
return decodeURIComponent(escape(atob(str)));
|
|
17318
|
+
} catch {
|
|
17319
|
+
return "";
|
|
17320
|
+
}
|
|
17321
|
+
}
|
|
17322
|
+
},
|
|
17323
|
+
/**
|
|
17324
|
+
* URL encode string
|
|
17325
|
+
* @param str String to encode
|
|
17326
|
+
* @returns URL encoded string
|
|
17327
|
+
*/
|
|
17328
|
+
urlEncode(str) {
|
|
17329
|
+
if (typeof str !== "string") {
|
|
17330
|
+
return "";
|
|
17331
|
+
}
|
|
17332
|
+
return encodeURIComponent(str);
|
|
17333
|
+
},
|
|
17334
|
+
/**
|
|
17335
|
+
* URL decode string
|
|
17336
|
+
* @param str URL encoded string to decode
|
|
17337
|
+
* @returns Decoded string
|
|
17338
|
+
*/
|
|
17339
|
+
urlDecode(str) {
|
|
17340
|
+
if (typeof str !== "string") {
|
|
17341
|
+
return "";
|
|
17342
|
+
}
|
|
17343
|
+
try {
|
|
17344
|
+
return decodeURIComponent(str);
|
|
17345
|
+
} catch {
|
|
17346
|
+
return str;
|
|
17347
|
+
}
|
|
17348
|
+
},
|
|
17349
|
+
/**
|
|
17350
|
+
* Return the first argument that is neither null nor undefined (a named
|
|
17351
|
+
* first-non-null / nullish coalesce). The script-side counterpart of the
|
|
17352
|
+
* `{{a ?? b}}` template operator — in templates prefer `{{a ?? b}}`; use
|
|
17353
|
+
* `helpers.coalesce(a, b)` inside transform-data scripts.
|
|
17354
|
+
* @param values Candidate values in priority order
|
|
17355
|
+
* @returns The first non-null/undefined value, or null if all are null/undefined
|
|
17356
|
+
*/
|
|
17357
|
+
coalesce(...values) {
|
|
17358
|
+
for (const value of values) {
|
|
17359
|
+
if (value !== null && value !== void 0) {
|
|
17360
|
+
return value;
|
|
17361
|
+
}
|
|
17362
|
+
}
|
|
17363
|
+
return null;
|
|
17364
|
+
}
|
|
17365
|
+
};
|
|
17366
|
+
}
|
|
17367
|
+
|
|
17020
17368
|
// ../shared/dist/index.mjs
|
|
17021
17369
|
var FORMULA_TRIGGER = /^[=+\-@\t\r\n]/;
|
|
17022
17370
|
var STRICT_NUMBER = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
|
|
@@ -17573,7 +17921,15 @@ function isBuiltInToolId(toolId) {
|
|
|
17573
17921
|
function isPlatformToolId(toolId) {
|
|
17574
17922
|
return toolId.startsWith("platform:");
|
|
17575
17923
|
}
|
|
17576
|
-
var INTEGRATION_SERVER_IDS = /* @__PURE__ */ new Set([
|
|
17924
|
+
var INTEGRATION_SERVER_IDS = /* @__PURE__ */ new Set([
|
|
17925
|
+
"slack",
|
|
17926
|
+
"google",
|
|
17927
|
+
"linear",
|
|
17928
|
+
"github",
|
|
17929
|
+
"telegram",
|
|
17930
|
+
"imessage",
|
|
17931
|
+
"granola"
|
|
17932
|
+
]);
|
|
17577
17933
|
function isBuiltInIntegrationToolId(toolId) {
|
|
17578
17934
|
if (!toolId.startsWith("builtin:")) return false;
|
|
17579
17935
|
const { baseId } = parseToolInstanceId(toolId);
|
|
@@ -22013,280 +22369,8 @@ function parseCreateFlowValidationInput(payload) {
|
|
|
22013
22369
|
};
|
|
22014
22370
|
}
|
|
22015
22371
|
var SERIALIZED_HELPERS_SOURCE = `
|
|
22016
|
-
// Transform helper functions
|
|
22017
|
-
const helpers = (
|
|
22018
|
-
// Regex-based HTML tag stripper for extracting text content
|
|
22019
|
-
const stripTags = (html) => html.replace(/<[^>]*>/g, ' ').replace(/\\s+/g, ' ').trim()
|
|
22020
|
-
|
|
22021
|
-
return {
|
|
22022
|
-
parseHTML: (html) => {
|
|
22023
|
-
if (typeof html !== 'string') throw new Error('parseHTML: input must be a string')
|
|
22024
|
-
try {
|
|
22025
|
-
// Extract title
|
|
22026
|
-
const titleMatch = html.match(/<title[^>]*>(.*?)<\\/title>/is)
|
|
22027
|
-
const title = titleMatch ? stripTags(titleMatch[1]).trim() || undefined : undefined
|
|
22028
|
-
|
|
22029
|
-
// Extract headings (h1-h6)
|
|
22030
|
-
const headingRegex = /<h[1-6][^>]*>(.*?)<\\/h[1-6]>/gis
|
|
22031
|
-
const headings = []
|
|
22032
|
-
let hMatch
|
|
22033
|
-
while ((hMatch = headingRegex.exec(html)) !== null) {
|
|
22034
|
-
const text = stripTags(hMatch[1]).trim()
|
|
22035
|
-
if (text) headings.push(text)
|
|
22036
|
-
}
|
|
22037
|
-
|
|
22038
|
-
// Extract links
|
|
22039
|
-
const linkRegex = /<a\\s[^>]*href=["']([^"']*)["'][^>]*>(.*?)<\\/a>/gis
|
|
22040
|
-
const links = []
|
|
22041
|
-
let lMatch
|
|
22042
|
-
while ((lMatch = linkRegex.exec(html)) !== null) {
|
|
22043
|
-
const href = lMatch[1]
|
|
22044
|
-
const text = stripTags(lMatch[2]).trim()
|
|
22045
|
-
if (href) links.push({ href, text })
|
|
22046
|
-
}
|
|
22047
|
-
|
|
22048
|
-
// Extract all text content
|
|
22049
|
-
const text = stripTags(html)
|
|
22050
|
-
|
|
22051
|
-
// Simple querySelector (CSS element selectors only)
|
|
22052
|
-
const querySelector = (selector) => {
|
|
22053
|
-
try {
|
|
22054
|
-
const tag = selector.replace(/[^a-zA-Z0-9-]/g, '')
|
|
22055
|
-
const match = html.match(new RegExp('<' + tag + '[^>]*>(.*?)<\\\\/' + tag + '>', 'is'))
|
|
22056
|
-
return match ? stripTags(match[1]).trim() || null : null
|
|
22057
|
-
} catch (error) {
|
|
22058
|
-
return null
|
|
22059
|
-
}
|
|
22060
|
-
}
|
|
22061
|
-
|
|
22062
|
-
// Simple querySelectorAll (CSS element selectors only)
|
|
22063
|
-
const querySelectorAll = (selector) => {
|
|
22064
|
-
try {
|
|
22065
|
-
const tag = selector.replace(/[^a-zA-Z0-9-]/g, '')
|
|
22066
|
-
const regex = new RegExp('<' + tag + '[^>]*>(.*?)<\\\\/' + tag + '>', 'gis')
|
|
22067
|
-
const results = []
|
|
22068
|
-
let m
|
|
22069
|
-
while ((m = regex.exec(html)) !== null) {
|
|
22070
|
-
const t = stripTags(m[1]).trim()
|
|
22071
|
-
if (t) results.push(t)
|
|
22072
|
-
}
|
|
22073
|
-
return results
|
|
22074
|
-
} catch (error) {
|
|
22075
|
-
return []
|
|
22076
|
-
}
|
|
22077
|
-
}
|
|
22078
|
-
|
|
22079
|
-
return { title, headings, links, text, querySelector, querySelectorAll }
|
|
22080
|
-
} catch (error) {
|
|
22081
|
-
throw new Error('parseHTML failed: ' + (error instanceof Error ? error.message : 'Unknown error'))
|
|
22082
|
-
}
|
|
22083
|
-
},
|
|
22084
|
-
|
|
22085
|
-
extractEmails: (text) => {
|
|
22086
|
-
if (typeof text !== 'string') return []
|
|
22087
|
-
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g
|
|
22088
|
-
const matches = text.match(emailRegex)
|
|
22089
|
-
return matches ? [...new Set(matches)] : []
|
|
22090
|
-
},
|
|
22091
|
-
|
|
22092
|
-
extractURLs: (text) => {
|
|
22093
|
-
if (typeof text !== 'string') return []
|
|
22094
|
-
const urlRegex = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&/=]*)/g
|
|
22095
|
-
const matches = text.match(urlRegex)
|
|
22096
|
-
return matches ? [...new Set(matches)] : []
|
|
22097
|
-
},
|
|
22098
|
-
|
|
22099
|
-
extractPhoneNumbers: (text) => {
|
|
22100
|
-
if (typeof text !== 'string') return []
|
|
22101
|
-
const phoneRegex = /(?:\\+?1[-.\\s]?)?(?:\\([0-9]{3}\\)|[0-9]{3})[-.\\s]?[0-9]{3}[-.\\s]?[0-9]{4}/g
|
|
22102
|
-
const matches = text.match(phoneRegex)
|
|
22103
|
-
return matches ? [...new Set(matches)] : []
|
|
22104
|
-
},
|
|
22105
|
-
|
|
22106
|
-
truncate: (text, length) => {
|
|
22107
|
-
if (typeof text !== 'string' || typeof length !== 'number') return text || ''
|
|
22108
|
-
if (text.length <= length) return text
|
|
22109
|
-
return text.substring(0, length).trim() + '...'
|
|
22110
|
-
},
|
|
22111
|
-
|
|
22112
|
-
slugify: (text) => {
|
|
22113
|
-
if (typeof text !== 'string') return ''
|
|
22114
|
-
return text
|
|
22115
|
-
.toLowerCase()
|
|
22116
|
-
.trim()
|
|
22117
|
-
.replace(/[^\\w\\s-]/g, '')
|
|
22118
|
-
.replace(/[\\s_-]+/g, '-')
|
|
22119
|
-
.replace(/^-+|-+$/g, '')
|
|
22120
|
-
},
|
|
22121
|
-
|
|
22122
|
-
markdown2html: (markdown) => {
|
|
22123
|
-
if (typeof markdown !== 'string') return ''
|
|
22124
|
-
return markdown
|
|
22125
|
-
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
|
|
22126
|
-
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
|
|
22127
|
-
.replace(/^# (.*$)/gim, '<h1>$1</h1>')
|
|
22128
|
-
.replace(/\\*\\*(.*?)\\*\\*/gim, '<strong>$1</strong>')
|
|
22129
|
-
.replace(/__(.*?)__/gim, '<strong>$1</strong>')
|
|
22130
|
-
.replace(/\\*(.*?)\\*/gim, '<em>$1</em>')
|
|
22131
|
-
.replace(/_(.*?)_/gim, '<em>$1</em>')
|
|
22132
|
-
.replace(/\`(.*?)\`/gim, '<code>$1</code>')
|
|
22133
|
-
.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/gim, '<a href="$2">$1</a>')
|
|
22134
|
-
.replace(/\\n\\n/gim, '</p><p>')
|
|
22135
|
-
.replace(/\\n/gim, '<br>')
|
|
22136
|
-
.replace(/^(?!<[h|u|o|l])/gim, '<p>')
|
|
22137
|
-
.replace(/$/gim, '</p>')
|
|
22138
|
-
.replace(/<p><\\/p>/gim, '')
|
|
22139
|
-
.replace(/<p>(<h[1-6]>.*<\\/h[1-6]>)<\\/p>/gim, '$1')
|
|
22140
|
-
},
|
|
22141
|
-
|
|
22142
|
-
html2markdown: (html) => {
|
|
22143
|
-
if (typeof html !== 'string') return ''
|
|
22144
|
-
return html
|
|
22145
|
-
.replace(/<h1[^>]*>(.*?)<\\/h1>/gim, '# $1\\n\\n')
|
|
22146
|
-
.replace(/<h2[^>]*>(.*?)<\\/h2>/gim, '## $1\\n\\n')
|
|
22147
|
-
.replace(/<h3[^>]*>(.*?)<\\/h3>/gim, '### $1\\n\\n')
|
|
22148
|
-
.replace(/<h4[^>]*>(.*?)<\\/h4>/gim, '#### $1\\n\\n')
|
|
22149
|
-
.replace(/<h5[^>]*>(.*?)<\\/h5>/gim, '##### $1\\n\\n')
|
|
22150
|
-
.replace(/<h6[^>]*>(.*?)<\\/h6>/gim, '###### $1\\n\\n')
|
|
22151
|
-
.replace(/<strong[^>]*>(.*?)<\\/strong>/gim, '**$1**')
|
|
22152
|
-
.replace(/<b[^>]*>(.*?)<\\/b>/gim, '**$1**')
|
|
22153
|
-
.replace(/<em[^>]*>(.*?)<\\/em>/gim, '*$1*')
|
|
22154
|
-
.replace(/<i[^>]*>(.*?)<\\/i>/gim, '*$1*')
|
|
22155
|
-
.replace(/<code[^>]*>(.*?)<\\/code>/gim, '\`$1\`')
|
|
22156
|
-
.replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\\/a>/gim, '[$2]($1)')
|
|
22157
|
-
.replace(/<br[^>]*>/gim, '\\n')
|
|
22158
|
-
.replace(/<\\/p>/gim, '\\n\\n')
|
|
22159
|
-
.replace(/<p[^>]*>/gim, '')
|
|
22160
|
-
.replace(/<li[^>]*>(.*?)<\\/li>/gim, '- $1\\n')
|
|
22161
|
-
.replace(/<ul[^>]*>/gim, '\\n')
|
|
22162
|
-
.replace(/<\\/ul>/gim, '\\n')
|
|
22163
|
-
.replace(/<ol[^>]*>/gim, '\\n')
|
|
22164
|
-
.replace(/<\\/ol>/gim, '\\n')
|
|
22165
|
-
.replace(/<[^>]+>/gim, '')
|
|
22166
|
-
.replace(/\\n\\s*\\n\\s*\\n/gim, '\\n\\n')
|
|
22167
|
-
.trim()
|
|
22168
|
-
},
|
|
22169
|
-
|
|
22170
|
-
parseDate: (dateStr) => {
|
|
22171
|
-
if (typeof dateStr !== 'string') return null
|
|
22172
|
-
try {
|
|
22173
|
-
const date = new Date(dateStr)
|
|
22174
|
-
return isNaN(date.getTime()) ? null : date
|
|
22175
|
-
} catch {
|
|
22176
|
-
return null
|
|
22177
|
-
}
|
|
22178
|
-
},
|
|
22179
|
-
|
|
22180
|
-
formatDate: (date, format) => {
|
|
22181
|
-
const defaultFormat = format || 'YYYY-MM-DD'
|
|
22182
|
-
let dateObj
|
|
22183
|
-
if (typeof date === 'string') {
|
|
22184
|
-
dateObj = new Date(date)
|
|
22185
|
-
} else if (date instanceof Date) {
|
|
22186
|
-
dateObj = date
|
|
22187
|
-
} else {
|
|
22188
|
-
return ''
|
|
22189
|
-
}
|
|
22190
|
-
if (isNaN(dateObj.getTime())) return ''
|
|
22191
|
-
const year = dateObj.getFullYear()
|
|
22192
|
-
const month = String(dateObj.getMonth() + 1).padStart(2, '0')
|
|
22193
|
-
const day = String(dateObj.getDate()).padStart(2, '0')
|
|
22194
|
-
const hours = String(dateObj.getHours()).padStart(2, '0')
|
|
22195
|
-
const minutes = String(dateObj.getMinutes()).padStart(2, '0')
|
|
22196
|
-
const seconds = String(dateObj.getSeconds()).padStart(2, '0')
|
|
22197
|
-
return defaultFormat
|
|
22198
|
-
.replace(/YYYY/g, String(year))
|
|
22199
|
-
.replace(/MM/g, month)
|
|
22200
|
-
.replace(/DD/g, day)
|
|
22201
|
-
.replace(/HH/g, hours)
|
|
22202
|
-
.replace(/mm/g, minutes)
|
|
22203
|
-
.replace(/ss/g, seconds)
|
|
22204
|
-
},
|
|
22205
|
-
|
|
22206
|
-
addDays: (date, days) => {
|
|
22207
|
-
let dateObj
|
|
22208
|
-
if (typeof date === 'string') {
|
|
22209
|
-
dateObj = new Date(date)
|
|
22210
|
-
} else if (date instanceof Date) {
|
|
22211
|
-
dateObj = new Date(date.getTime())
|
|
22212
|
-
} else {
|
|
22213
|
-
return null
|
|
22214
|
-
}
|
|
22215
|
-
if (isNaN(dateObj.getTime()) || typeof days !== 'number') return null
|
|
22216
|
-
dateObj.setDate(dateObj.getDate() + days)
|
|
22217
|
-
return dateObj
|
|
22218
|
-
},
|
|
22219
|
-
|
|
22220
|
-
isValidEmail: (email) => {
|
|
22221
|
-
if (typeof email !== 'string') return false
|
|
22222
|
-
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/
|
|
22223
|
-
return emailRegex.test(email)
|
|
22224
|
-
},
|
|
22225
|
-
|
|
22226
|
-
isValidURL: (url) => {
|
|
22227
|
-
if (typeof url !== 'string') return false
|
|
22228
|
-
try {
|
|
22229
|
-
new URL(url)
|
|
22230
|
-
return true
|
|
22231
|
-
} catch {
|
|
22232
|
-
return false
|
|
22233
|
-
}
|
|
22234
|
-
},
|
|
22235
|
-
|
|
22236
|
-
isValidJSON: (str) => {
|
|
22237
|
-
if (typeof str !== 'string') return false
|
|
22238
|
-
try {
|
|
22239
|
-
JSON.parse(str)
|
|
22240
|
-
return true
|
|
22241
|
-
} catch {
|
|
22242
|
-
return false
|
|
22243
|
-
}
|
|
22244
|
-
},
|
|
22245
|
-
|
|
22246
|
-
base64Encode: (str) => {
|
|
22247
|
-
if (typeof str !== 'string') return ''
|
|
22248
|
-
try {
|
|
22249
|
-
return btoa(str)
|
|
22250
|
-
} catch {
|
|
22251
|
-
return btoa(unescape(encodeURIComponent(str)))
|
|
22252
|
-
}
|
|
22253
|
-
},
|
|
22254
|
-
|
|
22255
|
-
base64Decode: (str) => {
|
|
22256
|
-
if (typeof str !== 'string') return ''
|
|
22257
|
-
try {
|
|
22258
|
-
return atob(str)
|
|
22259
|
-
} catch {
|
|
22260
|
-
try {
|
|
22261
|
-
return decodeURIComponent(escape(atob(str)))
|
|
22262
|
-
} catch {
|
|
22263
|
-
return ''
|
|
22264
|
-
}
|
|
22265
|
-
}
|
|
22266
|
-
},
|
|
22267
|
-
|
|
22268
|
-
urlEncode: (str) => {
|
|
22269
|
-
if (typeof str !== 'string') return ''
|
|
22270
|
-
return encodeURIComponent(str)
|
|
22271
|
-
},
|
|
22272
|
-
|
|
22273
|
-
urlDecode: (str) => {
|
|
22274
|
-
if (typeof str !== 'string') return ''
|
|
22275
|
-
try {
|
|
22276
|
-
return decodeURIComponent(str)
|
|
22277
|
-
} catch {
|
|
22278
|
-
return str
|
|
22279
|
-
}
|
|
22280
|
-
},
|
|
22281
|
-
|
|
22282
|
-
coalesce: (...values) => {
|
|
22283
|
-
for (const value of values) {
|
|
22284
|
-
if (value !== null && value !== undefined) return value
|
|
22285
|
-
}
|
|
22286
|
-
return null
|
|
22287
|
-
},
|
|
22288
|
-
}
|
|
22289
|
-
})()
|
|
22372
|
+
// Transform helper functions generated from the canonical portable factory.
|
|
22373
|
+
const helpers = (${createPortableHelpers.toString()})(${parseHTMLWithRegex.toString()})
|
|
22290
22374
|
`.trim();
|
|
22291
22375
|
var AGENT_EXECUTION_STATUSES = [
|
|
22292
22376
|
"queued",
|
|
@@ -22298,6 +22382,8 @@ var AGENT_EXECUTION_STATUSES = [
|
|
|
22298
22382
|
"interrupted"
|
|
22299
22383
|
];
|
|
22300
22384
|
var agentExecutionStatusSchema = external_exports.enum(AGENT_EXECUTION_STATUSES);
|
|
22385
|
+
var DEFAULT_BEDROCK_REGION = "us-east-1";
|
|
22386
|
+
var DEFAULT_VERTEX_LOCATION = "us-central1";
|
|
22301
22387
|
var PROVIDER_SECRET_SPECS = [
|
|
22302
22388
|
{
|
|
22303
22389
|
providerId: "mock",
|
|
@@ -22309,13 +22395,15 @@ var PROVIDER_SECRET_SPECS = [
|
|
|
22309
22395
|
providerId: "google-vertex-anthropic",
|
|
22310
22396
|
// Must come before google-vertex (shares vertex prefix) and anthropic (matches */claude-*).
|
|
22311
22397
|
matches: (m2) => m2.startsWith("vertex-anthropic/"),
|
|
22312
|
-
secretNames: ["GOOGLE_VERTEX_PROJECT", "
|
|
22398
|
+
secretNames: ["GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_CREDENTIALS"],
|
|
22399
|
+
optionalSettings: [{ name: "GOOGLE_VERTEX_LOCATION", defaultValue: DEFAULT_VERTEX_LOCATION }]
|
|
22313
22400
|
},
|
|
22314
22401
|
{
|
|
22315
22402
|
providerId: "google-vertex",
|
|
22316
22403
|
// Must come before google (matches */gemini-*).
|
|
22317
22404
|
matches: (m2) => m2.startsWith("vertex/"),
|
|
22318
|
-
secretNames: ["GOOGLE_VERTEX_PROJECT", "
|
|
22405
|
+
secretNames: ["GOOGLE_VERTEX_PROJECT", "GOOGLE_VERTEX_CREDENTIALS"],
|
|
22406
|
+
optionalSettings: [{ name: "GOOGLE_VERTEX_LOCATION", defaultValue: DEFAULT_VERTEX_LOCATION }]
|
|
22319
22407
|
},
|
|
22320
22408
|
{
|
|
22321
22409
|
providerId: "vercel-gateway",
|
|
@@ -22332,7 +22420,8 @@ var PROVIDER_SECRET_SPECS = [
|
|
|
22332
22420
|
{
|
|
22333
22421
|
providerId: "bedrock",
|
|
22334
22422
|
matches: (m2) => m2.startsWith("bedrock/"),
|
|
22335
|
-
secretNames: ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY",
|
|
22423
|
+
secretNames: ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"],
|
|
22424
|
+
optionalSettings: [{ name: "AWS_REGION", defaultValue: DEFAULT_BEDROCK_REGION }]
|
|
22336
22425
|
},
|
|
22337
22426
|
{
|
|
22338
22427
|
providerId: "tinfoil",
|
|
@@ -22345,15 +22434,6 @@ var PROVIDER_SECRET_SPECS = [
|
|
|
22345
22434
|
matches: (m2) => m2.startsWith("generic-openai/") || m2.startsWith("generic-openai:"),
|
|
22346
22435
|
secretNames: ["GENERIC_OPENAI_API_KEY", "GENERIC_OPENAI_BASE_URL"]
|
|
22347
22436
|
},
|
|
22348
|
-
{
|
|
22349
|
-
providerId: "general-compute",
|
|
22350
|
-
// General Compute (https://api.generalcompute.com/v1) is an OpenAI-compatible
|
|
22351
|
-
// host. Models are addressed only with the explicit `general-compute/` prefix
|
|
22352
|
-
// (e.g. `general-compute/minimax-m2.7`) so they never collide with the same
|
|
22353
|
-
// bare model id served by another gateway (Vercel already routes `minimax-m2.7`).
|
|
22354
|
-
matches: (m2) => m2.startsWith("general-compute/") || m2.startsWith("general-compute:"),
|
|
22355
|
-
secretNames: ["GENERAL_COMPUTE_API_KEY"]
|
|
22356
|
-
},
|
|
22357
22437
|
{
|
|
22358
22438
|
providerId: "workers-ai",
|
|
22359
22439
|
// Uses a CF platform binding, not a secret — secretNames is intentionally empty.
|
|
@@ -22403,6 +22483,13 @@ function resolveModelSecretNames(model) {
|
|
|
22403
22483
|
}
|
|
22404
22484
|
return [];
|
|
22405
22485
|
}
|
|
22486
|
+
function resolveModelOptionalSettings(model) {
|
|
22487
|
+
const lower = model.toLowerCase();
|
|
22488
|
+
for (const spec of PROVIDER_SECRET_SPECS) {
|
|
22489
|
+
if (spec.matches(lower)) return [...spec.optionalSettings ?? []];
|
|
22490
|
+
}
|
|
22491
|
+
return [];
|
|
22492
|
+
}
|
|
22406
22493
|
var RUNTIME_ARTIFACT_MANIFEST_VERSION = "2026-06-08";
|
|
22407
22494
|
var runtimeArtifactResourceTypeSchema = external_exports.enum(["flow", "agent"]);
|
|
22408
22495
|
var runtimeArtifactEntrypointSchema = external_exports.enum(["flow", "agent"]);
|
|
@@ -22510,6 +22597,77 @@ var runtimeArtifactManifestSchema = external_exports.object({
|
|
|
22510
22597
|
reasons: external_exports.array(runtimeArtifactEligibilityReasonSchema)
|
|
22511
22598
|
})
|
|
22512
22599
|
});
|
|
22600
|
+
var KNOWN_FLOW_STEP_TYPES = new Set(FLOW_STEP_TYPES);
|
|
22601
|
+
var API_INPROCESS_CAPABILITY_MATRIX = {
|
|
22602
|
+
target: "api-inprocess",
|
|
22603
|
+
// Bumped 2026-07-30: the IMPLICIT platform-default fallback candidate no
|
|
22604
|
+
// longer folds (see `implicitPlatformFallback` below). Carries forward
|
|
22605
|
+
// 2026-07-29.4: api-hosted runtime fulfills managed fetch methods through
|
|
22606
|
+
// ManagedFetchExecutor (the managed-fetch fact remains for attribution). The
|
|
22607
|
+
// EXPLICIT Layer-2 fallback fold and the remaining parity-audit folds are
|
|
22608
|
+
// unchanged.
|
|
22609
|
+
version: "2026-07-30.1",
|
|
22610
|
+
unsupportedStepTypes: ["wait-until", "crawl"],
|
|
22611
|
+
unsupportedFeatures: {
|
|
22612
|
+
approvalSteps: true,
|
|
22613
|
+
batchInputMode: true,
|
|
22614
|
+
claudeManagedAgent: true,
|
|
22615
|
+
inexpressibleVectorStep: true,
|
|
22616
|
+
unresolvableAgentRef: true,
|
|
22617
|
+
conditionalNestedPromptStep: true,
|
|
22618
|
+
conditionalNestedExecuteAgentStep: true,
|
|
22619
|
+
// SUPPORTED as of 2026-07-23 (slice 6 activation): the runtime flow lane
|
|
22620
|
+
// now PAUSES on definition-embedded client-executed (local / webmcp) tools
|
|
22621
|
+
// — `ClientToolRequiredError` → `step_await` / `flow_await` → durable KV
|
|
22622
|
+
// ResumeState → the runtime continuation leg — instead of failing the call
|
|
22623
|
+
// in-band. The `hasClientExecutedTools` FACT is still computed (for
|
|
22624
|
+
// decision-attribution logs), but it no longer folds the flow to legacy.
|
|
22625
|
+
// Rollback lever after retiring the flow request override: revert this bit
|
|
22626
|
+
// to `true` (the agent lane retains its separate rollout gate).
|
|
22627
|
+
clientExecutedTools: false,
|
|
22628
|
+
advisorTools: true,
|
|
22629
|
+
// G2 SUPPORTED: api-hosted runtime delegates Firecrawl / Massive fetch-url
|
|
22630
|
+
// methods through ManagedFetchExecutor to the same API implementations the
|
|
22631
|
+
// legacy executor uses. Keep the fact computed for attribution, like
|
|
22632
|
+
// clientExecutedTools above.
|
|
22633
|
+
unsupportedFetchMethod: false,
|
|
22634
|
+
// Remaining 2026-07-29 parity-audit BRIDGE folds (G4/G5/G10/G14): feature
|
|
22635
|
+
// classes the runtime flow lane still cannot faithfully run.
|
|
22636
|
+
transformDataCodeModeTools: true,
|
|
22637
|
+
unsupportedTransformExecution: true,
|
|
22638
|
+
promptMcpServers: true,
|
|
22639
|
+
promptArtifacts: true,
|
|
22640
|
+
// EXPLICIT author-configured Layer-2 chains stay unsupported: the runtime
|
|
22641
|
+
// flow engine cannot run them and cannot synthesize their `usedFallback` /
|
|
22642
|
+
// `fallbackModel` / `fallbackExecutions` attribution, so a folded flow would
|
|
22643
|
+
// both change behavior and undercount fallback usage.
|
|
22644
|
+
fallbackErrorHandling: true,
|
|
22645
|
+
// SUPPORTED as of 2026-07-30: the IMPLICIT platform-default chain (the
|
|
22646
|
+
// orchestrator's synthesized same-model-next-provider + cross-model rungs
|
|
22647
|
+
// for a prompt with NO explicit `errorHandling`) does not fold the flow to
|
|
22648
|
+
// legacy. Rationale: a prompt step without `errorHandling` is the DEFAULT
|
|
22649
|
+
// shape of nearly every hosted flow, so folding on it reverted the hosted
|
|
22650
|
+
// flow lane to legacy for the common case — the opposite of runtime-primary.
|
|
22651
|
+
// The runtime lane already carries Layer-1 resilience natively
|
|
22652
|
+
// (`withModelCallResilience`: TTFT + idle watchdog + bounded same-model
|
|
22653
|
+
// retry — packages/runtime prompt-executor.ts), so the residual delta is
|
|
22654
|
+
// narrow: on a retryable platform-key failure that survives Layer 1 with no
|
|
22655
|
+
// partial output, the runtime surfaces the step error where legacy would
|
|
22656
|
+
// additionally swap upstream/model. That is an availability nicety, not a
|
|
22657
|
+
// semantic difference — and unlike the folds above it cannot silently
|
|
22658
|
+
// produce a WRONG result. `hasImplicitPlatformFallbackCandidate` is still
|
|
22659
|
+
// computed for decision attribution. Rollback lever: flip this bit to `true`
|
|
22660
|
+
// (plus its test) to restore the fold.
|
|
22661
|
+
implicitPlatformFallback: false
|
|
22662
|
+
}
|
|
22663
|
+
};
|
|
22664
|
+
var DURABLE_HOSTED_STEP_TYPES = /* @__PURE__ */ new Set(["wait-until", "crawl"]);
|
|
22665
|
+
var API_DURABLE_RESUME_CAPABILITY_MATRIX = {
|
|
22666
|
+
...API_INPROCESS_CAPABILITY_MATRIX,
|
|
22667
|
+
unsupportedStepTypes: API_INPROCESS_CAPABILITY_MATRIX.unsupportedStepTypes.filter(
|
|
22668
|
+
(stepType) => !DURABLE_HOSTED_STEP_TYPES.has(stepType)
|
|
22669
|
+
)
|
|
22670
|
+
};
|
|
22513
22671
|
var edgeAuthSnapshotSchema = external_exports.object({
|
|
22514
22672
|
/**
|
|
22515
22673
|
* Schema version. A plain positive int (not a literal) so a consumer pinned
|
|
@@ -39931,7 +40089,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
|
|
|
39931
40089
|
"vercel": "xiaomi/mimo-v2.5-pro"
|
|
39932
40090
|
},
|
|
39933
40091
|
"minimax-m2-7": {
|
|
39934
|
-
"general-compute": "general-compute/minimax-m2.7",
|
|
39935
40092
|
"togetherai": "togetherai/MiniMaxAI/MiniMax-M2.7",
|
|
39936
40093
|
"vercel": "minimax/minimax-m2.7"
|
|
39937
40094
|
},
|
|
@@ -39939,7 +40096,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
|
|
|
39939
40096
|
"vercel": "minimax/minimax-m2.7-highspeed"
|
|
39940
40097
|
},
|
|
39941
40098
|
"minimax-m2.7": {
|
|
39942
|
-
"general-compute": "general-compute/minimax-m2.7",
|
|
39943
40099
|
"vercel": "minimax/minimax-m2.7"
|
|
39944
40100
|
},
|
|
39945
40101
|
"minimax-m2.7-highspeed": {
|
|
@@ -40315,7 +40471,6 @@ var PLATFORM_KEY_PROVIDER_MAP = {
|
|
|
40315
40471
|
"vertex-anthropic": false,
|
|
40316
40472
|
"tinfoil": false,
|
|
40317
40473
|
"generic-openai": false,
|
|
40318
|
-
"general-compute": true,
|
|
40319
40474
|
// Keyless platform provider: there is no API key (user or platform) — the
|
|
40320
40475
|
// Cloudflare `AI` binding IS the platform credential. Marking it true makes
|
|
40321
40476
|
// the router's platform-spend gate apply and keeps keySource attribution
|
|
@@ -40389,13 +40544,8 @@ var MANUAL_PROVIDER_MAP_OVERRIDES = {
|
|
|
40389
40544
|
"mixlayer": "z-ai/glm-5.2",
|
|
40390
40545
|
"vercel": "zai/glm-5.2"
|
|
40391
40546
|
},
|
|
40392
|
-
// MiniMax M2.7:
|
|
40393
|
-
// `general-compute` is NOT in PROVIDERS_WITHOUT_PREFIX, so resolveRoutedFamily
|
|
40394
|
-
// prepends `general-compute/` itself — store the BARE id here to avoid a double
|
|
40395
|
-
// prefix (`general-compute/general-compute/...`). Vercel IS prefixless, so its
|
|
40396
|
-
// value is the gateway-form `minimax/minimax-m2.7` used as-is.
|
|
40547
|
+
// MiniMax M2.7: Vercel's gateway-form id.
|
|
40397
40548
|
"minimax-m2.7": {
|
|
40398
|
-
"general-compute": "minimax-m2.7",
|
|
40399
40549
|
"vercel": "minimax/minimax-m2.7"
|
|
40400
40550
|
}
|
|
40401
40551
|
};
|
|
@@ -41313,7 +41463,55 @@ var sandboxConfigSchema = external_exports.object({
|
|
|
41313
41463
|
instanceType: external_exports.enum(["standard-1", "standard-2", "standard-3", "standard-4"]).optional(),
|
|
41314
41464
|
networkAccess: sandboxNetworkAccessSchema.optional(),
|
|
41315
41465
|
ttl: external_exports.enum(["5m", "1h", "24h", "unlimited"]).optional(),
|
|
41316
|
-
sleepAfter: external_exports.enum(["5m", "15m", "30m", "1h"]).optional()
|
|
41466
|
+
sleepAfter: external_exports.enum(["5m", "15m", "30m", "1h"]).optional(),
|
|
41467
|
+
// Operator-authored bootstrap commands. The API runs this batch once after
|
|
41468
|
+
// enforcing the sandbox's network policy and before the first model-authored
|
|
41469
|
+
// sandbox verb. Commands run in order from /workspace and must be foreground,
|
|
41470
|
+
// self-contained, and safe to retry after an interrupted container runtime;
|
|
41471
|
+
// the credential-bearing exec supervisor deliberately reaps every descendant
|
|
41472
|
+
// before a command returns, so setup cannot launch a daemon meant to outlive
|
|
41473
|
+
// it. Trusted Durable Object state plus a run-scoped memo prevents the batch
|
|
41474
|
+
// from being repeated for the same provisioned workspace. Changing the
|
|
41475
|
+
// commands or managed-secret KEY bindings creates a fresh sandbox identity;
|
|
41476
|
+
// rotating a value under the same key does not rerun setup.
|
|
41477
|
+
setupCommands: external_exports.array(external_exports.string().min(1, "setup commands must not be empty")).optional(),
|
|
41478
|
+
// Credential environment available ONLY to the operator-authored setup batch
|
|
41479
|
+
// above — never to a model-authored `bash` command. Keys are env var names;
|
|
41480
|
+
// values are MANAGED SECRET KEYS (e.g. `GITHUB_CLONE_TOKEN`), never raw
|
|
41481
|
+
// credential values. The API resolves them immediately before setup and
|
|
41482
|
+
// delivers them out-of-band over `cloudflareSandboxExecWithSecretEnv`, so the
|
|
41483
|
+
// values never appear in command strings, model-facing tool schemas, logs, or
|
|
41484
|
+
// spill files. Like `networkAccess`, both fields are operator Definition: the
|
|
41485
|
+
// model cannot author setup, name a managed secret, or grant itself one.
|
|
41486
|
+
//
|
|
41487
|
+
// TRUST BOUNDARY — read before configuring this. Every process started by a
|
|
41488
|
+
// credentialed setup batch can read the injected values. Keep setup authored
|
|
41489
|
+
// and reviewed by the operator; do not run model-, attacker-, or
|
|
41490
|
+
// supply-chain-authored code (for example an install script) while credentials
|
|
41491
|
+
// are present, and never persist a raw credential into /workspace for later
|
|
41492
|
+
// model access. The secret supervisor freezes pre-existing processes, reaps
|
|
41493
|
+
// every setup descendant, and destroys the sandbox fail-closed if cleanup
|
|
41494
|
+
// fails, but output redaction remains defense-in-depth rather than permission
|
|
41495
|
+
// to echo or transform a credential.
|
|
41496
|
+
// Therefore:
|
|
41497
|
+
// - Prefer `credentialProxies` (phantom tokens, swapped at the egress
|
|
41498
|
+
// proxy) for any HTTP(S) protocol it supports — the real credential
|
|
41499
|
+
// never enters the container at all.
|
|
41500
|
+
// - Scope the secret as narrowly as the provider allows (read-only,
|
|
41501
|
+
// single-repo) and pair it with a tight `networkAccess` profile.
|
|
41502
|
+
// - Keep credentialed setup separate from later uncredentialed dependency
|
|
41503
|
+
// installation and model-authored work.
|
|
41504
|
+
// Name shape and the 32-entry cap mirror the sandbox worker's
|
|
41505
|
+
// `validateSecretEnv`; `RUNTYPE_SECRET_COMMAND` is the worker's reserved
|
|
41506
|
+
// control-channel variable.
|
|
41507
|
+
secretEnv: external_exports.record(
|
|
41508
|
+
external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "must be a valid environment variable name").refine((name) => name !== "RUNTYPE_SECRET_COMMAND", {
|
|
41509
|
+
message: "RUNTYPE_SECRET_COMMAND is reserved"
|
|
41510
|
+
}),
|
|
41511
|
+
external_exports.string().min(1, "must be a managed secret key")
|
|
41512
|
+
).refine((record2) => Object.keys(record2).length <= 32, {
|
|
41513
|
+
message: "secretEnv supports at most 32 variables"
|
|
41514
|
+
}).optional()
|
|
41317
41515
|
// NOTE: a `requireApprovalForBash` knob was forward-declared here for Phase 3
|
|
41318
41516
|
// but never wired to any runtime gate, so it was REMOVED from the public
|
|
41319
41517
|
// schema rather than ship a misleading, inert control (post-Fable handoff 05,
|
|
@@ -41632,7 +41830,7 @@ var identityProofSchema = external_exports.object({
|
|
|
41632
41830
|
/** The customer-native proof (JWT / opaque session token). */
|
|
41633
41831
|
token: external_exports.string().min(1).max(8192)
|
|
41634
41832
|
}).describe(
|
|
41635
|
-
"Customer-native auth proof for the Identity Exchange. When present and the surface has a matching integration, the verified tenant/end-user replace any body-asserted tenant/endUser (which are never trusted for web-embedded callers).
|
|
41833
|
+
"Customer-native auth proof for the Identity Exchange. When present and the surface has a matching integration, the verified tenant/end-user replace any body-asserted tenant/endUser (which are never trusted for web-embedded callers). When Identity Exchange admission is disabled for the caller, the proof is accepted but ignored and confers no trust."
|
|
41636
41834
|
);
|
|
41637
41835
|
function extractSecretReferences(template) {
|
|
41638
41836
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -44699,6 +44897,27 @@ Only use a \`tool-call\` step when the tool must run deterministically at a fixe
|
|
|
44699
44897
|
- Nullish fallback: \`{{count ?? 0}}\` \u2014 keeps 0 / "" / false (only null/undefined fall through)
|
|
44700
44898
|
- Chains: \`{{a || b || "default"}}\` \u2014 supports paths and string/number/boolean/null literals; do NOT mix \`||\` and \`??\` in one expression
|
|
44701
44899
|
|
|
44900
|
+
### Prompt Caching: Where Large Context Goes
|
|
44901
|
+
|
|
44902
|
+
Runtype caches the request prefix automatically on Claude models. **The part that gets REUSED across runs is the tools + \`systemPrompt\` prefix.** A second boundary is placed at the end of the last message, but a cache hit there needs the whole request \u2014 \`userPrompt\` included \u2014 to repeat byte-for-byte, which per-request task text does not. (Within one request it still helps: a multi-turn or tool-looping step re-sends the grown prompt each round-trip and reads that boundary warm.) This applies to ordinary single-shot \`prompt\` steps, not just multi-turn agents.
|
|
44903
|
+
|
|
44904
|
+
- **Large STABLE context goes in \`systemPrompt\`** \u2014 style guides, voice/tone corpora, exemplars and few-shot examples, JSON schemas, policy documents, canonical reference text. Anything identical from run to run.
|
|
44905
|
+
- **Per-request content goes in \`userPrompt\`** \u2014 the task, the user's input, records retrieved for this run, prior-step outputs. A 25,000-token reference corpus pasted into \`userPrompt\` sits behind per-request text, so it is re-billed as uncached input on every single run.
|
|
44906
|
+
- **Reuse requires a byte-identical prefix.** Two steps share a cache entry only when their tools AND their \`systemPrompt\` strings match exactly. When a flow calls the same role more than once (draft \u2192 review \u2192 redraft, or the same analysis over N items), give those steps the SAME \`systemPrompt\` and put the per-call difference in \`userPrompt\`. Two near-identical system prompts are two cache entries and zero reuse.
|
|
44907
|
+
- **Below the model's minimum, nothing is stamped.** The prefix must exceed the model's minimum cacheable prefix (~1,024 tokens on Sonnet/Opus-class, up to 4,096 on Haiku-class) or the request goes out uncached. Do not contort a short system prompt to chase caching \u2014 this only matters when the stable context is genuinely large or the step runs many times.
|
|
44908
|
+
- **Per-run variables in \`systemPrompt\` kill the prefix.** \`{{_now.*}}\`, \`{{_execution.*}}\`, and \`{{_schedule.*}}\` re-render the system prompt on every execution, so it can never produce a cross-run hit; \`validate_flow\` reports this as \`CACHE_VOLATILE_SYSTEM_PROMPT\` (recommendation). Move the changing value into \`userPrompt\` or a later step. Other variables (\`{{_user.id}}\`, step outputs) do not disable caching, but they fork the cache per distinct substituted value \u2014 keep them out of a prefix you intend several steps or runs to share.
|
|
44909
|
+
|
|
44910
|
+
\`\`\`json
|
|
44911
|
+
// BEFORE \u2014 the corpus rides in userPrompt and is re-sent uncached on every run,
|
|
44912
|
+
// and the two steps have different system prompts, so neither shares a prefix
|
|
44913
|
+
{ "type": "prompt", "name": "Draft", "config": { "model": "claude-opus-5", "systemPrompt": "You are a copywriter.", "userPrompt": "STYLE GUIDE: <25,000 tokens of client style corpus> --- Write a launch email about {{topic}}.", "outputVariable": "draft" } }
|
|
44914
|
+
{ "type": "prompt", "name": "Revise", "config": { "model": "claude-opus-5", "systemPrompt": "You revise copy.", "userPrompt": "STYLE GUIDE: <the same 25,000 tokens again> --- Revise this draft: {{draft}}", "outputVariable": "final" } }
|
|
44915
|
+
|
|
44916
|
+
// AFTER \u2014 one byte-identical prefix; the second step and every later run read it warm
|
|
44917
|
+
{ "type": "prompt", "name": "Draft", "config": { "model": "claude-opus-5", "systemPrompt": "You write and revise copy for this client. STYLE GUIDE: <25,000 tokens of client style corpus>", "userPrompt": "Write a launch email about {{topic}}.", "outputVariable": "draft" } }
|
|
44918
|
+
{ "type": "prompt", "name": "Revise", "config": { "model": "claude-opus-5", "systemPrompt": "You write and revise copy for this client. STYLE GUIDE: <25,000 tokens of client style corpus>", "userPrompt": "Revise this draft: {{draft}}", "outputVariable": "final" } }
|
|
44919
|
+
\`\`\`
|
|
44920
|
+
|
|
44702
44921
|
### Model Selection
|
|
44703
44922
|
|
|
44704
44923
|
Use ONLY routed model IDs from the list below (platform-key compatible). Never
|
|
@@ -45647,7 +45866,7 @@ var InlineClientToolSchema = external_exports.object({
|
|
|
45647
45866
|
var ClientToolsPolicySchema = external_exports.object({
|
|
45648
45867
|
allowlist: external_exports.array(external_exports.string()).optional()
|
|
45649
45868
|
});
|
|
45650
|
-
var
|
|
45869
|
+
var DispatchRequestEnvelopeSchema = external_exports.object({
|
|
45651
45870
|
record: RecordInputSchema.optional(),
|
|
45652
45871
|
flow: FlowInputSchema.optional(),
|
|
45653
45872
|
agent: AgentInputSchema.optional(),
|
|
@@ -45684,7 +45903,9 @@ var DispatchRequestSchema = external_exports.object({
|
|
|
45684
45903
|
* every submitted webmcp tool. See {@link ClientToolsPolicySchema}.
|
|
45685
45904
|
*/
|
|
45686
45905
|
clientToolsPolicy: ClientToolsPolicySchema.optional(),
|
|
45687
|
-
secrets: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
45906
|
+
secrets: external_exports.record(external_exports.string(), external_exports.string()).optional().describe(
|
|
45907
|
+
"Per-request credentials for agent/external-tool execution. Ignored when `flow` is the hosted target; FLOW credentials must use managed {{secret:NAME}} references."
|
|
45908
|
+
),
|
|
45688
45909
|
credentialProxies: external_exports.array(credentialProxyConfigSchema).max(10).optional(),
|
|
45689
45910
|
inputs: external_exports.record(external_exports.string(), external_exports.any()).optional().refine(
|
|
45690
45911
|
(data) => {
|
|
@@ -45710,10 +45931,11 @@ var DispatchRequestSchema = external_exports.object({
|
|
|
45710
45931
|
id: external_exports.string().min(1)
|
|
45711
45932
|
}).passthrough().optional(),
|
|
45712
45933
|
// Identity Exchange proof (design §4.1): a customer-native auth token the
|
|
45713
|
-
// broker
|
|
45714
|
-
//
|
|
45715
|
-
//
|
|
45716
|
-
// live credential: never log or persist it (see
|
|
45934
|
+
// broker verifies server-side and admits as `verified` tenant/end-user when
|
|
45935
|
+
// Identity Exchange admission is enabled for the caller. With the rollout
|
|
45936
|
+
// gate disabled it remains accepted-but-ignored and confers no trust. The
|
|
45937
|
+
// token is a live credential: never log or persist it (see
|
|
45938
|
+
// identityProofSchema docs).
|
|
45717
45939
|
identityProof: identityProofSchema.optional(),
|
|
45718
45940
|
options: external_exports.object({
|
|
45719
45941
|
streamResponse: external_exports.boolean().optional().default(true),
|
|
@@ -45725,7 +45947,7 @@ var DispatchRequestSchema = external_exports.object({
|
|
|
45725
45947
|
debugMode: external_exports.boolean().optional().default(false),
|
|
45726
45948
|
loggingPolicy: external_exports.enum(["default", "on", "off"]).optional(),
|
|
45727
45949
|
useRuntimePackage: external_exports.boolean().optional().describe(
|
|
45728
|
-
"
|
|
45950
|
+
"For FLOW dispatches this compatibility field is accepted but ignored: eligible flows always use the @runtypelabs/runtime lane, while ineligible flows still fold to legacy silently. Agent dispatches still require an explicit `true` and remain subject to their separate runtime-agent rollout gate."
|
|
45729
45951
|
),
|
|
45730
45952
|
/** Route prompt model calls through an attached dashboard browser. */
|
|
45731
45953
|
localInference: LocalInferenceSelectionSchema.optional(),
|
|
@@ -45792,20 +46014,23 @@ var DispatchRequestSchema = external_exports.object({
|
|
|
45792
46014
|
storeResults: true,
|
|
45793
46015
|
autoAppendMetadata: false,
|
|
45794
46016
|
debugMode: false,
|
|
45795
|
-
// useRuntimePackage intentionally omitted
|
|
45796
|
-
//
|
|
46017
|
+
// useRuntimePackage intentionally omitted. Flow dispatch ignores the
|
|
46018
|
+
// compatibility field; agent dispatch still requires explicit true.
|
|
45797
46019
|
environment: "development",
|
|
45798
46020
|
createVersion: false
|
|
45799
46021
|
})
|
|
45800
|
-
})
|
|
45801
|
-
|
|
45802
|
-
|
|
46022
|
+
});
|
|
46023
|
+
var DispatchRequestSchema = external_exports.union([
|
|
46024
|
+
DispatchRequestEnvelopeSchema.extend({ flow: FlowInputSchema }),
|
|
46025
|
+
DispatchRequestEnvelopeSchema.extend({ agent: AgentInputSchema })
|
|
46026
|
+
]).superRefine((data, ctx) => {
|
|
45803
46027
|
if (!data.options.localInference) return;
|
|
45804
|
-
|
|
46028
|
+
const runtimeLaneDisabled = data.agent != null && data.options.useRuntimePackage !== true;
|
|
46029
|
+
if (runtimeLaneDisabled) {
|
|
45805
46030
|
ctx.addIssue({
|
|
45806
46031
|
code: "custom",
|
|
45807
46032
|
path: ["options", "useRuntimePackage"],
|
|
45808
|
-
message: "Local inference requires useRuntimePackage to be enabled"
|
|
46033
|
+
message: data.agent != null ? "Local agent inference requires useRuntimePackage to be enabled" : "Local flow inference cannot use the legacy engine"
|
|
45809
46034
|
});
|
|
45810
46035
|
}
|
|
45811
46036
|
if (data.options.modelOverride) {
|
|
@@ -53141,7 +53366,9 @@ import React14 from "react";
|
|
|
53141
53366
|
import { render as render14 } from "ink";
|
|
53142
53367
|
import { useState as useState15, useEffect as useEffect16 } from "react";
|
|
53143
53368
|
import { readFileSync as readFileSync5 } from "fs";
|
|
53144
|
-
import {
|
|
53369
|
+
import {
|
|
53370
|
+
processStream as processStream3
|
|
53371
|
+
} from "@runtypelabs/sdk";
|
|
53145
53372
|
var dispatchCommand = new Command15("dispatch").description("Execute a flow or agent via the dispatch API").option("-f, --flow <id>", "Flow ID to execute").option("-a, --agent <id>", "Agent ID to execute").option("-r, --record <id>", "Existing record ID").option("--record-json <file>", "JSON file with record data").option("-m, --message <text>", "Message to send").option("-v, --variable <key=value>", "Set a variable (repeatable)", collectVariables, []).option("--stream", "Stream the response (default)", true).option("--no-stream", "Wait for complete response").option("--json", "Output as JSON").option("--debug", "Show step-level details").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
53146
53373
|
if (!options.flow && !options.agent) {
|
|
53147
53374
|
console.error(chalk17.red("Error: Either --flow or --agent is required"));
|
|
@@ -53150,44 +53377,50 @@ var dispatchCommand = new Command15("dispatch").description("Execute a flow or a
|
|
|
53150
53377
|
const apiKey = await ensureAuth();
|
|
53151
53378
|
if (!apiKey) return;
|
|
53152
53379
|
const client = createCliClient(apiKey);
|
|
53153
|
-
|
|
53154
|
-
|
|
53155
|
-
payload
|
|
53380
|
+
let payload;
|
|
53381
|
+
try {
|
|
53382
|
+
payload = buildDispatchRequest(options);
|
|
53383
|
+
} catch (error51) {
|
|
53384
|
+
const message = error51 instanceof Error ? error51.message : "Unknown error";
|
|
53385
|
+
console.error(chalk17.red(`Failed to read record JSON: ${message}`));
|
|
53386
|
+
process.exit(1);
|
|
53387
|
+
}
|
|
53388
|
+
if (options.stream) {
|
|
53389
|
+
await handleStreaming(client, payload, options);
|
|
53390
|
+
} else {
|
|
53391
|
+
await handleNonStreaming(client, payload, options);
|
|
53156
53392
|
}
|
|
53393
|
+
});
|
|
53394
|
+
function collectVariables(value, previous) {
|
|
53395
|
+
return previous.concat([value]);
|
|
53396
|
+
}
|
|
53397
|
+
function buildDispatchRequest(options) {
|
|
53398
|
+
if (!options.flow && !options.agent) {
|
|
53399
|
+
throw new Error("Either --flow or --agent is required");
|
|
53400
|
+
}
|
|
53401
|
+
const payload = options.flow ? { flow: { id: options.flow } } : { agent: { agentId: options.agent } };
|
|
53157
53402
|
if (options.agent) {
|
|
53158
|
-
payload.agent = {
|
|
53403
|
+
payload.agent = { agentId: options.agent };
|
|
53159
53404
|
}
|
|
53160
53405
|
if (options.record) {
|
|
53161
53406
|
payload.record = { id: options.record };
|
|
53162
53407
|
} else if (options.recordJson) {
|
|
53163
|
-
|
|
53164
|
-
|
|
53165
|
-
payload.record = { metadata: data };
|
|
53166
|
-
} catch (error51) {
|
|
53167
|
-
const message = error51 instanceof Error ? error51.message : "Unknown error";
|
|
53168
|
-
console.error(chalk17.red(`Failed to read record JSON: ${message}`));
|
|
53169
|
-
process.exit(1);
|
|
53170
|
-
}
|
|
53408
|
+
const data = JSON.parse(readFileSync5(options.recordJson, "utf-8"));
|
|
53409
|
+
payload.record = { metadata: data };
|
|
53171
53410
|
}
|
|
53172
53411
|
if (options.message) {
|
|
53173
53412
|
payload.messages = [{ role: "user", content: options.message }];
|
|
53174
53413
|
}
|
|
53175
53414
|
if (options.variable && options.variable.length > 0) {
|
|
53176
|
-
const
|
|
53177
|
-
for (const
|
|
53178
|
-
const [key, ...rest] =
|
|
53179
|
-
|
|
53415
|
+
const inputs = {};
|
|
53416
|
+
for (const variable of options.variable) {
|
|
53417
|
+
const [key, ...rest] = variable.split("=");
|
|
53418
|
+
inputs[key] = rest.join("=");
|
|
53180
53419
|
}
|
|
53181
|
-
payload.
|
|
53420
|
+
payload.inputs = inputs;
|
|
53182
53421
|
}
|
|
53183
|
-
|
|
53184
|
-
|
|
53185
|
-
} else {
|
|
53186
|
-
await handleNonStreaming(client, payload, options);
|
|
53187
|
-
}
|
|
53188
|
-
});
|
|
53189
|
-
function collectVariables(value, previous) {
|
|
53190
|
-
return previous.concat([value]);
|
|
53422
|
+
payload.options = { streamResponse: options.stream };
|
|
53423
|
+
return payload;
|
|
53191
53424
|
}
|
|
53192
53425
|
async function handleStreaming(client, payload, options) {
|
|
53193
53426
|
console.log(chalk17.gray("Starting execution..."));
|
|
@@ -53241,7 +53474,6 @@ Error: ${err.message}`));
|
|
|
53241
53474
|
async function handleNonStreaming(client, payload, options) {
|
|
53242
53475
|
if (!isTTY(options)) {
|
|
53243
53476
|
try {
|
|
53244
|
-
payload.streamResponse = false;
|
|
53245
53477
|
const result = await client.post("/dispatch", payload);
|
|
53246
53478
|
if (options.json) {
|
|
53247
53479
|
printJson(result);
|
|
@@ -53276,7 +53508,6 @@ async function handleNonStreaming(client, payload, options) {
|
|
|
53276
53508
|
useEffect16(() => {
|
|
53277
53509
|
const run2 = async () => {
|
|
53278
53510
|
try {
|
|
53279
|
-
payload.streamResponse = false;
|
|
53280
53511
|
const result = await client.post("/dispatch", payload);
|
|
53281
53512
|
setLoading(false);
|
|
53282
53513
|
setSuccess(true);
|
|
@@ -68487,8 +68718,8 @@ import { execFileSync } from "child_process";
|
|
|
68487
68718
|
// src/lib/persona-init.ts
|
|
68488
68719
|
init_credential_store();
|
|
68489
68720
|
|
|
68490
|
-
// ../../node_modules/.pnpm/@runtypelabs+persona@4.
|
|
68491
|
-
var w = "4.
|
|
68721
|
+
// ../../node_modules/.pnpm/@runtypelabs+persona@4.14.0/node_modules/@runtypelabs/persona/dist/codegen.js
|
|
68722
|
+
var w = "4.14.0";
|
|
68492
68723
|
var S = w;
|
|
68493
68724
|
function b(e) {
|
|
68494
68725
|
return e?.cdnBase?.trim().replace(/\/+$/, "").replace(/[\\'"<>`]/g, (r) => `%${r.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`) || `https://cdn.jsdelivr.net/npm/@runtypelabs/persona@${S}/dist`;
|
|
@@ -71871,7 +72102,20 @@ echo " npm run build \u2014 compile TypeScript"
|
|
|
71871
72102
|
echo " gcloud run deploy --source . --region us-central1 --allow-unauthenticated --port 8080"
|
|
71872
72103
|
`;
|
|
71873
72104
|
}
|
|
71874
|
-
function
|
|
72105
|
+
function formatOptionalProviderSettings(settings) {
|
|
72106
|
+
return settings.map((setting) => `- \`${setting.name}\` (default: \`${setting.defaultValue}\`)`).join("\n");
|
|
72107
|
+
}
|
|
72108
|
+
function optionalProviderSettingsSection(settings) {
|
|
72109
|
+
if (settings.length === 0) return "";
|
|
72110
|
+
return `
|
|
72111
|
+
## Optional provider settings
|
|
72112
|
+
|
|
72113
|
+
These environment variables override runtime defaults and are not required:
|
|
72114
|
+
|
|
72115
|
+
${formatOptionalProviderSettings(settings)}
|
|
72116
|
+
`;
|
|
72117
|
+
}
|
|
72118
|
+
function readme(agentNames, secretNames, optionalSettings) {
|
|
71875
72119
|
const agentList = agentNames.map((n) => ` - ${n}`).join("\n");
|
|
71876
72120
|
const secretList = secretNames.length > 0 ? secretNames.map((s) => ` gcloud secrets create ${s} --data-file=-`).join("\n") : " (none detected)";
|
|
71877
72121
|
return `# Runtype Deployment
|
|
@@ -71908,6 +72152,8 @@ Set these before deploying to Cloud Run:
|
|
|
71908
72152
|
|
|
71909
72153
|
${secretList}
|
|
71910
72154
|
|
|
72155
|
+
${optionalProviderSettingsSection(optionalSettings)}
|
|
72156
|
+
|
|
71911
72157
|
## Deploy to Cloud Run
|
|
71912
72158
|
|
|
71913
72159
|
\`\`\`bash
|
|
@@ -72205,7 +72451,7 @@ echo " wrangler dev \u2014 preview locally"
|
|
|
72205
72451
|
echo " wrangler deploy \u2014 deploy to Cloudflare Workers"
|
|
72206
72452
|
`;
|
|
72207
72453
|
}
|
|
72208
|
-
function workerReadme(agentNames, secretNames) {
|
|
72454
|
+
function workerReadme(agentNames, secretNames, optionalSettings) {
|
|
72209
72455
|
const agentList = agentNames.map((n) => ` - ${n}`).join("\n");
|
|
72210
72456
|
const secretList = secretNames.length > 0 ? secretNames.map((s) => ` wrangler secret put ${s}`).join("\n") : " (none detected)";
|
|
72211
72457
|
return `# Runtype Cloudflare Workers Deployment
|
|
@@ -72228,6 +72474,8 @@ Set each API key your agents use:
|
|
|
72228
72474
|
${secretList}
|
|
72229
72475
|
\`\`\`
|
|
72230
72476
|
|
|
72477
|
+
${optionalProviderSettingsSection(optionalSettings)}
|
|
72478
|
+
|
|
72231
72479
|
## Run locally
|
|
72232
72480
|
|
|
72233
72481
|
\`\`\`bash
|
|
@@ -72482,7 +72730,7 @@ echo " vercel dev \u2014 preview locally"
|
|
|
72482
72730
|
echo " vercel deploy \u2014 deploy to Vercel Functions"
|
|
72483
72731
|
`;
|
|
72484
72732
|
}
|
|
72485
|
-
function vercelReadme(agentNames, secretNames) {
|
|
72733
|
+
function vercelReadme(agentNames, secretNames, optionalSettings) {
|
|
72486
72734
|
const agentList = agentNames.map((n) => ` - ${n}`).join("\n");
|
|
72487
72735
|
const secretList = secretNames.length > 0 ? secretNames.map((s) => ` vercel env add ${s}`).join("\n") : " (none detected)";
|
|
72488
72736
|
return `# Runtype Vercel Functions Deployment
|
|
@@ -72505,6 +72753,8 @@ Set each API key your agents use via the Vercel dashboard or CLI:
|
|
|
72505
72753
|
${secretList}
|
|
72506
72754
|
\`\`\`
|
|
72507
72755
|
|
|
72756
|
+
${optionalProviderSettingsSection(optionalSettings)}
|
|
72757
|
+
|
|
72508
72758
|
## Run locally
|
|
72509
72759
|
|
|
72510
72760
|
\`\`\`bash
|
|
@@ -72530,24 +72780,113 @@ curl https://<your-project>.vercel.app/agent/<name> \\
|
|
|
72530
72780
|
\`\`\`
|
|
72531
72781
|
`;
|
|
72532
72782
|
}
|
|
72533
|
-
function
|
|
72534
|
-
const
|
|
72535
|
-
const
|
|
72536
|
-
|
|
72537
|
-
|
|
72783
|
+
function collectExportedExecutionInventory(definition) {
|
|
72784
|
+
const models = /* @__PURE__ */ new Set();
|
|
72785
|
+
const namedSecrets = /* @__PURE__ */ new Set();
|
|
72786
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
72787
|
+
const isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
72788
|
+
const addModel = (value) => {
|
|
72789
|
+
if (typeof value === "string" && value) models.add(value);
|
|
72790
|
+
};
|
|
72791
|
+
const walkMcpServers = (servers) => {
|
|
72792
|
+
if (!Array.isArray(servers)) return;
|
|
72793
|
+
for (const server of servers) {
|
|
72794
|
+
if (!isObject2(server) || !isObject2(server.auth)) continue;
|
|
72795
|
+
for (const key of ["tokenSecretName", "usernameSecretName", "passwordSecretName"]) {
|
|
72796
|
+
const value = server.auth[key];
|
|
72797
|
+
if (typeof value === "string" && value) namedSecrets.add(value);
|
|
72798
|
+
}
|
|
72799
|
+
}
|
|
72800
|
+
};
|
|
72801
|
+
function walkRuntimeTools(runtimeTools) {
|
|
72802
|
+
if (!Array.isArray(runtimeTools)) return;
|
|
72803
|
+
for (const tool of runtimeTools) {
|
|
72804
|
+
if (!isObject2(tool) || !isObject2(tool.config)) continue;
|
|
72805
|
+
if (isObject2(tool.config.flow)) walkFlow(tool.config.flow);
|
|
72806
|
+
if (isObject2(tool.config.agent)) walkAgent(tool.config.agent);
|
|
72807
|
+
if (isObject2(tool.config.skill)) walkRuntimeTools(tool.config.skill.resolvedTools);
|
|
72808
|
+
}
|
|
72538
72809
|
}
|
|
72539
|
-
|
|
72540
|
-
|
|
72541
|
-
|
|
72542
|
-
|
|
72543
|
-
|
|
72544
|
-
|
|
72545
|
-
|
|
72546
|
-
|
|
72810
|
+
function walkTools(tools) {
|
|
72811
|
+
if (!isObject2(tools)) return;
|
|
72812
|
+
walkMcpServers(tools.mcpServers);
|
|
72813
|
+
walkRuntimeTools(tools.runtimeTools);
|
|
72814
|
+
}
|
|
72815
|
+
function walkFallbackModels(config3) {
|
|
72816
|
+
if (!isObject2(config3.errorHandling) || !Array.isArray(config3.errorHandling.fallbacks)) return;
|
|
72817
|
+
for (const fallback of config3.errorHandling.fallbacks) {
|
|
72818
|
+
if (isObject2(fallback) && fallback.type === "model") addModel(fallback.model);
|
|
72819
|
+
}
|
|
72820
|
+
}
|
|
72821
|
+
function walkSteps(steps) {
|
|
72822
|
+
if (!Array.isArray(steps)) return;
|
|
72823
|
+
for (const step of steps) {
|
|
72824
|
+
if (!isObject2(step) || !isObject2(step.config)) continue;
|
|
72825
|
+
if (step.type === "prompt") addModel(step.config.model);
|
|
72826
|
+
walkFallbackModels(step.config);
|
|
72827
|
+
walkTools(step.config.tools);
|
|
72828
|
+
if (step.type !== "conditional") continue;
|
|
72829
|
+
for (const key of ["trueSteps", "falseSteps", "otherwiseSteps"]) walkSteps(step.config[key]);
|
|
72830
|
+
if (Array.isArray(step.config.branches)) {
|
|
72831
|
+
for (const branch of step.config.branches) {
|
|
72832
|
+
if (isObject2(branch)) walkSteps(branch.steps);
|
|
72833
|
+
}
|
|
72834
|
+
}
|
|
72547
72835
|
}
|
|
72548
72836
|
}
|
|
72549
|
-
|
|
72550
|
-
|
|
72837
|
+
function walkFlow(flow) {
|
|
72838
|
+
if (visited.has(flow)) return;
|
|
72839
|
+
visited.add(flow);
|
|
72840
|
+
walkSteps(flow.steps);
|
|
72841
|
+
if (isObject2(flow.agents)) {
|
|
72842
|
+
for (const agent of Object.values(flow.agents)) {
|
|
72843
|
+
if (isObject2(agent)) walkAgent(agent);
|
|
72844
|
+
}
|
|
72845
|
+
}
|
|
72846
|
+
}
|
|
72847
|
+
function walkAgent(agent) {
|
|
72848
|
+
if (visited.has(agent)) return;
|
|
72849
|
+
visited.add(agent);
|
|
72850
|
+
if (isObject2(agent.config)) {
|
|
72851
|
+
addModel(agent.config.model);
|
|
72852
|
+
walkTools(agent.config.tools);
|
|
72853
|
+
}
|
|
72854
|
+
if (isObject2(agent.claudeManagedConfig)) addModel(agent.claudeManagedConfig.model);
|
|
72855
|
+
if (isObject2(agent.primaryFlow)) walkFlow(agent.primaryFlow);
|
|
72856
|
+
if (Array.isArray(agent.capabilities)) {
|
|
72857
|
+
for (const capability of agent.capabilities) {
|
|
72858
|
+
if (!isObject2(capability)) continue;
|
|
72859
|
+
if (isObject2(capability.flow)) walkFlow(capability.flow);
|
|
72860
|
+
if (isObject2(capability.subAgent)) walkAgent(capability.subAgent);
|
|
72861
|
+
}
|
|
72862
|
+
}
|
|
72863
|
+
}
|
|
72864
|
+
if (isObject2(definition)) {
|
|
72865
|
+
if (Array.isArray(definition.steps) && !isObject2(definition.config)) walkFlow(definition);
|
|
72866
|
+
else walkAgent(definition);
|
|
72867
|
+
}
|
|
72868
|
+
return {
|
|
72869
|
+
models: Array.from(models),
|
|
72870
|
+
namedSecrets: Array.from(namedSecrets)
|
|
72871
|
+
};
|
|
72872
|
+
}
|
|
72873
|
+
function collectDeploymentSecretInventory(agentDef) {
|
|
72874
|
+
const requiredNames = /* @__PURE__ */ new Set();
|
|
72875
|
+
const optionalSettings = /* @__PURE__ */ new Map();
|
|
72876
|
+
const executionInventory = collectExportedExecutionInventory(agentDef);
|
|
72877
|
+
for (const model of executionInventory.models) {
|
|
72878
|
+
for (const name of resolveModelSecretNames(model)) requiredNames.add(name);
|
|
72879
|
+
for (const setting of resolveModelOptionalSettings(model)) {
|
|
72880
|
+
optionalSettings.set(setting.name, setting);
|
|
72881
|
+
}
|
|
72882
|
+
}
|
|
72883
|
+
for (const name of executionInventory.namedSecrets) requiredNames.add(name);
|
|
72884
|
+
for (const name of extractSecretReferencesFromAnyValue(agentDef, 512)) requiredNames.add(name);
|
|
72885
|
+
for (const name of requiredNames) optionalSettings.delete(name);
|
|
72886
|
+
return {
|
|
72887
|
+
requiredNames: Array.from(requiredNames),
|
|
72888
|
+
optionalSettings: Array.from(optionalSettings.values())
|
|
72889
|
+
};
|
|
72551
72890
|
}
|
|
72552
72891
|
function slugify2(s) {
|
|
72553
72892
|
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 63);
|
|
@@ -72656,10 +72995,17 @@ Scaffolding ${target} deployment to ${outDir}
|
|
|
72656
72995
|
monorepoRoot = parent;
|
|
72657
72996
|
}
|
|
72658
72997
|
const allSecrets = /* @__PURE__ */ new Set();
|
|
72998
|
+
const allOptionalSettings = /* @__PURE__ */ new Map();
|
|
72659
72999
|
for (const { def } of agentDefs) {
|
|
72660
|
-
|
|
73000
|
+
const inventory = collectDeploymentSecretInventory(def);
|
|
73001
|
+
for (const name of inventory.requiredNames) allSecrets.add(name);
|
|
73002
|
+
for (const setting of inventory.optionalSettings) {
|
|
73003
|
+
allOptionalSettings.set(setting.name, setting);
|
|
73004
|
+
}
|
|
72661
73005
|
}
|
|
73006
|
+
for (const name of allSecrets) allOptionalSettings.delete(name);
|
|
72662
73007
|
const secretNames = Array.from(allSecrets);
|
|
73008
|
+
const optionalSettings = Array.from(allOptionalSettings.values());
|
|
72663
73009
|
if (target === "cloudflare") {
|
|
72664
73010
|
fs16.mkdirSync(path17.join(outDir, "src"), { recursive: true });
|
|
72665
73011
|
fs16.writeFileSync(path17.join(outDir, "src", "index.ts"), workerIndexTs(agentSlugs));
|
|
@@ -72669,7 +73015,10 @@ Scaffolding ${target} deployment to ${outDir}
|
|
|
72669
73015
|
const setupPath = path17.join(outDir, "setup.sh");
|
|
72670
73016
|
fs16.writeFileSync(setupPath, workerSetupSh(monorepoRoot));
|
|
72671
73017
|
fs16.chmodSync(setupPath, 493);
|
|
72672
|
-
fs16.writeFileSync(
|
|
73018
|
+
fs16.writeFileSync(
|
|
73019
|
+
path17.join(outDir, "README.md"),
|
|
73020
|
+
workerReadme(agentNames, secretNames, optionalSettings)
|
|
73021
|
+
);
|
|
72673
73022
|
} else if (target === "vercel") {
|
|
72674
73023
|
fs16.mkdirSync(path17.join(outDir, "api"), { recursive: true });
|
|
72675
73024
|
fs16.writeFileSync(path17.join(outDir, "api", "[[...route]].ts"), vercelRouteTs(agentSlugs));
|
|
@@ -72679,7 +73028,10 @@ Scaffolding ${target} deployment to ${outDir}
|
|
|
72679
73028
|
const setupPath = path17.join(outDir, "setup.sh");
|
|
72680
73029
|
fs16.writeFileSync(setupPath, vercelSetupSh(monorepoRoot));
|
|
72681
73030
|
fs16.chmodSync(setupPath, 493);
|
|
72682
|
-
fs16.writeFileSync(
|
|
73031
|
+
fs16.writeFileSync(
|
|
73032
|
+
path17.join(outDir, "README.md"),
|
|
73033
|
+
vercelReadme(agentNames, secretNames, optionalSettings)
|
|
73034
|
+
);
|
|
72683
73035
|
} else {
|
|
72684
73036
|
fs16.writeFileSync(path17.join(outDir, "server.ts"), serverTs());
|
|
72685
73037
|
fs16.writeFileSync(path17.join(outDir, "Dockerfile"), dockerfile());
|
|
@@ -72689,7 +73041,10 @@ Scaffolding ${target} deployment to ${outDir}
|
|
|
72689
73041
|
const setupPath = path17.join(outDir, "setup.sh");
|
|
72690
73042
|
fs16.writeFileSync(setupPath, setupSh(monorepoRoot));
|
|
72691
73043
|
fs16.chmodSync(setupPath, 493);
|
|
72692
|
-
fs16.writeFileSync(
|
|
73044
|
+
fs16.writeFileSync(
|
|
73045
|
+
path17.join(outDir, "README.md"),
|
|
73046
|
+
readme(agentNames, secretNames, optionalSettings)
|
|
73047
|
+
);
|
|
72693
73048
|
}
|
|
72694
73049
|
console.log("");
|
|
72695
73050
|
console.log(chalk38.green(`\u2713 Scaffold written to ${outDir}`));
|
|
@@ -72697,6 +73052,15 @@ Scaffolding ${target} deployment to ${outDir}
|
|
|
72697
73052
|
console.log(chalk38.bold("Next steps:"));
|
|
72698
73053
|
console.log(` cd ${options.output}`);
|
|
72699
73054
|
console.log(" chmod +x setup.sh && ./setup.sh # pack runtime + install deps");
|
|
73055
|
+
if (optionalSettings.length > 0) {
|
|
73056
|
+
console.log("");
|
|
73057
|
+
console.log(chalk38.yellow("Optional provider settings (defaults used when unset):"));
|
|
73058
|
+
for (const setting of optionalSettings) {
|
|
73059
|
+
console.log(
|
|
73060
|
+
` ${chalk38.cyan(setting.name)} (default: ${chalk38.cyan(setting.defaultValue)})`
|
|
73061
|
+
);
|
|
73062
|
+
}
|
|
73063
|
+
}
|
|
72700
73064
|
if (target === "cloudflare") {
|
|
72701
73065
|
console.log(" wrangler dev # test locally");
|
|
72702
73066
|
console.log("");
|