@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
package/dist/runtime.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { e as ThreadEnv, A as Agent, h as ThreadMetadata, i as ToolResult, M as Message, l as FileRecord, F as FlowState, n as FileStats, G as GrepResult, m as AttachmentRef, r as MessageContent, E as Env, g as ThreadInstance } from './index-D7KMmRgr.js';
2
- export { f as BuilderThreadEndpointHandler, B as Controller, a as ControllerContext, j as FlowResult, p as ImageContentPart, I as ImageMetadata, L as LLMResponse, q as MultimodalContent, R as RequestContext, S as StorageBackend, k as TelemetryEvent, o as TextContentPart, b as ThreadEndpointContext, T as ToolCall, c as createThreadEndpointHandler, d as defineController } from './index-D7KMmRgr.js';
1
+ import { e as ThreadEnv, A as Agent, h as ThreadMetadata, i as ToolResult, M as Message, l as FileRecord, F as FlowState, n as FileStats, G as GrepResult, m as AttachmentRef, r as MessageContent, E as Env, g as ThreadInstance } from './index-Bd--_E_1.js';
2
+ export { f as BuilderThreadEndpointHandler, B as Controller, a as ControllerContext, j as FlowResult, p as ImageContentPart, I as ImageMetadata, L as LLMResponse, q as MultimodalContent, R as RequestContext, S as StorageBackend, k as TelemetryEvent, o as TextContentPart, b as ThreadEndpointContext, T as ToolCall, c as createThreadEndpointHandler, d as defineController } from './index-Bd--_E_1.js';
3
3
  import { CodeExecutionOptions, CodeExecutionResult, SubagentRegistryEntry, InjectMessageInput, QueueMessageInput, ClientToolRequest, ClientToolResponse, SkillMetadata, SkillFileInput, ModelDefinition as ModelDefinition$1, ToolArgs, PromptTextPart, PromptEnvPart, VariableDefinition, SubpromptConfig as SubpromptConfig$1, PromptToolConfig as PromptToolConfig$1, SubagentToolConfig as SubagentToolConfig$1, ReasoningConfig, SideConfig as SideConfig$1, LLMProviderInterface, ContentPart, TextPart, ImagePart, FilePart, NamespaceContext, DefinitionLoader } from '@standardagents/spec';
4
4
  export { AgentType, DefinitionLoader, GlobalNamespaceContext, HookSignatures, ImageContent, ModelCapabilities, ModelProvider, NamespaceContext, PackageSignature, PackedExports, PackedMeta, PackedMetadata, PackedNamespaceContext, PromptInput, PromptTextPart, ProviderAssistantMessage, ProviderError, ProviderErrorCode, ProviderFactory, ProviderFactoryConfig, ProviderFinishReason, ProviderGeneratedImage, ProviderMessage, ProviderMessageContent, ModelCapabilities as ProviderModelCapabilities, ProviderReasoningDetail, ProviderRequest, ProviderResponse, ProviderStreamChunk, ProviderSystemMessage, ProviderTool, ProviderToolCallPart, ProviderToolMessage, ProviderToolResultContent, ProviderUsage, ProviderUserMessage, ReasoningConfig, StructuredPrompt, TextContent, Tool, ToolArgs, ToolArgsNode, ToolArgsRawShape, ToolContent, belongsToPackage, defineAgent, defineHook, defineModel, definePrompt, defineTool, isPacked, isVisibleInNamespace, mapReasoningLevel } from '@standardagents/spec';
5
5
  import { DurableObject, WorkerEntrypoint } from 'cloudflare:workers';
@@ -738,6 +738,7 @@ declare class DurableThread<Env extends ThreadEnv = ThreadEnv> extends DurableOb
738
738
  error: string | null;
739
739
  cost_total: number | null;
740
740
  input_tokens: number | null;
741
+ cached_tokens: number | null;
741
742
  output_tokens: number | null;
742
743
  total_tokens: number | null;
743
744
  is_complete: boolean;
@@ -755,10 +756,18 @@ declare class DurableThread<Env extends ThreadEnv = ThreadEnv> extends DurableOb
755
756
  */
756
757
  getCostSummary(): Promise<{
757
758
  totalCost: number;
759
+ inputCost: number;
760
+ cachedCost: number;
761
+ outputCost: number;
762
+ routerFeeCost: number;
758
763
  requestCount: number;
759
764
  messageCount: number;
760
765
  byModel: Record<string, {
761
766
  totalCost: number;
767
+ inputCost: number;
768
+ cachedCost: number;
769
+ outputCost: number;
770
+ routerFeeCost: number;
762
771
  count: number;
763
772
  }>;
764
773
  }>;
