@standardagents/builder 0.13.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/plugin.d.ts CHANGED
@@ -11,7 +11,7 @@ interface AgentPluginOptions {
11
11
  effectsDir?: string;
12
12
  /**
13
13
  * Additional provider packages to expose in the UI.
14
- * First-party providers (@standardagents/openai, @standardagents/openrouter) are always included.
14
+ * First-party providers (@standardagents/cerebras, @standardagents/openai, @standardagents/openrouter) are always included.
15
15
  * @example ['my-custom-provider', '@company/custom-openai']
16
16
  */
17
17
  providers?: string[];
package/dist/plugin.js CHANGED
@@ -1382,14 +1382,89 @@ function formatSessionBinding(binding) {
1382
1382
  return `{ ${parts.join(", ")} }`;
1383
1383
  }
1384
1384
 
1385
+ // src/providers/catalog.ts
1386
+ var FIRST_PARTY_PROVIDERS = [
1387
+ {
1388
+ name: "cloudflare",
1389
+ package: "@standardagents/cloudflare",
1390
+ label: "Cloudflare Workers AI",
1391
+ envKeys: ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"]
1392
+ },
1393
+ {
1394
+ name: "cerebras",
1395
+ package: "@standardagents/cerebras",
1396
+ label: "Cerebras",
1397
+ envKeys: ["CEREBRAS_API_KEY"]
1398
+ },
1399
+ {
1400
+ name: "google",
1401
+ package: "@standardagents/google",
1402
+ label: "Google Gemini",
1403
+ envKeys: ["GOOGLE_API_KEY"]
1404
+ },
1405
+ {
1406
+ name: "groq",
1407
+ package: "@standardagents/groq",
1408
+ label: "Groq",
1409
+ envKeys: ["GROQ_API_KEY"]
1410
+ },
1411
+ {
1412
+ name: "openai",
1413
+ package: "@standardagents/openai",
1414
+ label: "OpenAI",
1415
+ envKeys: ["OPENAI_API_KEY"]
1416
+ },
1417
+ {
1418
+ name: "openrouter",
1419
+ package: "@standardagents/openrouter",
1420
+ label: "OpenRouter",
1421
+ envKeys: ["OPENROUTER_API_KEY"]
1422
+ },
1423
+ {
1424
+ name: "xai",
1425
+ package: "@standardagents/xai",
1426
+ label: "xAI",
1427
+ envKeys: ["XAI_API_KEY"]
1428
+ }
1429
+ ];
1430
+ function humanizeProviderName(name) {
1431
+ return name.split(/[-_]/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
1432
+ }
1433
+ function packageToCustomProvider(pkg) {
1434
+ const name = pkg.split("/").pop() || pkg;
1435
+ return {
1436
+ name,
1437
+ package: pkg,
1438
+ label: humanizeProviderName(name),
1439
+ envKeys: [`${name.toUpperCase().replace(/-/g, "_")}_API_KEY`],
1440
+ isCustom: true
1441
+ };
1442
+ }
1443
+ function buildInstalledProviderCatalog(customProviderPackages = []) {
1444
+ const providers = [...FIRST_PARTY_PROVIDERS];
1445
+ const seen = new Set(providers.map((provider) => provider.name));
1446
+ for (const pkg of customProviderPackages) {
1447
+ const provider = packageToCustomProvider(pkg);
1448
+ if (seen.has(provider.name)) continue;
1449
+ providers.push(provider);
1450
+ seen.add(provider.name);
1451
+ }
1452
+ return providers;
1453
+ }
1454
+ function buildProviderPackageMap(customProviderPackages = []) {
1455
+ return Object.fromEntries(
1456
+ buildInstalledProviderCatalog(customProviderPackages).map((provider) => [
1457
+ provider.name,
1458
+ {
1459
+ name: provider.name,
1460
+ package: provider.package
1461
+ }
1462
+ ])
1463
+ );
1464
+ }
1465
+
1385
1466
  // src/sdk/persistence/index.ts
1386
- var PROVIDER_PACKAGE_MAP = {
1387
- openai: { name: "openai", package: "@standardagents/openai" },
1388
- openrouter: { name: "openrouter", package: "@standardagents/openrouter" },
1389
- anthropic: { name: "anthropic", package: "@standardagents/anthropic" },
1390
- google: { name: "google", package: "@standardagents/google" },
1391
- test: { name: "test", package: "@standardagents/builder/test" }
1392
- };
1467
+ var defaultProviderPackageMap = buildProviderPackageMap();
1393
1468
  function nameToFilename(name) {
1394
1469
  return name.replace(/[/\\]/g, "__").replace(/[:*?"<>|.]/g, "_").replace(/-/g, "_");
1395
1470
  }
@@ -1401,7 +1476,7 @@ function modelExists(modelsDir, name) {
1401
1476
  const filePath = getModelFilePath(modelsDir, name);
1402
1477
  return fs4__default.existsSync(filePath);
1403
1478
  }
1404
- async function saveModel(modelsDir, data, overwrite = false) {
1479
+ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap = defaultProviderPackageMap) {
1405
1480
  try {
1406
1481
  if (!fs4__default.existsSync(modelsDir)) {
1407
1482
  fs4__default.mkdirSync(modelsDir, { recursive: true });
@@ -1413,11 +1488,11 @@ async function saveModel(modelsDir, data, overwrite = false) {
1413
1488
  error: `Model file already exists: ${filePath}. Use update to modify existing models.`
1414
1489
  };
1415
1490
  }
1416
- const providerInfo = PROVIDER_PACKAGE_MAP[data.provider];
1491
+ const providerInfo = providerPackageMap[data.provider];
1417
1492
  if (!providerInfo) {
1418
1493
  return {
1419
1494
  success: false,
1420
- error: `Unknown provider '${data.provider}'. Must be one of: ${Object.keys(PROVIDER_PACKAGE_MAP).join(", ")}`
1495
+ error: `Unknown provider '${data.provider}'. Must be one of: ${Object.keys(providerPackageMap).join(", ")}`
1421
1496
  };
1422
1497
  }
1423
1498
  const content = generateModelFile(data, {
@@ -1480,7 +1555,7 @@ function transformModelData(data) {
1480
1555
  }
1481
1556
  return transformed;
1482
1557
  }
1483
- function validateModelData(data) {
1558
+ function validateModelDataWithProviders(data, providerPackageMap) {
1484
1559
  const errors = {};
1485
1560
  if (!data.name || typeof data.name !== "string") {
1486
1561
  errors["name"] = "Model name is required";
@@ -1488,7 +1563,7 @@ function validateModelData(data) {
1488
1563
  if (!data.provider || typeof data.provider !== "string") {
1489
1564
  errors["provider"] = "Provider is required";
1490
1565
  } else {
1491
- const validProviders = Object.keys(PROVIDER_PACKAGE_MAP);
1566
+ const validProviders = Object.keys(providerPackageMap);
1492
1567
  if (!validProviders.includes(data.provider)) {
1493
1568
  errors["provider"] = `Invalid provider '${data.provider}'. Must be one of: ${validProviders.join(", ")}`;
1494
1569
  }
@@ -5274,6 +5349,8 @@ function agentbuilder(options = {}) {
5274
5349
  const agentsDir = options.agentsDir ? path8__default.resolve(process.cwd(), options.agentsDir) : path8__default.resolve(process.cwd(), "agents/agents");
5275
5350
  const effectsDir = options.effectsDir ? path8__default.resolve(process.cwd(), options.effectsDir) : path8__default.resolve(process.cwd(), "agents/effects");
5276
5351
  const outputDir = path8__default.resolve(process.cwd(), ".agents");
5352
+ const installedProviders = buildInstalledProviderCatalog(options.providers || []);
5353
+ const installedProviderPackageMap = buildProviderPackageMap(options.providers || []);
5277
5354
  const typeGenConfig = {
5278
5355
  modelsDir,
5279
5356
  promptsDir,
@@ -6245,18 +6322,7 @@ export const effectNames = ${JSON.stringify(effects.filter((e) => !e.error).map(
6245
6322
  `;
6246
6323
  }
6247
6324
  if (id === RESOLVED_VIRTUAL_PROVIDERS_ID) {
6248
- const firstPartyProviders = [
6249
- { name: "openai", package: "@standardagents/openai", label: "OpenAI", envKey: "OPENAI_API_KEY" },
6250
- { name: "openrouter", package: "@standardagents/openrouter", label: "OpenRouter", envKey: "OPENROUTER_API_KEY" }
6251
- ];
6252
- const customProviders = (options.providers || []).map((pkg) => ({
6253
- name: pkg.split("/").pop() || pkg,
6254
- package: pkg,
6255
- label: pkg.split("/").pop() || pkg,
6256
- envKey: `${(pkg.split("/").pop() || pkg).toUpperCase().replace(/-/g, "_")}_API_KEY`,
6257
- isCustom: true
6258
- }));
6259
- const allProviders = [...firstPartyProviders, ...customProviders];
6325
+ const allProviders = installedProviders;
6260
6326
  return `// Virtual providers module - lists available LLM provider packages
6261
6327
  export const providers = ${JSON.stringify(allProviders, null, 2)};
6262
6328
 
@@ -6546,11 +6612,11 @@ export function getVisibleToolNames() {
6546
6612
  import { DurableThread as _BaseDurableThread } from '@standardagents/builder/runtime';
6547
6613
  import { DurableAgentBuilder as _BaseDurableAgentBuilder } from '@standardagents/builder/runtime';
6548
6614
 
6549
- // Import sip WASM module and initializer
6615
+ // Import sip WASM module and readiness helper
6550
6616
  // Static import allows workerd to pre-compile the WASM at bundle time
6551
6617
  // WASM is bundled in builder's dist to avoid transitive dependency resolution issues
6552
6618
  import _sipWasm from '@standardagents/builder/dist/sip.wasm';
6553
- import { initWithWasmModule as _initSipWasm } from '@standardagents/sip';
6619
+ import { ready as _initSipWasm } from '@standardagents/sip';
6554
6620
 
6555
6621
  // Re-export router from virtual:@standardagents-routes
6556
6622
  export { router } from 'virtual:@standardagents-routes';
@@ -6594,7 +6660,7 @@ export class DurableThread extends _BaseDurableThread {
6594
6660
  // blockConcurrencyWhile ensures WASM is ready before handling any requests
6595
6661
  // Pass the statically imported WASM module for workerd to pre-compile
6596
6662
  ctx.blockConcurrencyWhile(async () => {
6597
- await _initSipWasm(_sipWasm);
6663
+ await _initSipWasm({ wasm: _sipWasm });
6598
6664
  });
6599
6665
  }
6600
6666
 
@@ -6695,7 +6761,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6695
6761
  try {
6696
6762
  const rawBody = await parseRequestBody(req);
6697
6763
  const body = transformModelData(rawBody);
6698
- const fieldErrors = validateModelData(body);
6764
+ const fieldErrors = validateModelDataWithProviders(body, installedProviderPackageMap);
6699
6765
  if (fieldErrors) {
6700
6766
  res.statusCode = 400;
6701
6767
  res.setHeader("Content-Type", "application/json");
@@ -6708,7 +6774,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6708
6774
  res.end(JSON.stringify({ error: `Model '${body.name}' already exists. Use PUT to update.` }));
6709
6775
  return;
6710
6776
  }
6711
- const result = await saveModel(modelsDir, body, false);
6777
+ const result = await saveModel(modelsDir, body, false, installedProviderPackageMap);
6712
6778
  if (result.success) {
6713
6779
  await reloadModelsModule(server);
6714
6780
  await reloadRouterModule(server);
@@ -6740,7 +6806,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6740
6806
  const body = transformModelData(rawBody);
6741
6807
  const newName = body.name;
6742
6808
  const isNameChange = newName && newName !== urlModelName;
6743
- const fieldErrors = validateModelData(body);
6809
+ const fieldErrors = validateModelDataWithProviders(body, installedProviderPackageMap);
6744
6810
  if (fieldErrors) {
6745
6811
  res.statusCode = 400;
6746
6812
  res.setHeader("Content-Type", "application/json");
@@ -6758,7 +6824,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6758
6824
  }
6759
6825
  updatedPrompts = await updateModelReferencesInPrompts(promptsDir, urlModelName, newName);
6760
6826
  }
6761
- const result = await saveModel(modelsDir, body, true);
6827
+ const result = await saveModel(modelsDir, body, true, installedProviderPackageMap);
6762
6828
  if (result.success) {
6763
6829
  await reloadModelsModule(server);
6764
6830
  if (updatedPrompts.length > 0) {