@standardagents/builder 0.11.0-next.0fa8695 → 0.11.0-next.14455ae
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/built-in-routes.js +22754 -6950
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/assets/index.css +1 -1
- package/dist/client/index.js +26 -23
- package/dist/client/vendor.js +1 -1
- package/dist/client/vue.js +1 -1
- package/dist/index.d.ts +224 -26
- package/dist/index.js +3144 -1235
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +6 -0
- package/dist/plugin.js +269 -57
- package/dist/plugin.js.map +1 -1
- package/dist/sip.wasm +0 -0
- package/package.json +8 -6
- package/dist/client/assets/img/meta.svg +0 -19
- package/dist/client/assets/img/moonshotai.svg +0 -4
- package/dist/client/assets/img/zai.svg +0 -219
package/dist/plugin.d.ts
CHANGED
|
@@ -9,6 +9,12 @@ interface AgentPluginOptions {
|
|
|
9
9
|
promptsDir?: string;
|
|
10
10
|
agentsDir?: string;
|
|
11
11
|
effectsDir?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Additional provider packages to expose in the UI.
|
|
14
|
+
* First-party providers (@standardagents/openai, @standardagents/openrouter) are always included.
|
|
15
|
+
* @example ['my-custom-provider', '@company/custom-openai']
|
|
16
|
+
*/
|
|
17
|
+
providers?: string[];
|
|
12
18
|
}
|
|
13
19
|
declare function agentbuilder(options?: AgentPluginOptions): Plugin;
|
|
14
20
|
|
package/dist/plugin.js
CHANGED
|
@@ -397,6 +397,9 @@ declare module 'virtual:@standardagents/builder' {
|
|
|
397
397
|
listThreads(params?: {
|
|
398
398
|
agent_name?: string;
|
|
399
399
|
user_id?: string;
|
|
400
|
+
search?: string;
|
|
401
|
+
startDate?: number;
|
|
402
|
+
endDate?: number;
|
|
400
403
|
limit?: number;
|
|
401
404
|
offset?: number;
|
|
402
405
|
}): Promise<{ threads: ThreadRegistryEntry[]; total: number }>;
|
|
@@ -578,14 +581,91 @@ function needsRegeneration(config) {
|
|
|
578
581
|
return false;
|
|
579
582
|
}
|
|
580
583
|
|
|
584
|
+
// src/utils/model-parser.ts
|
|
585
|
+
function getName(content) {
|
|
586
|
+
return content.match(/name:\s*['"]([^'"]+)['"]/)?.[1];
|
|
587
|
+
}
|
|
588
|
+
function getProvider(content) {
|
|
589
|
+
const stringMatch = content.match(/provider:\s*['"]([^'"]+)['"]/)?.[1];
|
|
590
|
+
if (stringMatch) return stringMatch;
|
|
591
|
+
const refMatch = content.match(/provider:\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*[,\n}]/)?.[1];
|
|
592
|
+
return refMatch || void 0;
|
|
593
|
+
}
|
|
594
|
+
function getModel(content) {
|
|
595
|
+
return content.match(/model:\s*['"]([^'"]+)['"]/)?.[1];
|
|
596
|
+
}
|
|
597
|
+
function getInputPrice(content) {
|
|
598
|
+
const match = content.match(/inputPrice:\s*([\d.]+)/);
|
|
599
|
+
return match ? parseFloat(match[1]) : void 0;
|
|
600
|
+
}
|
|
601
|
+
function getOutputPrice(content) {
|
|
602
|
+
const match = content.match(/outputPrice:\s*([\d.]+)/);
|
|
603
|
+
return match ? parseFloat(match[1]) : void 0;
|
|
604
|
+
}
|
|
605
|
+
function getCachedPrice(content) {
|
|
606
|
+
const match = content.match(/cachedPrice:\s*([\d.]+)/);
|
|
607
|
+
return match ? parseFloat(match[1]) : void 0;
|
|
608
|
+
}
|
|
609
|
+
function getIncludedProviders(content) {
|
|
610
|
+
const match = content.match(/includedProviders:\s*\[([^\]]*)\]/);
|
|
611
|
+
if (!match) return void 0;
|
|
612
|
+
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
613
|
+
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
614
|
+
}
|
|
615
|
+
function getFallbacks(content) {
|
|
616
|
+
const match = content.match(/fallbacks:\s*\[([^\]]*)\]/);
|
|
617
|
+
if (!match) return [];
|
|
618
|
+
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
619
|
+
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
620
|
+
}
|
|
621
|
+
function getProviderTools(content) {
|
|
622
|
+
const match = content.match(/providerTools:\s*\[([^\]]*)\]/);
|
|
623
|
+
if (!match) return [];
|
|
624
|
+
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
625
|
+
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
626
|
+
}
|
|
627
|
+
function getCapabilities(content) {
|
|
628
|
+
const match = content.match(/capabilities:\s*\{([^}]*)\}/s);
|
|
629
|
+
if (!match) return void 0;
|
|
630
|
+
const inner = match[1];
|
|
631
|
+
const caps = {};
|
|
632
|
+
const boolMatches = inner.matchAll(/(\w+):\s*(true|false)/g);
|
|
633
|
+
for (const m of boolMatches) {
|
|
634
|
+
caps[m[1]] = m[2] === "true";
|
|
635
|
+
}
|
|
636
|
+
const numMatches = inner.matchAll(/(\w+):\s*(\d+)/g);
|
|
637
|
+
for (const m of numMatches) {
|
|
638
|
+
caps[m[1]] = parseInt(m[2], 10);
|
|
639
|
+
}
|
|
640
|
+
return Object.keys(caps).length > 0 ? caps : void 0;
|
|
641
|
+
}
|
|
642
|
+
function parseModelFile(content) {
|
|
643
|
+
const name = getName(content);
|
|
644
|
+
if (!name) return null;
|
|
645
|
+
return {
|
|
646
|
+
name,
|
|
647
|
+
provider: getProvider(content),
|
|
648
|
+
model: getModel(content),
|
|
649
|
+
inputPrice: getInputPrice(content),
|
|
650
|
+
outputPrice: getOutputPrice(content),
|
|
651
|
+
cachedPrice: getCachedPrice(content),
|
|
652
|
+
includedProviders: getIncludedProviders(content),
|
|
653
|
+
fallbacks: getFallbacks(content),
|
|
654
|
+
providerTools: getProviderTools(content),
|
|
655
|
+
capabilities: getCapabilities(content)
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
|
|
581
659
|
// src/sdk/generators/generateModelFile.ts
|
|
582
|
-
function generateModelFile(data) {
|
|
660
|
+
function generateModelFile(data, options) {
|
|
661
|
+
const { providerName, providerPackage } = options;
|
|
583
662
|
const lines = [
|
|
584
663
|
`import { defineModel } from '@standardagents/builder';`,
|
|
664
|
+
`import { ${providerName} } from '${providerPackage}';`,
|
|
585
665
|
"",
|
|
586
666
|
`export default defineModel({`,
|
|
587
667
|
` name: '${escapeString(data.name)}',`,
|
|
588
|
-
` provider:
|
|
668
|
+
` provider: ${providerName},`,
|
|
589
669
|
` model: '${escapeString(data.model)}',`
|
|
590
670
|
];
|
|
591
671
|
if (data.includedProviders && data.includedProviders.length > 0) {
|
|
@@ -594,6 +674,9 @@ function generateModelFile(data) {
|
|
|
594
674
|
if (data.fallbacks && data.fallbacks.length > 0) {
|
|
595
675
|
lines.push(` fallbacks: ${JSON.stringify(data.fallbacks)},`);
|
|
596
676
|
}
|
|
677
|
+
if (data.providerTools && data.providerTools.length > 0) {
|
|
678
|
+
lines.push(` providerTools: ${JSON.stringify(data.providerTools)},`);
|
|
679
|
+
}
|
|
597
680
|
if (data.inputPrice !== void 0) {
|
|
598
681
|
lines.push(` inputPrice: ${data.inputPrice},`);
|
|
599
682
|
}
|
|
@@ -603,6 +686,36 @@ function generateModelFile(data) {
|
|
|
603
686
|
if (data.cachedPrice !== void 0) {
|
|
604
687
|
lines.push(` cachedPrice: ${data.cachedPrice},`);
|
|
605
688
|
}
|
|
689
|
+
if (data.capabilities && Object.keys(data.capabilities).length > 0) {
|
|
690
|
+
const caps = data.capabilities;
|
|
691
|
+
const capLines = [];
|
|
692
|
+
if (caps.supportsImages !== void 0) {
|
|
693
|
+
capLines.push(` supportsImages: ${caps.supportsImages},`);
|
|
694
|
+
}
|
|
695
|
+
if (caps.supportsToolCalls !== void 0) {
|
|
696
|
+
capLines.push(` supportsToolCalls: ${caps.supportsToolCalls},`);
|
|
697
|
+
}
|
|
698
|
+
if (caps.supportsStreaming !== void 0) {
|
|
699
|
+
capLines.push(` supportsStreaming: ${caps.supportsStreaming},`);
|
|
700
|
+
}
|
|
701
|
+
if (caps.supportsJsonMode !== void 0) {
|
|
702
|
+
capLines.push(` supportsJsonMode: ${caps.supportsJsonMode},`);
|
|
703
|
+
}
|
|
704
|
+
if (caps.maxContextTokens !== void 0) {
|
|
705
|
+
capLines.push(` maxContextTokens: ${caps.maxContextTokens},`);
|
|
706
|
+
}
|
|
707
|
+
if (caps.maxOutputTokens !== void 0) {
|
|
708
|
+
capLines.push(` maxOutputTokens: ${caps.maxOutputTokens},`);
|
|
709
|
+
}
|
|
710
|
+
if (caps.reasoningLevels !== void 0) {
|
|
711
|
+
capLines.push(` reasoningLevels: ${JSON.stringify(caps.reasoningLevels)},`);
|
|
712
|
+
}
|
|
713
|
+
if (capLines.length > 0) {
|
|
714
|
+
lines.push(` capabilities: {`);
|
|
715
|
+
lines.push(...capLines);
|
|
716
|
+
lines.push(` },`);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
606
719
|
lines.push(`});`);
|
|
607
720
|
lines.push("");
|
|
608
721
|
return lines.join("\n");
|
|
@@ -857,6 +970,12 @@ function formatToolConfig(config) {
|
|
|
857
970
|
if (config.init_user_message_property !== void 0 && config.init_user_message_property !== null) {
|
|
858
971
|
parts.push(`initUserMessageProperty: '${escapeString2(config.init_user_message_property)}'`);
|
|
859
972
|
}
|
|
973
|
+
if (config.init_attachments_property !== void 0 && config.init_attachments_property !== null) {
|
|
974
|
+
parts.push(`initAttachmentsProperty: '${escapeString2(config.init_attachments_property)}'`);
|
|
975
|
+
}
|
|
976
|
+
if (config.tenvs && Object.keys(config.tenvs).length > 0) {
|
|
977
|
+
parts.push(`tenvs: ${JSON.stringify(config.tenvs)}`);
|
|
978
|
+
}
|
|
860
979
|
return `{ ${parts.join(", ")} }`;
|
|
861
980
|
}
|
|
862
981
|
function formatReasoningConfig(reasoning) {
|
|
@@ -989,6 +1108,9 @@ function generateAgentFile(data) {
|
|
|
989
1108
|
if (data.toolDescription) {
|
|
990
1109
|
lines.push(` toolDescription: '${escapeString3(data.toolDescription)}',`);
|
|
991
1110
|
}
|
|
1111
|
+
if (data.tenvs && Object.keys(data.tenvs).length > 0) {
|
|
1112
|
+
lines.push(` tenvs: ${JSON.stringify(data.tenvs)},`);
|
|
1113
|
+
}
|
|
992
1114
|
lines.push(`});`);
|
|
993
1115
|
lines.push("");
|
|
994
1116
|
return lines.join("\n");
|
|
@@ -1025,8 +1147,15 @@ function escapeString3(str) {
|
|
|
1025
1147
|
}
|
|
1026
1148
|
|
|
1027
1149
|
// src/sdk/persistence/index.ts
|
|
1150
|
+
var PROVIDER_PACKAGE_MAP = {
|
|
1151
|
+
openai: { name: "openai", package: "@standardagents/openai" },
|
|
1152
|
+
openrouter: { name: "openrouter", package: "@standardagents/openrouter" },
|
|
1153
|
+
anthropic: { name: "anthropic", package: "@standardagents/anthropic" },
|
|
1154
|
+
google: { name: "google", package: "@standardagents/google" },
|
|
1155
|
+
test: { name: "test", package: "@standardagents/builder/test" }
|
|
1156
|
+
};
|
|
1028
1157
|
function nameToFilename(name) {
|
|
1029
|
-
return name.replace(/[/\\]/g, "__").replace(/[:*?"
|
|
1158
|
+
return name.replace(/[/\\]/g, "__").replace(/[:*?"<>|.]/g, "_").replace(/-/g, "_");
|
|
1030
1159
|
}
|
|
1031
1160
|
function getModelFilePath(modelsDir, name) {
|
|
1032
1161
|
const filename = nameToFilename(name);
|
|
@@ -1048,7 +1177,17 @@ async function saveModel(modelsDir, data, overwrite = false) {
|
|
|
1048
1177
|
error: `Model file already exists: ${filePath}. Use update to modify existing models.`
|
|
1049
1178
|
};
|
|
1050
1179
|
}
|
|
1051
|
-
const
|
|
1180
|
+
const providerInfo = PROVIDER_PACKAGE_MAP[data.provider];
|
|
1181
|
+
if (!providerInfo) {
|
|
1182
|
+
return {
|
|
1183
|
+
success: false,
|
|
1184
|
+
error: `Unknown provider '${data.provider}'. Must be one of: ${Object.keys(PROVIDER_PACKAGE_MAP).join(", ")}`
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
const content = generateModelFile(data, {
|
|
1188
|
+
providerName: providerInfo.name,
|
|
1189
|
+
providerPackage: providerInfo.package
|
|
1190
|
+
});
|
|
1052
1191
|
await fs2.promises.writeFile(filePath, content, "utf-8");
|
|
1053
1192
|
return {
|
|
1054
1193
|
success: true,
|
|
@@ -1112,7 +1251,7 @@ function validateModelData(data) {
|
|
|
1112
1251
|
if (!data.provider || typeof data.provider !== "string") {
|
|
1113
1252
|
return "Model provider is required and must be a string";
|
|
1114
1253
|
}
|
|
1115
|
-
const validProviders =
|
|
1254
|
+
const validProviders = Object.keys(PROVIDER_PACKAGE_MAP);
|
|
1116
1255
|
if (!validProviders.includes(data.provider)) {
|
|
1117
1256
|
return `Invalid provider '${data.provider}'. Must be one of: ${validProviders.join(", ")}`;
|
|
1118
1257
|
}
|
|
@@ -1636,6 +1775,8 @@ var VIRTUAL_AGENTS_ID = "virtual:@standardagents-agents";
|
|
|
1636
1775
|
var RESOLVED_VIRTUAL_AGENTS_ID = "\0" + VIRTUAL_AGENTS_ID;
|
|
1637
1776
|
var VIRTUAL_EFFECTS_ID = "virtual:@standardagents-effects";
|
|
1638
1777
|
var RESOLVED_VIRTUAL_EFFECTS_ID = "\0" + VIRTUAL_EFFECTS_ID;
|
|
1778
|
+
var VIRTUAL_PROVIDERS_ID = "virtual:@standardagents-providers";
|
|
1779
|
+
var RESOLVED_VIRTUAL_PROVIDERS_ID = "\0" + VIRTUAL_PROVIDERS_ID;
|
|
1639
1780
|
var VIRTUAL_BUILDER_ID = "virtual:@standardagents/builder";
|
|
1640
1781
|
var RESOLVED_VIRTUAL_BUILDER_ID = "\0" + VIRTUAL_BUILDER_ID;
|
|
1641
1782
|
function scanApiDirectory(dir, baseRoute = "") {
|
|
@@ -2112,6 +2253,9 @@ function agentbuilder(options = {}) {
|
|
|
2112
2253
|
];
|
|
2113
2254
|
const depsToInclude = [
|
|
2114
2255
|
"zod",
|
|
2256
|
+
"zod/v3",
|
|
2257
|
+
"zod/v4",
|
|
2258
|
+
"zod/v4/core",
|
|
2115
2259
|
"openai"
|
|
2116
2260
|
];
|
|
2117
2261
|
config.optimizeDeps = config.optimizeDeps || {};
|
|
@@ -2152,6 +2296,9 @@ function agentbuilder(options = {}) {
|
|
|
2152
2296
|
if (id === VIRTUAL_EFFECTS_ID) {
|
|
2153
2297
|
return RESOLVED_VIRTUAL_EFFECTS_ID;
|
|
2154
2298
|
}
|
|
2299
|
+
if (id === VIRTUAL_PROVIDERS_ID) {
|
|
2300
|
+
return RESOLVED_VIRTUAL_PROVIDERS_ID;
|
|
2301
|
+
}
|
|
2155
2302
|
if (id === VIRTUAL_BUILDER_ID) {
|
|
2156
2303
|
return RESOLVED_VIRTUAL_BUILDER_ID;
|
|
2157
2304
|
}
|
|
@@ -2227,9 +2374,56 @@ function isPublicRoute(routePath) {
|
|
|
2227
2374
|
return true;
|
|
2228
2375
|
}
|
|
2229
2376
|
|
|
2377
|
+
// Provider icon routes are public (used by <img src>)
|
|
2378
|
+
if (routePath.startsWith('/api/providers/') && routePath.includes('/icon')) {
|
|
2379
|
+
return true;
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2230
2382
|
return false;
|
|
2231
2383
|
}
|
|
2232
2384
|
|
|
2385
|
+
// CORS headers for API responses
|
|
2386
|
+
const CORS_HEADERS = {
|
|
2387
|
+
"Access-Control-Allow-Origin": "*",
|
|
2388
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
2389
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
|
|
2390
|
+
"Access-Control-Max-Age": "86400",
|
|
2391
|
+
};
|
|
2392
|
+
|
|
2393
|
+
// Helper to create headers with CORS
|
|
2394
|
+
function corsHeaders(contentType) {
|
|
2395
|
+
return {
|
|
2396
|
+
"Content-Type": contentType,
|
|
2397
|
+
...CORS_HEADERS,
|
|
2398
|
+
};
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
// Helper to add CORS headers to any Response without touching the body
|
|
2402
|
+
function addCorsHeaders(response) {
|
|
2403
|
+
// Skip WebSocket upgrade responses - they can't be wrapped
|
|
2404
|
+
if (response.status === 101) {
|
|
2405
|
+
return response;
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
// Skip if already has CORS headers
|
|
2409
|
+
if (response.headers.has("Access-Control-Allow-Origin")) {
|
|
2410
|
+
return response;
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
// Create new headers with CORS added
|
|
2414
|
+
const newHeaders = new Headers(response.headers);
|
|
2415
|
+
for (const [key, value] of Object.entries(CORS_HEADERS)) {
|
|
2416
|
+
newHeaders.set(key, value);
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
// Return new Response with same body stream (not cloned, just transferred)
|
|
2420
|
+
return new Response(response.body, {
|
|
2421
|
+
status: response.status,
|
|
2422
|
+
statusText: response.statusText,
|
|
2423
|
+
headers: newHeaders,
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2233
2427
|
export async function router(request, env) {
|
|
2234
2428
|
const url = new URL(request.url);
|
|
2235
2429
|
const pathname = url.pathname;
|
|
@@ -2239,6 +2433,14 @@ export async function router(request, env) {
|
|
|
2239
2433
|
return null;
|
|
2240
2434
|
}
|
|
2241
2435
|
|
|
2436
|
+
// Handle CORS preflight requests
|
|
2437
|
+
if (request.method === "OPTIONS") {
|
|
2438
|
+
return new Response(null, {
|
|
2439
|
+
status: 204,
|
|
2440
|
+
headers: CORS_HEADERS,
|
|
2441
|
+
});
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2242
2444
|
// Strip mount point prefix for route matching, ensuring we keep the leading slash
|
|
2243
2445
|
let routePath = pathname.slice(MOUNT_POINT.length) || "/";
|
|
2244
2446
|
if (!routePath.startsWith('/')) {
|
|
@@ -2273,7 +2475,7 @@ ${threadRouteCode}
|
|
|
2273
2475
|
|
|
2274
2476
|
// If requireAuth returns a Response, it's an error (401)
|
|
2275
2477
|
if (authResult instanceof Response) {
|
|
2276
|
-
return authResult;
|
|
2478
|
+
return addCorsHeaders(authResult);
|
|
2277
2479
|
}
|
|
2278
2480
|
|
|
2279
2481
|
authContext = authResult;
|
|
@@ -2292,16 +2494,17 @@ ${threadRouteCode}
|
|
|
2292
2494
|
const result = await controller(context);
|
|
2293
2495
|
|
|
2294
2496
|
if (result instanceof Response) {
|
|
2295
|
-
return result;
|
|
2497
|
+
return addCorsHeaders(result);
|
|
2296
2498
|
}
|
|
2297
2499
|
if (typeof result === "string") {
|
|
2298
2500
|
return new Response(result, {
|
|
2299
|
-
headers:
|
|
2300
|
-
"Content-Type": "text/plain",
|
|
2301
|
-
},
|
|
2501
|
+
headers: corsHeaders("text/plain"),
|
|
2302
2502
|
});
|
|
2303
2503
|
}
|
|
2304
|
-
|
|
2504
|
+
// JSON responses get CORS headers
|
|
2505
|
+
return new Response(JSON.stringify(result), {
|
|
2506
|
+
headers: corsHeaders("application/json"),
|
|
2507
|
+
});
|
|
2305
2508
|
}
|
|
2306
2509
|
|
|
2307
2510
|
// Serve UI for all other routes (SPA fallback)
|
|
@@ -2496,6 +2699,30 @@ ${effectsCode}
|
|
|
2496
2699
|
};
|
|
2497
2700
|
|
|
2498
2701
|
export const effectNames = ${JSON.stringify(effects.filter((e) => !e.error).map((e) => e.name))};
|
|
2702
|
+
`;
|
|
2703
|
+
}
|
|
2704
|
+
if (id === RESOLVED_VIRTUAL_PROVIDERS_ID) {
|
|
2705
|
+
const firstPartyProviders = [
|
|
2706
|
+
{ name: "openai", package: "@standardagents/openai", label: "OpenAI", envKey: "OPENAI_API_KEY" },
|
|
2707
|
+
{ name: "openrouter", package: "@standardagents/openrouter", label: "OpenRouter", envKey: "OPENROUTER_API_KEY" }
|
|
2708
|
+
];
|
|
2709
|
+
const customProviders = (options.providers || []).map((pkg) => ({
|
|
2710
|
+
name: pkg.split("/").pop() || pkg,
|
|
2711
|
+
package: pkg,
|
|
2712
|
+
label: pkg.split("/").pop() || pkg,
|
|
2713
|
+
envKey: `${(pkg.split("/").pop() || pkg).toUpperCase().replace(/-/g, "_")}_API_KEY`,
|
|
2714
|
+
isCustom: true
|
|
2715
|
+
}));
|
|
2716
|
+
const allProviders = [...firstPartyProviders, ...customProviders];
|
|
2717
|
+
return `// Virtual providers module - lists available LLM provider packages
|
|
2718
|
+
export const providers = ${JSON.stringify(allProviders, null, 2)};
|
|
2719
|
+
|
|
2720
|
+
export const providerNames = ${JSON.stringify(allProviders.map((p) => p.name))};
|
|
2721
|
+
|
|
2722
|
+
// Provider factories - dynamic imports for code splitting
|
|
2723
|
+
export const providerFactories = {
|
|
2724
|
+
${allProviders.map((p) => ` "${p.name}": async () => (await import("${p.package}")).${p.name},`).join("\n")}
|
|
2725
|
+
};
|
|
2499
2726
|
`;
|
|
2500
2727
|
}
|
|
2501
2728
|
if (id === RESOLVED_VIRTUAL_BUILDER_ID) {
|
|
@@ -2609,7 +2836,8 @@ import { DurableAgentBuilder as _BaseDurableAgentBuilder } from '@standardagents
|
|
|
2609
2836
|
|
|
2610
2837
|
// Import sip WASM module and initializer
|
|
2611
2838
|
// Static import allows workerd to pre-compile the WASM at bundle time
|
|
2612
|
-
|
|
2839
|
+
// WASM is bundled in builder's dist to avoid transitive dependency resolution issues
|
|
2840
|
+
import _sipWasm from '@standardagents/builder/dist/sip.wasm';
|
|
2613
2841
|
import { initWithWasmModule as _initSipWasm } from '@standardagents/sip';
|
|
2614
2842
|
|
|
2615
2843
|
// Re-export router from virtual:@standardagents-routes
|
|
@@ -2748,51 +2976,26 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2748
2976
|
try {
|
|
2749
2977
|
const filePath = path3.join(modelsDir, file);
|
|
2750
2978
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
2751
|
-
const
|
|
2752
|
-
|
|
2753
|
-
const
|
|
2754
|
-
const getInputPrice = (c) => {
|
|
2755
|
-
const match = c.match(/inputPrice:\s*([\d.]+)/);
|
|
2756
|
-
return match ? parseFloat(match[1]) : void 0;
|
|
2757
|
-
};
|
|
2758
|
-
const getOutputPrice = (c) => {
|
|
2759
|
-
const match = c.match(/outputPrice:\s*([\d.]+)/);
|
|
2760
|
-
return match ? parseFloat(match[1]) : void 0;
|
|
2761
|
-
};
|
|
2762
|
-
const getCachedPrice = (c) => {
|
|
2763
|
-
const match = c.match(/cachedPrice:\s*([\d.]+)/);
|
|
2764
|
-
return match ? parseFloat(match[1]) : void 0;
|
|
2765
|
-
};
|
|
2766
|
-
const getIncludedProviders = (c) => {
|
|
2767
|
-
const match = c.match(/includedProviders:\s*\[([^\]]*)\]/);
|
|
2768
|
-
if (!match) return void 0;
|
|
2769
|
-
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
2770
|
-
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
2771
|
-
};
|
|
2772
|
-
const getFallbacks = (c) => {
|
|
2773
|
-
const match = c.match(/fallbacks:\s*\[([^\]]*)\]/);
|
|
2774
|
-
if (!match) return [];
|
|
2775
|
-
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
2776
|
-
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
2777
|
-
};
|
|
2778
|
-
const name = getName(content);
|
|
2779
|
-
if (!name) return null;
|
|
2780
|
-
const fallbacks = getFallbacks(content);
|
|
2781
|
-
const fallbackObjects = fallbacks.map((fallbackName, index) => ({
|
|
2979
|
+
const parsed = parseModelFile(content);
|
|
2980
|
+
if (!parsed || !parsed.name) return null;
|
|
2981
|
+
const fallbackObjects = parsed.fallbacks.map((fallbackName, index) => ({
|
|
2782
2982
|
id: fallbackName,
|
|
2783
2983
|
name: fallbackName,
|
|
2784
2984
|
order: index
|
|
2785
2985
|
}));
|
|
2786
2986
|
return {
|
|
2787
|
-
id: name,
|
|
2788
|
-
name,
|
|
2789
|
-
provider:
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2987
|
+
id: parsed.name,
|
|
2988
|
+
name: parsed.name,
|
|
2989
|
+
provider: parsed.provider,
|
|
2990
|
+
provider_id: parsed.provider,
|
|
2991
|
+
model: parsed.model,
|
|
2992
|
+
input_price: parsed.inputPrice,
|
|
2993
|
+
output_price: parsed.outputPrice,
|
|
2994
|
+
cached_price: parsed.cachedPrice,
|
|
2995
|
+
included_providers: parsed.includedProviders,
|
|
2795
2996
|
fallbacks: fallbackObjects,
|
|
2997
|
+
providerTools: parsed.providerTools,
|
|
2998
|
+
capabilities: parsed.capabilities,
|
|
2796
2999
|
created_at: Math.floor(Date.now() / 1e3)
|
|
2797
3000
|
};
|
|
2798
3001
|
} catch (error) {
|
|
@@ -2958,9 +3161,9 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2958
3161
|
try {
|
|
2959
3162
|
const filePath = path3.join(promptsDir, file);
|
|
2960
3163
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
2961
|
-
const
|
|
3164
|
+
const getName2 = (c) => c.match(/name:\s*['"]([^'"]+)['"]/)?.[1];
|
|
2962
3165
|
const getToolDescription = (c) => c.match(/toolDescription:\s*['"]([^'"]+)['"]/)?.[1];
|
|
2963
|
-
const
|
|
3166
|
+
const getModel2 = (c) => c.match(/model:\s*['"]([^'"]+)['"]/)?.[1];
|
|
2964
3167
|
const getIncludeChat = (c) => c.match(/includeChat:\s*(true|false)/)?.[1] === "true";
|
|
2965
3168
|
const getIncludePastTools = (c) => c.match(/includePastTools:\s*(true|false)/)?.[1] === "true";
|
|
2966
3169
|
const getParallelToolCalls = (c) => c.match(/parallelToolCalls:\s*(true|false)/)?.[1] === "true";
|
|
@@ -2980,9 +3183,9 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2980
3183
|
if (arrayMatch) return arrayMatch[1];
|
|
2981
3184
|
return "";
|
|
2982
3185
|
};
|
|
2983
|
-
const name =
|
|
3186
|
+
const name = getName2(content);
|
|
2984
3187
|
if (!name) return null;
|
|
2985
|
-
const modelId =
|
|
3188
|
+
const modelId = getModel2(content);
|
|
2986
3189
|
const modelDef = modelId ? modelMap[modelId] : null;
|
|
2987
3190
|
return {
|
|
2988
3191
|
id: name,
|
|
@@ -3153,7 +3356,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
3153
3356
|
try {
|
|
3154
3357
|
const filePath = path3.join(agentsDir, file);
|
|
3155
3358
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
3156
|
-
const
|
|
3359
|
+
const getName2 = (c) => c.match(/name:\s*['"]([^'"]+)['"]/)?.[1];
|
|
3157
3360
|
const getTitle = (c) => c.match(/title:\s*['"]([^'"]+)['"]/)?.[1];
|
|
3158
3361
|
const getType = (c) => c.match(/type:\s*['"]([^'"]+)['"]/)?.[1];
|
|
3159
3362
|
const getDefaultPrompt = (c) => c.match(/defaultPrompt:\s*['"]([^'"]+)['"]/)?.[1];
|
|
@@ -3164,7 +3367,14 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
3164
3367
|
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
3165
3368
|
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
3166
3369
|
};
|
|
3167
|
-
const
|
|
3370
|
+
const getSidePrompt = (c, side) => {
|
|
3371
|
+
const sideRegex = new RegExp(`${side}:\\s*\\{([^}]+)\\}`, "s");
|
|
3372
|
+
const sideMatch = c.match(sideRegex);
|
|
3373
|
+
if (!sideMatch) return null;
|
|
3374
|
+
const promptMatch = sideMatch[1].match(/prompt:\s*['"]([^'"]+)['"]/);
|
|
3375
|
+
return promptMatch ? promptMatch[1] : null;
|
|
3376
|
+
};
|
|
3377
|
+
const name = getName2(content);
|
|
3168
3378
|
if (!name) return null;
|
|
3169
3379
|
return {
|
|
3170
3380
|
id: name,
|
|
@@ -3174,6 +3384,8 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
3174
3384
|
default_prompt: getDefaultPrompt(content) || "",
|
|
3175
3385
|
default_model: getDefaultModel(content) || "",
|
|
3176
3386
|
tools: getTools(content),
|
|
3387
|
+
side_a_agent_prompt: getSidePrompt(content, "sideA"),
|
|
3388
|
+
side_b_agent_prompt: getSidePrompt(content, "sideB"),
|
|
3177
3389
|
created_at: Math.floor(Date.now() / 1e3)
|
|
3178
3390
|
};
|
|
3179
3391
|
} catch (error) {
|