@standardagents/builder 0.17.0 → 0.17.1

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.
@@ -1462,6 +1462,23 @@ function convertUsage(usage) {
1462
1462
  provider: usage.provider
1463
1463
  };
1464
1464
  }
1465
+ function inferProviderFromModelId(model) {
1466
+ const trimmed = model?.trim();
1467
+ if (!trimmed) return null;
1468
+ const slashIndex = trimmed.indexOf("/");
1469
+ if (slashIndex <= 0) return null;
1470
+ return trimmed.slice(0, slashIndex);
1471
+ }
1472
+ function inferInitialActualProvider(providerName, modelDef) {
1473
+ if (providerName !== "openrouter") return null;
1474
+ return inferProviderFromModelId(modelDef.model);
1475
+ }
1476
+ function normalizeProviderMetadataValue(value) {
1477
+ if (typeof value !== "string") return void 0;
1478
+ const trimmed = value.trim();
1479
+ if (!trimmed || trimmed.toLowerCase() === "unknown") return void 0;
1480
+ return trimmed;
1481
+ }
1465
1482
  var NON_VISION_PLACEHOLDER_TEXT, LLMRequest;
1466
1483
  var init_LLMRequest = __esm({
1467
1484
  "src/agents/LLMRequest.ts"() {
@@ -1630,6 +1647,7 @@ var init_LLMRequest = __esm({
1630
1647
  console.error("Failed to get provider name:", err);
1631
1648
  }
1632
1649
  const { requestBody, visionFiltering } = buildRequestBody(context, modelDef);
1650
+ const initialActualProvider = inferInitialActualProvider(providerName, modelDef);
1633
1651
  const requestBodyForLog = {
1634
1652
  ...requestBody,
1635
1653
  messages: stripBase64FromMessages(
@@ -1648,6 +1666,7 @@ var init_LLMRequest = __esm({
1648
1666
  id,
1649
1667
  message_id: state.rootMessageId || crypto.randomUUID(),
1650
1668
  provider: providerName || this.getProviderFromModel(modelId),
1669
+ actual_provider: initialActualProvider ?? void 0,
1651
1670
  model: modelId,
1652
1671
  model_name: modelDef.model,
1653
1672
  endpoint: "chat.completions",
@@ -1668,14 +1687,15 @@ var init_LLMRequest = __esm({
1668
1687
  await state.storage.sql.exec(
1669
1688
  `
1670
1689
  INSERT INTO logs (
1671
- id, message_id, provider, model, model_name, endpoint,
1690
+ id, message_id, provider, actual_provider, model, model_name, endpoint,
1672
1691
  request_body, tools_available, message_history_length, prompt_name,
1673
1692
  parent_log_id, retry_of_log_id, tools_schema, system_prompt, is_complete, created_at
1674
- ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16)
1693
+ ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17)
1675
1694
  `,
1676
1695
  logData.id,
1677
1696
  logData.message_id,
1678
1697
  logData.provider,
1698
+ logData.actual_provider,
1679
1699
  logData.model,
1680
1700
  logData.model_name,
1681
1701
  logData.endpoint,
@@ -1927,7 +1947,7 @@ var init_LLMRequest = __esm({
1927
1947
  const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
1928
1948
  const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
1929
1949
  const cost_total = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
1930
- const actualProvider = response.usage.provider;
1950
+ const actualProvider = normalizeProviderMetadataValue(response.usage.provider) ?? null;
1931
1951
  const aggregateResponse = response._aggregate_response;
1932
1952
  const responseBody = aggregateResponse ? JSON.stringify(aggregateResponse) : JSON.stringify(response);
1933
1953
  const providerTools = [];
@@ -2355,8 +2375,13 @@ ${errorStack}` : ""}${errorDetails}`;
2355
2375
  }).catch((err) => {
2356
2376
  console.error("Async metadata fetch failed (non-fatal):", err);
2357
2377
  });
2358
- state.rootState.pendingMetadataPromises = state.rootState.pendingMetadataPromises || [];
2359
- state.rootState.pendingMetadataPromises.push(metadataPromise);
2378
+ const rootState = state.rootState || state;
2379
+ rootState.pendingMetadataPromises = rootState.pendingMetadataPromises || [];
2380
+ rootState.pendingMetadataPromises.push(metadataPromise);
2381
+ if (rootState !== state) {
2382
+ state.pendingMetadataPromises = state.pendingMetadataPromises || [];
2383
+ state.pendingMetadataPromises.push(metadataPromise);
2384
+ }
2360
2385
  }
2361
2386
  /**
2362
2387
  * Update log record with async metadata from provider.
@@ -2366,9 +2391,12 @@ ${errorStack}` : ""}${errorDetails}`;
2366
2391
  const updates = [];
2367
2392
  const values = [];
2368
2393
  let paramIndex = 1;
2369
- if (metadata.actual_provider !== void 0) {
2394
+ const actualProvider = normalizeProviderMetadataValue(
2395
+ metadata.actual_provider ?? metadata.actualProvider ?? metadata.providerName
2396
+ );
2397
+ if (actualProvider !== void 0) {
2370
2398
  updates.push(`actual_provider = ?${paramIndex++}`);
2371
- values.push(metadata.actual_provider);
2399
+ values.push(actualProvider);
2372
2400
  }
2373
2401
  if (metadata.generation_cost !== void 0) {
2374
2402
  updates.push(`cost_total = ?${paramIndex++}`);
@@ -2386,7 +2414,7 @@ ${errorStack}` : ""}${errorDetails}`;
2386
2414
  log_id: logId,
2387
2415
  data: {
2388
2416
  id: logId,
2389
- ...metadata.actual_provider !== void 0 && { actual_provider: metadata.actual_provider },
2417
+ ...actualProvider !== void 0 && { actual_provider: actualProvider },
2390
2418
  ...metadata.generation_cost !== void 0 && { cost_total: metadata.generation_cost }
2391
2419
  }
2392
2420
  });
@@ -3112,6 +3140,11 @@ var init_ToolExecutor = __esm({
3112
3140
  state.sequence.queue.push(...toolCalls);
3113
3141
  state.sequence.isHandling = true;
3114
3142
  while (state.sequence.queue.length > 0) {
3143
+ if (state.stopped) {
3144
+ state.sequence.queue = [];
3145
+ state.sequence.isHandling = false;
3146
+ break;
3147
+ }
3115
3148
  if (await state.thread.instance.shouldStop() || state.abortController?.signal.aborted) {
3116
3149
  state.sequence.queue = [];
3117
3150
  state.sequence.isHandling = false;
@@ -3140,7 +3173,17 @@ var init_ToolExecutor = __esm({
3140
3173
  });
3141
3174
  continue;
3142
3175
  }
3143
- const result = await this.executeToolCall(call, state, toolMessageId);
3176
+ const previousToolCall = state.currentToolCall;
3177
+ state.currentToolCall = {
3178
+ id: call.id,
3179
+ name: call.function.name
3180
+ };
3181
+ let result;
3182
+ try {
3183
+ result = await this.executeToolCall(call, state, toolMessageId);
3184
+ } finally {
3185
+ state.currentToolCall = previousToolCall;
3186
+ }
3144
3187
  if (result.status === "error") {
3145
3188
  const error = new Error(result.error || "Tool execution failed");
3146
3189
  if (result.stack) {
@@ -5009,6 +5052,11 @@ ${attachmentPaths}`;
5009
5052
  }
5010
5053
  }
5011
5054
  const toolStatus = processedResult.status === "success" ? "success" : "error";
5055
+ const parentNotifications = this.consumeParentNotificationsForToolCall(
5056
+ state,
5057
+ call
5058
+ );
5059
+ const notificationContent = parentNotifications[parentNotifications.length - 1]?.content;
5012
5060
  let message = {
5013
5061
  id: messageId,
5014
5062
  role: "tool",
@@ -5022,15 +5070,20 @@ ${attachmentPaths}`;
5022
5070
  parent_id: state.parentMessageId || null,
5023
5071
  depth: state.depth,
5024
5072
  attachments: attachmentRefs && attachmentRefs.length > 0 ? JSON.stringify(attachmentRefs) : null,
5025
- subagent_id: typeof processedResult.subagent_id === "string" && processedResult.subagent_id.trim().length > 0 ? processedResult.subagent_id.trim() : null
5073
+ subagent_id: typeof processedResult.subagent_id === "string" && processedResult.subagent_id.trim().length > 0 ? processedResult.subagent_id.trim() : null,
5074
+ metadata: parentNotifications.length > 0 ? {
5075
+ parent_notification: true,
5076
+ parent_notifications: parentNotifications,
5077
+ parent_notification_content: notificationContent
5078
+ } : void 0
5026
5079
  };
5027
5080
  message = await FlowEngine2.runBeforeCreateMessageHook(state, message);
5028
5081
  message.created_at = Date.now() * TIMESTAMP_MULTIPLIER;
5029
5082
  const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
5030
5083
  await state.storage.sql.exec(
5031
5084
  `
5032
- INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, subagent_id, prompt)
5033
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
5085
+ INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, subagent_id, prompt, metadata)
5086
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
5034
5087
  `,
5035
5088
  message.id,
5036
5089
  message.role,
@@ -5043,7 +5096,8 @@ ${attachmentPaths}`;
5043
5096
  message.depth,
5044
5097
  message.attachments,
5045
5098
  message.subagent_id ?? null,
5046
- currentPrompt
5099
+ currentPrompt,
5100
+ message.metadata ? JSON.stringify(message.metadata) : null
5047
5101
  );
5048
5102
  await FlowEngine2.runAfterCreateMessageHook(state, message);
5049
5103
  const parentLogId = state.currentLogId || null;
@@ -5108,6 +5162,23 @@ ${attachmentPaths}`;
5108
5162
  await this.logError(state, error, `storeToolResult:${call.function.name}`);
5109
5163
  }
5110
5164
  }
5165
+ static consumeParentNotificationsForToolCall(state, call) {
5166
+ const pending = state.parentNotifications ?? [];
5167
+ if (pending.length === 0) return [];
5168
+ const matched = [];
5169
+ const remaining = [];
5170
+ for (const notification of pending) {
5171
+ const matchesCallId = notification.toolCallId === call.id;
5172
+ const matchesToolName = !notification.toolCallId && notification.toolName === call.function.name;
5173
+ if (matchesCallId || matchesToolName) {
5174
+ matched.push(notification);
5175
+ } else {
5176
+ remaining.push(notification);
5177
+ }
5178
+ }
5179
+ state.parentNotifications = remaining;
5180
+ return matched;
5181
+ }
5111
5182
  static async createSilentGeneratedAssetPathMessagesFromToolResult(state, sourceToolMessage, refs, enabled) {
5112
5183
  if (!enabled || !refs || refs.length === 0) {
5113
5184
  return;
@@ -5476,6 +5547,8 @@ var init_FlowEngine = __esm({
5476
5547
  stoppedBy: state.stoppedBy,
5477
5548
  stopReason: state.stopReason,
5478
5549
  stopReasonCode: state.stopReasonCode,
5550
+ sessionStopped: state.sessionStopped,
5551
+ sessionStopResult: state.sessionStopResult,
5479
5552
  stepCount: state.stepCount,
5480
5553
  stream: state.stream.httpStream
5481
5554
  };
@@ -5675,6 +5748,8 @@ var init_FlowEngine = __esm({
5675
5748
  stoppedBy: stateInput.stoppedBy,
5676
5749
  stopReason: stateInput.stopReason,
5677
5750
  stopReasonCode: stateInput.stopReasonCode,
5751
+ sessionStopped: stateInput.sessionStopped,
5752
+ sessionStopResult: stateInput.sessionStopResult,
5678
5753
  messageHistory: [],
5679
5754
  sequence: stateInput.sequence || {
5680
5755
  queue: [],
@@ -11367,34 +11442,79 @@ var init_ThreadStateImpl = __esm({
11367
11442
  this._metadata.tenvs = nextEnv;
11368
11443
  }
11369
11444
  async notifyParent(content) {
11370
- if (!content || !content.trim()) {
11445
+ const trimmedContent = content?.trim();
11446
+ if (!trimmedContent) {
11371
11447
  throw new Error("notifyParent requires non-empty content");
11372
11448
  }
11373
- const { parentThreadId, parentStub } = await this._getParentThreadStub();
11374
- if (typeof parentStub.queueMessage !== "function") {
11375
- throw new Error("notifyParent is not supported by this thread runtime");
11449
+ if (this._flowState) {
11450
+ const currentToolCall = this._flowState.currentToolCall;
11451
+ const notification = {
11452
+ content: trimmedContent,
11453
+ toolCallId: currentToolCall?.id ?? null,
11454
+ toolName: currentToolCall?.name ?? this._flowState.active?.tool ?? null,
11455
+ created_at: Date.now() * 1e3
11456
+ };
11457
+ this._flowState.parentNotifications = [
11458
+ ...this._flowState.parentNotifications ?? [],
11459
+ notification
11460
+ ];
11461
+ }
11462
+ const parentTarget = await this._getOptionalParentThreadStub();
11463
+ if (parentTarget && typeof parentTarget.parentStub.queueMessage === "function") {
11464
+ await parentTarget.parentStub.queueMessage(parentTarget.parentThreadId, {
11465
+ role: "user",
11466
+ content: trimmedContent,
11467
+ silent: true,
11468
+ metadata: { subagent_id: this.threadId }
11469
+ });
11376
11470
  }
11377
- await parentStub.queueMessage(parentThreadId, {
11378
- role: "user",
11379
- content: content.trim(),
11380
- silent: true,
11381
- metadata: { subagent_id: this.threadId }
11382
- });
11383
11471
  }
11384
11472
  async setStatus(status) {
11385
11473
  if (!status || !status.trim()) {
11386
11474
  throw new Error("setStatus requires non-empty status");
11387
11475
  }
11388
- const { parentThreadId, parentStub } = await this._getParentThreadStub();
11389
- if (typeof parentStub.updateChildRegistryStatus !== "function") {
11390
- throw new Error("setStatus is not supported by this thread runtime");
11476
+ const parentTarget = await this._getOptionalParentThreadStub();
11477
+ if (!parentTarget || typeof parentTarget.parentStub.updateChildRegistryStatus !== "function") {
11478
+ return;
11391
11479
  }
11392
- await parentStub.updateChildRegistryStatus(
11393
- parentThreadId,
11480
+ await parentTarget.parentStub.updateChildRegistryStatus(
11481
+ parentTarget.parentThreadId,
11394
11482
  this.threadId,
11395
11483
  status.trim()
11396
11484
  );
11397
11485
  }
11486
+ async stopSession(options = {}) {
11487
+ if (!this._flowState) {
11488
+ throw new Error("stopSession requires active execution");
11489
+ }
11490
+ const notifyParent = options.notifyParent?.trim();
11491
+ if (options.notifyParent !== void 0 && !notifyParent) {
11492
+ throw new Error("stopSession notifyParent requires non-empty content");
11493
+ }
11494
+ const status = options.status?.trim();
11495
+ if (options.status !== void 0 && !status) {
11496
+ throw new Error("stopSession status requires non-empty status");
11497
+ }
11498
+ if (notifyParent) {
11499
+ await this.notifyParent(notifyParent);
11500
+ }
11501
+ if (status) {
11502
+ await this.setStatus(status);
11503
+ }
11504
+ const result = options.result?.trim() || "Session stopped.";
11505
+ this._flowState.sessionStopped = true;
11506
+ this._flowState.sessionStopResult = result;
11507
+ this._flowState.stopped = true;
11508
+ this._flowState.stoppedBy = this._flowState.currentSide;
11509
+ this._flowState.stopReason = "Session stopped by state.stopSession()";
11510
+ this._flowState.stopReasonCode = "state_stop_session";
11511
+ this._flowState.emitTelemetry?.({
11512
+ type: "stopped",
11513
+ reason: this._flowState.stopReason,
11514
+ side: this._flowState.currentSide,
11515
+ timestamp: Date.now()
11516
+ });
11517
+ }
11398
11518
  async getChildThread(referenceId) {
11399
11519
  const agentBuilder = this._getAgentBuilderStub();
11400
11520
  const child = await agentBuilder.getThread(referenceId);
@@ -11807,19 +11927,47 @@ var init_ThreadStateImpl = __esm({
11807
11927
  return Object.keys(normalized).length > 0 ? normalized : null;
11808
11928
  }
11809
11929
  async _getParentThreadId() {
11930
+ const parent = await this._getOptionalParentThreadId();
11931
+ if (!parent) {
11932
+ throw new Error(`Thread ${this.threadId} has no parent thread`);
11933
+ }
11934
+ return parent;
11935
+ }
11936
+ async _getOptionalParentThreadId() {
11810
11937
  const metadataParent = typeof this._metadata.parent === "string" && this._metadata.parent.trim().length > 0 ? this._metadata.parent.trim() : null;
11811
11938
  if (metadataParent) {
11812
11939
  return metadataParent;
11813
11940
  }
11814
- const agentBuilder = this._getAgentBuilderStub();
11815
- const thread = await agentBuilder.getThread(this.threadId);
11941
+ let thread = null;
11942
+ try {
11943
+ const agentBuilder = this._getAgentBuilderStub();
11944
+ thread = await agentBuilder.getThread(this.threadId);
11945
+ } catch {
11946
+ return null;
11947
+ }
11816
11948
  const parent = thread && typeof thread.parent === "string" && thread.parent.trim().length > 0 ? thread.parent.trim() : null;
11817
- if (!parent) {
11818
- throw new Error(`Thread ${this.threadId} has no parent thread`);
11949
+ if (parent) {
11950
+ this._metadata.parent = parent;
11819
11951
  }
11820
- this._metadata.parent = parent;
11821
11952
  return parent;
11822
11953
  }
11954
+ async _getOptionalParentThreadStub() {
11955
+ const parentThreadId = await this._getOptionalParentThreadId();
11956
+ if (!parentThreadId) {
11957
+ return null;
11958
+ }
11959
+ try {
11960
+ const threadNamespace = this._threadInstance.env.AGENT_BUILDER_THREAD;
11961
+ if (!threadNamespace || typeof threadNamespace.idFromName !== "function" || typeof threadNamespace.get !== "function") {
11962
+ return null;
11963
+ }
11964
+ const durableId = threadNamespace.idFromName(parentThreadId);
11965
+ const parentStub = threadNamespace.get(durableId);
11966
+ return { parentThreadId, parentStub };
11967
+ } catch {
11968
+ return null;
11969
+ }
11970
+ }
11823
11971
  async _getParentThreadStub() {
11824
11972
  const parentThreadId = await this._getParentThreadId();
11825
11973
  const durableId = this._threadInstance.env.AGENT_BUILDER_THREAD.idFromName(parentThreadId);
@@ -33341,6 +33489,11 @@ function calculateGoogleUsageCost(modelId, usage, imageCount = 0) {
33341
33489
  function normalizeModelId3(modelId) {
33342
33490
  return modelId.trim().replace(/^google\//, "").replace(/^models\//, "").replace(/^publishers\/google\/models\//, "");
33343
33491
  }
33492
+ function googleRestBaseUrl(baseUrl) {
33493
+ const normalized = (baseUrl || "https://generativelanguage.googleapis.com/v1beta").replace(/\/$/, "");
33494
+ if (/\/v1(?:beta|alpha)?$/.test(normalized)) return normalized;
33495
+ return `${normalized}/v1beta`;
33496
+ }
33344
33497
  function supportsGoogleMultimodalFunctionResponses(modelId) {
33345
33498
  return normalizeModelId3(modelId).startsWith("gemini-3");
33346
33499
  }
@@ -34273,6 +34426,7 @@ var init_dist3 = __esm({
34273
34426
  };
34274
34427
  }
34275
34428
  async inspectRequest(request) {
34429
+ const baseUrl = googleRestBaseUrl(this.config.baseUrl);
34276
34430
  if (isImagenModel(request.model)) {
34277
34431
  const imagen = this.extractImagenRequest(request);
34278
34432
  return {
@@ -34284,11 +34438,12 @@ var init_dist3 = __esm({
34284
34438
  }
34285
34439
  };
34286
34440
  }
34441
+ const { model: _model, ...body } = this.buildGenerateContentParams(request);
34287
34442
  return {
34288
- body: this.buildGenerateContentParams(request),
34443
+ body,
34289
34444
  messagesPath: "contents",
34290
34445
  metadata: {
34291
- endpoint: `${this.config.baseUrl || "https://generativelanguage.googleapis.com"}/generateContent`,
34446
+ endpoint: `${baseUrl}/models/${encodeURIComponent(normalizeModelId3(request.model))}:generateContent`,
34292
34447
  headers: { "Content-Type": "application/json" }
34293
34448
  }
34294
34449
  };
@@ -51512,7 +51667,7 @@ function transformChatResponse3(response) {
51512
51667
  webSearchCitations,
51513
51668
  response.id
51514
51669
  );
51515
- const actualProvider = response.model?.split("/")[0] || void 0;
51670
+ const actualProvider = response.provider || response.model?.split("/")[0] || void 0;
51516
51671
  return {
51517
51672
  content,
51518
51673
  toolCalls,
@@ -51661,12 +51816,13 @@ function processChatStreamChunk2(chunk, state) {
51661
51816
  state.webSearchCitations,
51662
51817
  chunk.id
51663
51818
  ));
51664
- const actualProvider = chunk.model?.split("/")[0] || void 0;
51819
+ const actualProvider = chunk.provider || chunk.model?.split("/")[0] || void 0;
51665
51820
  const reasoningDetails = state.reasoningDetails.length > 0 ? state.reasoningDetails.map(({ _index, ...d }) => d) : void 0;
51666
51821
  chunks.push({
51667
51822
  type: "finish",
51668
51823
  finishReason: mapChatFinishReason2(state.finishReason),
51669
51824
  usage: transformChatUsage2(chunk.usage, actualProvider),
51825
+ responseId: chunk.id,
51670
51826
  reasoningDetails
51671
51827
  });
51672
51828
  }
@@ -52181,7 +52337,7 @@ function transformResponse3(response) {
52181
52337
  webSearchCitations,
52182
52338
  response.id
52183
52339
  );
52184
- const actualProvider = response.model?.split("/")[0] || void 0;
52340
+ const actualProvider = typeof response.provider === "string" ? response.provider : response.model?.split("/")[0] || void 0;
52185
52341
  return {
52186
52342
  content,
52187
52343
  toolCalls,
@@ -52438,7 +52594,7 @@ function processStreamEvent3(event, state) {
52438
52594
  if (state.hasReasoning) {
52439
52595
  chunks.push({ type: "reasoning-done" });
52440
52596
  }
52441
- const completedProvider = event.response.model?.split("/")[0] || void 0;
52597
+ const completedProvider = typeof event.response.provider === "string" ? event.response.provider : event.response.model?.split("/")[0] || void 0;
52442
52598
  const reasoningDetails = extractReasoningDetails(event.response.output, state.reasoningContent);
52443
52599
  const generatedImages = extractImages(event.response.output);
52444
52600
  if (generatedImages && generatedImages.length > 0) {
@@ -52483,7 +52639,7 @@ function processStreamEvent3(event, state) {
52483
52639
  if (state.hasReasoning) {
52484
52640
  chunks.push({ type: "reasoning-done" });
52485
52641
  }
52486
- const incompleteProvider = event.response.model?.split("/")[0] || void 0;
52642
+ const incompleteProvider = typeof event.response.provider === "string" ? event.response.provider : event.response.model?.split("/")[0] || void 0;
52487
52643
  const incompleteReasoningDetails = extractReasoningDetails(event.response.output, state.reasoningContent);
52488
52644
  const incompleteImages = extractImages(event.response.output);
52489
52645
  if (incompleteImages && incompleteImages.length > 0) {
@@ -52725,6 +52881,47 @@ async function fetchGenerationMetadata(apiKey, generationId, baseUrl = "https://
52725
52881
  }
52726
52882
  return null;
52727
52883
  }
52884
+ function normalizeOpenRouterProviderId(providerId) {
52885
+ return providerId.trim().toLowerCase();
52886
+ }
52887
+ function buildOpenRouterProviderUrlMap() {
52888
+ const urls = {};
52889
+ for (const entry of OPENROUTER_PROVIDER_URL_ENTRIES) {
52890
+ const keys = [entry.name, entry.slug, ...entry.aliases ?? []];
52891
+ for (const key of keys) {
52892
+ urls[normalizeOpenRouterProviderId(key)] = entry.url;
52893
+ }
52894
+ }
52895
+ return urls;
52896
+ }
52897
+ function extractOpenRouterProviderName(iconId) {
52898
+ if (!iconId.toLowerCase().startsWith(OPENROUTER_PROVIDER_ICON_PREFIX)) {
52899
+ return void 0;
52900
+ }
52901
+ const providerName = iconId.slice(OPENROUTER_PROVIDER_ICON_PREFIX.length).trim();
52902
+ return providerName || void 0;
52903
+ }
52904
+ function getOpenRouterProviderIconUrl(providerName) {
52905
+ const providerUrl = OPENROUTER_PROVIDER_URLS[normalizeOpenRouterProviderId(providerName)];
52906
+ if (!providerUrl) {
52907
+ return void 0;
52908
+ }
52909
+ const params = new URLSearchParams({
52910
+ client: "SOCIAL",
52911
+ type: "FAVICON",
52912
+ fallback_opts: "TYPE,SIZE,URL",
52913
+ url: providerUrl,
52914
+ size: "256"
52915
+ });
52916
+ return `https://t0.gstatic.com/faviconV2?${params.toString()}`;
52917
+ }
52918
+ function getOpenRouterProviderIconUrlFromLookupId(iconId) {
52919
+ const providerName = extractOpenRouterProviderName(iconId);
52920
+ if (!providerName) {
52921
+ return void 0;
52922
+ }
52923
+ return getOpenRouterProviderIconUrl(providerName);
52924
+ }
52728
52925
  function svgToDataUri7(svg) {
52729
52926
  const encoded = encodeURIComponent(svg).replace(/'/g, "%27").replace(/"/g, "%22");
52730
52927
  return `data:image/svg+xml,${encoded}`;
@@ -52752,7 +52949,7 @@ function getModelIconDataUri(modelId) {
52752
52949
  }
52753
52950
  return void 0;
52754
52951
  }
52755
- 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, OpenRouterProvider, percentileSchema, providerRoutingSchema, serverToolParametersSchema, serverToolsSchema, openrouterProviderOptions, openrouter;
52952
+ 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;
52756
52953
  var init_dist6 = __esm({
52757
52954
  "../openrouter/dist/index.js"() {
52758
52955
  OPENROUTER_SERVER_TOOL_NAMES = [
@@ -52841,6 +53038,85 @@ var init_dist6 = __esm({
52841
53038
  cohere: COHERE_ICON,
52842
53039
  perplexity: PERPLEXITY_ICON
52843
53040
  };
53041
+ OPENROUTER_PROVIDER_ICON_PREFIX = "provider:";
53042
+ OPENROUTER_PROVIDER_URL_ENTRIES = [
53043
+ { name: "SambaNova", slug: "sambanova", url: "https://sambanova.ai/" },
53044
+ { name: "Reka", slug: "reka", url: "https://reka.ai/" },
53045
+ { name: "Cerebras", slug: "cerebras", url: "https://www.cerebras.ai/" },
53046
+ { name: "Morph", slug: "morph", url: "https://morphllm.com/" },
53047
+ { name: "AkashML", slug: "akashml", url: "https://akashml.com/" },
53048
+ { name: "Moonshot AI", slug: "moonshotai", url: "https://platform.moonshot.ai/" },
53049
+ { name: "OpenAI", slug: "openai", url: "https://openai.com/" },
53050
+ { name: "Z.AI", slug: "z-ai", url: "https://chat.z.ai/" },
53051
+ { name: "WandB", slug: "wandb", url: "https://wandb.ai/" },
53052
+ { name: "Black Forest Labs", slug: "black-forest-labs", url: "https://bfl.ai/" },
53053
+ { name: "Ionstream", slug: "ionstream", url: "https://ionstream.ai/" },
53054
+ { name: "AI21", slug: "ai21", url: "https://www.ai21.com/" },
53055
+ { name: "Minimax", slug: "minimax", url: "https://www.minimax.io/" },
53056
+ { name: "Featherless", slug: "featherless", url: "https://featherless.ai/" },
53057
+ { name: "Io Net", slug: "io-net", url: "https://io.net/" },
53058
+ { name: "Fireworks", slug: "fireworks", url: "https://fireworks.ai/" },
53059
+ { name: "BaseTen", slug: "baseten", url: "https://www.baseten.co/" },
53060
+ { name: "Groq", slug: "groq", url: "https://groq.com/" },
53061
+ { name: "NCompass", slug: "ncompass", url: "https://ncompass.tech/" },
53062
+ { name: "Cohere", slug: "cohere", url: "https://cohere.com/" },
53063
+ { name: "Crusoe", slug: "crusoe", url: "https://legal.crusoe.ai/" },
53064
+ { name: "NextBit", slug: "nextbit", url: "https://www.nextbit256.com/" },
53065
+ { name: "Mancer 2", slug: "mancer", url: "https://mancer.tech/", aliases: ["Mancer"] },
53066
+ { name: "DeepSeek", slug: "deepseek", url: "https://chat.deepseek.com/" },
53067
+ { name: "Perplexity", slug: "perplexity", url: "https://www.perplexity.ai/" },
53068
+ { name: "SiliconFlow", slug: "siliconflow", url: "https://docs.siliconflow.com/" },
53069
+ { name: "Infermatic", slug: "infermatic", url: "https://infermatic.ai/" },
53070
+ { name: "Avian", slug: "avian", url: "https://avian.io/" },
53071
+ { name: "xAI", slug: "xai", url: "https://x.ai/" },
53072
+ { name: "Alibaba", slug: "alibaba", url: "https://www.alibabacloud.com/" },
53073
+ { name: "Inflection", slug: "inflection", url: "https://inflection.ai/" },
53074
+ { name: "Wafer", slug: "wafer", url: "https://www.wafer.ai/" },
53075
+ { name: "Novita", slug: "novita", url: "https://novita.ai/", aliases: ["NovitaAI"] },
53076
+ { name: "DeepInfra", slug: "deepinfra", url: "https://deepinfra.com/" },
53077
+ { name: "Sourceful", slug: "sourceful", url: "https://www.sourceful.com/" },
53078
+ { name: "Perceptron", slug: "perceptron", url: "https://www.perceptron.inc/" },
53079
+ { name: "Mara", slug: "mara", url: "https://www.mara.com/" },
53080
+ { name: "InferenceNet", slug: "inference-net", url: "https://inference.net/" },
53081
+ { name: "DigitalOcean", slug: "digitalocean", url: "https://www.digitalocean.com/" },
53082
+ { name: "Xiaomi", slug: "xiaomi", url: "https://platform.xiaomimimo.com/" },
53083
+ { name: "Azure", slug: "azure", url: "https://www.microsoft.com/" },
53084
+ { name: "Nvidia", slug: "nvidia", url: "https://www.nvidia.com/en-us/" },
53085
+ { name: "Friendli", slug: "friendli", url: "https://friendli.ai/" },
53086
+ { name: "Inception", slug: "inception", url: "https://www.inceptionlabs.ai/" },
53087
+ { name: "Decart", slug: "decart", url: "https://cogito.decart.ai/" },
53088
+ { name: "Mistral", slug: "mistral", url: "https://mistral.ai/" },
53089
+ { name: "Darkbloom", slug: "darkbloom", url: "https://www.darkbloom.dev/" },
53090
+ { name: "Nebius", slug: "nebius", url: "https://docs.nebius.com/" },
53091
+ { name: "AionLabs", slug: "aion-labs", url: "https://www.aionlabs.ai/" },
53092
+ { name: "Cloudflare", slug: "cloudflare", url: "https://developers.cloudflare.com/" },
53093
+ { name: "Liquid", slug: "liquid", url: "https://www.liquid.ai/" },
53094
+ { name: "OpenInference", slug: "open-inference", url: "https://www.openinference.xyz/" },
53095
+ { name: "Relace", slug: "relace", url: "https://www.relace.ai/" },
53096
+ { name: "DekaLLM", slug: "dekallm", url: "https://www.cloudeka.id/" },
53097
+ { name: "Phala", slug: "phala", url: "https://red-pill.ai/" },
53098
+ { name: "Poolside", slug: "poolside", url: "https://poolside.ai/" },
53099
+ { name: "Parasail", slug: "parasail", url: "https://www.parasail.io/" },
53100
+ { name: "ModelRun", slug: "modelrun", url: "https://modelrun.org/" },
53101
+ { name: "Seed", slug: "seed", url: "https://docs.byteplus.com/" },
53102
+ { name: "GMICloud", slug: "gmicloud", url: "https://docs.gmicloud.ai/" },
53103
+ { name: "Modular", slug: "modular", url: "https://www.runmodelrun.com/" },
53104
+ { name: "Cirrascale", slug: "cirrascale", url: "https://www.cirrascale.com/" },
53105
+ { name: "Clarifai", slug: "clarifai", url: "https://www.clarifai.com/" },
53106
+ { name: "Anthropic", slug: "anthropic", url: "https://www.anthropic.com/" },
53107
+ { name: "Baidu", slug: "baidu", url: "https://intl.cloud.baidu.com/" },
53108
+ { name: "AtlasCloud", slug: "atlas-cloud", url: "https://www.atlascloud.ai/" },
53109
+ { name: "Together", slug: "together", url: "https://www.together.ai/" },
53110
+ { name: "Amazon Bedrock", slug: "amazon-bedrock", url: "https://aws.amazon.com/" },
53111
+ { name: "Venice", slug: "venice", url: "https://venice.ai/" },
53112
+ { name: "Inceptron", slug: "inceptron", url: "https://www.inceptron.io/" },
53113
+ { name: "StreamLake", slug: "streamlake", url: "https://www.streamlake.ai/" },
53114
+ { name: "Google", slug: "google-vertex", url: "https://cloud.google.com/", aliases: ["Google Vertex"] },
53115
+ { name: "Nex AGI", slug: "nex-agi", url: "https://api.nex-agi.cn/" },
53116
+ { name: "Chutes", slug: "chutes", url: "https://chutes.ai/" },
53117
+ { name: "Google AI Studio", slug: "google-ai-studio", url: "https://cloud.google.com/" }
53118
+ ];
53119
+ OPENROUTER_PROVIDER_URLS = buildOpenRouterProviderUrlMap();
52844
53120
  OpenRouterProvider = class _OpenRouterProvider {
52845
53121
  name = "openrouter";
52846
53122
  specificationVersion = "1";
@@ -52954,6 +53230,10 @@ var init_dist6 = __esm({
52954
53230
  if (!modelId) {
52955
53231
  return svgToDataUri7(OPENROUTER_ICON);
52956
53232
  }
53233
+ const providerIcon = getOpenRouterProviderIconUrlFromLookupId(modelId);
53234
+ if (providerIcon) {
53235
+ return providerIcon;
53236
+ }
52957
53237
  const modelIcon = getModelIconDataUri(modelId);
52958
53238
  if (modelIcon) {
52959
53239
  return modelIcon;
@@ -67027,13 +67307,16 @@ var tenvs_get_default = defineController2(async ({ params, agents, prompts, tool
67027
67307
 
67028
67308
  // src/api/models/[name]/curl-data.get.ts
67029
67309
  init_platform_routing();
67310
+ function normalizeGoogleModelId3(model) {
67311
+ return model?.trim().replace(/^google\//, "").replace(/^models\//, "").replace(/^publishers\/google\/models\//, "");
67312
+ }
67030
67313
  var PROVIDER_ENDPOINTS = {
67031
67314
  cloudflare: (env2) => env2.CLOUDFLARE_ACCOUNT_ID ? `https://api.cloudflare.com/client/v4/accounts/${env2.CLOUDFLARE_ACCOUNT_ID}/ai/v1/chat/completions` : "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1/chat/completions",
67032
67315
  cerebras: () => "https://api.cerebras.ai/v1/chat/completions",
67033
67316
  openai: () => "https://api.openai.com/v1/responses",
67034
67317
  openrouter: () => "https://openrouter.ai/api/v1/responses",
67035
67318
  anthropic: () => "https://api.anthropic.com/v1/messages",
67036
- google: () => "https://generativelanguage.googleapis.com/v1beta/models",
67319
+ google: (_env, model) => normalizeGoogleModelId3(model) ? `https://generativelanguage.googleapis.com/v1beta/models/${encodeURIComponent(normalizeGoogleModelId3(model))}:generateContent` : "https://generativelanguage.googleapis.com/v1beta/models/{MODEL}:generateContent",
67037
67320
  groq: () => "https://api.groq.com/openai/v1/chat/completions",
67038
67321
  xai: () => "https://api.x.ai/v1/chat/completions"
67039
67322
  };
@@ -67042,7 +67325,7 @@ var PLATFORM_ENDPOINT_PATHS = {
67042
67325
  cerebras: "/chat/completions",
67043
67326
  openai: "/responses",
67044
67327
  openrouter: "/responses",
67045
- google: "/v1beta/models",
67328
+ google: "/v1beta/models/{MODEL}:generateContent",
67046
67329
  groq: "/chat/completions",
67047
67330
  xai: "/chat/completions"
67048
67331
  };
@@ -67080,7 +67363,7 @@ var curl_data_get_default = defineController2(async ({ params, models, env: env2
67080
67363
  const apiKey = apiKeyEnvName ? env2[apiKeyEnvName] : null;
67081
67364
  if (apiKey) {
67082
67365
  const endpointResolver = PROVIDER_ENDPOINTS[provider];
67083
- const endpoint = endpointResolver ? endpointResolver(env2) : `https://api.${provider}.com/v1/chat/completions`;
67366
+ const endpoint = endpointResolver ? endpointResolver(env2, definition.model) : `https://api.${provider}.com/v1/chat/completions`;
67084
67367
  return Response.json({
67085
67368
  endpoint,
67086
67369
  api_key: apiKey,
@@ -67089,8 +67372,10 @@ var curl_data_get_default = defineController2(async ({ params, models, env: env2
67089
67372
  }
67090
67373
  const routing = resolvePlatformRouting(provider, env2);
67091
67374
  if (routing) {
67375
+ const platformPath2 = PLATFORM_ENDPOINT_PATHS[provider] ?? "/chat/completions";
67376
+ const endpointPath = provider === "google" ? platformPath2.replace("{MODEL}", encodeURIComponent(normalizeGoogleModelId3(definition.model) ?? definition.model)) : platformPath2;
67092
67377
  return Response.json({
67093
- endpoint: `${routing.baseUrl}${PLATFORM_ENDPOINT_PATHS[provider] ?? "/chat/completions"}`,
67378
+ endpoint: `${routing.baseUrl}${endpointPath}`,
67094
67379
  api_key: routing.apiKey,
67095
67380
  sdk: provider
67096
67381
  });