@@ -848,6 +857,8 @@ declare class DurableThread<Env extends ThreadEnv = ThreadEnv> extends DurableOb
848
857
  cost_input: number | null;
849
858
  cost_cached: number | null;
850
859
  cost_output: number | null;
860
+ cost_router_fee: number | null;
861
+ router_fee_percent: number | null;
851
862
  cost_total: number | null;
852
863
  message_history_length: number | null;
853
864
  tools_available: number | null;
@@ -3305,6 +3316,12 @@ interface ProviderLookupResult {
3305
3316
  modelDef: ModelDefinition$1<string>;
3306
3317
  /** True when requests route through the Standard Agents platform (hosted routing or a registered override). */
3307
3318
  viaPlatform: boolean;
3319
+ /**
3320
+ * Platform origin serving the passthrough proxy when built-in hosted routing
3321
+ * is active. Lets request logging look up the router-fee percent observed on
3322
+ * this origin's proxied responses.
3323
+ */
3324
+ platformProxyOrigin?: string;
3308
3325
  }
3309
3326
  /**
3310
3327
  * Provider registry implementation
package/dist/runtime.js CHANGED
@@ -208,6 +208,18 @@ function getFallbackPricing(providerName, modelId) {
208
208
  const pricing = getProviderModelPricing(providerName, modelId);
209
209
  return pricing ? toResolvedModelPricing(pricing) : null;
210
210
  }
211
+ function resolveUsageReportedPricing(usage) {
212
+ const pricing = usage.pricing;
213
+ if (!pricing || typeof pricing.inputPerMillion !== "number" || typeof pricing.outputPerMillion !== "number") {
214
+ return null;
215
+ }
216
+ return {
217
+ inputPrice: pricing.inputPerMillion,
218
+ outputPrice: pricing.outputPerMillion,
219
+ cachedPrice: pricing.cachedInputPerMillion,
220
+ source: "provider"
221
+ };
222
+ }
211
223
  function resolveModelPricing(modelDef, providerName) {
212
224
  if (typeof modelDef.inputPrice === "number" && typeof modelDef.outputPrice === "number") {
213
225
  return {
@@ -222,6 +234,12 @@ function resolveModelPricing(modelDef, providerName) {
222
234
  }
223
235
  return null;
224
236
  }
237
+ function calculateRouterFee(rawCost, feePercent) {
238
+ if (!(rawCost > 0) || !(feePercent > 0)) {
239
+ return 0;
240
+ }
241
+ return roundCost(rawCost * feePercent / 100);
242
+ }
225
243
  function calculateUsageCost(usage, pricing) {
226
244
  if (!pricing) {
227
245
  return null;
@@ -252,6 +270,66 @@ var init_pricing = __esm({
252
270
  TOKENS_PER_MILLION = 1e6;
253
271
  }
254
272
  });
273
+
274
+ // src/agents/providers/router-fee.ts
275
+ function requestUrl(input) {
276
+ if (typeof input === "string") return input;
277
+ if (input instanceof URL) return input.toString();
278
+ if (typeof input === "object" && input !== null && typeof input.url === "string") {
279
+ return input.url;
280
+ }
281
+ return null;
282
+ }
283
+ function observeResponse(url, headers) {
284
+ if (!url) return;
285
+ for (const origin of registeredOrigins) {
286
+ if (!url.startsWith(`${origin}/v1/proxy/`)) continue;
287
+ const raw = headers.get(ROUTER_FEE_HEADER);
288
+ if (raw !== null) {
289
+ const percent = Number(raw);
290
+ if (Number.isFinite(percent) && percent >= 0) {
291
+ observedFeePercentByOrigin.set(origin, percent);
292
+ }
293
+ }
294
+ return;
295
+ }
296
+ }
297
+ function installObserver() {
298
+ if (observerInstalled) return;
299
+ const original = globalThis.fetch;
300
+ if (typeof original !== "function") return;
301
+ const bound = original.bind(globalThis);
302
+ const wrapped = async (input, init) => {
303
+ const response = await bound(input, init);
304
+ try {
305
+ observeResponse(requestUrl(input), response.headers);
306
+ } catch {
307
+ }
308
+ return response;
309
+ };
310
+ try {
311
+ globalThis.fetch = wrapped;
312
+ observerInstalled = true;
313
+ } catch {
314
+ }
315
+ }
316
+ function registerPlatformProxyOrigin(origin) {
317
+ if (!origin) return;
318
+ registeredOrigins.add(origin.replace(/\/+$/, ""));
319
+ installObserver();
320
+ }
321
+ function getObservedRouterFeePercent(origin) {
322
+ return observedFeePercentByOrigin.get(origin.replace(/\/+$/, "")) ?? null;
323
+ }
324
+ var ROUTER_FEE_HEADER, registeredOrigins, observedFeePercentByOrigin, observerInstalled;
325
+ var init_router_fee = __esm({
326
+ "src/agents/providers/router-fee.ts"() {
327
+ ROUTER_FEE_HEADER = "X-Standard-Agents-Router-Fee-Percent";
328
+ registeredOrigins = /* @__PURE__ */ new Set();
329
+ observedFeePercentByOrigin = /* @__PURE__ */ new Map();
330
+ observerInstalled = false;
331
+ }
332
+ });
255
333
  async function readCompletedArg(partialJson, argName) {
256
334
  if (!partialJson || !argName) return void 0;
257
335
  try {
@@ -802,6 +880,7 @@ var init_ProviderRegistry = __esm({
802
880
  "src/agents/providers/ProviderRegistry.ts"() {
803
881
  init_TestProvider();
804
882
  init_platform_routing();
883
+ init_router_fee();
805
884
  init_factory();
806
885
  ProviderRegistryImpl = class {
807
886
  providerCache = /* @__PURE__ */ new Map();
@@ -896,21 +975,22 @@ var init_ProviderRegistry = __esm({
896
975
  apiKey: routing.apiKey,
897
976
  baseUrl: routing.baseUrl
898
977
  };
978
+ registerPlatformProxyOrigin(routing.origin);
899
979
  const fingerprint = this.getProviderFingerprint(`platform:${providerName}`, modelDef, config);
900
980
  const cached = this.providerCache.get(modelName);
901
981
  if (cached?.fingerprint === fingerprint) {
902
- return this.buildResult(cached.provider, modelDef, true);
982
+ return this.buildResult(cached.provider, modelDef, true, routing.origin);
903
983
  }
904
- return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint, true);
984
+ return this.cacheAndReturn(modelName, providerFactory(config), modelDef, fingerprint, true, routing.origin);
905
985
  }
906
986
  throw new Error(`No API key found for provider: ${providerName}. Set the provider key or STANDARD_AGENTS_API_KEY.`);
907
987
  }
908
- buildResult(provider, modelDef, viaPlatform) {
909
- return { provider, modelName: modelDef.model, modelDef, viaPlatform };
988
+ buildResult(provider, modelDef, viaPlatform, platformProxyOrigin) {
989
+ return { provider, modelName: modelDef.model, modelDef, viaPlatform, platformProxyOrigin };
910
990
  }
911
- cacheAndReturn(modelName, provider, modelDef, fingerprint, viaPlatform) {
991
+ cacheAndReturn(modelName, provider, modelDef, fingerprint, viaPlatform, platformProxyOrigin) {
912
992
  this.providerCache.set(modelName, { provider, fingerprint, viaPlatform });
913
- return this.buildResult(provider, modelDef, viaPlatform);
993
+ return this.buildResult(provider, modelDef, viaPlatform, platformProxyOrigin);
914
994
  }
915
995
  getProviderFingerprint(providerName, modelDef, config) {
916
996
  return JSON.stringify({
@@ -1349,7 +1429,8 @@ function convertUsage(usage) {
1349
1429
  prompt_tokens_details: usage.cachedTokens ? { cached_tokens: usage.cachedTokens } : void 0,
1350
1430
  completion_tokens_details: usage.reasoningTokens ? { reasoning_tokens: usage.reasoningTokens } : void 0,
1351
1431
  cost: usage.cost,
1352
- provider: usage.provider
1432
+ provider: usage.provider,
1433
+ pricing: usage.pricing
1353
1434
  };
1354
1435
  }
1355
1436
  function inferProviderFromModelId(model) {
@@ -1373,6 +1454,7 @@ var NON_VISION_PLACEHOLDER_TEXT, STREAM_FIRST_CHUNK_TIMEOUT_MS, STREAM_STALL_TIM
1373
1454
  var init_LLMRequest = __esm({
1374
1455
  "src/agents/LLMRequest.ts"() {
1375
1456
  init_pricing();
1457
+ init_router_fee();
1376
1458
  init_types();
1377
1459
  init_FlowEngine();
1378
1460
  init_toolProgress();
@@ -1636,11 +1718,7 @@ var init_LLMRequest = __esm({
1636
1718
  */
1637
1719
  static async callModel(modelId, context, state, logId) {
1638
1720
  const { ProviderRegistry: ProviderRegistry2 } = await Promise.resolve().then(() => (init_providers(), providers_exports));
1639
- const { provider, modelName, modelDef, viaPlatform } = await ProviderRegistry2.getProvider(
1640
- modelId,
1641
- state.env,
1642
- state.thread.instance
1643
- );
1721
+ const { provider, modelName, modelDef, viaPlatform, platformProxyOrigin } = await ProviderRegistry2.getProvider(modelId, state.env, state.thread.instance);
1644
1722
  const streamAbort = new AbortController();
1645
1723
  const parentSignal = state.abortController?.signal;
1646
1724
  let onParentAbort;
@@ -1919,6 +1997,12 @@ var init_LLMRequest = __esm({
1919
1997
  };
1920
1998
  response._provider = provider;
1921
1999
  response._viaPlatform = viaPlatform;
2000
+ if (platformProxyOrigin) {
2001
+ const feePercent = getObservedRouterFeePercent(platformProxyOrigin);
2002
+ if (feePercent !== null) {
2003
+ response._routerFeePercent = feePercent;
2004
+ }
2005
+ }
1922
2006
  response._providerResponseId = providerResponseId;
1923
2007
  response._timing = {
1924
2008
  latencyMs: firstChunkAt > 0 ? firstChunkAt - requestSentAt : null,
@@ -2044,10 +2128,13 @@ var init_LLMRequest = __esm({
2044
2128
  const toolsCalled = response.tool_calls ? JSON.stringify(response.tool_calls.map((tc) => tc.function.name)) : null;
2045
2129
  const providerName = response._provider?.name;
2046
2130
  const standardAgentsRouterUsed = response._viaPlatform === true || providerName === "platform";
2047
- const resolvedPricing = resolveModelPricing(modelDef, providerName);
2131
+ const resolvedPricing = resolveModelPricing(modelDef) ?? resolveUsageReportedPricing(response.usage) ?? resolveModelPricing(modelDef, providerName);
2048
2132
  const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
2049
2133
  const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
2050
- const cost_total = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
2134
+ const rawProviderCost = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
2135
+ const routerFeePercent = standardAgentsRouterUsed && typeof response._routerFeePercent === "number" && response._routerFeePercent > 0 ? response._routerFeePercent : null;
2136
+ const costRouterFee = routerFeePercent !== null && rawProviderCost !== null ? calculateRouterFee(rawProviderCost, routerFeePercent) : null;
2137
+ const cost_total = rawProviderCost !== null && costRouterFee !== null && costRouterFee > 0 ? roundCost(rawProviderCost + costRouterFee) : rawProviderCost;
2051
2138
  const actualProvider = normalizeProviderMetadataValue(response.usage.provider) ?? null;
2052
2139
  const aggregateResponse = response._aggregate_response;
2053
2140
  const responseBody = aggregateResponse ? JSON.stringify(aggregateResponse) : JSON.stringify(response);
@@ -2113,6 +2200,8 @@ var init_LLMRequest = __esm({
2113
2200
  cost_input: calculatedCost?.costInput,
2114
2201
  cost_cached: calculatedCost?.costCached,
2115
2202
  cost_output: calculatedCost?.costOutput,
2203
+ cost_router_fee: costRouterFee ?? void 0,
2204
+ router_fee_percent: routerFeePercent ?? void 0,
2116
2205
  latency_ms: Date.now() - startTime,
2117
2206
  time_to_first_token_ms: timing?.latencyMs ?? void 0,
2118
2207
  generation_ms: timing?.generationMs ?? void 0,
@@ -2153,8 +2242,10 @@ var init_LLMRequest = __esm({
2153
2242
  actual_provider = ?17,
2154
2243
  standard_agents_router_used = ?18,
2155
2244
  time_to_first_token_ms = ?19,
2156
- generation_ms = ?20
2157
- WHERE id = ?21
2245
+ generation_ms = ?20,
2246
+ cost_router_fee = ?21,
2247
+ router_fee_percent = ?22
2248
+ WHERE id = ?23
2158
2249
  `,
2159
2250
  logData.response_body,
2160
2251
  logData.input_tokens,
@@ -2176,6 +2267,8 @@ var init_LLMRequest = __esm({
2176
2267
  standardAgentsRouterUsed ? 1 : 0,
2177
2268
  logData.time_to_first_token_ms ?? null,
2178
2269
  logData.generation_ms ?? null,
2270
+ logData.cost_router_fee ?? null,
2271
+ logData.router_fee_percent ?? null,
2179
2272
  logId
2180
2273
  );
2181
2274
  }
@@ -2514,9 +2607,24 @@ ${errorStack}` : ""}${errorDetails}`;
2514
2607
  updates.push(`actual_provider = ?${paramIndex++}`);
2515
2608
  values.push(actualProvider);
2516
2609
  }
2610
+ let updatedCostTotal;
2611
+ let updatedRouterFee;
2517
2612
  if (metadata.generation_cost !== void 0) {
2613
+ updatedCostTotal = metadata.generation_cost;
2614
+ const rawCost = typeof metadata.generation_cost === "number" ? metadata.generation_cost : Number(metadata.generation_cost);
2615
+ if (Number.isFinite(rawCost)) {
2616
+ const feePercent = await this.readRouterFeePercent(state, logId);
2617
+ if (feePercent !== null && feePercent > 0) {
2618
+ updatedRouterFee = calculateRouterFee(rawCost, feePercent);
2619
+ updatedCostTotal = roundCost(rawCost + updatedRouterFee);
2620
+ }
2621
+ }
2518
2622
  updates.push(`cost_total = ?${paramIndex++}`);
2519
- values.push(metadata.generation_cost);
2623
+ values.push(updatedCostTotal);
2624
+ if (updatedRouterFee !== void 0) {
2625
+ updates.push(`cost_router_fee = ?${paramIndex++}`);
2626
+ values.push(updatedRouterFee);
2627
+ }
2520
2628
  }
2521
2629
  if (updates.length === 0) {
2522
2630
  return;
@@ -2531,7 +2639,8 @@ ${errorStack}` : ""}${errorDetails}`;
2531
2639
  data: {
2532
2640
  id: logId,
2533
2641
  ...actualProvider !== void 0 && { actual_provider: actualProvider },
2534
- ...metadata.generation_cost !== void 0 && { cost_total: metadata.generation_cost }
2642
+ ...metadata.generation_cost !== void 0 && { cost_total: updatedCostTotal },
2643
+ ...updatedRouterFee !== void 0 && { cost_router_fee: updatedRouterFee }
2535
2644
  }
2536
2645
  });
2537
2646
  }
@@ -2539,6 +2648,23 @@ ${errorStack}` : ""}${errorDetails}`;
2539
2648
  console.error("Failed to update log with metadata (non-fatal):", error);
2540
2649
  }
2541
2650
  }
2651
+ /**
2652
+ * Router-fee percent recorded on a log row by logSuccess, or null when the
2653
+ * row has none (BYOK) or the storage shape doesn't expose it.
2654
+ */
2655
+ static async readRouterFeePercent(state, logId) {
2656
+ try {
2657
+ const cursor = await state.storage.sql.exec(
2658
+ `SELECT router_fee_percent FROM logs WHERE id = ?`,
2659
+ logId
2660
+ );
2661
+ const row = cursor?.toArray?.()[0];
2662
+ const percent = row?.router_fee_percent;
2663
+ return typeof percent === "number" && Number.isFinite(percent) ? percent : null;
2664
+ } catch {
2665
+ return null;
2666
+ }
2667
+ }
2542
2668
  };
2543
2669
  }
2544
2670
  });
@@ -14689,8 +14815,28 @@ var migration32 = {
14689
14815
  }
14690
14816
  };
14691
14817
 
14818
+ // src/durable-objects/migrations/033_add_router_fee.ts
14819
+ var migration33 = {
14820
+ version: 33,
14821
+ name: "add_router_fee",
14822
+ async up(sql) {
14823
+ const tableInfo = sql.exec(`PRAGMA table_info(logs)`).toArray();
14824
+ const hasColumn = (name) => tableInfo.some((col) => col.name === name);
14825
+ if (!hasColumn("cost_router_fee")) {
14826
+ await sql.exec(`
14827
+ ALTER TABLE logs ADD COLUMN cost_router_fee REAL;
14828
+ `);
14829
+ }
14830
+ if (!hasColumn("router_fee_percent")) {
14831
+ await sql.exec(`
14832
+ ALTER TABLE logs ADD COLUMN router_fee_percent REAL;
14833
+ `);
14834
+ }
14835
+ }
14836
+ };
14837
+
14692
14838
  // src/durable-objects/migrations/index.ts
14693
- var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22, migration23, migration24, migration25, migration26, migration27, migration28, migration29, migration30, migration31, migration32];
14839
+ var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22, migration23, migration24, migration25, migration26, migration27, migration28, migration29, migration30, migration31, migration32, migration33];
14694
14840
  var LATEST_SCHEMA_VERSION = migrations.length;
14695
14841
 
14696
14842
  // src/durable-objects/DurableThread.ts
@@ -16170,8 +16316,10 @@ var DurableThread = class _DurableThread extends DurableObject {
16170
16316
  async setValue(key, value) {
16171
16317
  await this.ensureMigrated();
16172
16318
  this.assertValidThreadValueKey(key);
16319
+ const updatedAt = Date.now() * 1e3;
16173
16320
  if (value === null || value === void 0) {
16174
16321
  await this.ctx.storage.sql.exec(`DELETE FROM thread_values WHERE key = ?`, key);
16322
+ this.broadcastLog({ type: "kv_data", key, deleted: true, updated_at: updatedAt });
16175
16323
  return;
16176
16324
  }
16177
16325
  const serialized = this.serializeThreadValue(value);
@@ -16185,8 +16333,9 @@ var DurableThread = class _DurableThread extends DurableObject {
16185
16333
  `,
16186
16334
  key,
16187
16335
  serialized,
16188
- Date.now() * 1e3
16336
+ updatedAt
16189
16337
  );
16338
+ this.broadcastLog({ type: "kv_data", key, deleted: false, updated_at: updatedAt });
16190
16339
  }
16191
16340
  async listValues(options = {}) {
16192
16341
  await this.ensureMigrated();
@@ -16806,9 +16955,9 @@ var DurableThread = class _DurableThread extends DurableObject {
16806
16955
  * Each migration is run in order, starting from the current version + 1.
16807
16956
  */
16808
16957
  async runMigrations(fromVersion) {
16809
- for (const migration43 of migrations) {
16810
- if (migration43.version > fromVersion) {
16811
- await migration43.up(this.ctx.storage.sql);
16958
+ for (const migration44 of migrations) {
16959
+ if (migration44.version > fromVersion) {
16960
+ await migration44.up(this.ctx.storage.sql);
16812
16961
  }
16813
16962
  }
16814
16963
  }
@@ -18242,7 +18391,7 @@ ${resultContent}${attachmentSummary}`;
18242
18391
  SELECT
18243
18392
  id, message_id, provider, actual_provider, standard_agents_router_used, model, model_name, prompt_name,
18244
18393
  tools_called, queued_tools, provider_tools, parent_log_id, retry_of_log_id, error, cost_total,
18245
- input_tokens, output_tokens, total_tokens,
18394
+ input_tokens, cached_tokens, output_tokens, total_tokens,
18246
18395
  is_complete, created_at, request_body
18247
18396
  FROM logs
18248
18397
  ORDER BY created_at ${order}
@@ -18268,6 +18417,7 @@ ${resultContent}${attachmentSummary}`;
18268
18417
  error: row.error,
18269
18418
  cost_total: row.cost_total,
18270
18419
  input_tokens: row.input_tokens,
18420
+ cached_tokens: row.cached_tokens,
18271
18421
  output_tokens: row.output_tokens,
18272
18422
  total_tokens: row.total_tokens,
18273
18423
  is_complete: row.is_complete === 1,
@@ -18291,11 +18441,19 @@ ${resultContent}${attachmentSummary}`;
18291
18441
  await this.ensureMigrated();
18292
18442
  const byModel = {};
18293
18443
  let totalCost = 0;
18444
+ let inputCost = 0;
18445
+ let cachedCost = 0;
18446
+ let outputCost = 0;
18447
+ let routerFeeCost = 0;
18294
18448
  let requestCount = 0;
18295
18449
  const modelRows = await this.ctx.storage.sql.exec(
18296
18450
  `
18297
18451
  SELECT COALESCE(model_name, model, 'unknown') AS model_key,
18298
18452
  SUM(cost_total) AS total_cost,
18453
+ SUM(CASE WHEN cost_cached IS NOT NULL THEN cost_input END) AS input_cost,
18454
+ SUM(cost_cached) AS cached_cost,
18455
+ SUM(cost_output) AS output_cost,
18456
+ SUM(cost_router_fee) AS router_fee_cost,
18299
18457
  COUNT(*) AS request_count
18300
18458
  FROM logs
18301
18459
  WHERE cost_total IS NOT NULL
@@ -18303,15 +18461,35 @@ ${resultContent}${attachmentSummary}`;
18303
18461
  `
18304
18462
  );
18305
18463
  for (const row of modelRows.toArray()) {
18306
- byModel[row.model_key] = { totalCost: row.total_cost, count: row.request_count };
18464
+ byModel[row.model_key] = {
18465
+ totalCost: row.total_cost,
18466
+ inputCost: row.input_cost ?? 0,
18467
+ cachedCost: row.cached_cost ?? 0,
18468
+ outputCost: row.output_cost ?? 0,
18469
+ routerFeeCost: row.router_fee_cost ?? 0,
18470
+ count: row.request_count
18471
+ };
18307
18472
  totalCost += row.total_cost;
18473
+ inputCost += row.input_cost ?? 0;
18474
+ cachedCost += row.cached_cost ?? 0;
18475
+ outputCost += row.output_cost ?? 0;
18476
+ routerFeeCost += row.router_fee_cost ?? 0;
18308
18477
  requestCount += row.request_count;
18309
18478
  }
18310
18479
  const messageRow = await this.ctx.storage.sql.exec(
18311
18480
  `SELECT COUNT(DISTINCT message_id) AS message_count FROM logs WHERE cost_total IS NOT NULL`
18312
18481
  );
18313
18482
  const messageCount = messageRow.one().message_count || 0;
18314
- return { totalCost, requestCount, messageCount, byModel };
18483
+ return {
18484
+ totalCost,
18485
+ inputCost,
18486
+ cachedCost,
18487
+ outputCost,
18488
+ routerFeeCost,
18489
+ requestCount,
18490
+ messageCount,
18491
+ byModel
18492
+ };
18315
18493
  }
18316
18494
  /**
18317
18495
  * Get specific logs, optionally including all descendant logs.
@@ -18524,7 +18702,7 @@ ${resultContent}${attachmentSummary}`;
18524
18702
  l.request_body, l.request_headers, l.response_body, l.response_headers,
18525
18703
  l.status_code, l.reasoning_content, l.input_tokens, l.cached_tokens, l.output_tokens,
18526
18704
  l.reasoning_tokens, l.total_tokens, l.latency_ms, l.time_to_first_token_ms, l.generation_ms,
18527
- l.finish_reason, l.error, l.error_type, l.cost_input, l.cost_cached, l.cost_output, l.cost_total,
18705
+ l.finish_reason, l.error, l.error_type, l.cost_input, l.cost_cached, l.cost_output, l.cost_router_fee, l.router_fee_percent, l.cost_total,
18528
18706
  l.message_history_length, l.tools_available, l.prompt_name, l.tools_called,
18529
18707
  l.queued_tools, l.provider_tools, l.parent_log_id, l.tools_schema, l.system_prompt,
18530
18708
  l.errors, l.retry_of_log_id, l.tool_results, l.is_complete, l.created_at,
@@ -18616,6 +18794,8 @@ ${resultContent}${attachmentSummary}`;
18616
18794
  cost_input: row.cost_input,
18617
18795
  cost_cached: row.cost_cached,
18618
18796
  cost_output: row.cost_output,
18797
+ cost_router_fee: row.cost_router_fee,
18798
+ router_fee_percent: row.router_fee_percent,
18619
18799
  cost_total: row.cost_total,
18620
18800
  message_history_length: row.message_history_length,
18621
18801
  tools_available: row.tools_available,
@@ -19114,6 +19294,7 @@ ${resultContent}${attachmentSummary}`;
19114
19294
  * Broadcast a log record to all connected WebSocket clients
19115
19295
  */
19116
19296
  broadcastLog(log) {
19297
+ if (!this.logSockets || this.logSockets.size === 0) return;
19117
19298
  const payload = JSON.stringify(log);
19118
19299
  for (const ws of Array.from(this.logSockets)) {
19119
19300
  try {
@@ -20517,7 +20698,7 @@ ${resultContent}${attachmentSummary}`;
20517
20698
  };
20518
20699
 
20519
20700
  // src/durable-objects/agentbuilder-migrations/0001_initial.ts
20520
- var migration33 = {
20701
+ var migration34 = {
20521
20702
  version: 1,
20522
20703
  async up(sql) {
20523
20704
  sql.exec(`
@@ -20616,7 +20797,7 @@ var migration33 = {
20616
20797
  };
20617
20798
 
20618
20799
  // src/durable-objects/agentbuilder-migrations/0002_add_tenvs_properties.ts
20619
- var migration34 = {
20800
+ var migration35 = {
20620
20801
  version: 2,
20621
20802
  async up(sql) {
20622
20803
  sql.exec(`ALTER TABLE threads ADD COLUMN tenvs TEXT`);
@@ -20628,7 +20809,7 @@ var migration34 = {
20628
20809
  };
20629
20810
 
20630
20811
  // src/durable-objects/agentbuilder-migrations/0003_add_parent_and_terminated.ts
20631
- var migration35 = {
20812
+ var migration36 = {
20632
20813
  version: 3,
20633
20814
  async up(sql) {
20634
20815
  sql.exec(`ALTER TABLE threads ADD COLUMN parent TEXT REFERENCES threads(id)`);
@@ -20641,7 +20822,7 @@ var migration35 = {
20641
20822
  };
20642
20823
 
20643
20824
  // src/durable-objects/agentbuilder-migrations/0004_add_env_tables.ts
20644
- var migration36 = {
20825
+ var migration37 = {
20645
20826
  version: 4,
20646
20827
  async up(sql) {
20647
20828
  sql.exec(`ALTER TABLE threads ADD COLUMN env TEXT`);
@@ -20665,7 +20846,7 @@ var migration36 = {
20665
20846
  };
20666
20847
 
20667
20848
  // src/durable-objects/agentbuilder-migrations/0005_add_pending_subagent_env_requests.ts
20668
- var migration37 = {
20849
+ var migration38 = {
20669
20850
  version: 5,
20670
20851
  async up(sql) {
20671
20852
  sql.exec(`
@@ -20691,7 +20872,7 @@ var migration37 = {
20691
20872
  };
20692
20873
 
20693
20874
  // src/durable-objects/agentbuilder-migrations/0006_add_env_value_types.ts
20694
- var migration38 = {
20875
+ var migration39 = {
20695
20876
  version: 6,
20696
20877
  async up(sql) {
20697
20878
  sql.exec(
@@ -20706,7 +20887,7 @@ var migration38 = {
20706
20887
  };
20707
20888
 
20708
20889
  // src/durable-objects/agentbuilder-migrations/0007_platform_identity_replica.ts
20709
- var migration39 = {
20890
+ var migration40 = {
20710
20891
  version: 7,
20711
20892
  async up(sql) {
20712
20893
  sql.exec(`ALTER TABLE users ADD COLUMN platform_user_id TEXT`);
@@ -20735,7 +20916,7 @@ var migration39 = {
20735
20916
  };
20736
20917
 
20737
20918
  // src/durable-objects/agentbuilder-migrations/0008_add_skills.ts
20738
- var migration40 = {
20919
+ var migration41 = {
20739
20920
  version: 8,
20740
20921
  async up(sql) {
20741
20922
  sql.exec(`
@@ -20766,7 +20947,7 @@ var migration40 = {
20766
20947
  };
20767
20948
 
20768
20949
  // src/durable-objects/agentbuilder-migrations/0009_add_user_permissions.ts
20769
- var migration41 = {
20950
+ var migration42 = {
20770
20951
  version: 9,
20771
20952
  async up(sql) {
20772
20953
  sql.exec(`ALTER TABLE users ADD COLUMN permissions TEXT`);
@@ -20777,7 +20958,7 @@ var migration41 = {
20777
20958
  };
20778
20959
 
20779
20960
  // src/durable-objects/agentbuilder-migrations/0010_add_device_logins.ts
20780
- var migration42 = {
20961
+ var migration43 = {
20781
20962
  version: 10,
20782
20963
  async up(sql) {
20783
20964
  sql.exec(`
@@ -20797,7 +20978,7 @@ var migration42 = {
20797
20978
  };
20798
20979
 
20799
20980
  // src/durable-objects/agentbuilder-migrations/index.ts
20800
- var migrations2 = [migration33, migration34, migration35, migration36, migration37, migration38, migration39, migration40, migration41, migration42];
20981
+ var migrations2 = [migration34, migration35, migration36, migration37, migration38, migration39, migration40, migration41, migration42, migration43];
20801
20982
  var LATEST_SCHEMA_VERSION2 = 10;
20802
20983
 
20803
20984
  // src/utils/crypto.ts
@@ -21560,9 +21741,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
21560
21741
  }
21561
21742
  }
21562
21743
  async runMigrations(fromVersion) {
21563
- for (const migration43 of migrations2) {
21564
- if (migration43.version > fromVersion) {
21565
- await migration43.up(this.ctx.storage.sql);
21744
+ for (const migration44 of migrations2) {
21745
+ if (migration44.version > fromVersion) {
21746
+ await migration44.up(this.ctx.storage.sql);
21566
21747
  }
21567
21748
  }
21568
21749
  }