@standardagents/builder 0.12.7 → 0.12.9

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.js CHANGED
@@ -1322,49 +1322,55 @@ function transformModelData(data) {
1322
1322
  return transformed;
1323
1323
  }
1324
1324
  function validateModelData(data) {
1325
+ const errors = {};
1325
1326
  if (!data.name || typeof data.name !== "string") {
1326
- return "Model name is required and must be a string";
1327
+ errors["name"] = "Model name is required";
1327
1328
  }
1328
1329
  if (!data.provider || typeof data.provider !== "string") {
1329
- return "Model provider is required and must be a string";
1330
- }
1331
- const validProviders = Object.keys(PROVIDER_PACKAGE_MAP);
1332
- if (!validProviders.includes(data.provider)) {
1333
- return `Invalid provider '${data.provider}'. Must be one of: ${validProviders.join(", ")}`;
1330
+ errors["provider"] = "Provider is required";
1331
+ } else {
1332
+ const validProviders = Object.keys(PROVIDER_PACKAGE_MAP);
1333
+ if (!validProviders.includes(data.provider)) {
1334
+ errors["provider"] = `Invalid provider '${data.provider}'. Must be one of: ${validProviders.join(", ")}`;
1335
+ }
1334
1336
  }
1335
1337
  if (!data.model || typeof data.model !== "string") {
1336
- return "Model ID is required and must be a string";
1338
+ errors["model"] = "Model ID is required";
1337
1339
  }
1338
1340
  if (data.inputPrice !== void 0 && typeof data.inputPrice !== "number") {
1339
- return "inputPrice must be a number";
1341
+ errors["input_price"] = "Input price must be a number";
1340
1342
  }
1341
1343
  if (data.outputPrice !== void 0 && typeof data.outputPrice !== "number") {
1342
- return "outputPrice must be a number";
1344
+ errors["output_price"] = "Output price must be a number";
1343
1345
  }
1344
1346
  if (data.cachedPrice !== void 0 && typeof data.cachedPrice !== "number") {
1345
- return "cachedPrice must be a number";
1347
+ errors["cached_price"] = "Cached price must be a number";
1346
1348
  }
1347
1349
  if (data.fallbacks !== void 0) {
1348
1350
  if (!Array.isArray(data.fallbacks)) {
1349
- return "fallbacks must be an array";
1350
- }
1351
- for (const fallback of data.fallbacks) {
1352
- if (typeof fallback !== "string") {
1353
- return "Each fallback must be a string (model name)";
1351
+ errors["fallbacks"] = "Fallbacks must be an array";
1352
+ } else {
1353
+ for (const fallback of data.fallbacks) {
1354
+ if (typeof fallback !== "string") {
1355
+ errors["fallbacks"] = "Each fallback must be a string (model name)";
1356
+ break;
1357
+ }
1354
1358
  }
1355
1359
  }
1356
1360
  }
1357
1361
  if (data.includedProviders !== void 0) {
1358
1362
  if (!Array.isArray(data.includedProviders)) {
1359
- return "includedProviders must be an array";
1360
- }
1361
- for (const provider of data.includedProviders) {
1362
- if (typeof provider !== "string") {
1363
- return "Each includedProvider must be a string";
1363
+ errors["included_providers"] = "Included providers must be an array";
1364
+ } else {
1365
+ for (const provider of data.includedProviders) {
1366
+ if (typeof provider !== "string") {
1367
+ errors["included_providers"] = "Each included provider must be a string";
1368
+ break;
1369
+ }
1364
1370
  }
1365
1371
  }
1366
1372
  }
1367
- return null;
1373
+ return Object.keys(errors).length > 0 ? errors : null;
1368
1374
  }
1369
1375
  function transformPromptData(data) {
1370
1376
  const transformed = {};
@@ -1395,8 +1401,11 @@ function transformPromptData(data) {
1395
1401
  if (transformed.reasoningEffort) {
1396
1402
  transformed.reasoning.effort = transformed.reasoningEffort;
1397
1403
  }
1398
- if (transformed.reasoningMaxTokens) {
1399
- transformed.reasoning.maxTokens = transformed.reasoningMaxTokens;
1404
+ if (transformed.reasoningMaxTokens !== void 0 && transformed.reasoningMaxTokens !== null && transformed.reasoningMaxTokens !== "") {
1405
+ const num = Number(transformed.reasoningMaxTokens);
1406
+ if (!isNaN(num)) {
1407
+ transformed.reasoning.maxTokens = num;
1408
+ }
1400
1409
  }
1401
1410
  if (transformed.reasoningExclude !== void 0) {
1402
1411
  transformed.reasoning.exclude = transformed.reasoningExclude;
@@ -1500,51 +1509,56 @@ async function renamePrompt(promptsDir, oldName, newName) {
1500
1509
  }
1501
1510
  }
1502
1511
  function validatePromptData(data) {
1512
+ const errors = {};
1503
1513
  if (!data.name || typeof data.name !== "string") {
1504
- return "Prompt name is required and must be a string";
1505
- }
1506
- if (data.name.includes("/")) {
1507
- return "Prompt name cannot contain '/'. Reserved for namespace qualification.";
1514
+ errors["name"] = "Prompt name is required";
1515
+ } else if (data.name.includes("/")) {
1516
+ errors["name"] = "Prompt name cannot contain '/'";
1508
1517
  }
1509
1518
  if (!data.model || typeof data.model !== "string") {
1510
- return "Prompt model is required and must be a string";
1519
+ errors["model_id"] = "Model is required";
1511
1520
  }
1512
1521
  if (data.toolDescription !== void 0 && typeof data.toolDescription !== "string") {
1513
- return "toolDescription must be a string";
1522
+ errors["tool_description"] = "Tool description must be a string";
1514
1523
  }
1515
1524
  if (data.prompt !== void 0 && typeof data.prompt !== "string") {
1516
- return "prompt must be a string";
1525
+ errors["prompt"] = "Prompt must be a string";
1517
1526
  }
1518
- const booleanFields = ["includeChat", "includePastTools", "parallelToolCalls"];
1519
- for (const field of booleanFields) {
1520
- if (data[field] !== void 0 && typeof data[field] !== "boolean") {
1521
- return `${field} must be a boolean`;
1527
+ const booleanFieldMap = {
1528
+ includeChat: "include_chat",
1529
+ includePastTools: "include_past_tools",
1530
+ parallelToolCalls: "parallel_tool_calls"
1531
+ };
1532
+ for (const [camelField, snakeField] of Object.entries(booleanFieldMap)) {
1533
+ if (data[camelField] !== void 0 && typeof data[camelField] !== "boolean") {
1534
+ errors[snakeField] = `${snakeField} must be a boolean`;
1522
1535
  }
1523
1536
  }
1524
1537
  if (data.toolChoice !== void 0) {
1525
1538
  const validChoices = ["auto", "none", "required"];
1526
1539
  if (!validChoices.includes(data.toolChoice)) {
1527
- return `Invalid toolChoice '${data.toolChoice}'. Must be one of: ${validChoices.join(", ")}`;
1540
+ errors["tool_choice"] = `Invalid tool choice '${data.toolChoice}'. Must be one of: ${validChoices.join(", ")}`;
1528
1541
  }
1529
1542
  }
1530
1543
  if (data.tools !== void 0 && !Array.isArray(data.tools)) {
1531
- return "tools must be an array";
1544
+ errors["tools"] = "Tools must be an array";
1532
1545
  }
1533
1546
  if (data.reasoning !== void 0) {
1534
1547
  if (typeof data.reasoning !== "object") {
1535
- return "reasoning must be an object";
1536
- }
1537
- if (data.reasoning.effort !== void 0) {
1538
- const validEfforts = ["low", "medium", "high"];
1539
- if (!validEfforts.includes(data.reasoning.effort)) {
1540
- return `Invalid reasoning.effort '${data.reasoning.effort}'. Must be one of: ${validEfforts.join(", ")}`;
1548
+ errors["reasoning_effort"] = "Reasoning configuration is invalid";
1549
+ } else {
1550
+ if (data.reasoning.effort !== void 0) {
1551
+ const validEfforts = ["low", "medium", "high"];
1552
+ if (!validEfforts.includes(data.reasoning.effort)) {
1553
+ errors["reasoning_effort"] = `Invalid reasoning effort '${data.reasoning.effort}'. Must be one of: ${validEfforts.join(", ")}`;
1554
+ }
1555
+ }
1556
+ if (data.reasoning.maxTokens !== void 0 && typeof data.reasoning.maxTokens !== "number") {
1557
+ errors["reasoning_max_tokens"] = "Max reasoning tokens must be a number";
1541
1558
  }
1542
- }
1543
- if (data.reasoning.maxTokens !== void 0 && typeof data.reasoning.maxTokens !== "number") {
1544
- return "reasoning.maxTokens must be a number";
1545
1559
  }
1546
1560
  }
1547
- return null;
1561
+ return Object.keys(errors).length > 0 ? errors : null;
1548
1562
  }
1549
1563
  function transformAgentData(data) {
1550
1564
  const transformed = {
@@ -1804,69 +1818,65 @@ function escapeRegExp(string) {
1804
1818
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1805
1819
  }
1806
1820
  function validateAgentData(data) {
1821
+ const errors = {};
1807
1822
  if (!data.name || typeof data.name !== "string") {
1808
- return "Agent name is required and must be a string";
1809
- }
1810
- if (data.name.includes("/")) {
1811
- return "Agent name cannot contain '/'. Reserved for namespace qualification.";
1823
+ errors["name"] = "Agent name is required";
1824
+ } else if (data.name.includes("/")) {
1825
+ errors["name"] = "Agent name cannot contain '/'";
1812
1826
  }
1813
1827
  if (data.title !== void 0 && typeof data.title !== "string") {
1814
- return "Agent title must be a string if provided";
1828
+ errors["title"] = "Agent title must be a string";
1815
1829
  }
1816
1830
  if (data.type !== void 0) {
1817
1831
  const validTypes = ["ai_human", "dual_ai"];
1818
1832
  if (!validTypes.includes(data.type)) {
1819
- return `Invalid type '${data.type}'. Must be one of: ${validTypes.join(", ")}`;
1833
+ errors["type"] = `Invalid type '${data.type}'. Must be one of: ${validTypes.join(", ")}`;
1820
1834
  }
1821
1835
  }
1822
1836
  if (!data.sideA || typeof data.sideA !== "object") {
1823
- return "sideA configuration is required";
1824
- }
1825
- if (!data.sideA.prompt || typeof data.sideA.prompt !== "string") {
1826
- return "sideA.prompt is required and must be a string";
1827
- }
1828
- if (data.sideA.label !== void 0 && typeof data.sideA.label !== "string") {
1829
- return "sideA.label must be a string";
1830
- }
1831
- if (data.sideA.stopOnResponse !== void 0 && typeof data.sideA.stopOnResponse !== "boolean") {
1832
- return "sideA.stopOnResponse must be a boolean";
1833
- }
1834
- if (data.sideA.stopTool !== void 0 && typeof data.sideA.stopTool !== "string") {
1835
- return "sideA.stopTool must be a string";
1836
- }
1837
- if (data.sideA.stopTool && !data.sideA.stopToolResponseProperty) {
1838
- return "sideA.stopToolResponseProperty is required when sideA.stopTool is set";
1839
- }
1840
- if (data.sideA.maxSteps !== void 0) {
1841
- if (typeof data.sideA.maxSteps !== "number" || data.sideA.maxSteps <= 0) {
1842
- return "sideA.maxSteps must be a positive number";
1837
+ errors["side_a_agent_prompt"] = "Side A configuration is required";
1838
+ } else {
1839
+ if (!data.sideA.prompt || typeof data.sideA.prompt !== "string") {
1840
+ errors["side_a_agent_prompt"] = "Side A prompt is required";
1843
1841
  }
1844
- }
1845
- if (data.type === "dual_ai") {
1846
- if (!data.sideB || typeof data.sideB !== "object") {
1847
- return "sideB configuration is required for dual_ai type";
1842
+ if (data.sideA.label !== void 0 && typeof data.sideA.label !== "string") {
1843
+ errors["side_a_label"] = "Side A label must be a string";
1848
1844
  }
1849
- if (!data.sideB.prompt || typeof data.sideB.prompt !== "string") {
1850
- return "sideB.prompt is required for dual_ai type";
1845
+ if (data.sideA.stopTool && !data.sideA.stopToolResponseProperty) {
1846
+ errors["side_a_stop_tool_response_property"] = "Response property is required when stop tool is set";
1851
1847
  }
1852
- if (data.sideB.stopTool && !data.sideB.stopToolResponseProperty) {
1853
- return "sideB.stopToolResponseProperty is required when sideB.stopTool is set";
1848
+ if (data.sideA.maxSteps !== void 0) {
1849
+ if (typeof data.sideA.maxSteps !== "number" || data.sideA.maxSteps <= 0) {
1850
+ errors["side_a_max_steps"] = "Max steps must be a positive number";
1851
+ }
1854
1852
  }
1855
- if (data.sideB.maxSteps !== void 0) {
1856
- if (typeof data.sideB.maxSteps !== "number" || data.sideB.maxSteps <= 0) {
1857
- return "sideB.maxSteps must be a positive number";
1853
+ }
1854
+ if (data.type === "dual_ai") {
1855
+ if (!data.sideB || typeof data.sideB !== "object") {
1856
+ errors["side_b_agent_prompt"] = "Side B configuration is required for dual_ai type";
1857
+ } else {
1858
+ if (!data.sideB.prompt || typeof data.sideB.prompt !== "string") {
1859
+ errors["side_b_agent_prompt"] = "Side B prompt is required for dual_ai type";
1860
+ }
1861
+ if (data.sideB.stopTool && !data.sideB.stopToolResponseProperty) {
1862
+ errors["side_b_stop_tool_response_property"] = "Response property is required when stop tool is set";
1863
+ }
1864
+ if (data.sideB.maxSteps !== void 0) {
1865
+ if (typeof data.sideB.maxSteps !== "number" || data.sideB.maxSteps <= 0) {
1866
+ errors["side_b_max_steps"] = "Max steps must be a positive number";
1867
+ }
1858
1868
  }
1859
1869
  }
1860
1870
  }
1861
1871
  if (data.exposeAsTool && !data.toolDescription) {
1862
- return "toolDescription is required when exposeAsTool is true";
1872
+ errors["tool_description"] = "Tool description is required when expose as tool is enabled";
1863
1873
  }
1864
1874
  if (data.maxSessionTurns !== void 0 && data.maxSessionTurns !== null) {
1865
1875
  if (typeof data.maxSessionTurns !== "number" || data.maxSessionTurns <= 0) {
1866
- return "maxSessionTurns must be a positive number";
1876
+ errors["max_session_turns"] = "Max session turns must be a positive number";
1867
1877
  }
1868
1878
  }
1869
- return null;
1879
+ return Object.keys(errors).length > 0 ? errors : null;
1870
1880
  }
1871
1881
  var MetadataService = class {
1872
1882
  metadataDir;
@@ -5865,11 +5875,11 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
5865
5875
  try {
5866
5876
  const rawBody = await parseRequestBody(req);
5867
5877
  const body = transformModelData(rawBody);
5868
- const validationError = validateModelData(body);
5869
- if (validationError) {
5878
+ const fieldErrors = validateModelData(body);
5879
+ if (fieldErrors) {
5870
5880
  res.statusCode = 400;
5871
5881
  res.setHeader("Content-Type", "application/json");
5872
- res.end(JSON.stringify({ error: validationError }));
5882
+ res.end(JSON.stringify({ error: "Validation failed", fieldErrors }));
5873
5883
  return;
5874
5884
  }
5875
5885
  if (modelExists(modelsDir, body.name)) {
@@ -5910,11 +5920,11 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
5910
5920
  const body = transformModelData(rawBody);
5911
5921
  const newName = body.name;
5912
5922
  const isNameChange = newName && newName !== urlModelName;
5913
- const validationError = validateModelData(body);
5914
- if (validationError) {
5923
+ const fieldErrors = validateModelData(body);
5924
+ if (fieldErrors) {
5915
5925
  res.statusCode = 400;
5916
5926
  res.setHeader("Content-Type", "application/json");
5917
- res.end(JSON.stringify({ error: validationError }));
5927
+ res.end(JSON.stringify({ error: "Validation failed", fieldErrors }));
5918
5928
  return;
5919
5929
  }
5920
5930
  let updatedPrompts = [];
@@ -5989,11 +5999,11 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
5989
5999
  try {
5990
6000
  const rawBody = await parseRequestBody(req);
5991
6001
  const body = transformPromptData(rawBody);
5992
- const validationError = validatePromptData(body);
5993
- if (validationError) {
6002
+ const fieldErrors = validatePromptData(body);
6003
+ if (fieldErrors) {
5994
6004
  res.statusCode = 400;
5995
6005
  res.setHeader("Content-Type", "application/json");
5996
- res.end(JSON.stringify({ error: validationError }));
6006
+ res.end(JSON.stringify({ error: "Validation failed", fieldErrors }));
5997
6007
  return;
5998
6008
  }
5999
6009
  if (promptExists(promptsDir, body.name)) {
@@ -6034,11 +6044,11 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6034
6044
  const body = transformPromptData(rawBody);
6035
6045
  const newName = body.name;
6036
6046
  const isNameChange = newName && newName !== urlPromptName;
6037
- const validationError = validatePromptData(body);
6038
- if (validationError) {
6047
+ const fieldErrors = validatePromptData(body);
6048
+ if (fieldErrors) {
6039
6049
  res.statusCode = 400;
6040
6050
  res.setHeader("Content-Type", "application/json");
6041
- res.end(JSON.stringify({ error: validationError }));
6051
+ res.end(JSON.stringify({ error: "Validation failed", fieldErrors }));
6042
6052
  return;
6043
6053
  }
6044
6054
  let updatedPrompts = [];
@@ -6114,11 +6124,11 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6114
6124
  try {
6115
6125
  const rawBody = await parseRequestBody(req);
6116
6126
  const body = transformAgentData(rawBody);
6117
- const validationError = validateAgentData(body);
6118
- if (validationError) {
6127
+ const fieldErrors = validateAgentData(body);
6128
+ if (fieldErrors) {
6119
6129
  res.statusCode = 400;
6120
6130
  res.setHeader("Content-Type", "application/json");
6121
- res.end(JSON.stringify({ error: validationError }));
6131
+ res.end(JSON.stringify({ error: "Validation failed", fieldErrors }));
6122
6132
  return;
6123
6133
  }
6124
6134
  if (agentExists(agentsDir, body.name)) {
@@ -6158,11 +6168,11 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6158
6168
  const rawBody = await parseRequestBody(req);
6159
6169
  const body = transformAgentData(rawBody);
6160
6170
  body.name = agentName;
6161
- const validationError = validateAgentData(body);
6162
- if (validationError) {
6171
+ const fieldErrors = validateAgentData(body);
6172
+ if (fieldErrors) {
6163
6173
  res.statusCode = 400;
6164
6174
  res.setHeader("Content-Type", "application/json");
6165
- res.end(JSON.stringify({ error: validationError }));
6175
+ res.end(JSON.stringify({ error: "Validation failed", fieldErrors }));
6166
6176
  return;
6167
6177
  }
6168
6178
  const result = await saveAgent(agentsDir, body, true);
@@ -6586,7 +6596,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
6586
6596
  let content = fs2__default.readFileSync(filePath);
6587
6597
  const ext = path8__default.extname(filePath).toLowerCase();
6588
6598
  if (ext === ".html") {
6589
- const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}" };</script>`;
6599
+ const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { mountPoint: "${mountPoint}", devMode: true };</script>`;
6590
6600
  let htmlContent = content.toString();
6591
6601
  const assetPrefix = mountPoint === "/" ? "/" : `${mountPoint}/`;
6592
6602
  htmlContent = htmlContent.replace(/\/agents\//g, assetPrefix);