@standardagents/builder 0.13.1 → 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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ProviderError, mapReasoningLevel, defineTool } from '@standardagents/spec';
2
2
  export { ProviderError, belongsToPackage, defineAgent, defineHook, defineModel, definePrompt, defineTool, isPacked, isVisibleInNamespace, mapReasoningLevel } from '@standardagents/spec';
3
3
  import { z } from 'zod';
4
- import { sip } from '@standardagents/sip';
4
+ import { transform, collect } from '@standardagents/sip';
5
5
  import * as fs4 from 'fs';
6
6
  import fs4__default from 'fs';
7
7
  import * as path8 from 'path';
@@ -193,6 +193,274 @@ var init_StreamManager = __esm({
193
193
  };
194
194
  }
195
195
  });
196
+
197
+ // src/agents/pricing.ts
198
+ function getGoogleFallbackPricing(modelId) {
199
+ const normalized = normalizeGoogleModelId(modelId);
200
+ const exact = GOOGLE_MODEL_PRICING[normalized];
201
+ if (exact) return { ...exact, source: "google-static" };
202
+ const prefixMatch = GOOGLE_MODEL_PRICING_PREFIXES.find((entry) => normalized.startsWith(entry.prefix));
203
+ if (prefixMatch) return { ...prefixMatch.pricing, source: "google-static" };
204
+ return null;
205
+ }
206
+ function getGroqFallbackPricing(modelId) {
207
+ const pricing = GROQ_MODEL_PRICING[normalizeModelId(modelId)];
208
+ return pricing ? { ...pricing, source: "groq-static" } : null;
209
+ }
210
+ function getXAIFallbackPricing(modelId) {
211
+ const pricing = XAI_MODEL_PRICING[normalizeModelId(modelId)];
212
+ return pricing ? { ...pricing, source: "xai-static" } : null;
213
+ }
214
+ function normalizeModelId(modelId) {
215
+ return (modelId || "").trim().toLowerCase();
216
+ }
217
+ function normalizeGoogleModelId(modelId) {
218
+ return normalizeModelId(modelId).replace(/^google\//, "").replace(/^models\//, "").replace(/^publishers\/google\/models\//, "");
219
+ }
220
+ function roundCost(value) {
221
+ return Number(value.toFixed(12));
222
+ }
223
+ function getCerebrasFallbackPricing(modelId) {
224
+ const pricing = CEREBRAS_MODEL_PRICING[normalizeModelId(modelId)];
225
+ return pricing ? { ...pricing, source: "cerebras-static" } : null;
226
+ }
227
+ function resolveModelPricing(modelDef, providerName) {
228
+ if (typeof modelDef.inputPrice === "number" && typeof modelDef.outputPrice === "number") {
229
+ return {
230
+ inputPrice: modelDef.inputPrice,
231
+ outputPrice: modelDef.outputPrice,
232
+ cachedPrice: modelDef.cachedPrice,
233
+ source: "model"
234
+ };
235
+ }
236
+ if (providerName === "cerebras") {
237
+ return getCerebrasFallbackPricing(modelDef.model);
238
+ }
239
+ if (providerName === "google") {
240
+ return getGoogleFallbackPricing(modelDef.model);
241
+ }
242
+ if (providerName === "groq") {
243
+ return getGroqFallbackPricing(modelDef.model);
244
+ }
245
+ if (providerName === "xai") {
246
+ return getXAIFallbackPricing(modelDef.model);
247
+ }
248
+ return null;
249
+ }
250
+ function calculateUsageCost(usage, pricing) {
251
+ if (!pricing) {
252
+ return null;
253
+ }
254
+ const cachedTokens = Math.max(usage.prompt_tokens_details?.cached_tokens || 0, 0);
255
+ const promptTokens = Math.max(usage.prompt_tokens || 0, 0);
256
+ const completionTokens = Math.max(usage.completion_tokens || 0, 0);
257
+ const reasoningTokens = pricing.source === "google-static" ? Math.max(usage.completion_tokens_details?.reasoning_tokens || 0, 0) : 0;
258
+ const billableOutputTokens = completionTokens + reasoningTokens;
259
+ const uncachedPromptTokens = Math.max(promptTokens - cachedTokens, 0);
260
+ const cachedTokenPrice = pricing.cachedPrice ?? pricing.inputPrice;
261
+ const costInput = roundCost(
262
+ (uncachedPromptTokens * pricing.inputPrice + cachedTokens * cachedTokenPrice) / TOKENS_PER_MILLION
263
+ );
264
+ const costOutput = roundCost(billableOutputTokens * pricing.outputPrice / TOKENS_PER_MILLION);
265
+ return {
266
+ costInput,
267
+ costOutput,
268
+ costTotal: roundCost(costInput + costOutput)
269
+ };
270
+ }
271
+ var TOKENS_PER_MILLION, CEREBRAS_MODEL_PRICING, GOOGLE_MODEL_PRICING, GOOGLE_MODEL_PRICING_PREFIXES, GROQ_MODEL_PRICING, XAI_MODEL_PRICING;
272
+ var init_pricing = __esm({
273
+ "src/agents/pricing.ts"() {
274
+ TOKENS_PER_MILLION = 1e6;
275
+ CEREBRAS_MODEL_PRICING = {
276
+ "zai-glm-4.7": {
277
+ inputPrice: 2.25,
278
+ outputPrice: 2.75
279
+ },
280
+ "gpt-oss-120b": {
281
+ inputPrice: 0.35,
282
+ outputPrice: 0.75
283
+ },
284
+ "llama3.1-8b": {
285
+ inputPrice: 0.1,
286
+ outputPrice: 0.1
287
+ },
288
+ "qwen-3-235b-a22b-instruct-2507": {
289
+ inputPrice: 0.6,
290
+ outputPrice: 1.2
291
+ }
292
+ };
293
+ GOOGLE_MODEL_PRICING = {
294
+ "gemini-3-pro-preview": {
295
+ inputPrice: 2,
296
+ outputPrice: 12,
297
+ cachedPrice: 0.2
298
+ },
299
+ "gemini-3.1-pro-preview": {
300
+ inputPrice: 2,
301
+ outputPrice: 12,
302
+ cachedPrice: 0.2
303
+ },
304
+ "gemini-2.5-pro": {
305
+ inputPrice: 1.25,
306
+ outputPrice: 10,
307
+ cachedPrice: 0.125
308
+ },
309
+ "gemini-2.5-flash": {
310
+ inputPrice: 0.3,
311
+ outputPrice: 2.5,
312
+ cachedPrice: 0.03
313
+ },
314
+ "gemini-2.5-flash-lite": {
315
+ inputPrice: 0.1,
316
+ outputPrice: 0.4,
317
+ cachedPrice: 0.01
318
+ },
319
+ "gemini-3-flash-preview": {
320
+ inputPrice: 0.5,
321
+ outputPrice: 3,
322
+ cachedPrice: 0.05
323
+ },
324
+ "gemini-3.1-flash-lite-preview": {
325
+ inputPrice: 0.25,
326
+ outputPrice: 1.5,
327
+ cachedPrice: 0.025
328
+ },
329
+ "deep-research-pro-preview-12-2025": {
330
+ inputPrice: 2,
331
+ outputPrice: 12,
332
+ cachedPrice: 0.2
333
+ },
334
+ "gemini-2.0-flash": {
335
+ inputPrice: 0.1,
336
+ outputPrice: 0.4,
337
+ cachedPrice: 0.025
338
+ },
339
+ "gemini-2.0-flash-001": {
340
+ inputPrice: 0.1,
341
+ outputPrice: 0.4,
342
+ cachedPrice: 0.025
343
+ },
344
+ "gemini-2.0-flash-lite": {
345
+ inputPrice: 0.075,
346
+ outputPrice: 0.3
347
+ },
348
+ "gemini-2.0-flash-lite-001": {
349
+ inputPrice: 0.075,
350
+ outputPrice: 0.3
351
+ },
352
+ "gemini-2.5-computer-use-preview-10-2025": {
353
+ inputPrice: 1.25,
354
+ outputPrice: 10
355
+ },
356
+ "gemini-2.5-flash-image": {
357
+ inputPrice: 0.3,
358
+ outputPrice: 0
359
+ },
360
+ "gemini-3.1-flash-image-preview": {
361
+ inputPrice: 0.5,
362
+ outputPrice: 3
363
+ },
364
+ "gemini-3-pro-image-preview": {
365
+ inputPrice: 2,
366
+ outputPrice: 0
367
+ },
368
+ "nano-banana-pro-preview": {
369
+ inputPrice: 2,
370
+ outputPrice: 0
371
+ },
372
+ "gemma-4-31b-it": {
373
+ inputPrice: 0,
374
+ outputPrice: 0,
375
+ cachedPrice: 0
376
+ }
377
+ };
378
+ GOOGLE_MODEL_PRICING_PREFIXES = [
379
+ {
380
+ prefix: "gemini-3.1-pro-preview",
381
+ pricing: GOOGLE_MODEL_PRICING["gemini-3.1-pro-preview"]
382
+ },
383
+ {
384
+ prefix: "gemini-3-pro-preview",
385
+ pricing: GOOGLE_MODEL_PRICING["gemini-3-pro-preview"]
386
+ },
387
+ {
388
+ prefix: "gemini-3-flash-preview",
389
+ pricing: GOOGLE_MODEL_PRICING["gemini-3-flash-preview"]
390
+ },
391
+ {
392
+ prefix: "gemini-3.1-flash-lite-preview",
393
+ pricing: GOOGLE_MODEL_PRICING["gemini-3.1-flash-lite-preview"]
394
+ },
395
+ {
396
+ prefix: "gemini-2.5-flash-lite-preview-",
397
+ pricing: GOOGLE_MODEL_PRICING["gemini-2.5-flash-lite"]
398
+ },
399
+ {
400
+ prefix: "gemini-flash-latest",
401
+ pricing: GOOGLE_MODEL_PRICING["gemini-2.5-flash"]
402
+ },
403
+ {
404
+ prefix: "gemini-flash-lite-latest",
405
+ pricing: GOOGLE_MODEL_PRICING["gemini-2.5-flash-lite"]
406
+ },
407
+ {
408
+ prefix: "gemini-pro-latest",
409
+ pricing: GOOGLE_MODEL_PRICING["gemini-2.5-pro"]
410
+ },
411
+ {
412
+ prefix: "gemma-4-",
413
+ pricing: {
414
+ inputPrice: 0,
415
+ outputPrice: 0,
416
+ cachedPrice: 0
417
+ }
418
+ },
419
+ {
420
+ prefix: "gemma-3-",
421
+ pricing: {
422
+ inputPrice: 0,
423
+ outputPrice: 0,
424
+ cachedPrice: 0
425
+ }
426
+ },
427
+ {
428
+ prefix: "gemma-3n-",
429
+ pricing: {
430
+ inputPrice: 0,
431
+ outputPrice: 0,
432
+ cachedPrice: 0
433
+ }
434
+ }
435
+ ];
436
+ GROQ_MODEL_PRICING = {
437
+ "llama-3.1-8b-instant": { inputPrice: 0.05, outputPrice: 0.08 },
438
+ "llama-3.3-70b-versatile": { inputPrice: 0.59, outputPrice: 0.79 },
439
+ "meta-llama/llama-4-scout-17b-16e-instruct": { inputPrice: 0.11, outputPrice: 0.34 },
440
+ "moonshotai/kimi-k2-instruct": { inputPrice: 1, outputPrice: 3 },
441
+ "openai/gpt-oss-120b": { inputPrice: 0.15, cachedPrice: 0.075, outputPrice: 0.6 },
442
+ "openai/gpt-oss-20b": { inputPrice: 0.075, cachedPrice: 0.037, outputPrice: 0.3 },
443
+ "qwen/qwen3-32b": { inputPrice: 0.29, outputPrice: 0.59 }
444
+ };
445
+ XAI_MODEL_PRICING = {
446
+ "grok-4-0709": { inputPrice: 30, cachedPrice: 7.5, outputPrice: 150 },
447
+ "grok-4": { inputPrice: 30, cachedPrice: 7.5, outputPrice: 150 },
448
+ "grok-4-latest": { inputPrice: 30, cachedPrice: 7.5, outputPrice: 150 },
449
+ "grok-4-fast-reasoning": { inputPrice: 2, cachedPrice: 0.5, outputPrice: 5 },
450
+ "grok-4-fast-non-reasoning": { inputPrice: 2, cachedPrice: 0.5, outputPrice: 5 },
451
+ "grok-4-1-fast-reasoning": { inputPrice: 2, cachedPrice: 0.5, outputPrice: 5 },
452
+ "grok-4-1-fast-non-reasoning": { inputPrice: 2, cachedPrice: 0.5, outputPrice: 5 },
453
+ "grok-4.20-0309-reasoning": { inputPrice: 20, cachedPrice: 2, outputPrice: 60 },
454
+ "grok-4.20-0309-non-reasoning": { inputPrice: 20, cachedPrice: 2, outputPrice: 60 },
455
+ "grok-4.20-multi-agent-0309": { inputPrice: 20, cachedPrice: 2, outputPrice: 60 },
456
+ "grok-code-fast-1": { inputPrice: 2, cachedPrice: 0.2, outputPrice: 15 },
457
+ "grok-3": { inputPrice: 30, cachedPrice: 7.5, outputPrice: 150 },
458
+ "grok-3-latest": { inputPrice: 30, cachedPrice: 7.5, outputPrice: 150 },
459
+ "grok-3-mini": { inputPrice: 3, cachedPrice: 0.75, outputPrice: 5 },
460
+ "grok-3-mini-latest": { inputPrice: 3, cachedPrice: 0.75, outputPrice: 5 }
461
+ };
462
+ }
463
+ });
196
464
  var init_types2 = __esm({
197
465
  "src/agents/providers/types.ts"() {
198
466
  }
@@ -648,6 +916,12 @@ var init_ProviderRegistry = __esm({
648
916
  if (modelDef.providerOptions?.baseUrl) {
649
917
  config.baseUrl = modelDef.providerOptions.baseUrl;
650
918
  }
919
+ if (providerName === "cloudflare" && !config.baseUrl && env.CLOUDFLARE_ACCOUNT_ID) {
920
+ config.baseUrl = `https://api.cloudflare.com/client/v4/accounts/${env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`;
921
+ }
922
+ if (providerName === "cloudflare" && env.CLOUDFLARE_ACCOUNT_ID) {
923
+ config.accountId = env.CLOUDFLARE_ACCOUNT_ID;
924
+ }
651
925
  return this.cacheAndReturn(modelName, providerFactory(config), modelDef);
652
926
  }
653
927
  buildResult(provider, modelDef) {
@@ -662,11 +936,14 @@ var init_ProviderRegistry = __esm({
662
936
  */
663
937
  getApiKeyForProvider(providerName, env) {
664
938
  const apiKeyEnvVarMap = {
939
+ cloudflare: "CLOUDFLARE_API_TOKEN",
665
940
  cerebras: "CEREBRAS_API_KEY",
941
+ google: "GOOGLE_API_KEY",
942
+ groq: "GROQ_API_KEY",
666
943
  openai: "OPENAI_API_KEY",
667
944
  openrouter: "OPENROUTER_API_KEY",
668
945
  anthropic: "ANTHROPIC_API_KEY",
669
- google: "GOOGLE_API_KEY"
946
+ xai: "XAI_API_KEY"
670
947
  };
671
948
  const envVar = apiKeyEnvVarMap[providerName.toLowerCase()];
672
949
  if (envVar && env[envVar]) {
@@ -716,6 +993,13 @@ function modelSupportsImageInput(modelDef) {
716
993
  }
717
994
  return true;
718
995
  }
996
+ function modelSupportsToolCalls(modelDef) {
997
+ const supportsToolCalls = modelDef.capabilities?.supportsToolCalls;
998
+ if (typeof supportsToolCalls === "boolean") {
999
+ return supportsToolCalls;
1000
+ }
1001
+ return true;
1002
+ }
719
1003
  function filterImagesFromProviderMessages(messages) {
720
1004
  let removedUserImageParts = 0;
721
1005
  let removedToolImageAttachments = 0;
@@ -767,6 +1051,15 @@ function filterImagesFromProviderMessages(messages) {
767
1051
  removedToolImageAttachments
768
1052
  };
769
1053
  }
1054
+ function filterEmptyAssistantProviderMessages(messages) {
1055
+ return messages.filter((message) => {
1056
+ if (message.role !== "assistant") return true;
1057
+ const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
1058
+ const hasReasoning = typeof message.reasoning === "string" ? message.reasoning.trim().length > 0 : Boolean(message.reasoningDetails);
1059
+ const hasContent = typeof message.content === "string" ? message.content.trim().length > 0 : message.content !== null;
1060
+ return hasToolCalls || hasReasoning || hasContent;
1061
+ });
1062
+ }
770
1063
  function stripBase64FromMessages(messages, imagePathMap) {
771
1064
  return messages.map((msg) => {
772
1065
  if (msg.role === "user" && Array.isArray(msg.content)) {
@@ -912,25 +1205,31 @@ function transformToolChoice(toolChoice) {
912
1205
  function buildRequestBody(context, modelDef) {
913
1206
  const transformedMessages = transformMessages(context.messages);
914
1207
  const supportsImageInput = modelSupportsImageInput(modelDef);
1208
+ const supportsToolCalls = modelSupportsToolCalls(modelDef);
915
1209
  let requestMessages = transformedMessages;
916
1210
  let visionFiltering;
917
1211
  if (!supportsImageInput) {
918
1212
  const filtered = filterImagesFromProviderMessages(transformedMessages);
919
1213
  requestMessages = filtered.messages;
920
- visionFiltering = {
921
- enabled: true,
922
- reason: "model_no_vision",
923
- removedUserImageParts: filtered.removedUserImageParts,
924
- removedToolImageAttachments: filtered.removedToolImageAttachments
925
- };
1214
+ if (filtered.removedUserImageParts > 0 || filtered.removedToolImageAttachments > 0) {
1215
+ visionFiltering = {
1216
+ enabled: true,
1217
+ reason: "model_no_vision",
1218
+ removedUserImageParts: filtered.removedUserImageParts,
1219
+ removedToolImageAttachments: filtered.removedToolImageAttachments
1220
+ };
1221
+ }
926
1222
  }
1223
+ requestMessages = filterEmptyAssistantProviderMessages(requestMessages);
1224
+ const tools = supportsToolCalls ? transformTools(context.tools) : void 0;
1225
+ const toolChoice = supportsToolCalls ? transformToolChoice(context.tool_choice) : void 0;
927
1226
  return {
928
1227
  requestBody: {
929
1228
  model: modelDef.model,
930
1229
  messages: requestMessages,
931
- tools: transformTools(context.tools),
932
- toolChoice: transformToolChoice(context.tool_choice),
933
- parallelToolCalls: context.parallel_tool_calls,
1230
+ tools,
1231
+ toolChoice,
1232
+ parallelToolCalls: supportsToolCalls ? context.parallel_tool_calls : void 0,
934
1233
  reasoning: context.reasoning ? {
935
1234
  level: reasoningEffortToLevel(context.reasoning.effort),
936
1235
  maxTokens: context.reasoning.max_tokens,
@@ -972,6 +1271,7 @@ function convertUsage(usage) {
972
1271
  var NON_VISION_PLACEHOLDER_TEXT, LLMRequest;
973
1272
  var init_LLMRequest = __esm({
974
1273
  "src/agents/LLMRequest.ts"() {
1274
+ init_pricing();
975
1275
  init_types();
976
1276
  NON_VISION_PLACEHOLDER_TEXT = "[Image omitted: model does not support vision]";
977
1277
  LLMRequest = class {
@@ -1081,7 +1381,7 @@ var init_LLMRequest = __esm({
1081
1381
  timestamp: Date.now()
1082
1382
  });
1083
1383
  const response = await this.callModel(actualModelId, context, state, logId);
1084
- await this.logSuccess(response, state, actualModelId, startTime, context, logId);
1384
+ await this.logSuccess(response, state, actualModelId, startTime, context, logId, modelDef);
1085
1385
  state.emitTelemetry?.({
1086
1386
  type: "llm_response",
1087
1387
  tokens: response.usage.total_tokens,
@@ -1406,10 +1706,14 @@ var init_LLMRequest = __esm({
1406
1706
  /**
1407
1707
  * Update log with successful response data (best-effort, non-blocking)
1408
1708
  */
1409
- static async logSuccess(response, state, modelId, startTime, context, logId) {
1709
+ static async logSuccess(response, state, modelId, startTime, context, logId, modelDef) {
1410
1710
  try {
1411
1711
  const toolsCalled = response.tool_calls ? JSON.stringify(response.tool_calls.map((tc) => tc.function.name)) : null;
1412
- const cost_total = response.usage.cost ? parseFloat(response.usage.cost) : null;
1712
+ const providerName = response._provider?.name;
1713
+ const resolvedPricing = resolveModelPricing(modelDef, providerName);
1714
+ const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
1715
+ const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
1716
+ const cost_total = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
1413
1717
  const actualProvider = response.usage.provider;
1414
1718
  const aggregateResponse = response._aggregate_response;
1415
1719
  const responseBody = aggregateResponse ? JSON.stringify(aggregateResponse) : JSON.stringify(response);
@@ -1450,6 +1754,8 @@ var init_LLMRequest = __esm({
1450
1754
  output_tokens: response.usage.completion_tokens,
1451
1755
  reasoning_tokens: response.usage.completion_tokens_details?.reasoning_tokens || 0,
1452
1756
  total_tokens: response.usage.total_tokens,
1757
+ cost_input: calculatedCost?.costInput,
1758
+ cost_output: calculatedCost?.costOutput,
1453
1759
  latency_ms: Date.now() - startTime,
1454
1760
  finish_reason: response.finish_reason,
1455
1761
  tools_called: toolsCalled ?? void 0,
@@ -1474,15 +1780,17 @@ var init_LLMRequest = __esm({
1474
1780
  output_tokens = ?4,
1475
1781
  reasoning_tokens = ?5,
1476
1782
  total_tokens = ?6,
1477
- latency_ms = ?7,
1478
- finish_reason = ?8,
1479
- tools_called = ?9,
1480
- cost_total = ?10,
1481
- is_complete = ?11,
1482
- reasoning_content = ?12,
1483
- provider_tools = ?13,
1484
- actual_provider = ?14
1485
- WHERE id = ?15
1783
+ cost_input = ?7,
1784
+ cost_output = ?8,
1785
+ latency_ms = ?9,
1786
+ finish_reason = ?10,
1787
+ tools_called = ?11,
1788
+ cost_total = ?12,
1789
+ is_complete = ?13,
1790
+ reasoning_content = ?14,
1791
+ provider_tools = ?15,
1792
+ actual_provider = ?16
1793
+ WHERE id = ?17
1486
1794
  `,
1487
1795
  logData.response_body,
1488
1796
  logData.input_tokens,
@@ -1490,6 +1798,8 @@ var init_LLMRequest = __esm({
1490
1798
  logData.output_tokens,
1491
1799
  logData.reasoning_tokens,
1492
1800
  logData.total_tokens,
1801
+ logData.cost_input ?? null,
1802
+ logData.cost_output ?? null,
1493
1803
  logData.latency_ms,
1494
1804
  logData.finish_reason,
1495
1805
  logData.tools_called,
@@ -5559,10 +5869,16 @@ function svgToDataUri(svg) {
5559
5869
  const encoded = encodeURIComponent(svg).replace(/'/g, "%27").replace(/"/g, "%22");
5560
5870
  return `data:image/svg+xml,${encoded}`;
5561
5871
  }
5872
+ function normalizeIcon(icon) {
5873
+ if (icon.startsWith("data:") || icon.endsWith(".svg") || icon.includes(".svg?")) {
5874
+ return icon;
5875
+ }
5876
+ return svgToDataUri(icon);
5877
+ }
5562
5878
  function getOpenAIIconDataUri() {
5563
- return svgToDataUri(OPENAI_ICON);
5879
+ return normalizeIcon(OPENAI_ICON);
5564
5880
  }
5565
- var DEFAULT_REASONING_LEVELS, OPENAI_NATIVE_TOOLS, OPENAI_ICON, OpenAIProvider, openaiProviderOptions, openai;
5881
+ var DEFAULT_REASONING_LEVELS, OPENAI_NATIVE_TOOLS, openai_default, OPENAI_ICON, OpenAIProvider, openaiProviderOptions, openai;
5566
5882
  var init_dist = __esm({
5567
5883
  "../openai/dist/index.js"() {
5568
5884
  DEFAULT_REASONING_LEVELS = {
@@ -5577,10 +5893,8 @@ var init_dist = __esm({
5577
5893
  "code_interpreter",
5578
5894
  "file_search"
5579
5895
  ]);
5580
- OPENAI_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
5581
- <rect width="48" height="48" rx="24" fill="white"/>
5582
- <path d="M19.3418 18.5599V14.7599C19.3418 14.4399 19.4608 14.1998 19.7382 14.04L27.3102 9.63997C28.3409 9.03999 29.5699 8.76014 30.8383 8.76014C35.5954 8.76014 38.6085 12.4802 38.6085 16.4401C38.6085 16.72 38.6085 17.04 38.5687 17.3601L30.7194 12.72C30.2437 12.4401 29.7678 12.4401 29.2922 12.72L19.3418 18.5599ZM37.0226 33.36V24.2799C37.0226 23.7197 36.7846 23.3197 36.309 23.0398L26.3586 17.1998L29.6093 15.3197C29.8868 15.1599 30.1247 15.1599 30.4022 15.3197L37.9741 19.7197C40.1547 20.9999 41.6213 23.7197 41.6213 26.3596C41.6213 29.3995 39.8375 32.1999 37.0226 33.36ZM17.0029 25.3601L13.7522 23.4402C13.4748 23.2804 13.3557 23.0402 13.3557 22.7202V13.9203C13.3557 9.64039 16.6065 6.40016 21.0069 6.40016C22.6722 6.40016 24.2179 6.96029 25.5265 7.96025L17.7168 12.5204C17.2412 12.8003 17.0033 13.2002 17.0033 13.7605L17.0029 25.3601ZM24 29.44L19.3418 26.8001V21.2003L24 18.5604L28.6578 21.2003V26.8001L24 29.44ZM26.993 41.6002C25.3278 41.6002 23.7821 41.04 22.4735 40.0402L30.2831 35.4799C30.7588 35.2001 30.9967 34.8001 30.9967 34.2399V22.6399L34.2873 24.5598C34.5646 24.7196 34.6837 24.9597 34.6837 25.2798V34.0797C34.6837 38.3596 31.3931 41.6002 26.993 41.6002ZM17.5975 32.6802L10.0255 28.2803C7.84493 27.0001 6.37833 24.2803 6.37833 21.6404C6.37833 18.5604 8.20193 15.8004 11.0164 14.6403V23.7602C11.0164 24.3204 11.2544 24.7204 11.73 25.0003L21.641 30.8001L18.3902 32.6802C18.1129 32.84 17.8749 32.84 17.5975 32.6802ZM17.1617 39.2402C12.682 39.2402 9.39151 35.8402 9.39151 31.6401C9.39151 31.3201 9.43125 31.0001 9.47066 30.68L17.2803 35.2402C17.7559 35.5201 18.2319 35.5201 18.7074 35.2402L28.6578 29.4404V33.2404C28.6578 33.5605 28.5388 33.8005 28.2614 33.9604L20.6894 38.3604C19.6586 38.9603 18.4301 39.2402 17.1617 39.2402ZM26.993 44C31.7899 44 35.7936 40.5601 36.7057 36C41.1457 34.8399 44 30.6399 44 26.36C44 23.5598 42.8108 20.8401 40.6701 18.88C40.8683 18.0399 40.9872 17.1998 40.9872 16.3602C40.9872 10.6403 36.3885 6.35998 31.0763 6.35998C30.0062 6.35998 28.9754 6.51979 27.9446 6.88001C26.1604 5.11992 23.7025 4 21.0069 4C16.2101 4 12.2064 7.4398 11.2943 12C6.8543 13.1601 4 17.3601 4 21.6399C4 24.4401 5.18916 27.1599 7.32995 29.1199C7.13174 29.96 7.01277 30.8001 7.01277 31.6398C7.01277 37.3597 11.6114 41.6399 16.9236 41.6399C17.9938 41.6399 19.0246 41.4801 20.0554 41.1199C21.8392 42.88 24.2971 44 26.993 44Z" fill="black"/>
5583
- </svg>`;
5896
+ openai_default = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" fill="none" viewBox="0 0 128 128"><g clip-path="url(%23clip0_2138_504)"><g clip-path="url(%23clip1_2138_504)"><path fill="%23000" d="M118.824 52.388a31.9 31.9 0 0 0-2.74-26.192 32.25 32.25 0 0 0-34.736-15.472A31.9 31.9 0 0 0 57.296 0C43.28-.032 30.844 8.992 26.532 22.328A31.9 31.9 0 0 0 5.208 37.796C-1.828 49.924-.224 65.212 9.176 75.612a31.9 31.9 0 0 0 2.74 26.192 32.25 32.25 0 0 0 34.736 15.472 31.88 31.88 0 0 0 24.052 10.72c14.024.036 26.464-8.996 30.776-22.344a31.9 31.9 0 0 0 21.324-15.468 32.26 32.26 0 0 0-3.976-37.804zm-48.112 67.244a23.9 23.9 0 0 1-15.356-5.552c.196-.104.536-.292.756-.428L81.6 98.932a4.14 4.14 0 0 0 2.096-3.628V59.372l10.772 6.22a.38.38 0 0 1 .208.296v29.756c-.016 13.232-10.732 23.96-23.964 23.988M19.176 97.62a23.88 23.88 0 0 1-2.86-16.072c.188.112.52.316.756.452L42.56 96.72a4.15 4.15 0 0 0 4.188 0l31.116-17.968v12.44a.4.4 0 0 1-.152.332L51.948 106.4c-11.476 6.608-26.132 2.68-32.768-8.78zm-6.708-55.636a23.9 23.9 0 0 1 12.484-10.516c0 .22-.012.608-.012.88v29.444a4.15 4.15 0 0 0 2.092 3.624L58.148 83.38 47.376 89.6a.38.38 0 0 1-.364.032L21.244 74.744c-11.452-6.632-15.38-21.284-8.78-32.756zm88.504 20.596L69.856 44.612l10.772-6.216a.38.38 0 0 1 .364-.032L106.76 53.24c11.472 6.628 15.404 21.304 8.776 32.776a23.98 23.98 0 0 1-12.48 10.512V66.204a4.14 4.14 0 0 0-2.08-3.624zm10.72-16.136c-.188-.116-.52-.316-.756-.452l-25.488-14.72a4.15 4.15 0 0 0-4.188 0L50.144 49.24V36.8a.4.4 0 0 1 .152-.332L76.06 21.604c11.476-6.62 26.148-2.68 32.764 8.8a23.98 23.98 0 0 1 2.86 16.04zM44.288 68.616l-10.776-6.22a.38.38 0 0 1-.208-.296V32.344C33.312 19.096 44.06 8.36 57.308 8.368a23.98 23.98 0 0 1 15.336 5.552c-.196.104-.532.292-.756.428L46.4 29.068a4.14 4.14 0 0 0-2.096 3.624l-.016 35.916zM50.14 56 64 47.996l13.86 8V72L64 80l-13.86-8z"/></g></g><defs><clipPath id="clip0_2138_504"><path fill="%23fff" d="M0 0h128v128H0z"/></clipPath><clipPath id="clip1_2138_504"><path fill="%23fff" d="M0 0h128v128H0z"/></clipPath></defs></svg>';
5897
+ OPENAI_ICON = openai_default;
5584
5898
  OpenAIProvider = class _OpenAIProvider {
5585
5899
  name = "openai";
5586
5900
  specificationVersion = "1";
@@ -10871,22 +11185,42 @@ __export(image_processing_exports, {
10871
11185
  needsProcessing: () => needsProcessing,
10872
11186
  processImage: () => processImage
10873
11187
  });
11188
+ function clampQuality(quality) {
11189
+ return Math.max(1, Math.min(100, Math.round(quality)));
11190
+ }
11191
+ async function collectTransformedImage(input, width, height, quality) {
11192
+ const image = transform(input, { width, height, quality: clampQuality(quality) });
11193
+ const { data, info } = await collect(image);
11194
+ return {
11195
+ data,
11196
+ mimeType: "image/jpeg",
11197
+ width: info.width,
11198
+ height: info.height
11199
+ };
11200
+ }
11201
+ async function transformToTargetSize(input, maxWidth, maxHeight, maxBytes, quality) {
11202
+ let currentQuality = clampQuality(quality);
11203
+ let result = await collectTransformedImage(input, maxWidth, maxHeight, currentQuality);
11204
+ while (result.data.byteLength > maxBytes && currentQuality > MIN_QUALITY) {
11205
+ currentQuality -= 10;
11206
+ result = await collectTransformedImage(input, maxWidth, maxHeight, currentQuality);
11207
+ }
11208
+ while (result.data.byteLength > maxBytes) {
11209
+ const scaleFactor = Math.sqrt(maxBytes / result.data.byteLength) * 0.9;
11210
+ const nextWidth = Math.max(1, Math.min(result.width - 1, Math.round(result.width * scaleFactor)));
11211
+ const nextHeight = Math.max(1, Math.min(result.height - 1, Math.round(result.height * scaleFactor)));
11212
+ if (nextWidth >= result.width && nextHeight >= result.height) {
11213
+ break;
11214
+ }
11215
+ result = await collectTransformedImage(input, nextWidth, nextHeight, currentQuality);
11216
+ }
11217
+ return result;
11218
+ }
10874
11219
  async function processImage(input, inputMimeType) {
10875
11220
  if (input.byteLength > MAX_INPUT_SIZE) {
10876
11221
  throw new Error(`Image too large: ${input.byteLength} bytes exceeds ${MAX_INPUT_SIZE} byte limit`);
10877
11222
  }
10878
- const result = await sip.process(input, {
10879
- maxWidth: MAX_DIMENSION,
10880
- maxHeight: MAX_DIMENSION,
10881
- maxBytes: MAX_SIZE,
10882
- quality: 85
10883
- });
10884
- return {
10885
- data: result.data,
10886
- mimeType: "image/jpeg",
10887
- width: result.width,
10888
- height: result.height
10889
- };
11223
+ return await transformToTargetSize(input, MAX_DIMENSION, MAX_DIMENSION, MAX_SIZE, 85);
10890
11224
  }
10891
11225
  function needsProcessing(data, mimeType) {
10892
11226
  const binaryLength = Math.ceil(data.length * 3 / 4);
@@ -10908,12 +11242,13 @@ function arrayBufferToBase64(buffer) {
10908
11242
  }
10909
11243
  return btoa(binary);
10910
11244
  }
10911
- var MAX_SIZE, MAX_DIMENSION, MAX_INPUT_SIZE;
11245
+ var MAX_SIZE, MAX_DIMENSION, MAX_INPUT_SIZE, MIN_QUALITY;
10912
11246
  var init_image_processing = __esm({
10913
11247
  "src/image-processing/index.ts"() {
10914
11248
  MAX_SIZE = 1.5 * 1024 * 1024;
10915
11249
  MAX_DIMENSION = 4096;
10916
11250
  MAX_INPUT_SIZE = 20 * 1024 * 1024;
11251
+ MIN_QUALITY = 45;
10917
11252
  }
10918
11253
  });
10919
11254
  var TSCONFIG_CONTENT = `{
@@ -12292,23 +12627,47 @@ function formatSessionBinding(binding) {
12292
12627
 
12293
12628
  // src/providers/catalog.ts
12294
12629
  var FIRST_PARTY_PROVIDERS = [
12630
+ {
12631
+ name: "cloudflare",
12632
+ package: "@standardagents/cloudflare",
12633
+ label: "Cloudflare Workers AI",
12634
+ envKeys: ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID"]
12635
+ },
12295
12636
  {
12296
12637
  name: "cerebras",
12297
12638
  package: "@standardagents/cerebras",
12298
12639
  label: "Cerebras",
12299
- envKey: "CEREBRAS_API_KEY"
12640
+ envKeys: ["CEREBRAS_API_KEY"]
12641
+ },
12642
+ {
12643
+ name: "google",
12644
+ package: "@standardagents/google",
12645
+ label: "Google Gemini",
12646
+ envKeys: ["GOOGLE_API_KEY"]
12647
+ },
12648
+ {
12649
+ name: "groq",
12650
+ package: "@standardagents/groq",
12651
+ label: "Groq",
12652
+ envKeys: ["GROQ_API_KEY"]
12300
12653
  },
12301
12654
  {
12302
12655
  name: "openai",
12303
12656
  package: "@standardagents/openai",
12304
12657
  label: "OpenAI",
12305
- envKey: "OPENAI_API_KEY"
12658
+ envKeys: ["OPENAI_API_KEY"]
12306
12659
  },
12307
12660
  {
12308
12661
  name: "openrouter",
12309
12662
  package: "@standardagents/openrouter",
12310
12663
  label: "OpenRouter",
12311
- envKey: "OPENROUTER_API_KEY"
12664
+ envKeys: ["OPENROUTER_API_KEY"]
12665
+ },
12666
+ {
12667
+ name: "xai",
12668
+ package: "@standardagents/xai",
12669
+ label: "xAI",
12670
+ envKeys: ["XAI_API_KEY"]
12312
12671
  }
12313
12672
  ];
12314
12673
  function humanizeProviderName(name) {
@@ -12320,7 +12679,7 @@ function packageToCustomProvider(pkg) {
12320
12679
  name,
12321
12680
  package: pkg,
12322
12681
  label: humanizeProviderName(name),
12323
- envKey: `${name.toUpperCase().replace(/-/g, "_")}_API_KEY`,
12682
+ envKeys: [`${name.toUpperCase().replace(/-/g, "_")}_API_KEY`],
12324
12683
  isCustom: true
12325
12684
  };
12326
12685
  }
@@ -17500,11 +17859,11 @@ export function getVisibleToolNames() {
17500
17859
  import { DurableThread as _BaseDurableThread } from '@standardagents/builder/runtime';
17501
17860
  import { DurableAgentBuilder as _BaseDurableAgentBuilder } from '@standardagents/builder/runtime';
17502
17861
 
17503
- // Import sip WASM module and initializer
17862
+ // Import sip WASM module and readiness helper
17504
17863
  // Static import allows workerd to pre-compile the WASM at bundle time
17505
17864
  // WASM is bundled in builder's dist to avoid transitive dependency resolution issues
17506
17865
  import _sipWasm from '@standardagents/builder/dist/sip.wasm';
17507
- import { initWithWasmModule as _initSipWasm } from '@standardagents/sip';
17866
+ import { ready as _initSipWasm } from '@standardagents/sip';
17508
17867
 
17509
17868
  // Re-export router from virtual:@standardagents-routes
17510
17869
  export { router } from 'virtual:@standardagents-routes';
@@ -17548,7 +17907,7 @@ export class DurableThread extends _BaseDurableThread {
17548
17907
  // blockConcurrencyWhile ensures WASM is ready before handling any requests
17549
17908
  // Pass the statically imported WASM module for workerd to pre-compile
17550
17909
  ctx.blockConcurrencyWhile(async () => {
17551
- await _initSipWasm(_sipWasm);
17910
+ await _initSipWasm({ wasm: _sipWasm });
17552
17911
  });
17553
17912
  }
17554
17913