@standardagents/builder 0.24.5 → 0.24.7

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.
Files changed (54) hide show
  1. package/dist/built-in-routes.js +303 -37
  2. package/dist/built-in-routes.js.map +1 -1
  3. package/dist/client/{ApiKeysView-CmObAp7n.js → ApiKeysView-C_QyBNy2.js} +1 -1
  4. package/dist/client/CenteredContentView-c7OLhxvd.js +1 -0
  5. package/dist/client/CompositionView-DqKI6dJ9.js +32 -0
  6. package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-A1C0eTY7.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-DQIo2wlE.js} +1 -1
  7. package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-D5q8qf4n.js → CopyButton.vue_vue_type_script_setup_true_lang-q-A7DQTq.js} +1 -1
  8. package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-DzPpurCp.js → DataTable.vue_vue_type_script_setup_true_lang-B0UNyBiO.js} +1 -1
  9. package/dist/client/{JsonViewer-CKqMMqjU.js → JsonViewer-DrA7M9_g.js} +1 -1
  10. package/dist/client/{LoginView-BY2NMQQF.js → LoginView-BxbNgfzz.js} +1 -1
  11. package/dist/client/{MarketplaceView-DVEMUvDq.js → MarketplaceView-DXrtN6-0.js} +1 -1
  12. package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-1t6cxO9H.js → Modal.vue_vue_type_script_setup_true_lang-CLZzFYMW.js} +1 -1
  13. package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-WFlATqyT.js → ModelModal.vue_vue_type_script_setup_true_lang-BaLZApRs.js} +1 -1
  14. package/dist/client/{ModelsView-_qZmXle8.js → ModelsView-CVtPgAVZ.js} +1 -1
  15. package/dist/client/{PromptEditView-DzY493YB.js → PromptEditView-Dhc0rBHD.js} +1 -1
  16. package/dist/client/{PromptModal-BQYwnWKw.js → PromptModal-DXt6M359.js} +1 -1
  17. package/dist/client/{PromptsView-DBiQ9X1g.js → PromptsView-y3yvzkjM.js} +1 -1
  18. package/dist/client/{ProvidersView-DEH34_v0.js → ProvidersView-DN-SmDPF.js} +1 -1
  19. package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-lIW3rtYB.js +22 -0
  20. package/dist/client/ThreadsView-B1Xo2bP0.js +1 -0
  21. package/dist/client/{ToolsView-D-qvyctb.js → ToolsView-DYj_Mk9L.js} +1 -1
  22. package/dist/client/{UiCodeBlock.vue_vue_type_script_setup_true_lang-BawOR_eB.js → UiCodeBlock.vue_vue_type_script_setup_true_lang-BH3WC9G_.js} +1 -1
  23. package/dist/client/{UsersView-DaXRB61v.js → UsersView-BLNNFDUM.js} +1 -1
  24. package/dist/client/{VariablesView-DDomn-IB.js → VariablesView-D4-5tNwt.js} +1 -1
  25. package/dist/client/assets/{ThreadInspectorPane-CjK6SKEi.css → ThreadInspectorPane-CGrBd6US.css} +1 -1
  26. package/dist/client/assets/index-B38KmIlM.css +1 -0
  27. package/dist/client/{check-DKLwABgc.js → check-Dkzs1C3V.js} +1 -1
  28. package/dist/client/{chevron-right-DJJGHNE5.js → chevron-right-BGirddPg.js} +1 -1
  29. package/dist/client/{copy-CLWiDcxB.js → copy-C08OR8rY.js} +1 -1
  30. package/dist/client/{formkit-DcuuXZjC.js → formkit-YJ1Z7D5r.js} +1 -1
  31. package/dist/client/{index-DihZBCmQ.js → index-0OxNDXyK.js} +3 -3
  32. package/dist/client/index.html +4 -4
  33. package/dist/client/{package-CarOhnUs.js → package-guyzMTDG.js} +1 -1
  34. package/dist/client/{plus-zGapov7j.js → plus-DG3ZN5wg.js} +1 -1
  35. package/dist/client/{timeAgo-ASgzq6bq.js → timeAgo-D7V247YG.js} +1 -1
  36. package/dist/client/{useActionFeedback-uUrfjlCo.js → useActionFeedback-byARNQjQ.js} +1 -1
  37. package/dist/client/vue-BqC6IZDY.js +1 -0
  38. package/dist/{index-D7KMmRgr.d.ts → index-Bd--_E_1.d.ts} +18 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.js +224 -41
  41. package/dist/index.js.map +1 -1
  42. package/dist/plugin.js +2 -0
  43. package/dist/plugin.js.map +1 -1
  44. package/dist/runtime.d.ts +19 -2
  45. package/dist/runtime.js +222 -41
  46. package/dist/runtime.js.map +1 -1
  47. package/dist/test.d.ts +1 -1
  48. package/package.json +5 -5
  49. package/dist/client/CenteredContentView-gJXa9UHE.js +0 -1
  50. package/dist/client/CompositionView-BohQwGLE.js +0 -32
  51. package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-Dtd1VFrj.js +0 -22
  52. package/dist/client/ThreadsView-m1CAq3Aw.js +0 -1
  53. package/dist/client/assets/index-V68N0r_5.css +0 -1
  54. package/dist/client/vue-2tGL2Ulx.js +0 -1
@@ -224,6 +224,18 @@ function getFallbackPricing(providerName, modelId) {
224
224
  const pricing = getProviderModelPricing(providerName, modelId);
225
225
  return pricing ? toResolvedModelPricing(pricing) : null;
226
226
  }
227
+ function resolveUsageReportedPricing(usage) {
228
+ const pricing = usage.pricing;
229
+ if (!pricing || typeof pricing.inputPerMillion !== "number" || typeof pricing.outputPerMillion !== "number") {
230
+ return null;
231
+ }
232
+ return {
233
+ inputPrice: pricing.inputPerMillion,
234
+ outputPrice: pricing.outputPerMillion,
235
+ cachedPrice: pricing.cachedInputPerMillion,
236
+ source: "provider"
237
+ };
238
+ }
227
239
  function resolveModelPricing(modelDef, providerName) {
228
240
  if (typeof modelDef.inputPrice === "number" && typeof modelDef.outputPrice === "number") {
229
241
  return {
@@ -238,6 +250,12 @@ function resolveModelPricing(modelDef, providerName) {
238
250
  }
239
251
  return null;
240
252
  }
253
+ function calculateRouterFee(rawCost, feePercent) {
254
+ if (!(rawCost > 0) || !(feePercent > 0)) {
255
+ return 0;
256
+ }
257
+ return roundCost(rawCost * feePercent / 100);
258
+ }
241
259
  function calculateUsageCost(usage, pricing) {
242
260
  if (!pricing) {
243
261
  return null;
@@ -268,6 +286,66 @@ var init_pricing = __esm({
268
286
  TOKENS_PER_MILLION = 1e6;
269
287
  }
270
288
  });
289
+
290
+ // src/agents/providers/router-fee.ts
291
+ function requestUrl(input) {
292
+ if (typeof input === "string") return input;
293
+ if (input instanceof URL) return input.toString();
294
+ if (typeof input === "object" && input !== null && typeof input.url === "string") {
295
+ return input.url;
296
+ }
297
+ return null;
298
+ }
299
+ function observeResponse(url, headers) {
300
+ if (!url) return;
301
+ for (const origin of registeredOrigins) {
302
+ if (!url.startsWith(`${origin}/v1/proxy/`)) continue;
303
+ const raw = headers.get(ROUTER_FEE_HEADER);
304
+ if (raw !== null) {
305
+ const percent = Number(raw);
306
+ if (Number.isFinite(percent) && percent >= 0) {
307
+ observedFeePercentByOrigin.set(origin, percent);
308
+ }
309
+ }
310
+ return;
311
+ }
312
+ }
313
+ function installObserver() {
314
+ if (observerInstalled) return;
315
+ const original = globalThis.fetch;
316
+ if (typeof original !== "function") return;
317
+ const bound = original.bind(globalThis);
318
+ const wrapped = async (input, init) => {
319
+ const response = await bound(input, init);
320
+ try {
321
+ observeResponse(requestUrl(input), response.headers);
322
+ } catch {
323
+ }
324
+ return response;
325
+ };
326
+ try {
327
+ globalThis.fetch = wrapped;
328
+ observerInstalled = true;
329
+ } catch {
330
+ }
331
+ }
332
+ function registerPlatformProxyOrigin(origin) {
333
+ if (!origin) return;
334
+ registeredOrigins.add(origin.replace(/\/+$/, ""));
335
+ installObserver();
336
+ }
337
+ function getObservedRouterFeePercent(origin) {
338
+ return observedFeePercentByOrigin.get(origin.replace(/\/+$/, "")) ?? null;
339
+ }
340
+ var ROUTER_FEE_HEADER, registeredOrigins, observedFeePercentByOrigin, observerInstalled;
341
+ var init_router_fee = __esm({
342
+ "src/agents/providers/router-fee.ts"() {
343
+ ROUTER_FEE_HEADER = "X-Standard-Agents-Router-Fee-Percent";
344
+ registeredOrigins = /* @__PURE__ */ new Set();
345
+ observedFeePercentByOrigin = /* @__PURE__ */ new Map();
346
+ observerInstalled = false;
347
+ }
348
+ });
271
349
  async function readCompletedArg(partialJson, argName) {
272
350
  if (!partialJson || !argName) return void 0;
273
351
  try {
@@ -827,6 +905,7 @@ var init_ProviderRegistry = __esm({
827
905
  "src/agents/providers/ProviderRegistry.ts"() {
828
906
  init_TestProvider();
829
907
  init_platform_routing();
908
+ init_router_fee();
830
909
  init_factory();
831
910
  ProviderRegistryImpl = class {
832
911
  providerCache = /* @__PURE__ */ new Map();
@@ -921,21 +1000,22 @@ var init_ProviderRegistry = __esm({
921
1000
  apiKey: routing.apiKey,
922
1001
  baseUrl: routing.baseUrl
923
1002
  };
1003
+ registerPlatformProxyOrigin(routing.origin);
924
1004
  const fingerprint = this.getProviderFingerprint(`platform:${providerName}`, modelDef, config);
925
1005
  const cached = this.providerCache.get(modelName);
926
1006
  if (cached?.fingerprint === fingerprint) {
927
- return this.buildResult(cached.provider, modelDef, true);
1007
+ return this.buildResult(cached.provider, modelDef, true, routing.origin);
928
1008
  }
929
- return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint, true);
1009
+ return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint, true, routing.origin);
930
1010
  }
931
1011
  throw new Error(`No API key found for provider: ${providerName}. Set the provider key or STANDARD_AGENTS_API_KEY.`);
932
1012
  }
933
- buildResult(provider, modelDef, viaPlatform) {
934
- return { provider, modelName: modelDef.model, modelDef, viaPlatform };
1013
+ buildResult(provider, modelDef, viaPlatform, platformProxyOrigin) {
1014
+ return { provider, modelName: modelDef.model, modelDef, viaPlatform, platformProxyOrigin };
935
1015
  }
936
- cacheAndReturn(modelName, provider, modelDef, fingerprint, viaPlatform) {
1016
+ cacheAndReturn(modelName, provider, modelDef, fingerprint, viaPlatform, platformProxyOrigin) {
937
1017
  this.providerCache.set(modelName, { provider, fingerprint, viaPlatform });
938
- return this.buildResult(provider, modelDef, viaPlatform);
1018
+ return this.buildResult(provider, modelDef, viaPlatform, platformProxyOrigin);
939
1019
  }
940
1020
  getProviderFingerprint(providerName, modelDef, config) {
941
1021
  return JSON.stringify({
@@ -1374,7 +1454,8 @@ function convertUsage(usage) {
1374
1454
  prompt_tokens_details: usage.cachedTokens ? { cached_tokens: usage.cachedTokens } : void 0,
1375
1455
  completion_tokens_details: usage.reasoningTokens ? { reasoning_tokens: usage.reasoningTokens } : void 0,
1376
1456
  cost: usage.cost,
1377
- provider: usage.provider
1457
+ provider: usage.provider,
1458
+ pricing: usage.pricing
1378
1459
  };
1379
1460
  }
1380
1461
  function inferProviderFromModelId(model) {
@@ -1398,6 +1479,7 @@ var NON_VISION_PLACEHOLDER_TEXT, STREAM_FIRST_CHUNK_TIMEOUT_MS, STREAM_STALL_TIM
1398
1479
  var init_LLMRequest = __esm({
1399
1480
  "src/agents/LLMRequest.ts"() {
1400
1481
  init_pricing();
1482
+ init_router_fee();
1401
1483
  init_types();
1402
1484
  init_FlowEngine();
1403
1485
  init_toolProgress();
@@ -1661,11 +1743,7 @@ var init_LLMRequest = __esm({
1661
1743
  */
1662
1744
  static async callModel(modelId, context, state, logId) {
1663
1745
  const { ProviderRegistry: ProviderRegistry2 } = await Promise.resolve().then(() => (init_providers(), providers_exports));
1664
- const { provider, modelName, modelDef, viaPlatform } = await ProviderRegistry2.getProvider(
1665
- modelId,
1666
- state.env,
1667
- state.thread.instance
1668
- );
1746
+ const { provider, modelName, modelDef, viaPlatform, platformProxyOrigin } = await ProviderRegistry2.getProvider(modelId, state.env, state.thread.instance);
1669
1747
  const streamAbort = new AbortController();
1670
1748
  const parentSignal = state.abortController?.signal;
1671
1749
  let onParentAbort;
@@ -1944,6 +2022,12 @@ var init_LLMRequest = __esm({
1944
2022
  };
1945
2023
  response._provider = provider;
1946
2024
  response._viaPlatform = viaPlatform;
2025
+ if (platformProxyOrigin) {
2026
+ const feePercent = getObservedRouterFeePercent(platformProxyOrigin);
2027
+ if (feePercent !== null) {
2028
+ response._routerFeePercent = feePercent;
2029
+ }
2030
+ }
1947
2031
  response._providerResponseId = providerResponseId;
1948
2032
  response._timing = {
1949
2033
  latencyMs: firstChunkAt > 0 ? firstChunkAt - requestSentAt : null,
@@ -2069,10 +2153,13 @@ var init_LLMRequest = __esm({
2069
2153
  const toolsCalled = response.tool_calls ? JSON.stringify(response.tool_calls.map((tc) => tc.function.name)) : null;
2070
2154
  const providerName = response._provider?.name;
2071
2155
  const standardAgentsRouterUsed = response._viaPlatform === true || providerName === "platform";
2072
- const resolvedPricing = resolveModelPricing(modelDef, providerName);
2156
+ const resolvedPricing = resolveModelPricing(modelDef) ?? resolveUsageReportedPricing(response.usage) ?? resolveModelPricing(modelDef, providerName);
2073
2157
  const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
2074
2158
  const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
2075
- const cost_total = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
2159
+ const rawProviderCost = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
2160
+ const routerFeePercent = standardAgentsRouterUsed && typeof response._routerFeePercent === "number" && response._routerFeePercent > 0 ? response._routerFeePercent : null;
2161
+ const costRouterFee = routerFeePercent !== null && rawProviderCost !== null ? calculateRouterFee(rawProviderCost, routerFeePercent) : null;
2162
+ const cost_total = rawProviderCost !== null && costRouterFee !== null && costRouterFee > 0 ? roundCost(rawProviderCost + costRouterFee) : rawProviderCost;
2076
2163
  const actualProvider = normalizeProviderMetadataValue(response.usage.provider) ?? null;
2077
2164
  const aggregateResponse = response._aggregate_response;
2078
2165
  const responseBody = aggregateResponse ? JSON.stringify(aggregateResponse) : JSON.stringify(response);
@@ -2138,6 +2225,8 @@ var init_LLMRequest = __esm({
2138
2225
  cost_input: calculatedCost?.costInput,
2139
2226
  cost_cached: calculatedCost?.costCached,
2140
2227
  cost_output: calculatedCost?.costOutput,
2228
+ cost_router_fee: costRouterFee ?? void 0,
2229
+ router_fee_percent: routerFeePercent ?? void 0,
2141
2230
  latency_ms: Date.now() - startTime,
2142
2231
  time_to_first_token_ms: timing?.latencyMs ?? void 0,
2143
2232
  generation_ms: timing?.generationMs ?? void 0,
@@ -2178,8 +2267,10 @@ var init_LLMRequest = __esm({
2178
2267
  actual_provider = ?17,
2179
2268
  standard_agents_router_used = ?18,
2180
2269
  time_to_first_token_ms = ?19,
2181
- generation_ms = ?20
2182
- WHERE id = ?21
2270
+ generation_ms = ?20,
2271
+ cost_router_fee = ?21,
2272
+ router_fee_percent = ?22
2273
+ WHERE id = ?23
2183
2274
  `,
2184
2275
  logData.response_body,
2185
2276
  logData.input_tokens,
@@ -2201,6 +2292,8 @@ var init_LLMRequest = __esm({
2201
2292
  standardAgentsRouterUsed ? 1 : 0,
2202
2293
  logData.time_to_first_token_ms ?? null,
2203
2294
  logData.generation_ms ?? null,
2295
+ logData.cost_router_fee ?? null,
2296
+ logData.router_fee_percent ?? null,
2204
2297
  logId
2205
2298
  );
2206
2299
  }
@@ -2539,9 +2632,24 @@ ${errorStack}` : ""}${errorDetails}`;
2539
2632
  updates.push(`actual_provider = ?${paramIndex++}`);
2540
2633
  values.push(actualProvider);
2541
2634
  }
2635
+ let updatedCostTotal;
2636
+ let updatedRouterFee;
2542
2637
  if (metadata.generation_cost !== void 0) {
2638
+ updatedCostTotal = metadata.generation_cost;
2639
+ const rawCost = typeof metadata.generation_cost === "number" ? metadata.generation_cost : Number(metadata.generation_cost);
2640
+ if (Number.isFinite(rawCost)) {
2641
+ const feePercent = await this.readRouterFeePercent(state, logId);
2642
+ if (feePercent !== null && feePercent > 0) {
2643
+ updatedRouterFee = calculateRouterFee(rawCost, feePercent);
2644
+ updatedCostTotal = roundCost(rawCost + updatedRouterFee);
2645
+ }
2646
+ }
2543
2647
  updates.push(`cost_total = ?${paramIndex++}`);
2544
- values.push(metadata.generation_cost);
2648
+ values.push(updatedCostTotal);
2649
+ if (updatedRouterFee !== void 0) {
2650
+ updates.push(`cost_router_fee = ?${paramIndex++}`);
2651
+ values.push(updatedRouterFee);
2652
+ }
2545
2653
  }
2546
2654
  if (updates.length === 0) {
2547
2655
  return;
@@ -2556,7 +2664,8 @@ ${errorStack}` : ""}${errorDetails}`;
2556
2664
  data: {
2557
2665
  id: logId,
2558
2666
  ...actualProvider !== void 0 && { actual_provider: actualProvider },
2559
- ...metadata.generation_cost !== void 0 && { cost_total: metadata.generation_cost }
2667
+ ...metadata.generation_cost !== void 0 && { cost_total: updatedCostTotal },
2668
+ ...updatedRouterFee !== void 0 && { cost_router_fee: updatedRouterFee }
2560
2669
  }
2561
2670
  });
2562
2671
  }
@@ -2564,6 +2673,23 @@ ${errorStack}` : ""}${errorDetails}`;
2564
2673
  console.error("Failed to update log with metadata (non-fatal):", error);
2565
2674
  }
2566
2675
  }
2676
+ /**
2677
+ * Router-fee percent recorded on a log row by logSuccess, or null when the
2678
+ * row has none (BYOK) or the storage shape doesn't expose it.
2679
+ */
2680
+ static async readRouterFeePercent(state, logId) {
2681
+ try {
2682
+ const cursor = await state.storage.sql.exec(
2683
+ `SELECT router_fee_percent FROM logs WHERE id = ?`,
2684
+ logId
2685
+ );
2686
+ const row = cursor?.toArray?.()[0];
2687
+ const percent = row?.router_fee_percent;
2688
+ return typeof percent === "number" && Number.isFinite(percent) ? percent : null;
2689
+ } catch {
2690
+ return null;
2691
+ }
2692
+ }
2567
2693
  };
2568
2694
  }
2569
2695
  });
@@ -54700,11 +54826,17 @@ function transformChatAssistantMessage3(msg) {
54700
54826
  }));
54701
54827
  }
54702
54828
  if (msg.reasoningDetails && msg.reasoningDetails.length > 0) {
54703
- const details = msg.reasoningDetails.filter((detail) => detail.type !== "encrypted" || typeof detail.data === "string" && detail.data.length > 0).map((detail) => {
54704
- if (detail.type === "text") {
54829
+ const details = msg.reasoningDetails.filter((detail) => {
54830
+ const type = detail.type;
54831
+ if (type !== "encrypted" && type !== "reasoning.encrypted") return true;
54832
+ return typeof detail.data === "string" && detail.data.length > 0;
54833
+ }).map((detail) => {
54834
+ const type = detail.type;
54835
+ const legacy = detail;
54836
+ if (type === "text" || type === "reasoning.text") {
54705
54837
  return { type: "reasoning.text", text: detail.text, format: detail.format };
54706
- } else if (detail.type === "summary") {
54707
- return { type: "reasoning.summary", summary: detail.text, format: detail.format };
54838
+ } else if (type === "summary" || type === "reasoning.summary") {
54839
+ return { type: "reasoning.summary", summary: detail.text ?? legacy.summary, format: detail.format };
54708
54840
  }
54709
54841
  return { type: "reasoning.encrypted", data: detail.data, id: detail.id, format: detail.format };
54710
54842
  });
@@ -56247,6 +56379,25 @@ function getModelIconDataUri(modelId) {
56247
56379
  }
56248
56380
  return void 0;
56249
56381
  }
56382
+ function usagePricingFromCatalogPricing(pricing) {
56383
+ if (!pricing) return void 0;
56384
+ const perMillion = (value) => {
56385
+ if (value === void 0) return void 0;
56386
+ const parsed = Number.parseFloat(value);
56387
+ if (!Number.isFinite(parsed)) return void 0;
56388
+ return Number((parsed * 1e6).toFixed(12));
56389
+ };
56390
+ const inputPerMillion = perMillion(pricing.prompt);
56391
+ const outputPerMillion = perMillion(pricing.completion);
56392
+ if (inputPerMillion === void 0 || outputPerMillion === void 0) {
56393
+ return void 0;
56394
+ }
56395
+ return {
56396
+ inputPerMillion,
56397
+ cachedInputPerMillion: perMillion(pricing.input_cache_read),
56398
+ outputPerMillion
56399
+ };
56400
+ }
56250
56401
  var OPENROUTER_SERVER_TOOL_NAMES, google_default3, meta_default4, mistralai_default3, moonshotai_default3, nvidia_default2, openai_default5, qwen_default4, zai_org_default4, ANTHROPIC_ICON2, GOOGLE_ICON3, META_ICON3, NVIDIA_ICON, ALIBABA_ICON2, DEEPSEEK_ICON2, QWEN_ICON2, MINIMAX_ICON, MOONSHOTAI_ICON, XAI_ICON, ZAI_ICON3, EXAONE_ICON, OPENROUTER_ICON, OPENAI_ICON4, MISTRAL_ICON2, COHERE_ICON, PERPLEXITY_ICON, LAB_ICONS, OPENROUTER_PROVIDER_ICON_PREFIX, OPENROUTER_PROVIDER_URL_ENTRIES, OPENROUTER_PROVIDER_URLS, OpenRouterProvider, percentileSchema, providerRoutingSchema, serverToolParametersSchema, serverToolsSchema, openrouterProviderOptions, openrouter;
56251
56402
  var init_dist6 = __esm({
56252
56403
  "../openrouter/dist/index.js"() {
@@ -56548,6 +56699,11 @@ var init_dist6 = __esm({
56548
56699
  static modelsCacheTime = 0;
56549
56700
  static CACHE_TTL = 5 * 60 * 1e3;
56550
56701
  // 5 minutes
56702
+ /** In-flight catalog download shared by concurrent callers. */
56703
+ static modelsFetchPromise = null;
56704
+ /** Timestamp of the last failed catalog fetch, for negative caching. */
56705
+ static modelsFetchFailedAt = 0;
56706
+ static FAILURE_RETRY_MS = 60 * 1e3;
56551
56707
  /**
56552
56708
  * Get capabilities for a specific model.
56553
56709
  * Fetches from OpenRouter's models API which provides rich metadata.
@@ -56565,19 +56721,73 @@ var init_dist6 = __esm({
56565
56721
  return null;
56566
56722
  }
56567
56723
  }
56724
+ /**
56725
+ * How long a streaming finish chunk may wait on the catalog pricing lookup.
56726
+ * The lookup is started when the stream starts, so by finish time it is
56727
+ * almost always resolved; the bound guarantees a slow catalog download can
56728
+ * never stall the finish chunk into the runtime's stream watchdog.
56729
+ */
56730
+ static USAGE_PRICING_FINISH_WAIT_MS = 2500;
56731
+ static async settleUsagePricing(pricingPromise) {
56732
+ let timer;
56733
+ const timeout = new Promise((resolve2) => {
56734
+ timer = setTimeout(() => resolve2(void 0), _OpenRouterProvider.USAGE_PRICING_FINISH_WAIT_MS);
56735
+ });
56736
+ try {
56737
+ return await Promise.race([pricingPromise, timeout]);
56738
+ } finally {
56739
+ if (timer !== void 0) clearTimeout(timer);
56740
+ }
56741
+ }
56742
+ /** Bounded-wait pricing attachment shared by the non-streaming paths. */
56743
+ async attachUsagePricing(result, pricingPromise) {
56744
+ const pricing = await _OpenRouterProvider.settleUsagePricing(pricingPromise);
56745
+ if (pricing) result.usage.pricing = pricing;
56746
+ return result;
56747
+ }
56748
+ /**
56749
+ * Exact unit prices for a model from OpenRouter's live catalog (cached),
56750
+ * attached to response usage so request logs can record specific prices.
56751
+ * Best-effort: any failure just leaves pricing off the usage payload.
56752
+ */
56753
+ async getUsagePricing(modelId) {
56754
+ if (!modelId) return void 0;
56755
+ try {
56756
+ const models = await this.fetchModelsWithCache();
56757
+ const model = models.find((m) => m.id === modelId);
56758
+ return usagePricingFromCatalogPricing(model?.pricing);
56759
+ } catch {
56760
+ return void 0;
56761
+ }
56762
+ }
56568
56763
  async fetchModelsWithCache() {
56569
56764
  const now = Date.now();
56570
56765
  if (_OpenRouterProvider.modelsCache && now - _OpenRouterProvider.modelsCacheTime < _OpenRouterProvider.CACHE_TTL) {
56571
56766
  return _OpenRouterProvider.modelsCache;
56572
56767
  }
56573
- const response = await fetch("https://openrouter.ai/api/v1/models");
56574
- if (!response.ok) {
56575
- throw new Error(`OpenRouter API error: ${response.status}`);
56768
+ if (now - _OpenRouterProvider.modelsFetchFailedAt < _OpenRouterProvider.FAILURE_RETRY_MS) {
56769
+ throw new Error("OpenRouter models fetch recently failed");
56576
56770
  }
56577
- const data = await response.json();
56578
- _OpenRouterProvider.modelsCache = data.data || [];
56579
- _OpenRouterProvider.modelsCacheTime = now;
56580
- return _OpenRouterProvider.modelsCache;
56771
+ if (!_OpenRouterProvider.modelsFetchPromise) {
56772
+ _OpenRouterProvider.modelsFetchPromise = (async () => {
56773
+ try {
56774
+ const response = await fetch("https://openrouter.ai/api/v1/models");
56775
+ if (!response.ok) {
56776
+ throw new Error(`OpenRouter API error: ${response.status}`);
56777
+ }
56778
+ const data = await response.json();
56779
+ _OpenRouterProvider.modelsCache = data.data || [];
56780
+ _OpenRouterProvider.modelsCacheTime = Date.now();
56781
+ return _OpenRouterProvider.modelsCache;
56782
+ } catch (error) {
56783
+ _OpenRouterProvider.modelsFetchFailedAt = Date.now();
56784
+ throw error;
56785
+ } finally {
56786
+ _OpenRouterProvider.modelsFetchPromise = null;
56787
+ }
56788
+ })();
56789
+ }
56790
+ return _OpenRouterProvider.modelsFetchPromise;
56581
56791
  }
56582
56792
  mapOpenRouterCapabilities(model) {
56583
56793
  const capabilities = {
@@ -56662,6 +56872,7 @@ var init_dist6 = __esm({
56662
56872
  if (this.config.providers && this.config.providers.length > 0) {
56663
56873
  params.provider = { only: this.config.providers };
56664
56874
  }
56875
+ const pricingPromise = this.getUsagePricing(params.model);
56665
56876
  const response = await fetch(`${baseUrl}/chat/completions`, {
56666
56877
  method: "POST",
56667
56878
  headers: {
@@ -56683,7 +56894,7 @@ var init_dist6 = __esm({
56683
56894
  throw new ProviderError(errorMessage, "invalid_request", response.status);
56684
56895
  }
56685
56896
  const data = await response.json();
56686
- return transformChatResponse3(data);
56897
+ return this.attachUsagePricing(transformChatResponse3(data), pricingPromise);
56687
56898
  } catch (error) {
56688
56899
  throw this.toProviderError(error);
56689
56900
  }
@@ -56697,6 +56908,7 @@ var init_dist6 = __esm({
56697
56908
  try {
56698
56909
  const params = buildCreateParams3(request);
56699
56910
  this.applyConfiguredProvidersToResponses(params);
56911
+ const pricingPromise = this.getUsagePricing(params.model);
56700
56912
  if (this.hasOpenRouterServerTools(params)) {
56701
56913
  const response2 = await fetch(`${baseUrl}/responses`, {
56702
56914
  method: "POST",
@@ -56714,14 +56926,14 @@ var init_dist6 = __esm({
56714
56926
  await this.throwOpenRouterFetchError(response2);
56715
56927
  }
56716
56928
  const data = await response2.json();
56717
- return transformResponse3(data);
56929
+ return this.attachUsagePricing(transformResponse3(data), pricingPromise);
56718
56930
  }
56719
56931
  const client = await this.getClient();
56720
56932
  const response = await client.beta.responses.send({
56721
56933
  ...this.toSdkResponsesRequest(params),
56722
56934
  stream: false
56723
56935
  });
56724
- return transformResponse3(response);
56936
+ return this.attachUsagePricing(transformResponse3(response), pricingPromise);
56725
56937
  } catch (error) {
56726
56938
  throw this.toProviderError(error);
56727
56939
  }
@@ -56745,6 +56957,7 @@ var init_dist6 = __esm({
56745
56957
  if (this.config.providers && this.config.providers.length > 0) {
56746
56958
  params.provider = { only: this.config.providers };
56747
56959
  }
56960
+ const pricingPromise = this.getUsagePricing(params.model);
56748
56961
  const response = await fetch(`${baseUrl}/chat/completions`, {
56749
56962
  method: "POST",
56750
56963
  headers: {
@@ -56784,6 +56997,10 @@ var init_dist6 = __esm({
56784
56997
  }
56785
56998
  }
56786
56999
  if (finishChunk) {
57000
+ if (finishChunk.type === "finish") {
57001
+ const pricing = await _OpenRouterProvider.settleUsagePricing(pricingPromise);
57002
+ if (pricing) finishChunk.usage.pricing = pricing;
57003
+ }
56787
57004
  const finishWithMeta = {
56788
57005
  ...finishChunk,
56789
57006
  _asyncMetadata: responseId ? {
@@ -56814,6 +57031,7 @@ var init_dist6 = __esm({
56814
57031
  try {
56815
57032
  const params = buildCreateParams3(request);
56816
57033
  this.applyConfiguredProvidersToResponses(params);
57034
+ const pricingPromise = this.getUsagePricing(params.model);
56817
57035
  const response = await fetch(`${baseUrl}/responses`, {
56818
57036
  method: "POST",
56819
57037
  headers: {
@@ -56852,6 +57070,10 @@ var init_dist6 = __esm({
56852
57070
  }
56853
57071
  }
56854
57072
  if (finishChunk) {
57073
+ if (finishChunk.type === "finish") {
57074
+ const pricing = await _OpenRouterProvider.settleUsagePricing(pricingPromise);
57075
+ if (pricing) finishChunk.usage.pricing = pricing;
57076
+ }
56855
57077
  const finishWithMeta = {
56856
57078
  ...finishChunk,
56857
57079
  // Include what's needed to fetch metadata later
@@ -64601,8 +64823,8 @@ function getHostname(urlValue) {
64601
64823
  return null;
64602
64824
  }
64603
64825
  }
64604
- function deriveOrbPlatformEndpoint(requestUrl) {
64605
- const requestHost = getHostname(requestUrl);
64826
+ function deriveOrbPlatformEndpoint(requestUrl2) {
64827
+ const requestHost = getHostname(requestUrl2);
64606
64828
  if (!requestHost) return null;
64607
64829
  const match2 = requestHost.match(ORB_CORE_HOST_PATTERN);
64608
64830
  if (!match2 || !match2[1]) return null;
@@ -69112,14 +69334,34 @@ var continue_post_default = defineController2(async ({ req, params, env: env2 })
69112
69334
 
69113
69335
  // src/agents/cost-summary.ts
69114
69336
  function emptyCostSummary() {
69115
- return { totalCost: 0, requestCount: 0, messageCount: 0, byModel: {} };
69337
+ return {
69338
+ totalCost: 0,
69339
+ inputCost: 0,
69340
+ cachedCost: 0,
69341
+ outputCost: 0,
69342
+ routerFeeCost: 0,
69343
+ requestCount: 0,
69344
+ messageCount: 0,
69345
+ byModel: {}
69346
+ };
69116
69347
  }
69117
69348
  function mergeByModel(summaries) {
69118
69349
  const merged = {};
69119
69350
  for (const summary of summaries) {
69120
69351
  for (const [modelName, acc] of Object.entries(summary.byModel)) {
69121
- const entry = merged[modelName] ?? { totalCost: 0, count: 0 };
69352
+ const entry = merged[modelName] ?? {
69353
+ totalCost: 0,
69354
+ inputCost: 0,
69355
+ cachedCost: 0,
69356
+ outputCost: 0,
69357
+ routerFeeCost: 0,
69358
+ count: 0
69359
+ };
69122
69360
  entry.totalCost += acc.totalCost;
69361
+ entry.inputCost = (entry.inputCost ?? 0) + (acc.inputCost ?? 0);
69362
+ entry.cachedCost = (entry.cachedCost ?? 0) + (acc.cachedCost ?? 0);
69363
+ entry.outputCost = (entry.outputCost ?? 0) + (acc.outputCost ?? 0);
69364
+ entry.routerFeeCost = (entry.routerFeeCost ?? 0) + (acc.routerFeeCost ?? 0);
69123
69365
  entry.count += acc.count;
69124
69366
  merged[modelName] = entry;
69125
69367
  }
@@ -69128,19 +69370,31 @@ function mergeByModel(summaries) {
69128
69370
  }
69129
69371
  function sumSummaries(summaries) {
69130
69372
  let totalCost = 0;
69373
+ let inputCost = 0;
69374
+ let cachedCost = 0;
69375
+ let outputCost = 0;
69376
+ let routerFeeCost = 0;
69131
69377
  let requestCount = 0;
69132
69378
  let messageCount = 0;
69133
69379
  for (const summary of summaries) {
69134
69380
  totalCost += summary.totalCost;
69381
+ inputCost += summary.inputCost ?? 0;
69382
+ cachedCost += summary.cachedCost ?? 0;
69383
+ outputCost += summary.outputCost ?? 0;
69384
+ routerFeeCost += summary.routerFeeCost ?? 0;
69135
69385
  requestCount += summary.requestCount;
69136
69386
  messageCount += summary.messageCount;
69137
69387
  }
69138
- return { totalCost, requestCount, messageCount };
69388
+ return { totalCost, inputCost, cachedCost, outputCost, routerFeeCost, requestCount, messageCount };
69139
69389
  }
69140
69390
  function buildModelBreakdown(byModel) {
69141
69391
  return Object.entries(byModel).map(([modelName, acc]) => ({
69142
69392
  modelName,
69143
69393
  totalCost: acc.totalCost,
69394
+ inputCost: acc.inputCost ?? 0,
69395
+ cachedCost: acc.cachedCost ?? 0,
69396
+ outputCost: acc.outputCost ?? 0,
69397
+ routerFeeCost: acc.routerFeeCost ?? 0,
69144
69398
  requestCount: acc.count,
69145
69399
  avgCostPerRequest: acc.count > 0 ? acc.totalCost / acc.count : 0
69146
69400
  })).sort((a, b) => b.totalCost - a.totalCost);
@@ -69215,6 +69469,10 @@ var cost_get_default = defineController2(async ({ req, params, env: env2 }) => {
69215
69469
  parent: null,
69216
69470
  isRoot: true,
69217
69471
  totalCost: ownSummary.totalCost,
69472
+ inputCost: ownSummary.inputCost ?? 0,
69473
+ cachedCost: ownSummary.cachedCost ?? 0,
69474
+ outputCost: ownSummary.outputCost ?? 0,
69475
+ routerFeeCost: ownSummary.routerFeeCost ?? 0,
69218
69476
  requestCount: ownSummary.requestCount
69219
69477
  },
69220
69478
  ...descendants.map((child, index) => ({
@@ -69224,11 +69482,19 @@ var cost_get_default = defineController2(async ({ req, params, env: env2 }) => {
69224
69482
  parent: child.parent,
69225
69483
  isRoot: false,
69226
69484
  totalCost: descendantSummaries[index]?.totalCost ?? 0,
69485
+ inputCost: descendantSummaries[index]?.inputCost ?? 0,
69486
+ cachedCost: descendantSummaries[index]?.cachedCost ?? 0,
69487
+ outputCost: descendantSummaries[index]?.outputCost ?? 0,
69488
+ routerFeeCost: descendantSummaries[index]?.routerFeeCost ?? 0,
69227
69489
  requestCount: descendantSummaries[index]?.requestCount ?? 0
69228
69490
  })).filter((row) => row.requestCount > 0)
69229
69491
  ];
69230
69492
  return Response.json({
69231
69493
  totalCost: totals.totalCost,
69494
+ inputCost: totals.inputCost,
69495
+ cachedCost: totals.cachedCost,
69496
+ outputCost: totals.outputCost,
69497
+ routerFeeCost: totals.routerFeeCost,
69232
69498
  ownCost: ownSummary.totalCost,
69233
69499
  requestCount: totals.requestCount,
69234
69500
  messageCount: totals.messageCount,