@opentiny/next-sdk 0.2.10 → 0.3.0-alpha.0

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.
@@ -16196,7 +16196,7 @@ function getParseErrorMessage(error) {
16196
16196
  }
16197
16197
  return String(error);
16198
16198
  }
16199
- function getSchemaDescription(schema) {
16199
+ function getSchemaDescription$1(schema) {
16200
16200
  return schema.description;
16201
16201
  }
16202
16202
  function isSchemaOptional(schema) {
@@ -23670,7 +23670,7 @@ function promptArgumentsFromSchema(schema) {
23670
23670
  if (!shape)
23671
23671
  return [];
23672
23672
  return Object.entries(shape).map(([name16, field]) => {
23673
- const description2 = getSchemaDescription(field);
23673
+ const description2 = getSchemaDescription$1(field);
23674
23674
  const isOptional = isSchemaOptional(field);
23675
23675
  return {
23676
23676
  name: name16,
@@ -24319,7 +24319,7 @@ class ExtensionClientTransport {
24319
24319
  console.log("【Client Transport】处理server消息错误:", error);
24320
24320
  }
24321
24321
  },
24322
- "content->side"
24322
+ "content->bg"
24323
24323
  );
24324
24324
  }
24325
24325
  // 是否已关闭
@@ -24342,13 +24342,21 @@ class ExtensionClientTransport {
24342
24342
  async send(message, _options) {
24343
24343
  this._throwError(() => !this._isStarted, "【Client Transport】 未启动,无法发送消息");
24344
24344
  this._throwError(() => this._isClosed, "【Client Transport】 已关闭,无法发送消息");
24345
- const sessionInfo = chrome.sessionRegistry.get(this.targetSessionId);
24346
- this._throwError(() => !sessionInfo, `【Client Transport】sessionRegistry中未找到${this.targetSessionId}`);
24347
- const tabId = sessionInfo.tabIds[sessionInfo.tabIds.length - 1];
24345
+ let tabId;
24346
+ if (chrome.sessionRegistry) {
24347
+ const sessionInfo = chrome.sessionRegistry.get(this.targetSessionId);
24348
+ if (sessionInfo && sessionInfo.tabIds.length > 0) {
24349
+ tabId = sessionInfo.tabIds[sessionInfo.tabIds.length - 1];
24350
+ }
24351
+ }
24352
+ if (tabId == null) {
24353
+ tabId = await chrome.runtime.sendMessage({ type: "get-session-tab-id", sessionId: this.targetSessionId });
24354
+ }
24355
+ this._throwError(() => tabId == null, `【Client Transport】后台未找到活动的tabId用于${this.targetSessionId}`);
24348
24356
  sendRuntimeMessage(
24349
24357
  "mcp-client-to-server",
24350
24358
  { sessionId: this.targetSessionId, tabId, mcpMessage: message },
24351
- "side->content"
24359
+ "bg->content"
24352
24360
  );
24353
24361
  }
24354
24362
  /** 关闭 transport */
@@ -24380,17 +24388,6 @@ class ExtensionPageServerTransport {
24380
24388
  this._isClosed = false;
24381
24389
  this._lastRegistration = null;
24382
24390
  this.sessionId = sessionId || randomUUID();
24383
- this._messageListener1 = onWindowMessage(
24384
- "sidepanel-ready-to-page",
24385
- () => {
24386
- if (this._lastRegistration && this._isStarted) {
24387
- this.notifyRegistration(this._lastRegistration).catch((error) => {
24388
- console.error("【Page Svr Transport】 notifyRegistration失败:", error);
24389
- });
24390
- }
24391
- },
24392
- "content->page"
24393
- );
24394
24391
  this._messageListener2 = onWindowMessage(
24395
24392
  "mcp-client-to-server-to-page",
24396
24393
  (data) => {
@@ -24473,7 +24470,6 @@ class ExtensionPageServerTransport {
24473
24470
  async close() {
24474
24471
  if (this._isClosed) return;
24475
24472
  try {
24476
- this._messageListener1 && this._messageListener1();
24477
24473
  this._messageListener2 && this._messageListener2();
24478
24474
  this._isClosed = true;
24479
24475
  this._isStarted = false;
@@ -24490,18 +24486,6 @@ class ContentScriptServerTransport {
24490
24486
  this._lastRegistration = null;
24491
24487
  this.sessionId = sessionId || randomUUID();
24492
24488
  this.tabId = tabId;
24493
- onRuntimeMessage(
24494
- "sidepanel-ready",
24495
- () => {
24496
- if (this._lastRegistration && this._isStarted) {
24497
- this.notifyRegistration(this._lastRegistration).catch((error) => {
24498
- console.log("【Content Svr Transport】 notifyRegistration 失败", error);
24499
- });
24500
- }
24501
- },
24502
- "side->content",
24503
- this.tabId
24504
- );
24505
24489
  }
24506
24490
  // 最后一次注册信息(用于 Sidepanel 刷新后重新注册)
24507
24491
  _throwError(whenFn, message) {
@@ -24540,7 +24524,7 @@ class ContentScriptServerTransport {
24540
24524
  console.log("【Content Svr Transport】 处理消息时发生错误:", error);
24541
24525
  }
24542
24526
  },
24543
- "side->content",
24527
+ "bg->content",
24544
24528
  this.tabId
24545
24529
  );
24546
24530
  this._isStarted = true;
@@ -24557,7 +24541,7 @@ class ContentScriptServerTransport {
24557
24541
  sessionId: this.sessionId,
24558
24542
  mcpMessage: message
24559
24543
  },
24560
- "content->side"
24544
+ "content->bg"
24561
24545
  );
24562
24546
  if ("result" in message && message.result?.content) {
24563
24547
  sendWindowMessage(
@@ -24585,7 +24569,7 @@ class ContentScriptServerTransport {
24585
24569
  title: document.title
24586
24570
  }
24587
24571
  },
24588
- "content->side"
24572
+ "content->bg"
24589
24573
  );
24590
24574
  }
24591
24575
  async close() {
@@ -28391,6 +28375,9 @@ async function downloadBlob(url2, options) {
28391
28375
  const response = await fetch(url2, {
28392
28376
  signal: options == null ? void 0 : options.abortSignal
28393
28377
  });
28378
+ if (response.redirected) {
28379
+ validateDownloadUrl(response.url);
28380
+ }
28394
28381
  if (!response.ok) {
28395
28382
  throw new DownloadError({
28396
28383
  url: url2,
@@ -28552,7 +28539,7 @@ function withUserAgentSuffix$1(headers, ...userAgentSuffixParts) {
28552
28539
  );
28553
28540
  return Object.fromEntries(normalizedHeaders.entries());
28554
28541
  }
28555
- var VERSION$7 = "4.0.19";
28542
+ var VERSION$7 = "4.0.21";
28556
28543
  var getOriginalFetch = () => globalThis.fetch;
28557
28544
  var getFromApi = async ({
28558
28545
  url: url2,
@@ -28776,7 +28763,7 @@ function visit(def) {
28776
28763
  if (typeof def === "boolean") return def;
28777
28764
  return addAdditionalPropertiesToJsonSchema(def);
28778
28765
  }
28779
- var ignoreOverride = Symbol(
28766
+ var ignoreOverride = /* @__PURE__ */ Symbol(
28780
28767
  "Let zodToJsonSchema decide on which parser to use"
28781
28768
  );
28782
28769
  var defaultOptions = {
@@ -29868,7 +29855,7 @@ var zod3ToJsonSchema = (schema, options) => {
29868
29855
  combined.$schema = "http://json-schema.org/draft-07/schema#";
29869
29856
  return combined;
29870
29857
  };
29871
- var schemaSymbol = Symbol.for("vercel.ai.schema");
29858
+ var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
29872
29859
  function lazySchema(createSchema) {
29873
29860
  let schema;
29874
29861
  return () => {
@@ -30976,6 +30963,187 @@ var gatewayCreditsResponseSchema = lazySchema(
30976
30963
  }))
30977
30964
  )
30978
30965
  );
30966
+ var GatewaySpendReport = class {
30967
+ constructor(config2) {
30968
+ this.config = config2;
30969
+ }
30970
+ async getSpendReport(params) {
30971
+ try {
30972
+ const baseUrl = new URL(this.config.baseURL);
30973
+ const searchParams = new URLSearchParams();
30974
+ searchParams.set("start_date", params.startDate);
30975
+ searchParams.set("end_date", params.endDate);
30976
+ if (params.groupBy) {
30977
+ searchParams.set("group_by", params.groupBy);
30978
+ }
30979
+ if (params.datePart) {
30980
+ searchParams.set("date_part", params.datePart);
30981
+ }
30982
+ if (params.userId) {
30983
+ searchParams.set("user_id", params.userId);
30984
+ }
30985
+ if (params.model) {
30986
+ searchParams.set("model", params.model);
30987
+ }
30988
+ if (params.provider) {
30989
+ searchParams.set("provider", params.provider);
30990
+ }
30991
+ if (params.credentialType) {
30992
+ searchParams.set("credential_type", params.credentialType);
30993
+ }
30994
+ if (params.tags && params.tags.length > 0) {
30995
+ searchParams.set("tags", params.tags.join(","));
30996
+ }
30997
+ const { value } = await getFromApi({
30998
+ url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`,
30999
+ headers: await resolve(this.config.headers()),
31000
+ successfulResponseHandler: createJsonResponseHandler$1(
31001
+ gatewaySpendReportResponseSchema
31002
+ ),
31003
+ failedResponseHandler: createJsonErrorResponseHandler$1({
31004
+ errorSchema: any(),
31005
+ errorToMessage: (data) => data
31006
+ }),
31007
+ fetch: this.config.fetch
31008
+ });
31009
+ return value;
31010
+ } catch (error) {
31011
+ throw await asGatewayError(error);
31012
+ }
31013
+ }
31014
+ };
31015
+ var gatewaySpendReportResponseSchema = lazySchema(
31016
+ () => zodSchema(
31017
+ object$2({
31018
+ results: array$1(
31019
+ object$2({
31020
+ day: string().optional(),
31021
+ hour: string().optional(),
31022
+ user: string().optional(),
31023
+ model: string().optional(),
31024
+ tag: string().optional(),
31025
+ provider: string().optional(),
31026
+ credential_type: _enum(["byok", "system"]).optional(),
31027
+ total_cost: number$1(),
31028
+ market_cost: number$1().optional(),
31029
+ input_tokens: number$1().optional(),
31030
+ output_tokens: number$1().optional(),
31031
+ cached_input_tokens: number$1().optional(),
31032
+ cache_creation_input_tokens: number$1().optional(),
31033
+ reasoning_tokens: number$1().optional(),
31034
+ request_count: number$1().optional()
31035
+ }).transform(
31036
+ ({
31037
+ credential_type,
31038
+ total_cost,
31039
+ market_cost,
31040
+ input_tokens,
31041
+ output_tokens,
31042
+ cached_input_tokens,
31043
+ cache_creation_input_tokens,
31044
+ reasoning_tokens,
31045
+ request_count,
31046
+ ...rest
31047
+ }) => ({
31048
+ ...rest,
31049
+ ...credential_type !== void 0 ? { credentialType: credential_type } : {},
31050
+ totalCost: total_cost,
31051
+ ...market_cost !== void 0 ? { marketCost: market_cost } : {},
31052
+ ...input_tokens !== void 0 ? { inputTokens: input_tokens } : {},
31053
+ ...output_tokens !== void 0 ? { outputTokens: output_tokens } : {},
31054
+ ...cached_input_tokens !== void 0 ? { cachedInputTokens: cached_input_tokens } : {},
31055
+ ...cache_creation_input_tokens !== void 0 ? { cacheCreationInputTokens: cache_creation_input_tokens } : {},
31056
+ ...reasoning_tokens !== void 0 ? { reasoningTokens: reasoning_tokens } : {},
31057
+ ...request_count !== void 0 ? { requestCount: request_count } : {}
31058
+ })
31059
+ )
31060
+ )
31061
+ })
31062
+ )
31063
+ );
31064
+ var GatewayGenerationInfoFetcher = class {
31065
+ constructor(config2) {
31066
+ this.config = config2;
31067
+ }
31068
+ async getGenerationInfo(params) {
31069
+ try {
31070
+ const baseUrl = new URL(this.config.baseURL);
31071
+ const { value } = await getFromApi({
31072
+ url: `${baseUrl.origin}/v1/generation?id=${encodeURIComponent(params.id)}`,
31073
+ headers: await resolve(this.config.headers()),
31074
+ successfulResponseHandler: createJsonResponseHandler$1(
31075
+ gatewayGenerationInfoResponseSchema
31076
+ ),
31077
+ failedResponseHandler: createJsonErrorResponseHandler$1({
31078
+ errorSchema: any(),
31079
+ errorToMessage: (data) => data
31080
+ }),
31081
+ fetch: this.config.fetch
31082
+ });
31083
+ return value;
31084
+ } catch (error) {
31085
+ throw await asGatewayError(error);
31086
+ }
31087
+ }
31088
+ };
31089
+ var gatewayGenerationInfoResponseSchema = lazySchema(
31090
+ () => zodSchema(
31091
+ object$2({
31092
+ data: object$2({
31093
+ id: string(),
31094
+ total_cost: number$1(),
31095
+ upstream_inference_cost: number$1(),
31096
+ usage: number$1(),
31097
+ created_at: string(),
31098
+ model: string(),
31099
+ is_byok: boolean(),
31100
+ provider_name: string(),
31101
+ streamed: boolean(),
31102
+ finish_reason: string(),
31103
+ latency: number$1(),
31104
+ generation_time: number$1(),
31105
+ native_tokens_prompt: number$1(),
31106
+ native_tokens_completion: number$1(),
31107
+ native_tokens_reasoning: number$1(),
31108
+ native_tokens_cached: number$1(),
31109
+ native_tokens_cache_creation: number$1(),
31110
+ billable_web_search_calls: number$1()
31111
+ }).transform(
31112
+ ({
31113
+ total_cost,
31114
+ upstream_inference_cost,
31115
+ created_at,
31116
+ is_byok,
31117
+ provider_name,
31118
+ finish_reason,
31119
+ generation_time,
31120
+ native_tokens_prompt,
31121
+ native_tokens_completion,
31122
+ native_tokens_reasoning,
31123
+ native_tokens_cached,
31124
+ native_tokens_cache_creation,
31125
+ billable_web_search_calls,
31126
+ ...rest
31127
+ }) => ({
31128
+ ...rest,
31129
+ totalCost: total_cost,
31130
+ upstreamInferenceCost: upstream_inference_cost,
31131
+ createdAt: created_at,
31132
+ isByok: is_byok,
31133
+ providerName: provider_name,
31134
+ finishReason: finish_reason,
31135
+ generationTime: generation_time,
31136
+ promptTokens: native_tokens_prompt,
31137
+ completionTokens: native_tokens_completion,
31138
+ reasoningTokens: native_tokens_reasoning,
31139
+ cachedTokens: native_tokens_cached,
31140
+ cacheCreationTokens: native_tokens_cache_creation,
31141
+ billableWebSearchCalls: billable_web_search_calls
31142
+ })
31143
+ )
31144
+ }).transform(({ data }) => data)
31145
+ )
31146
+ );
30979
31147
  var GatewayLanguageModel = class {
30980
31148
  constructor(modelId, config2) {
30981
31149
  this.modelId = modelId;
@@ -31700,7 +31868,7 @@ async function getVercelRequestId() {
31700
31868
  var _a92;
31701
31869
  return (_a92 = indexBrowserExports.getContext().headers) == null ? void 0 : _a92["x-vercel-id"];
31702
31870
  }
31703
- var VERSION$6 = "3.0.66";
31871
+ var VERSION$6 = "3.0.83";
31704
31872
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
31705
31873
  function createGatewayProvider(options = {}) {
31706
31874
  var _a92, _b9;
@@ -31800,6 +31968,30 @@ function createGatewayProvider(options = {}) {
31800
31968
  );
31801
31969
  });
31802
31970
  };
31971
+ const getSpendReport = async (params) => {
31972
+ return new GatewaySpendReport({
31973
+ baseURL,
31974
+ headers: getHeaders,
31975
+ fetch: options.fetch
31976
+ }).getSpendReport(params).catch(async (error) => {
31977
+ throw await asGatewayError(
31978
+ error,
31979
+ await parseAuthMethod(await getHeaders())
31980
+ );
31981
+ });
31982
+ };
31983
+ const getGenerationInfo = async (params) => {
31984
+ return new GatewayGenerationInfoFetcher({
31985
+ baseURL,
31986
+ headers: getHeaders,
31987
+ fetch: options.fetch
31988
+ }).getGenerationInfo(params).catch(async (error) => {
31989
+ throw await asGatewayError(
31990
+ error,
31991
+ await parseAuthMethod(await getHeaders())
31992
+ );
31993
+ });
31994
+ };
31803
31995
  const provider = function(modelId) {
31804
31996
  if (new.target) {
31805
31997
  throw new Error(
@@ -31811,6 +32003,8 @@ function createGatewayProvider(options = {}) {
31811
32003
  provider.specificationVersion = "v3";
31812
32004
  provider.getAvailableModels = getAvailableModels;
31813
32005
  provider.getCredits = getCredits;
32006
+ provider.getSpendReport = getSpendReport;
32007
+ provider.getGenerationInfo = getGenerationInfo;
31814
32008
  provider.imageModel = (modelId) => {
31815
32009
  return new GatewayImageModel(modelId, {
31816
32010
  provider: "gateway",
@@ -33146,7 +33340,7 @@ function detectMediaType({
33146
33340
  }
33147
33341
  return void 0;
33148
33342
  }
33149
- var VERSION$4 = "6.0.116";
33343
+ var VERSION$4 = "6.0.141";
33150
33344
  var download = async ({
33151
33345
  url: url2,
33152
33346
  maxBytes,
@@ -33164,6 +33358,9 @@ var download = async ({
33164
33358
  ),
33165
33359
  signal: abortSignal
33166
33360
  });
33361
+ if (response.redirected) {
33362
+ validateDownloadUrl(response.url);
33363
+ }
33167
33364
  if (!response.ok) {
33168
33365
  throw new DownloadError({
33169
33366
  url: urlText,
@@ -35937,7 +36134,7 @@ async function generateText({
35937
36134
  }),
35938
36135
  tracer,
35939
36136
  fn: async (span) => {
35940
- var _a21, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
36137
+ var _a21, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
35941
36138
  const initialMessages = initialPrompt.messages;
35942
36139
  const responseMessages = [];
35943
36140
  const { approvedToolApprovals, deniedToolApprovals } = collectToolApprovals({ messages: initialMessages });
@@ -36154,6 +36351,7 @@ async function generateText({
36154
36351
  headers: (_g2 = result.response) == null ? void 0 : _g2.headers,
36155
36352
  body: (_h2 = result.response) == null ? void 0 : _h2.body
36156
36353
  };
36354
+ const usage = asLanguageModelUsage(result.usage);
36157
36355
  span2.setAttributes(
36158
36356
  await selectTelemetryAttributes({
36159
36357
  telemetry,
@@ -36177,9 +36375,16 @@ async function generateText({
36177
36375
  "ai.response.providerMetadata": JSON.stringify(
36178
36376
  result.providerMetadata
36179
36377
  ),
36180
- // TODO rename telemetry attributes to inputTokens and outputTokens
36181
- "ai.usage.promptTokens": result.usage.inputTokens.total,
36182
- "ai.usage.completionTokens": result.usage.outputTokens.total,
36378
+ "ai.usage.inputTokens": result.usage.inputTokens.total,
36379
+ "ai.usage.inputTokenDetails.noCacheTokens": result.usage.inputTokens.noCache,
36380
+ "ai.usage.inputTokenDetails.cacheReadTokens": result.usage.inputTokens.cacheRead,
36381
+ "ai.usage.inputTokenDetails.cacheWriteTokens": result.usage.inputTokens.cacheWrite,
36382
+ "ai.usage.outputTokens": result.usage.outputTokens.total,
36383
+ "ai.usage.outputTokenDetails.textTokens": result.usage.outputTokens.text,
36384
+ "ai.usage.outputTokenDetails.reasoningTokens": result.usage.outputTokens.reasoning,
36385
+ "ai.usage.totalTokens": usage.totalTokens,
36386
+ "ai.usage.reasoningTokens": result.usage.outputTokens.reasoning,
36387
+ "ai.usage.cachedInputTokens": result.usage.inputTokens.cacheRead,
36183
36388
  // standardized gen-ai llm span attributes:
36184
36389
  "gen_ai.response.finish_reasons": [
36185
36390
  result.finishReason.unified
@@ -36380,10 +36585,7 @@ async function generateText({
36380
36585
  },
36381
36586
  "ai.response.providerMetadata": JSON.stringify(
36382
36587
  currentModelResponse.providerMetadata
36383
- ),
36384
- // TODO rename telemetry attributes to inputTokens and outputTokens
36385
- "ai.usage.promptTokens": currentModelResponse.usage.inputTokens.total,
36386
- "ai.usage.completionTokens": currentModelResponse.usage.outputTokens.total
36588
+ )
36387
36589
  }
36388
36590
  })
36389
36591
  );
@@ -36400,6 +36602,23 @@ async function generateText({
36400
36602
  cachedInputTokens: void 0
36401
36603
  }
36402
36604
  );
36605
+ span.setAttributes(
36606
+ await selectTelemetryAttributes({
36607
+ telemetry,
36608
+ attributes: {
36609
+ "ai.usage.inputTokens": totalUsage.inputTokens,
36610
+ "ai.usage.inputTokenDetails.noCacheTokens": (_n = totalUsage.inputTokenDetails) == null ? void 0 : _n.noCacheTokens,
36611
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_o = totalUsage.inputTokenDetails) == null ? void 0 : _o.cacheReadTokens,
36612
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_p = totalUsage.inputTokenDetails) == null ? void 0 : _p.cacheWriteTokens,
36613
+ "ai.usage.outputTokens": totalUsage.outputTokens,
36614
+ "ai.usage.outputTokenDetails.textTokens": (_q = totalUsage.outputTokenDetails) == null ? void 0 : _q.textTokens,
36615
+ "ai.usage.outputTokenDetails.reasoningTokens": (_r = totalUsage.outputTokenDetails) == null ? void 0 : _r.reasoningTokens,
36616
+ "ai.usage.totalTokens": totalUsage.totalTokens,
36617
+ "ai.usage.reasoningTokens": (_s = totalUsage.outputTokenDetails) == null ? void 0 : _s.reasoningTokens,
36618
+ "ai.usage.cachedInputTokens": (_t = totalUsage.inputTokenDetails) == null ? void 0 : _t.cacheReadTokens
36619
+ }
36620
+ })
36621
+ );
36403
36622
  await notify({
36404
36623
  event: {
36405
36624
  stepNumber: lastStep.stepNumber,
@@ -36627,7 +36846,8 @@ function asContent({
36627
36846
  input: void 0,
36628
36847
  error: part.result,
36629
36848
  providerExecuted: true,
36630
- dynamic: part.dynamic
36849
+ dynamic: part.dynamic,
36850
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36631
36851
  });
36632
36852
  } else {
36633
36853
  contentParts.push({
@@ -36637,7 +36857,8 @@ function asContent({
36637
36857
  input: void 0,
36638
36858
  output: part.result,
36639
36859
  providerExecuted: true,
36640
- dynamic: part.dynamic
36860
+ dynamic: part.dynamic,
36861
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36641
36862
  });
36642
36863
  }
36643
36864
  break;
@@ -36650,7 +36871,8 @@ function asContent({
36650
36871
  input: toolCall.input,
36651
36872
  error: part.result,
36652
36873
  providerExecuted: true,
36653
- dynamic: toolCall.dynamic
36874
+ dynamic: toolCall.dynamic,
36875
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36654
36876
  });
36655
36877
  } else {
36656
36878
  contentParts.push({
@@ -36660,7 +36882,8 @@ function asContent({
36660
36882
  input: toolCall.input,
36661
36883
  output: part.result,
36662
36884
  providerExecuted: true,
36663
- dynamic: toolCall.dynamic
36885
+ dynamic: toolCall.dynamic,
36886
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36664
36887
  });
36665
36888
  }
36666
36889
  break;
@@ -36891,8 +37114,14 @@ function processUIMessageStream({
36891
37114
  anyPart.title = options.title;
36892
37115
  }
36893
37116
  anyPart.providerExecuted = (_a22 = anyOptions.providerExecuted) != null ? _a22 : part.providerExecuted;
36894
- if (anyOptions.providerMetadata != null) {
36895
- part.callProviderMetadata = anyOptions.providerMetadata;
37117
+ const providerMetadata = anyOptions.providerMetadata;
37118
+ if (providerMetadata != null) {
37119
+ if (options.state === "output-available" || options.state === "output-error") {
37120
+ const resultPart = part;
37121
+ resultPart.resultProviderMetadata = providerMetadata;
37122
+ } else {
37123
+ part.callProviderMetadata = providerMetadata;
37124
+ }
36896
37125
  }
36897
37126
  } else {
36898
37127
  state.message.parts.push({
@@ -36906,7 +37135,8 @@ function processUIMessageStream({
36906
37135
  errorText: anyOptions.errorText,
36907
37136
  providerExecuted: anyOptions.providerExecuted,
36908
37137
  preliminary: anyOptions.preliminary,
36909
- ...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37138
+ ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {},
37139
+ ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
36910
37140
  });
36911
37141
  }
36912
37142
  }
@@ -36929,8 +37159,14 @@ function processUIMessageStream({
36929
37159
  anyPart.title = options.title;
36930
37160
  }
36931
37161
  anyPart.providerExecuted = (_b22 = anyOptions.providerExecuted) != null ? _b22 : part.providerExecuted;
36932
- if (anyOptions.providerMetadata != null) {
36933
- part.callProviderMetadata = anyOptions.providerMetadata;
37162
+ const providerMetadata = anyOptions.providerMetadata;
37163
+ if (providerMetadata != null) {
37164
+ if (options.state === "output-available" || options.state === "output-error") {
37165
+ const resultPart = part;
37166
+ resultPart.resultProviderMetadata = providerMetadata;
37167
+ } else {
37168
+ part.callProviderMetadata = providerMetadata;
37169
+ }
36934
37170
  }
36935
37171
  } else {
36936
37172
  state.message.parts.push({
@@ -36944,7 +37180,8 @@ function processUIMessageStream({
36944
37180
  preliminary: anyOptions.preliminary,
36945
37181
  providerExecuted: anyOptions.providerExecuted,
36946
37182
  title: options.title,
36947
- ...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37183
+ ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {},
37184
+ ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
36948
37185
  });
36949
37186
  }
36950
37187
  }
@@ -37228,6 +37465,7 @@ function processUIMessageStream({
37228
37465
  output: chunk.output,
37229
37466
  preliminary: chunk.preliminary,
37230
37467
  providerExecuted: chunk.providerExecuted,
37468
+ providerMetadata: chunk.providerMetadata,
37231
37469
  title: toolInvocation.title
37232
37470
  });
37233
37471
  } else {
@@ -37239,6 +37477,7 @@ function processUIMessageStream({
37239
37477
  output: chunk.output,
37240
37478
  providerExecuted: chunk.providerExecuted,
37241
37479
  preliminary: chunk.preliminary,
37480
+ providerMetadata: chunk.providerMetadata,
37242
37481
  title: toolInvocation.title
37243
37482
  });
37244
37483
  }
@@ -37255,6 +37494,7 @@ function processUIMessageStream({
37255
37494
  input: toolInvocation.input,
37256
37495
  errorText: chunk.errorText,
37257
37496
  providerExecuted: chunk.providerExecuted,
37497
+ providerMetadata: chunk.providerMetadata,
37258
37498
  title: toolInvocation.title
37259
37499
  });
37260
37500
  } else {
@@ -37266,6 +37506,7 @@ function processUIMessageStream({
37266
37506
  rawInput: toolInvocation.rawInput,
37267
37507
  errorText: chunk.errorText,
37268
37508
  providerExecuted: chunk.providerExecuted,
37509
+ providerMetadata: chunk.providerMetadata,
37269
37510
  title: toolInvocation.title
37270
37511
  });
37271
37512
  }
@@ -37838,7 +38079,8 @@ function runToolsTransformation({
37838
38079
  input: toolInputs.get(chunk.toolCallId),
37839
38080
  providerExecuted: true,
37840
38081
  error: chunk.result,
37841
- dynamic: chunk.dynamic
38082
+ dynamic: chunk.dynamic,
38083
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37842
38084
  });
37843
38085
  } else {
37844
38086
  controller.enqueue({
@@ -37848,7 +38090,8 @@ function runToolsTransformation({
37848
38090
  input: toolInputs.get(chunk.toolCallId),
37849
38091
  output: chunk.result,
37850
38092
  providerExecuted: true,
37851
- dynamic: chunk.dynamic
38093
+ dynamic: chunk.dynamic,
38094
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37852
38095
  });
37853
38096
  }
37854
38097
  break;
@@ -38271,6 +38514,7 @@ var DefaultStreamTextResult = class {
38271
38514
  }
38272
38515
  },
38273
38516
  async flush(controller) {
38517
+ var _a21, _b9, _c, _d, _e, _f, _g;
38274
38518
  try {
38275
38519
  if (recordedSteps.length === 0) {
38276
38520
  const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : new NoOutputGeneratedError({
@@ -38334,18 +38578,23 @@ var DefaultStreamTextResult = class {
38334
38578
  },
38335
38579
  "ai.response.toolCalls": {
38336
38580
  output: () => {
38337
- var _a21;
38338
- return ((_a21 = finalStep.toolCalls) == null ? void 0 : _a21.length) ? JSON.stringify(finalStep.toolCalls) : void 0;
38581
+ var _a22;
38582
+ return ((_a22 = finalStep.toolCalls) == null ? void 0 : _a22.length) ? JSON.stringify(finalStep.toolCalls) : void 0;
38339
38583
  }
38340
38584
  },
38341
38585
  "ai.response.providerMetadata": JSON.stringify(
38342
38586
  finalStep.providerMetadata
38343
38587
  ),
38344
38588
  "ai.usage.inputTokens": totalUsage.inputTokens,
38589
+ "ai.usage.inputTokenDetails.noCacheTokens": (_a21 = totalUsage.inputTokenDetails) == null ? void 0 : _a21.noCacheTokens,
38590
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_b9 = totalUsage.inputTokenDetails) == null ? void 0 : _b9.cacheReadTokens,
38591
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_c = totalUsage.inputTokenDetails) == null ? void 0 : _c.cacheWriteTokens,
38345
38592
  "ai.usage.outputTokens": totalUsage.outputTokens,
38593
+ "ai.usage.outputTokenDetails.textTokens": (_d = totalUsage.outputTokenDetails) == null ? void 0 : _d.textTokens,
38594
+ "ai.usage.outputTokenDetails.reasoningTokens": (_e = totalUsage.outputTokenDetails) == null ? void 0 : _e.reasoningTokens,
38346
38595
  "ai.usage.totalTokens": totalUsage.totalTokens,
38347
- "ai.usage.reasoningTokens": totalUsage.reasoningTokens,
38348
- "ai.usage.cachedInputTokens": totalUsage.cachedInputTokens
38596
+ "ai.usage.reasoningTokens": (_f = totalUsage.outputTokenDetails) == null ? void 0 : _f.reasoningTokens,
38597
+ "ai.usage.cachedInputTokens": (_g = totalUsage.inputTokenDetails) == null ? void 0 : _g.cacheReadTokens
38349
38598
  }
38350
38599
  })
38351
38600
  );
@@ -38957,6 +39206,7 @@ var DefaultStreamTextResult = class {
38957
39206
  },
38958
39207
  // invoke onFinish callback and resolve toolResults promise when the stream is about to close:
38959
39208
  async flush(controller) {
39209
+ var _a22, _b22, _c2, _d2, _e2, _f2, _g2;
38960
39210
  const stepToolCallsJson = stepToolCalls.length > 0 ? JSON.stringify(stepToolCalls) : void 0;
38961
39211
  try {
38962
39212
  doStreamSpan.setAttributes(
@@ -38964,29 +39214,22 @@ var DefaultStreamTextResult = class {
38964
39214
  telemetry,
38965
39215
  attributes: {
38966
39216
  "ai.response.finishReason": stepFinishReason,
38967
- "ai.response.text": {
38968
- output: () => activeText
38969
- },
38970
- "ai.response.reasoning": {
38971
- output: () => {
38972
- const reasoningParts = recordedContent.filter(
38973
- (c) => c.type === "reasoning"
38974
- );
38975
- return reasoningParts.length > 0 ? reasoningParts.map((r) => r.text).join("\n") : void 0;
38976
- }
38977
- },
38978
39217
  "ai.response.toolCalls": {
38979
39218
  output: () => stepToolCallsJson
38980
39219
  },
38981
39220
  "ai.response.id": stepResponse.id,
38982
39221
  "ai.response.model": stepResponse.modelId,
38983
39222
  "ai.response.timestamp": stepResponse.timestamp.toISOString(),
38984
- "ai.response.providerMetadata": JSON.stringify(stepProviderMetadata),
38985
39223
  "ai.usage.inputTokens": stepUsage.inputTokens,
39224
+ "ai.usage.inputTokenDetails.noCacheTokens": (_a22 = stepUsage.inputTokenDetails) == null ? void 0 : _a22.noCacheTokens,
39225
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_b22 = stepUsage.inputTokenDetails) == null ? void 0 : _b22.cacheReadTokens,
39226
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_c2 = stepUsage.inputTokenDetails) == null ? void 0 : _c2.cacheWriteTokens,
38986
39227
  "ai.usage.outputTokens": stepUsage.outputTokens,
39228
+ "ai.usage.outputTokenDetails.textTokens": (_d2 = stepUsage.outputTokenDetails) == null ? void 0 : _d2.textTokens,
39229
+ "ai.usage.outputTokenDetails.reasoningTokens": (_e2 = stepUsage.outputTokenDetails) == null ? void 0 : _e2.reasoningTokens,
38987
39230
  "ai.usage.totalTokens": stepUsage.totalTokens,
38988
- "ai.usage.reasoningTokens": stepUsage.reasoningTokens,
38989
- "ai.usage.cachedInputTokens": stepUsage.cachedInputTokens,
39231
+ "ai.usage.reasoningTokens": (_f2 = stepUsage.outputTokenDetails) == null ? void 0 : _f2.reasoningTokens,
39232
+ "ai.usage.cachedInputTokens": (_g2 = stepUsage.inputTokenDetails) == null ? void 0 : _g2.cacheReadTokens,
38990
39233
  // standardized gen-ai llm span attributes:
38991
39234
  "gen_ai.response.finish_reasons": [
38992
39235
  stepFinishReason
@@ -38999,8 +39242,6 @@ var DefaultStreamTextResult = class {
38999
39242
  })
39000
39243
  );
39001
39244
  } catch (error) {
39002
- } finally {
39003
- doStreamSpan.end();
39004
39245
  }
39005
39246
  controller.enqueue({
39006
39247
  type: "finish-step",
@@ -39018,6 +39259,28 @@ var DefaultStreamTextResult = class {
39018
39259
  stepUsage
39019
39260
  );
39020
39261
  await stepFinish.promise;
39262
+ const processedStep = recordedSteps[recordedSteps.length - 1];
39263
+ try {
39264
+ doStreamSpan.setAttributes(
39265
+ await selectTelemetryAttributes({
39266
+ telemetry,
39267
+ attributes: {
39268
+ "ai.response.text": {
39269
+ output: () => processedStep.text
39270
+ },
39271
+ "ai.response.reasoning": {
39272
+ output: () => processedStep.reasoningText
39273
+ },
39274
+ "ai.response.providerMetadata": JSON.stringify(
39275
+ processedStep.providerMetadata
39276
+ )
39277
+ }
39278
+ })
39279
+ );
39280
+ } catch (error) {
39281
+ } finally {
39282
+ doStreamSpan.end();
39283
+ }
39021
39284
  const clientToolCalls = stepToolCalls.filter(
39022
39285
  (toolCall) => toolCall.providerExecuted !== true
39023
39286
  );
@@ -39448,6 +39711,7 @@ var DefaultStreamTextResult = class {
39448
39711
  toolCallId: part.toolCallId,
39449
39712
  output: part.output,
39450
39713
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
39714
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
39451
39715
  ...part.preliminary != null ? { preliminary: part.preliminary } : {},
39452
39716
  ...dynamic != null ? { dynamic } : {}
39453
39717
  });
@@ -39458,8 +39722,9 @@ var DefaultStreamTextResult = class {
39458
39722
  controller.enqueue({
39459
39723
  type: "tool-output-error",
39460
39724
  toolCallId: part.toolCallId,
39461
- errorText: onError(part.error),
39725
+ errorText: part.providerExecuted ? typeof part.error === "string" ? part.error : JSON.stringify(part.error) : onError(part.error),
39462
39726
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
39727
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
39463
39728
  ...dynamic != null ? { dynamic } : {}
39464
39729
  });
39465
39730
  break;
@@ -39632,9 +39897,10 @@ var MCPClientError = class extends (_b = AISDKError$1, _a$1 = symbol$1, _b) {
39632
39897
  return AISDKError$1.hasMarker(error, marker$1);
39633
39898
  }
39634
39899
  };
39635
- var LATEST_PROTOCOL_VERSION = "2025-06-18";
39900
+ var LATEST_PROTOCOL_VERSION = "2025-11-25";
39636
39901
  var SUPPORTED_PROTOCOL_VERSIONS = [
39637
39902
  LATEST_PROTOCOL_VERSION,
39903
+ "2025-06-18",
39638
39904
  "2025-03-26",
39639
39905
  "2024-11-05"
39640
39906
  ];
@@ -40489,6 +40755,7 @@ async function selectResourceURL(serverUrl, provider, resourceMetadata) {
40489
40755
  async function authInternal(provider, {
40490
40756
  serverUrl,
40491
40757
  authorizationCode,
40758
+ callbackState,
40492
40759
  scope: scope2,
40493
40760
  resourceMetadataUrl,
40494
40761
  fetchFn
@@ -40541,6 +40808,14 @@ async function authInternal(provider, {
40541
40808
  clientInformation = fullInformation;
40542
40809
  }
40543
40810
  if (authorizationCode !== void 0) {
40811
+ if (provider.storedState) {
40812
+ const expectedState = await provider.storedState();
40813
+ if (expectedState !== void 0 && expectedState !== callbackState) {
40814
+ throw new Error(
40815
+ "OAuth state parameter mismatch - possible CSRF attack"
40816
+ );
40817
+ }
40818
+ }
40544
40819
  const codeVerifier2 = await provider.codeVerifier();
40545
40820
  const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
40546
40821
  metadata: metadata2,
@@ -40579,6 +40854,9 @@ async function authInternal(provider, {
40579
40854
  }
40580
40855
  }
40581
40856
  const state = provider.state ? await provider.state() : void 0;
40857
+ if (state && provider.saveState) {
40858
+ await provider.saveState(state);
40859
+ }
40582
40860
  const { authorizationUrl, codeVerifier } = await startAuthorization(
40583
40861
  authorizationServerUrl,
40584
40862
  {
@@ -40598,12 +40876,14 @@ var SseMCPTransport = class {
40598
40876
  constructor({
40599
40877
  url: url2,
40600
40878
  headers,
40601
- authProvider
40879
+ authProvider,
40880
+ redirect = "follow"
40602
40881
  }) {
40603
40882
  this.connected = false;
40604
40883
  this.url = new URL(url2);
40605
40884
  this.headers = headers;
40606
40885
  this.authProvider = authProvider;
40886
+ this.redirectMode = redirect;
40607
40887
  }
40608
40888
  async commonHeaders(base) {
40609
40889
  const headers = {
@@ -40637,7 +40917,8 @@ var SseMCPTransport = class {
40637
40917
  });
40638
40918
  const response = await fetch(this.url.href, {
40639
40919
  headers,
40640
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
40920
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
40921
+ redirect: this.redirectMode
40641
40922
  });
40642
40923
  if (response.status === 401 && this.authProvider && !triedAuth) {
40643
40924
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
@@ -40756,7 +41037,8 @@ var SseMCPTransport = class {
40756
41037
  method: "POST",
40757
41038
  headers,
40758
41039
  body: JSON.stringify(message),
40759
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41040
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41041
+ redirect: this.redirectMode
40760
41042
  };
40761
41043
  const response = await fetch(endpoint, init);
40762
41044
  if (response.status === 401 && this.authProvider && !triedAuth) {
@@ -40797,7 +41079,8 @@ var HttpMCPTransport = class {
40797
41079
  constructor({
40798
41080
  url: url2,
40799
41081
  headers,
40800
- authProvider
41082
+ authProvider,
41083
+ redirect = "follow"
40801
41084
  }) {
40802
41085
  this.inboundReconnectAttempts = 0;
40803
41086
  this.reconnectionOptions = {
@@ -40809,6 +41092,7 @@ var HttpMCPTransport = class {
40809
41092
  this.url = new URL(url2);
40810
41093
  this.headers = headers;
40811
41094
  this.authProvider = authProvider;
41095
+ this.redirectMode = redirect;
40812
41096
  }
40813
41097
  async commonHeaders(base) {
40814
41098
  const headers = {
@@ -40849,7 +41133,8 @@ var HttpMCPTransport = class {
40849
41133
  await fetch(this.url, {
40850
41134
  method: "DELETE",
40851
41135
  headers,
40852
- signal: this.abortController.signal
41136
+ signal: this.abortController.signal,
41137
+ redirect: this.redirectMode
40853
41138
  }).catch(() => void 0);
40854
41139
  }
40855
41140
  } catch (e) {
@@ -40869,7 +41154,8 @@ var HttpMCPTransport = class {
40869
41154
  method: "POST",
40870
41155
  headers,
40871
41156
  body: JSON.stringify(message),
40872
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41157
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41158
+ redirect: this.redirectMode
40873
41159
  };
40874
41160
  const response = await fetch(this.url, init);
40875
41161
  const sessionId = response.headers.get("mcp-session-id");
@@ -41018,7 +41304,8 @@ var HttpMCPTransport = class {
41018
41304
  const response = await fetch(this.url.href, {
41019
41305
  method: "GET",
41020
41306
  headers,
41021
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41307
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41308
+ redirect: this.redirectMode
41022
41309
  });
41023
41310
  const sessionId = response.headers.get("mcp-session-id");
41024
41311
  if (sessionId) {
@@ -41679,9 +41966,9 @@ var openaiFailedResponseHandler = createJsonErrorResponseHandler$1({
41679
41966
  });
41680
41967
  function getOpenAILanguageModelCapabilities(modelId) {
41681
41968
  const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41682
- const supportsPriorityProcessing = modelId.startsWith("gpt-4") || modelId.startsWith("gpt-5-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-nano") && !modelId.startsWith("gpt-5-chat") || modelId.startsWith("o3") || modelId.startsWith("o4-mini");
41969
+ const supportsPriorityProcessing = modelId.startsWith("gpt-4") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-nano") && !modelId.startsWith("gpt-5-chat") && !modelId.startsWith("gpt-5.4-nano") || modelId.startsWith("o3") || modelId.startsWith("o4-mini");
41683
41970
  const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41684
- const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2");
41971
+ const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2") || modelId.startsWith("gpt-5.3") || modelId.startsWith("gpt-5.4");
41685
41972
  const systemMessageMode = isReasoningModel ? "developer" : "system";
41686
41973
  return {
41687
41974
  supportsFlexProcessing,
@@ -43802,6 +44089,36 @@ var shell = createProviderToolFactoryWithOutputSchema({
43802
44089
  inputSchema: shellInputSchema,
43803
44090
  outputSchema: shellOutputSchema
43804
44091
  });
44092
+ var toolSearchArgsSchema = lazySchema(
44093
+ () => zodSchema(
44094
+ object$2({
44095
+ execution: _enum(["server", "client"]).optional(),
44096
+ description: string().optional(),
44097
+ parameters: record(string(), unknown()).optional()
44098
+ })
44099
+ )
44100
+ );
44101
+ var toolSearchInputSchema = lazySchema(
44102
+ () => zodSchema(
44103
+ object$2({
44104
+ arguments: unknown().optional(),
44105
+ call_id: string().nullish()
44106
+ })
44107
+ )
44108
+ );
44109
+ var toolSearchOutputSchema = lazySchema(
44110
+ () => zodSchema(
44111
+ object$2({
44112
+ tools: array$1(record(string(), unknown()))
44113
+ })
44114
+ )
44115
+ );
44116
+ var toolSearchToolFactory = createProviderToolFactoryWithOutputSchema({
44117
+ id: "openai.tool_search",
44118
+ inputSchema: toolSearchInputSchema,
44119
+ outputSchema: toolSearchOutputSchema
44120
+ });
44121
+ var toolSearch = (args = {}) => toolSearchToolFactory(args);
43805
44122
  var webSearchArgsSchema = lazySchema(
43806
44123
  () => zodSchema(
43807
44124
  object$2({
@@ -44058,7 +44375,17 @@ var openaiTools = {
44058
44375
  * @param serverDescription - Optional description of the server.
44059
44376
  * @param serverUrl - URL for the MCP server.
44060
44377
  */
44061
- mcp
44378
+ mcp,
44379
+ /**
44380
+ * Tool search allows the model to dynamically search for and load deferred
44381
+ * tools into the model's context as needed. This helps reduce overall token
44382
+ * usage, cost, and latency by only loading tools when the model needs them.
44383
+ *
44384
+ * To use tool search, mark functions or namespaces with `defer_loading: true`
44385
+ * in the tools array. The model will use tool search to load these tools
44386
+ * when it determines they are needed.
44387
+ */
44388
+ toolSearch
44062
44389
  };
44063
44390
  function convertOpenAIResponsesUsage(usage) {
44064
44391
  var _a10, _b9, _c, _d;
@@ -44114,8 +44441,8 @@ async function convertToOpenAIResponsesInput({
44114
44441
  hasApplyPatchTool = false,
44115
44442
  customProviderToolNames
44116
44443
  }) {
44117
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
44118
- const input = [];
44444
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
44445
+ let input = [];
44119
44446
  const warnings = [];
44120
44447
  const processedApprovalIds = /* @__PURE__ */ new Set();
44121
44448
  for (const { role, content } of prompt) {
@@ -44218,6 +44545,32 @@ async function convertToOpenAIResponsesInput({
44218
44545
  if (hasConversation && id2 != null) {
44219
44546
  break;
44220
44547
  }
44548
+ const resolvedToolName = toolNameMapping.toProviderToolName(
44549
+ part.toolName
44550
+ );
44551
+ if (resolvedToolName === "tool_search") {
44552
+ if (store && id2 != null) {
44553
+ input.push({ type: "item_reference", id: id2 });
44554
+ break;
44555
+ }
44556
+ const parsedInput = typeof part.input === "string" ? await parseJSON$1({
44557
+ text: part.input,
44558
+ schema: toolSearchInputSchema
44559
+ }) : await validateTypes$1({
44560
+ value: part.input,
44561
+ schema: toolSearchInputSchema
44562
+ });
44563
+ const execution = parsedInput.call_id != null ? "client" : "server";
44564
+ input.push({
44565
+ type: "tool_search_call",
44566
+ id: id2 != null ? id2 : part.toolCallId,
44567
+ execution,
44568
+ call_id: (_g = parsedInput.call_id) != null ? _g : null,
44569
+ status: "completed",
44570
+ arguments: parsedInput.arguments
44571
+ });
44572
+ break;
44573
+ }
44221
44574
  if (part.providerExecuted) {
44222
44575
  if (store && id2 != null) {
44223
44576
  input.push({ type: "item_reference", id: id2 });
@@ -44228,9 +44581,6 @@ async function convertToOpenAIResponsesInput({
44228
44581
  input.push({ type: "item_reference", id: id2 });
44229
44582
  break;
44230
44583
  }
44231
- const resolvedToolName = toolNameMapping.toProviderToolName(
44232
- part.toolName
44233
- );
44234
44584
  if (hasLocalShellTool && resolvedToolName === "local_shell") {
44235
44585
  const parsedInput = await validateTypes$1({
44236
44586
  value: part.input,
@@ -44313,6 +44663,26 @@ async function convertToOpenAIResponsesInput({
44313
44663
  const resolvedResultToolName = toolNameMapping.toProviderToolName(
44314
44664
  part.toolName
44315
44665
  );
44666
+ if (resolvedResultToolName === "tool_search") {
44667
+ const itemId = (_j = (_i = (_h = part.providerOptions) == null ? void 0 : _h[providerOptionsName]) == null ? void 0 : _i.itemId) != null ? _j : part.toolCallId;
44668
+ if (store) {
44669
+ input.push({ type: "item_reference", id: itemId });
44670
+ } else if (part.output.type === "json") {
44671
+ const parsedOutput = await validateTypes$1({
44672
+ value: part.output.value,
44673
+ schema: toolSearchOutputSchema
44674
+ });
44675
+ input.push({
44676
+ type: "tool_search_output",
44677
+ id: itemId,
44678
+ execution: "server",
44679
+ call_id: null,
44680
+ status: "completed",
44681
+ tools: parsedOutput.tools
44682
+ });
44683
+ }
44684
+ break;
44685
+ }
44316
44686
  if (hasShellTool && resolvedResultToolName === "shell") {
44317
44687
  if (part.output.type === "json") {
44318
44688
  const parsedOutput = await validateTypes$1({
@@ -44335,7 +44705,7 @@ async function convertToOpenAIResponsesInput({
44335
44705
  break;
44336
44706
  }
44337
44707
  if (store) {
44338
- const itemId = (_i = (_h = (_g = part.providerOptions) == null ? void 0 : _g[providerOptionsName]) == null ? void 0 : _h.itemId) != null ? _i : part.toolCallId;
44708
+ const itemId = (_m = (_l = (_k = part.providerOptions) == null ? void 0 : _k[providerOptionsName]) == null ? void 0 : _l.itemId) != null ? _m : part.toolCallId;
44339
44709
  input.push({ type: "item_reference", id: itemId });
44340
44710
  } else {
44341
44711
  warnings.push({
@@ -44445,7 +44815,7 @@ async function convertToOpenAIResponsesInput({
44445
44815
  }
44446
44816
  const output = part.output;
44447
44817
  if (output.type === "execution-denied") {
44448
- const approvalId = (_k = (_j = output.providerOptions) == null ? void 0 : _j.openai) == null ? void 0 : _k.approvalId;
44818
+ const approvalId = (_o = (_n = output.providerOptions) == null ? void 0 : _n.openai) == null ? void 0 : _o.approvalId;
44449
44819
  if (approvalId) {
44450
44820
  continue;
44451
44821
  }
@@ -44453,6 +44823,20 @@ async function convertToOpenAIResponsesInput({
44453
44823
  const resolvedToolName = toolNameMapping.toProviderToolName(
44454
44824
  part.toolName
44455
44825
  );
44826
+ if (resolvedToolName === "tool_search" && output.type === "json") {
44827
+ const parsedOutput = await validateTypes$1({
44828
+ value: output.value,
44829
+ schema: toolSearchOutputSchema
44830
+ });
44831
+ input.push({
44832
+ type: "tool_search_output",
44833
+ execution: "client",
44834
+ call_id: part.toolCallId,
44835
+ status: "completed",
44836
+ tools: parsedOutput.tools
44837
+ });
44838
+ continue;
44839
+ }
44456
44840
  if (hasLocalShellTool && resolvedToolName === "local_shell" && output.type === "json") {
44457
44841
  const parsedOutput = await validateTypes$1({
44458
44842
  value: output.value,
@@ -44505,7 +44889,7 @@ async function convertToOpenAIResponsesInput({
44505
44889
  outputValue = output.value;
44506
44890
  break;
44507
44891
  case "execution-denied":
44508
- outputValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
44892
+ outputValue = (_p = output.reason) != null ? _p : "Tool execution denied.";
44509
44893
  break;
44510
44894
  case "json":
44511
44895
  case "error-json":
@@ -44559,7 +44943,7 @@ async function convertToOpenAIResponsesInput({
44559
44943
  contentValue = output.value;
44560
44944
  break;
44561
44945
  case "execution-denied":
44562
- contentValue = (_m = output.reason) != null ? _m : "Tool execution denied.";
44946
+ contentValue = (_q = output.reason) != null ? _q : "Tool execution denied.";
44563
44947
  break;
44564
44948
  case "json":
44565
44949
  case "error-json":
@@ -44616,6 +45000,17 @@ async function convertToOpenAIResponsesInput({
44616
45000
  }
44617
45001
  }
44618
45002
  }
45003
+ if (!store && input.some(
45004
+ (item) => "type" in item && item.type === "reasoning" && item.encrypted_content == null
45005
+ )) {
45006
+ warnings.push({
45007
+ type: "other",
45008
+ message: "Reasoning parts without encrypted content are not supported when store is false. Skipping reasoning parts."
45009
+ });
45010
+ input = input.filter(
45011
+ (item) => !("type" in item) || item.type !== "reasoning" || item.encrypted_content != null
45012
+ );
45013
+ }
44619
45014
  return { input, warnings };
44620
45015
  }
44621
45016
  var openaiResponsesReasoningProviderOptionsSchema = object$2({
@@ -44638,6 +45033,16 @@ function mapOpenAIResponseFinishReason({
44638
45033
  return hasFunctionCall ? "tool-calls" : "other";
44639
45034
  }
44640
45035
  }
45036
+ var jsonValueSchema2 = lazy(
45037
+ () => union([
45038
+ string(),
45039
+ number$1(),
45040
+ boolean(),
45041
+ _null(),
45042
+ array$1(jsonValueSchema2),
45043
+ record(string(), jsonValueSchema2.optional())
45044
+ ])
45045
+ );
44641
45046
  var openaiResponsesChunkSchema = lazySchema(
44642
45047
  () => zodSchema(
44643
45048
  union([
@@ -44671,6 +45076,23 @@ var openaiResponsesChunkSchema = lazySchema(
44671
45076
  service_tier: string().nullish()
44672
45077
  })
44673
45078
  }),
45079
+ object$2({
45080
+ type: literal("response.failed"),
45081
+ response: object$2({
45082
+ error: object$2({
45083
+ code: string().nullish(),
45084
+ message: string()
45085
+ }).nullish(),
45086
+ incomplete_details: object$2({ reason: string() }).nullish(),
45087
+ usage: object$2({
45088
+ input_tokens: number$1(),
45089
+ input_tokens_details: object$2({ cached_tokens: number$1().nullish() }).nullish(),
45090
+ output_tokens: number$1(),
45091
+ output_tokens_details: object$2({ reasoning_tokens: number$1().nullish() }).nullish()
45092
+ }).nullish(),
45093
+ service_tier: string().nullish()
45094
+ })
45095
+ }),
44674
45096
  object$2({
44675
45097
  type: literal("response.created"),
44676
45098
  response: object$2({
@@ -44802,6 +45224,22 @@ var openaiResponsesChunkSchema = lazySchema(
44802
45224
  ])
44803
45225
  })
44804
45226
  )
45227
+ }),
45228
+ object$2({
45229
+ type: literal("tool_search_call"),
45230
+ id: string(),
45231
+ execution: _enum(["server", "client"]),
45232
+ call_id: string().nullable(),
45233
+ status: _enum(["in_progress", "completed", "incomplete"]),
45234
+ arguments: unknown()
45235
+ }),
45236
+ object$2({
45237
+ type: literal("tool_search_output"),
45238
+ id: string(),
45239
+ execution: _enum(["server", "client"]),
45240
+ call_id: string().nullable(),
45241
+ status: _enum(["in_progress", "completed", "incomplete"]),
45242
+ tools: array$1(record(string(), jsonValueSchema2.optional()))
44805
45243
  })
44806
45244
  ])
44807
45245
  }),
@@ -45009,6 +45447,22 @@ var openaiResponsesChunkSchema = lazySchema(
45009
45447
  ])
45010
45448
  })
45011
45449
  )
45450
+ }),
45451
+ object$2({
45452
+ type: literal("tool_search_call"),
45453
+ id: string(),
45454
+ execution: _enum(["server", "client"]),
45455
+ call_id: string().nullable(),
45456
+ status: _enum(["in_progress", "completed", "incomplete"]),
45457
+ arguments: unknown()
45458
+ }),
45459
+ object$2({
45460
+ type: literal("tool_search_output"),
45461
+ id: string(),
45462
+ execution: _enum(["server", "client"]),
45463
+ call_id: string().nullable(),
45464
+ status: _enum(["in_progress", "completed", "incomplete"]),
45465
+ tools: array$1(record(string(), jsonValueSchema2.optional()))
45012
45466
  })
45013
45467
  ])
45014
45468
  }),
@@ -45390,6 +45844,22 @@ var openaiResponsesResponseSchema = lazySchema(
45390
45844
  ])
45391
45845
  })
45392
45846
  )
45847
+ }),
45848
+ object$2({
45849
+ type: literal("tool_search_call"),
45850
+ id: string(),
45851
+ execution: _enum(["server", "client"]),
45852
+ call_id: string().nullable(),
45853
+ status: _enum(["in_progress", "completed", "incomplete"]),
45854
+ arguments: unknown()
45855
+ }),
45856
+ object$2({
45857
+ type: literal("tool_search_output"),
45858
+ id: string(),
45859
+ execution: _enum(["server", "client"]),
45860
+ call_id: string().nullable(),
45861
+ status: _enum(["in_progress", "completed", "incomplete"]),
45862
+ tools: array$1(record(string(), jsonValueSchema2.optional()))
45393
45863
  })
45394
45864
  ])
45395
45865
  ).optional(),
@@ -45565,7 +46035,7 @@ async function prepareResponsesTools({
45565
46035
  toolNameMapping,
45566
46036
  customProviderToolNames
45567
46037
  }) {
45568
- var _a10;
46038
+ var _a10, _b9;
45569
46039
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
45570
46040
  const toolWarnings = [];
45571
46041
  if (tools == null) {
@@ -45575,15 +46045,19 @@ async function prepareResponsesTools({
45575
46045
  const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
45576
46046
  for (const tool2 of tools) {
45577
46047
  switch (tool2.type) {
45578
- case "function":
46048
+ case "function": {
46049
+ const openaiOptions = (_a10 = tool2.providerOptions) == null ? void 0 : _a10.openai;
46050
+ const deferLoading = openaiOptions == null ? void 0 : openaiOptions.deferLoading;
45579
46051
  openaiTools2.push({
45580
46052
  type: "function",
45581
46053
  name: tool2.name,
45582
46054
  description: tool2.description,
45583
46055
  parameters: tool2.inputSchema,
45584
- ...tool2.strict != null ? { strict: tool2.strict } : {}
46056
+ ...tool2.strict != null ? { strict: tool2.strict } : {},
46057
+ ...deferLoading != null ? { defer_loading: deferLoading } : {}
45585
46058
  });
45586
46059
  break;
46060
+ }
45587
46061
  case "provider": {
45588
46062
  switch (tool2.id) {
45589
46063
  case "openai.file_search": {
@@ -45728,6 +46202,19 @@ async function prepareResponsesTools({
45728
46202
  resolvedCustomProviderToolNames.add(args.name);
45729
46203
  break;
45730
46204
  }
46205
+ case "openai.tool_search": {
46206
+ const args = await validateTypes$1({
46207
+ value: tool2.args,
46208
+ schema: toolSearchArgsSchema
46209
+ });
46210
+ openaiTools2.push({
46211
+ type: "tool_search",
46212
+ ...args.execution != null ? { execution: args.execution } : {},
46213
+ ...args.description != null ? { description: args.description } : {},
46214
+ ...args.parameters != null ? { parameters: args.parameters } : {}
46215
+ });
46216
+ break;
46217
+ }
45731
46218
  }
45732
46219
  break;
45733
46220
  }
@@ -45749,7 +46236,7 @@ async function prepareResponsesTools({
45749
46236
  case "required":
45750
46237
  return { tools: openaiTools2, toolChoice: type2, toolWarnings };
45751
46238
  case "tool": {
45752
- const resolvedToolName = (_a10 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _a10 : toolChoice.toolName;
46239
+ const resolvedToolName = (_b9 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _b9 : toolChoice.toolName;
45753
46240
  return {
45754
46241
  tools: openaiTools2,
45755
46242
  toolChoice: resolvedToolName === "code_interpreter" || resolvedToolName === "file_search" || resolvedToolName === "image_generation" || resolvedToolName === "web_search_preview" || resolvedToolName === "web_search" || resolvedToolName === "mcp" || resolvedToolName === "apply_patch" ? { type: resolvedToolName } : resolvedCustomProviderToolNames.has(resolvedToolName) ? { type: "custom", name: resolvedToolName } : { type: "function", name: resolvedToolName },
@@ -45903,7 +46390,8 @@ var OpenAIResponsesLanguageModel = class {
45903
46390
  "openai.web_search": "web_search",
45904
46391
  "openai.web_search_preview": "web_search_preview",
45905
46392
  "openai.mcp": "mcp",
45906
- "openai.apply_patch": "apply_patch"
46393
+ "openai.apply_patch": "apply_patch",
46394
+ "openai.tool_search": "tool_search"
45907
46395
  },
45908
46396
  resolveProviderToolName: (tool2) => tool2.id === "openai.custom" ? tool2.args.name : void 0
45909
46397
  });
@@ -46081,7 +46569,7 @@ var OpenAIResponsesLanguageModel = class {
46081
46569
  };
46082
46570
  }
46083
46571
  async doGenerate(options) {
46084
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
46572
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
46085
46573
  const {
46086
46574
  args: body,
46087
46575
  warnings,
@@ -46124,6 +46612,7 @@ var OpenAIResponsesLanguageModel = class {
46124
46612
  const content = [];
46125
46613
  const logprobs = [];
46126
46614
  let hasFunctionCall = false;
46615
+ const hostedToolSearchCallIds = [];
46127
46616
  for (const part of response.output) {
46128
46617
  switch (part.type) {
46129
46618
  case "reasoning": {
@@ -46162,6 +46651,46 @@ var OpenAIResponsesLanguageModel = class {
46162
46651
  });
46163
46652
  break;
46164
46653
  }
46654
+ case "tool_search_call": {
46655
+ const toolCallId = (_b9 = part.call_id) != null ? _b9 : part.id;
46656
+ const isHosted = part.execution === "server";
46657
+ if (isHosted) {
46658
+ hostedToolSearchCallIds.push(toolCallId);
46659
+ }
46660
+ content.push({
46661
+ type: "tool-call",
46662
+ toolCallId,
46663
+ toolName: toolNameMapping.toCustomToolName("tool_search"),
46664
+ input: JSON.stringify({
46665
+ arguments: part.arguments,
46666
+ call_id: part.call_id
46667
+ }),
46668
+ ...isHosted ? { providerExecuted: true } : {},
46669
+ providerMetadata: {
46670
+ [providerOptionsName]: {
46671
+ itemId: part.id
46672
+ }
46673
+ }
46674
+ });
46675
+ break;
46676
+ }
46677
+ case "tool_search_output": {
46678
+ const toolCallId = (_d = (_c = part.call_id) != null ? _c : hostedToolSearchCallIds.shift()) != null ? _d : part.id;
46679
+ content.push({
46680
+ type: "tool-result",
46681
+ toolCallId,
46682
+ toolName: toolNameMapping.toCustomToolName("tool_search"),
46683
+ result: {
46684
+ tools: part.tools
46685
+ },
46686
+ providerMetadata: {
46687
+ [providerOptionsName]: {
46688
+ itemId: part.id
46689
+ }
46690
+ }
46691
+ });
46692
+ break;
46693
+ }
46165
46694
  case "local_shell_call": {
46166
46695
  content.push({
46167
46696
  type: "tool-call",
@@ -46217,7 +46746,7 @@ var OpenAIResponsesLanguageModel = class {
46217
46746
  }
46218
46747
  case "message": {
46219
46748
  for (const contentPart of part.content) {
46220
- if (((_c = (_b9 = options.providerOptions) == null ? void 0 : _b9[providerOptionsName]) == null ? void 0 : _c.logprobs) && contentPart.logprobs) {
46749
+ if (((_f = (_e = options.providerOptions) == null ? void 0 : _e[providerOptionsName]) == null ? void 0 : _f.logprobs) && contentPart.logprobs) {
46221
46750
  logprobs.push(contentPart.logprobs);
46222
46751
  }
46223
46752
  const providerMetadata2 = {
@@ -46239,7 +46768,7 @@ var OpenAIResponsesLanguageModel = class {
46239
46768
  content.push({
46240
46769
  type: "source",
46241
46770
  sourceType: "url",
46242
- id: (_f = (_e = (_d = this.config).generateId) == null ? void 0 : _e.call(_d)) != null ? _f : generateId$1(),
46771
+ id: (_i = (_h = (_g = this.config).generateId) == null ? void 0 : _h.call(_g)) != null ? _i : generateId$1(),
46243
46772
  url: annotation.url,
46244
46773
  title: annotation.title
46245
46774
  });
@@ -46247,7 +46776,7 @@ var OpenAIResponsesLanguageModel = class {
46247
46776
  content.push({
46248
46777
  type: "source",
46249
46778
  sourceType: "document",
46250
- id: (_i = (_h = (_g = this.config).generateId) == null ? void 0 : _h.call(_g)) != null ? _i : generateId$1(),
46779
+ id: (_l = (_k = (_j = this.config).generateId) == null ? void 0 : _k.call(_j)) != null ? _l : generateId$1(),
46251
46780
  mediaType: "text/plain",
46252
46781
  title: annotation.filename,
46253
46782
  filename: annotation.filename,
@@ -46263,7 +46792,7 @@ var OpenAIResponsesLanguageModel = class {
46263
46792
  content.push({
46264
46793
  type: "source",
46265
46794
  sourceType: "document",
46266
- id: (_l = (_k = (_j = this.config).generateId) == null ? void 0 : _k.call(_j)) != null ? _l : generateId$1(),
46795
+ id: (_o = (_n = (_m = this.config).generateId) == null ? void 0 : _n.call(_m)) != null ? _o : generateId$1(),
46267
46796
  mediaType: "text/plain",
46268
46797
  title: annotation.filename,
46269
46798
  filename: annotation.filename,
@@ -46279,7 +46808,7 @@ var OpenAIResponsesLanguageModel = class {
46279
46808
  content.push({
46280
46809
  type: "source",
46281
46810
  sourceType: "document",
46282
- id: (_o = (_n = (_m = this.config).generateId) == null ? void 0 : _n.call(_m)) != null ? _o : generateId$1(),
46811
+ id: (_r = (_q = (_p = this.config).generateId) == null ? void 0 : _q.call(_p)) != null ? _r : generateId$1(),
46283
46812
  mediaType: "application/octet-stream",
46284
46813
  title: annotation.file_id,
46285
46814
  filename: annotation.file_id,
@@ -46348,7 +46877,7 @@ var OpenAIResponsesLanguageModel = class {
46348
46877
  break;
46349
46878
  }
46350
46879
  case "mcp_call": {
46351
- const toolCallId = part.approval_request_id != null ? (_p = approvalRequestIdToDummyToolCallIdFromPrompt[part.approval_request_id]) != null ? _p : part.id : part.id;
46880
+ const toolCallId = part.approval_request_id != null ? (_s = approvalRequestIdToDummyToolCallIdFromPrompt[part.approval_request_id]) != null ? _s : part.id : part.id;
46352
46881
  const toolName = `mcp.${part.name}`;
46353
46882
  content.push({
46354
46883
  type: "tool-call",
@@ -46382,8 +46911,8 @@ var OpenAIResponsesLanguageModel = class {
46382
46911
  break;
46383
46912
  }
46384
46913
  case "mcp_approval_request": {
46385
- const approvalRequestId = (_q = part.approval_request_id) != null ? _q : part.id;
46386
- const dummyToolCallId = (_t = (_s = (_r = this.config).generateId) == null ? void 0 : _s.call(_r)) != null ? _t : generateId$1();
46914
+ const approvalRequestId = (_t = part.approval_request_id) != null ? _t : part.id;
46915
+ const dummyToolCallId = (_w = (_v = (_u = this.config).generateId) == null ? void 0 : _v.call(_u)) != null ? _w : generateId$1();
46387
46916
  const toolName = `mcp.${part.name}`;
46388
46917
  content.push({
46389
46918
  type: "tool-call",
@@ -46433,13 +46962,13 @@ var OpenAIResponsesLanguageModel = class {
46433
46962
  toolName: toolNameMapping.toCustomToolName("file_search"),
46434
46963
  result: {
46435
46964
  queries: part.queries,
46436
- results: (_v = (_u = part.results) == null ? void 0 : _u.map((result) => ({
46965
+ results: (_y = (_x = part.results) == null ? void 0 : _x.map((result) => ({
46437
46966
  attributes: result.attributes,
46438
46967
  fileId: result.file_id,
46439
46968
  filename: result.filename,
46440
46969
  score: result.score,
46441
46970
  text: result.text
46442
- }))) != null ? _v : null
46971
+ }))) != null ? _y : null
46443
46972
  }
46444
46973
  });
46445
46974
  break;
@@ -46496,10 +47025,10 @@ var OpenAIResponsesLanguageModel = class {
46496
47025
  content,
46497
47026
  finishReason: {
46498
47027
  unified: mapOpenAIResponseFinishReason({
46499
- finishReason: (_w = response.incomplete_details) == null ? void 0 : _w.reason,
47028
+ finishReason: (_z = response.incomplete_details) == null ? void 0 : _z.reason,
46500
47029
  hasFunctionCall
46501
47030
  }),
46502
- raw: (_y = (_x = response.incomplete_details) == null ? void 0 : _x.reason) != null ? _y : void 0
47031
+ raw: (_B = (_A = response.incomplete_details) == null ? void 0 : _A.reason) != null ? _B : void 0
46503
47032
  },
46504
47033
  usage: convertOpenAIResponsesUsage(usage),
46505
47034
  request: { body },
@@ -46557,6 +47086,7 @@ var OpenAIResponsesLanguageModel = class {
46557
47086
  let hasFunctionCall = false;
46558
47087
  const activeReasoning = {};
46559
47088
  let serviceTier;
47089
+ const hostedToolSearchCallIds = [];
46560
47090
  return {
46561
47091
  stream: response.pipeThrough(
46562
47092
  new TransformStream({
@@ -46564,7 +47094,7 @@ var OpenAIResponsesLanguageModel = class {
46564
47094
  controller.enqueue({ type: "stream-start", warnings });
46565
47095
  },
46566
47096
  transform(chunk, controller) {
46567
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F;
47097
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L;
46568
47098
  if (options.includeRawChunks) {
46569
47099
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
46570
47100
  }
@@ -46672,7 +47202,25 @@ var OpenAIResponsesLanguageModel = class {
46672
47202
  input: "{}",
46673
47203
  providerExecuted: true
46674
47204
  });
46675
- } else if (value.item.type === "mcp_call" || value.item.type === "mcp_list_tools" || value.item.type === "mcp_approval_request") ;
47205
+ } else if (value.item.type === "tool_search_call") {
47206
+ const toolCallId = value.item.id;
47207
+ const toolName = toolNameMapping.toCustomToolName("tool_search");
47208
+ const isHosted = value.item.execution === "server";
47209
+ ongoingToolCalls[value.output_index] = {
47210
+ toolName,
47211
+ toolCallId,
47212
+ toolSearchExecution: (_a10 = value.item.execution) != null ? _a10 : "server"
47213
+ };
47214
+ if (isHosted) {
47215
+ controller.enqueue({
47216
+ type: "tool-input-start",
47217
+ id: toolCallId,
47218
+ toolName,
47219
+ providerExecuted: true
47220
+ });
47221
+ }
47222
+ } else if (value.item.type === "tool_search_output") ;
47223
+ else if (value.item.type === "mcp_call" || value.item.type === "mcp_list_tools" || value.item.type === "mcp_approval_request") ;
46676
47224
  else if (value.item.type === "apply_patch_call") {
46677
47225
  const { call_id: callId, operation } = value.item;
46678
47226
  ongoingToolCalls[value.output_index] = {
@@ -46718,7 +47266,7 @@ var OpenAIResponsesLanguageModel = class {
46718
47266
  } else if (value.item.type === "shell_call_output") ;
46719
47267
  else if (value.item.type === "message") {
46720
47268
  ongoingAnnotations.splice(0, ongoingAnnotations.length);
46721
- activeMessagePhase = (_a10 = value.item.phase) != null ? _a10 : void 0;
47269
+ activeMessagePhase = (_b9 = value.item.phase) != null ? _b9 : void 0;
46722
47270
  controller.enqueue({
46723
47271
  type: "text-start",
46724
47272
  id: value.item.id,
@@ -46742,14 +47290,14 @@ var OpenAIResponsesLanguageModel = class {
46742
47290
  providerMetadata: {
46743
47291
  [providerOptionsName]: {
46744
47292
  itemId: value.item.id,
46745
- reasoningEncryptedContent: (_b9 = value.item.encrypted_content) != null ? _b9 : null
47293
+ reasoningEncryptedContent: (_c = value.item.encrypted_content) != null ? _c : null
46746
47294
  }
46747
47295
  }
46748
47296
  });
46749
47297
  }
46750
47298
  } else if (isResponseOutputItemDoneChunk(value)) {
46751
47299
  if (value.item.type === "message") {
46752
- const phase = (_c = value.item.phase) != null ? _c : activeMessagePhase;
47300
+ const phase = (_d = value.item.phase) != null ? _d : activeMessagePhase;
46753
47301
  activeMessagePhase = void 0;
46754
47302
  controller.enqueue({
46755
47303
  type: "text-end",
@@ -46843,13 +47391,13 @@ var OpenAIResponsesLanguageModel = class {
46843
47391
  toolName: toolNameMapping.toCustomToolName("file_search"),
46844
47392
  result: {
46845
47393
  queries: value.item.queries,
46846
- results: (_e = (_d = value.item.results) == null ? void 0 : _d.map((result) => ({
47394
+ results: (_f = (_e = value.item.results) == null ? void 0 : _e.map((result) => ({
46847
47395
  attributes: result.attributes,
46848
47396
  fileId: result.file_id,
46849
47397
  filename: result.filename,
46850
47398
  score: result.score,
46851
47399
  text: result.text
46852
- }))) != null ? _e : null
47400
+ }))) != null ? _f : null
46853
47401
  }
46854
47402
  });
46855
47403
  } else if (value.item.type === "code_interpreter_call") {
@@ -46871,12 +47419,62 @@ var OpenAIResponsesLanguageModel = class {
46871
47419
  result: value.item.result
46872
47420
  }
46873
47421
  });
47422
+ } else if (value.item.type === "tool_search_call") {
47423
+ const toolCall = ongoingToolCalls[value.output_index];
47424
+ const isHosted = value.item.execution === "server";
47425
+ if (toolCall != null) {
47426
+ const toolCallId = isHosted ? toolCall.toolCallId : (_g = value.item.call_id) != null ? _g : value.item.id;
47427
+ if (isHosted) {
47428
+ hostedToolSearchCallIds.push(toolCallId);
47429
+ } else {
47430
+ controller.enqueue({
47431
+ type: "tool-input-start",
47432
+ id: toolCallId,
47433
+ toolName: toolCall.toolName
47434
+ });
47435
+ }
47436
+ controller.enqueue({
47437
+ type: "tool-input-end",
47438
+ id: toolCallId
47439
+ });
47440
+ controller.enqueue({
47441
+ type: "tool-call",
47442
+ toolCallId,
47443
+ toolName: toolCall.toolName,
47444
+ input: JSON.stringify({
47445
+ arguments: value.item.arguments,
47446
+ call_id: isHosted ? null : toolCallId
47447
+ }),
47448
+ ...isHosted ? { providerExecuted: true } : {},
47449
+ providerMetadata: {
47450
+ [providerOptionsName]: {
47451
+ itemId: value.item.id
47452
+ }
47453
+ }
47454
+ });
47455
+ }
47456
+ ongoingToolCalls[value.output_index] = void 0;
47457
+ } else if (value.item.type === "tool_search_output") {
47458
+ const toolCallId = (_i = (_h = value.item.call_id) != null ? _h : hostedToolSearchCallIds.shift()) != null ? _i : value.item.id;
47459
+ controller.enqueue({
47460
+ type: "tool-result",
47461
+ toolCallId,
47462
+ toolName: toolNameMapping.toCustomToolName("tool_search"),
47463
+ result: {
47464
+ tools: value.item.tools
47465
+ },
47466
+ providerMetadata: {
47467
+ [providerOptionsName]: {
47468
+ itemId: value.item.id
47469
+ }
47470
+ }
47471
+ });
46874
47472
  } else if (value.item.type === "mcp_call") {
46875
47473
  ongoingToolCalls[value.output_index] = void 0;
46876
- const approvalRequestId = (_f = value.item.approval_request_id) != null ? _f : void 0;
46877
- const aliasedToolCallId = approvalRequestId != null ? (_h = (_g = approvalRequestIdToDummyToolCallIdFromStream.get(
47474
+ const approvalRequestId = (_j = value.item.approval_request_id) != null ? _j : void 0;
47475
+ const aliasedToolCallId = approvalRequestId != null ? (_l = (_k = approvalRequestIdToDummyToolCallIdFromStream.get(
46878
47476
  approvalRequestId
46879
- )) != null ? _g : approvalRequestIdToDummyToolCallIdFromPrompt[approvalRequestId]) != null ? _h : value.item.id : value.item.id;
47477
+ )) != null ? _k : approvalRequestIdToDummyToolCallIdFromPrompt[approvalRequestId]) != null ? _l : value.item.id : value.item.id;
46880
47478
  const toolName = `mcp.${value.item.name}`;
46881
47479
  controller.enqueue({
46882
47480
  type: "tool-call",
@@ -46946,8 +47544,8 @@ var OpenAIResponsesLanguageModel = class {
46946
47544
  ongoingToolCalls[value.output_index] = void 0;
46947
47545
  } else if (value.item.type === "mcp_approval_request") {
46948
47546
  ongoingToolCalls[value.output_index] = void 0;
46949
- const dummyToolCallId = (_k = (_j = (_i = self2.config).generateId) == null ? void 0 : _j.call(_i)) != null ? _k : generateId$1();
46950
- const approvalRequestId = (_l = value.item.approval_request_id) != null ? _l : value.item.id;
47547
+ const dummyToolCallId = (_o = (_n = (_m = self2.config).generateId) == null ? void 0 : _n.call(_m)) != null ? _o : generateId$1();
47548
+ const approvalRequestId = (_p = value.item.approval_request_id) != null ? _p : value.item.id;
46951
47549
  approvalRequestIdToDummyToolCallIdFromStream.set(
46952
47550
  approvalRequestId,
46953
47551
  dummyToolCallId
@@ -47036,7 +47634,7 @@ var OpenAIResponsesLanguageModel = class {
47036
47634
  providerMetadata: {
47037
47635
  [providerOptionsName]: {
47038
47636
  itemId: value.item.id,
47039
- reasoningEncryptedContent: (_m = value.item.encrypted_content) != null ? _m : null
47637
+ reasoningEncryptedContent: (_q = value.item.encrypted_content) != null ? _q : null
47040
47638
  }
47041
47639
  }
47042
47640
  });
@@ -47149,7 +47747,7 @@ var OpenAIResponsesLanguageModel = class {
47149
47747
  id: value.item_id,
47150
47748
  delta: value.delta
47151
47749
  });
47152
- if (((_o = (_n = options.providerOptions) == null ? void 0 : _n[providerOptionsName]) == null ? void 0 : _o.logprobs) && value.logprobs) {
47750
+ if (((_s = (_r = options.providerOptions) == null ? void 0 : _r[providerOptionsName]) == null ? void 0 : _s.logprobs) && value.logprobs) {
47153
47751
  logprobs.push(value.logprobs);
47154
47752
  }
47155
47753
  } else if (value.type === "response.reasoning_summary_part.added") {
@@ -47178,7 +47776,7 @@ var OpenAIResponsesLanguageModel = class {
47178
47776
  providerMetadata: {
47179
47777
  [providerOptionsName]: {
47180
47778
  itemId: value.item_id,
47181
- reasoningEncryptedContent: (_q = (_p = activeReasoning[value.item_id]) == null ? void 0 : _p.encryptedContent) != null ? _q : null
47779
+ reasoningEncryptedContent: (_u = (_t = activeReasoning[value.item_id]) == null ? void 0 : _t.encryptedContent) != null ? _u : null
47182
47780
  }
47183
47781
  }
47184
47782
  });
@@ -47212,22 +47810,32 @@ var OpenAIResponsesLanguageModel = class {
47212
47810
  } else if (isResponseFinishedChunk(value)) {
47213
47811
  finishReason = {
47214
47812
  unified: mapOpenAIResponseFinishReason({
47215
- finishReason: (_r = value.response.incomplete_details) == null ? void 0 : _r.reason,
47813
+ finishReason: (_v = value.response.incomplete_details) == null ? void 0 : _v.reason,
47216
47814
  hasFunctionCall
47217
47815
  }),
47218
- raw: (_t = (_s = value.response.incomplete_details) == null ? void 0 : _s.reason) != null ? _t : void 0
47816
+ raw: (_x = (_w = value.response.incomplete_details) == null ? void 0 : _w.reason) != null ? _x : void 0
47219
47817
  };
47220
47818
  usage = value.response.usage;
47221
47819
  if (typeof value.response.service_tier === "string") {
47222
47820
  serviceTier = value.response.service_tier;
47223
47821
  }
47822
+ } else if (isResponseFailedChunk(value)) {
47823
+ const incompleteReason = (_y = value.response.incomplete_details) == null ? void 0 : _y.reason;
47824
+ finishReason = {
47825
+ unified: incompleteReason ? mapOpenAIResponseFinishReason({
47826
+ finishReason: incompleteReason,
47827
+ hasFunctionCall
47828
+ }) : "error",
47829
+ raw: incompleteReason != null ? incompleteReason : "error"
47830
+ };
47831
+ usage = (_z = value.response.usage) != null ? _z : void 0;
47224
47832
  } else if (isResponseAnnotationAddedChunk(value)) {
47225
47833
  ongoingAnnotations.push(value.annotation);
47226
47834
  if (value.annotation.type === "url_citation") {
47227
47835
  controller.enqueue({
47228
47836
  type: "source",
47229
47837
  sourceType: "url",
47230
- id: (_w = (_v = (_u = self2.config).generateId) == null ? void 0 : _v.call(_u)) != null ? _w : generateId$1(),
47838
+ id: (_C = (_B = (_A = self2.config).generateId) == null ? void 0 : _B.call(_A)) != null ? _C : generateId$1(),
47231
47839
  url: value.annotation.url,
47232
47840
  title: value.annotation.title
47233
47841
  });
@@ -47235,7 +47843,7 @@ var OpenAIResponsesLanguageModel = class {
47235
47843
  controller.enqueue({
47236
47844
  type: "source",
47237
47845
  sourceType: "document",
47238
- id: (_z = (_y = (_x = self2.config).generateId) == null ? void 0 : _y.call(_x)) != null ? _z : generateId$1(),
47846
+ id: (_F = (_E = (_D = self2.config).generateId) == null ? void 0 : _E.call(_D)) != null ? _F : generateId$1(),
47239
47847
  mediaType: "text/plain",
47240
47848
  title: value.annotation.filename,
47241
47849
  filename: value.annotation.filename,
@@ -47251,7 +47859,7 @@ var OpenAIResponsesLanguageModel = class {
47251
47859
  controller.enqueue({
47252
47860
  type: "source",
47253
47861
  sourceType: "document",
47254
- id: (_C = (_B = (_A = self2.config).generateId) == null ? void 0 : _B.call(_A)) != null ? _C : generateId$1(),
47862
+ id: (_I = (_H = (_G = self2.config).generateId) == null ? void 0 : _H.call(_G)) != null ? _I : generateId$1(),
47255
47863
  mediaType: "text/plain",
47256
47864
  title: value.annotation.filename,
47257
47865
  filename: value.annotation.filename,
@@ -47267,7 +47875,7 @@ var OpenAIResponsesLanguageModel = class {
47267
47875
  controller.enqueue({
47268
47876
  type: "source",
47269
47877
  sourceType: "document",
47270
- id: (_F = (_E = (_D = self2.config).generateId) == null ? void 0 : _E.call(_D)) != null ? _F : generateId$1(),
47878
+ id: (_L = (_K = (_J = self2.config).generateId) == null ? void 0 : _K.call(_J)) != null ? _L : generateId$1(),
47271
47879
  mediaType: "application/octet-stream",
47272
47880
  title: value.annotation.file_id,
47273
47881
  filename: value.annotation.file_id,
@@ -47315,6 +47923,9 @@ function isResponseOutputItemDoneChunk(chunk) {
47315
47923
  function isResponseFinishedChunk(chunk) {
47316
47924
  return chunk.type === "response.completed" || chunk.type === "response.incomplete";
47317
47925
  }
47926
+ function isResponseFailedChunk(chunk) {
47927
+ return chunk.type === "response.failed";
47928
+ }
47318
47929
  function isResponseCreatedChunk(chunk) {
47319
47930
  return chunk.type === "response.created";
47320
47931
  }
@@ -47705,7 +48316,7 @@ var OpenAITranscriptionModel = class {
47705
48316
  };
47706
48317
  }
47707
48318
  };
47708
- var VERSION$2 = "3.0.41";
48319
+ var VERSION$2 = "3.0.48";
47709
48320
  function createOpenAI(options = {}) {
47710
48321
  var _a10, _b9;
47711
48322
  const baseURL = (_a10 = withoutTrailingSlash$1(
@@ -49755,6 +50366,11 @@ class AgentModelProvider {
49755
50366
  await this._createMpcTools();
49756
50367
  this.onUpdatedTools?.();
49757
50368
  }
50369
+ /** 仅刷新已连接 clients 的 tools(不重建 client,适合工具目录动态变化场景) */
50370
+ async refreshTools() {
50371
+ await this._createMpcTools();
50372
+ this.onUpdatedTools?.();
50373
+ }
49758
50374
  /** 全量更新所有的 mcpServers */
49759
50375
  async updateMcpServers(mcpServers) {
49760
50376
  await this.closeAll();
@@ -50160,13 +50776,37 @@ ${observationText}
50160
50776
  throw new Error("LLM is not initialized");
50161
50777
  }
50162
50778
  await this.initClientsAndTools();
50163
- const allTools = this._tempMergeTools(options.tools, false);
50779
+ const extraTools = options.tools || {};
50780
+ const allTools = this._tempMergeTools(extraTools, false);
50781
+ const syncToolsForStep = () => {
50782
+ const latestTools = this._tempMergeTools(extraTools, false);
50783
+ Object.entries(latestTools).forEach(([name16, tool2]) => {
50784
+ allTools[name16] = tool2;
50785
+ });
50786
+ Object.keys(allTools).forEach((name16) => {
50787
+ if (!(name16 in latestTools)) {
50788
+ delete allTools[name16];
50789
+ }
50790
+ });
50791
+ };
50792
+ const userPrepareStep = options.prepareStep;
50793
+ const wrappedPrepareStep = async (stepOptions) => {
50794
+ syncToolsForStep();
50795
+ const latestActiveTools = this._getActiveToolNames(allTools);
50796
+ const userStepPatch = typeof userPrepareStep === "function" ? await userPrepareStep(stepOptions) : void 0;
50797
+ const safeUserStepPatch = userStepPatch && typeof userStepPatch === "object" ? userStepPatch : {};
50798
+ return {
50799
+ ...safeUserStepPatch,
50800
+ activeTools: Array.isArray(safeUserStepPatch.activeTools) ? safeUserStepPatch.activeTools.filter((name16) => latestActiveTools.includes(name16)) : latestActiveTools
50801
+ };
50802
+ };
50164
50803
  const chatOptions = {
50165
50804
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
50166
50805
  model: this.llm(model),
50167
50806
  stopWhen: stepCountIs(maxSteps),
50168
50807
  ...options,
50169
50808
  tools: allTools,
50809
+ prepareStep: wrappedPrepareStep,
50170
50810
  activeTools: this._getActiveToolNames(allTools)
50171
50811
  };
50172
50812
  let lastUserMessage = null;
@@ -50479,6 +51119,7 @@ const MSG_PAGE_READY = "next-sdk:page-ready";
50479
51119
  const MSG_PAGE_LEAVE = "next-sdk:page-leave";
50480
51120
  const MSG_REMOTER_READY = "next-sdk:remoter-ready";
50481
51121
  const MSG_ROUTE_STATE_INITIAL = "next-sdk:route-state-initial";
51122
+ const MSG_TOOL_CATALOG_CHANGED = "next-sdk:tool-catalog-changed";
50482
51123
  const activePages = /* @__PURE__ */ new Map();
50483
51124
  const normalizeRoute = (value) => value.replace(/\/+$/, "") || "/";
50484
51125
  const broadcastTargets = /* @__PURE__ */ new Set();
@@ -50488,8 +51129,8 @@ function initBroadcastTargets() {
50488
51129
  }
50489
51130
  }
50490
51131
  initBroadcastTargets();
50491
- function broadcastRouteChange(type2, route) {
50492
- const msg = { type: type2, route };
51132
+ function broadcastRouteChange(type2, route, extra = {}) {
51133
+ const msg = { type: type2, route, ...extra };
50493
51134
  broadcastTargets.forEach(({ win, origin }) => {
50494
51135
  try {
50495
51136
  win.postMessage(msg, origin);
@@ -50504,30 +51145,413 @@ function setupIframeRemoterBridge() {
50504
51145
  if (event.origin !== window.location.origin) return;
50505
51146
  const target = event.source;
50506
51147
  broadcastTargets.add({ win: target, origin: event.origin || "*" });
50507
- const payload = {
50508
- type: MSG_ROUTE_STATE_INITIAL,
50509
- toolRouteMap: Array.from(toolRouteMap.entries()),
50510
- activeRoutes: Array.from(activePages.keys())
50511
- };
51148
+ });
51149
+ }
51150
+ setupIframeRemoterBridge();
51151
+ const runtimeRegisteredTools = /* @__PURE__ */ new Map();
51152
+ function broadcastToolCatalogChanged() {
51153
+ if (typeof window === "undefined") return;
51154
+ const payload = {
51155
+ type: MSG_TOOL_CATALOG_CHANGED
51156
+ };
51157
+ broadcastTargets.forEach(({ win, origin }) => {
50512
51158
  try {
50513
- target.postMessage(payload, event.origin || "*");
51159
+ win.postMessage(payload, origin);
50514
51160
  } catch {
50515
51161
  }
50516
51162
  });
50517
51163
  }
50518
- setupIframeRemoterBridge();
50519
- const toolRouteMap = /* @__PURE__ */ new Map();
51164
+ function notifyServerToolListChanged(server) {
51165
+ const maybeServer = server;
51166
+ try {
51167
+ maybeServer.sendToolListChanged?.();
51168
+ } catch {
51169
+ }
51170
+ }
50520
51171
  function getToolRouteMap() {
50521
- return new Map(toolRouteMap);
51172
+ return /* @__PURE__ */ new Map();
50522
51173
  }
50523
51174
  function getActiveRoutes() {
50524
51175
  return new Set(activePages.keys());
50525
51176
  }
51177
+ function getActivePageTools() {
51178
+ const snapshot = /* @__PURE__ */ new Map();
51179
+ activePages.forEach((toolNames, route) => {
51180
+ snapshot.set(route, Array.from(toolNames));
51181
+ });
51182
+ return snapshot;
51183
+ }
51184
+ function isToolReadyOnRoute(route, toolName) {
51185
+ const toolNames = activePages.get(route);
51186
+ return !!toolNames && toolNames.has(toolName);
51187
+ }
51188
+ const nativeRegisteredTools = /* @__PURE__ */ new Set();
51189
+ const nativeToolDisposers = /* @__PURE__ */ new Map();
51190
+ const nativeRegisteredToolDefs = /* @__PURE__ */ new Map();
51191
+ const nativeRegisterTasks = /* @__PURE__ */ new Map();
51192
+ const BUILTIN_REMOVE_PATCH_SYMBOL = Symbol("builtin-remove-patched");
51193
+ function attachBuiltinUnregisterOnRemove(name16, tool2) {
51194
+ const mutableTool = tool2;
51195
+ if (mutableTool[BUILTIN_REMOVE_PATCH_SYMBOL]) return tool2;
51196
+ if (typeof mutableTool.remove !== "function") return tool2;
51197
+ const originalRemove = mutableTool.remove.bind(mutableTool);
51198
+ mutableTool.remove = () => {
51199
+ try {
51200
+ originalRemove();
51201
+ } finally {
51202
+ void unregisterBuiltinWebMcpTool(name16);
51203
+ }
51204
+ };
51205
+ mutableTool[BUILTIN_REMOVE_PATCH_SYMBOL] = true;
51206
+ return mutableTool;
51207
+ }
51208
+ function getBuiltinModelContext() {
51209
+ if (typeof navigator === "undefined") return null;
51210
+ const nav = navigator;
51211
+ if (!nav.modelContext?.registerTool) return null;
51212
+ return nav.modelContext;
51213
+ }
51214
+ function getBuiltinModelContextTesting() {
51215
+ if (typeof navigator === "undefined") return null;
51216
+ const nav = navigator;
51217
+ return nav.modelContextTesting ?? null;
51218
+ }
51219
+ function isWebMcpDebugEnabled() {
51220
+ if (typeof window === "undefined") return false;
51221
+ const w = window;
51222
+ if (w.__NEXT_SDK_WEBMCP_DEBUG__ === true) return true;
51223
+ try {
51224
+ return window.localStorage?.getItem("next-sdk:webmcp-debug") === "1";
51225
+ } catch {
51226
+ return false;
51227
+ }
51228
+ }
51229
+ function debugWebMcpLog(event, payload = {}) {
51230
+ if (!isWebMcpDebugEnabled()) return;
51231
+ try {
51232
+ console.info("[next-sdk/webmcp]", event, payload);
51233
+ } catch {
51234
+ }
51235
+ }
51236
+ async function debugBuiltinToolSnapshot(event) {
51237
+ if (!isWebMcpDebugEnabled()) return;
51238
+ const testingApi = getBuiltinModelContextTesting();
51239
+ if (!testingApi) {
51240
+ debugWebMcpLog(`${event}:snapshot`, { available: false });
51241
+ return;
51242
+ }
51243
+ try {
51244
+ const list = testingApi.listTools ?? testingApi.getTools;
51245
+ if (!list) {
51246
+ debugWebMcpLog(`${event}:snapshot`, { available: false, reason: "no-list-method" });
51247
+ return;
51248
+ }
51249
+ const result = await list();
51250
+ const tools = Array.isArray(result) ? result : [];
51251
+ const names2 = tools.map((item) => {
51252
+ if (!item || typeof item !== "object") return "";
51253
+ return String(item.name ?? "");
51254
+ }).filter(Boolean);
51255
+ debugWebMcpLog(`${event}:snapshot`, { count: names2.length, names: names2 });
51256
+ } catch (error) {
51257
+ debugWebMcpLog(`${event}:snapshot-error`, { error: error instanceof Error ? error.message : String(error) });
51258
+ }
51259
+ }
51260
+ function tryDirectBuiltinUnregisterByName(name16) {
51261
+ const modelContext = getBuiltinModelContext();
51262
+ if (!modelContext?.unregisterTool) {
51263
+ debugWebMcpLog("direct-unregister-skip", { name: name16, reason: "missing-unregister" });
51264
+ return;
51265
+ }
51266
+ debugWebMcpLog("direct-unregister-start", { name: name16 });
51267
+ try {
51268
+ const result = modelContext.unregisterTool.call(modelContext, name16);
51269
+ if (result && typeof result === "object" && "then" in result) {
51270
+ void result.then(() => {
51271
+ debugWebMcpLog("direct-unregister-done", { name: name16, async: true });
51272
+ void debugBuiltinToolSnapshot(`direct-unregister-done:${name16}`);
51273
+ }).catch((error) => {
51274
+ debugWebMcpLog("direct-unregister-error", { name: name16, async: true, error: error instanceof Error ? error.message : String(error) });
51275
+ });
51276
+ return;
51277
+ }
51278
+ debugWebMcpLog("direct-unregister-done", { name: name16, async: false });
51279
+ void debugBuiltinToolSnapshot(`direct-unregister-done:${name16}`);
51280
+ } catch {
51281
+ debugWebMcpLog("direct-unregister-error", { name: name16, async: false });
51282
+ }
51283
+ }
51284
+ function resolveBuiltinToolDisposer(result) {
51285
+ if (typeof result === "function") {
51286
+ return result;
51287
+ }
51288
+ if (!result || typeof result !== "object") {
51289
+ return null;
51290
+ }
51291
+ const value = result;
51292
+ if (typeof value.unregister === "function") return value.unregister.bind(value);
51293
+ if (typeof value.remove === "function") return value.remove.bind(value);
51294
+ if (typeof value.dispose === "function") return value.dispose.bind(value);
51295
+ if (typeof value.close === "function") return value.close.bind(value);
51296
+ return null;
51297
+ }
51298
+ function isBuiltinWebMcpSupported() {
51299
+ return !!getBuiltinModelContext();
51300
+ }
51301
+ function getSchemaTypeName(schema) {
51302
+ return schema._def?.typeName;
51303
+ }
51304
+ function getSchemaDescription(schema) {
51305
+ return schema.description;
51306
+ }
51307
+ function withSchemaDescription(schema, base) {
51308
+ const description2 = getSchemaDescription(schema);
51309
+ return description2 ? { ...base, description: description2 } : base;
51310
+ }
51311
+ function isOptionalSchema(schema) {
51312
+ const typeName = getSchemaTypeName(schema);
51313
+ if (typeName === ZodFirstPartyTypeKind.ZodOptional || typeName === ZodFirstPartyTypeKind.ZodDefault) {
51314
+ return true;
51315
+ }
51316
+ if (typeName === ZodFirstPartyTypeKind.ZodEffects) {
51317
+ const inner = schema._def.schema;
51318
+ return isOptionalSchema(inner);
51319
+ }
51320
+ return false;
51321
+ }
51322
+ function toPrimitiveJsonType(value) {
51323
+ if (typeof value === "string") return "string";
51324
+ if (typeof value === "number") return "number";
51325
+ if (typeof value === "boolean") return "boolean";
51326
+ if (value === null) return "null";
51327
+ return void 0;
51328
+ }
51329
+ function zodTypeToJsonSchema(schema) {
51330
+ const typeName = getSchemaTypeName(schema);
51331
+ switch (typeName) {
51332
+ case ZodFirstPartyTypeKind.ZodString:
51333
+ return withSchemaDescription(schema, { type: "string" });
51334
+ case ZodFirstPartyTypeKind.ZodNumber:
51335
+ return withSchemaDescription(schema, { type: "number" });
51336
+ case ZodFirstPartyTypeKind.ZodBoolean:
51337
+ return withSchemaDescription(schema, { type: "boolean" });
51338
+ case ZodFirstPartyTypeKind.ZodArray: {
51339
+ const itemSchema = schema._def.type;
51340
+ return withSchemaDescription(schema, { type: "array", items: zodTypeToJsonSchema(itemSchema) });
51341
+ }
51342
+ case ZodFirstPartyTypeKind.ZodEnum: {
51343
+ const values = schema.options ?? [];
51344
+ return withSchemaDescription(schema, { type: "string", enum: values });
51345
+ }
51346
+ case ZodFirstPartyTypeKind.ZodNativeEnum: {
51347
+ const rawValues = Object.values(schema._def.values);
51348
+ const enumValues = rawValues.filter(
51349
+ (value) => typeof value === "string" || typeof value === "number"
51350
+ );
51351
+ return withSchemaDescription(schema, { enum: enumValues });
51352
+ }
51353
+ case ZodFirstPartyTypeKind.ZodLiteral: {
51354
+ const literalValue = schema._def.value;
51355
+ const primitiveType = toPrimitiveJsonType(literalValue);
51356
+ return withSchemaDescription(schema, {
51357
+ ...primitiveType ? { type: primitiveType } : {},
51358
+ const: literalValue ?? null
51359
+ });
51360
+ }
51361
+ case ZodFirstPartyTypeKind.ZodUnion: {
51362
+ const options = schema._def.options ?? [];
51363
+ return withSchemaDescription(schema, { anyOf: options.map((item) => zodTypeToJsonSchema(item)) });
51364
+ }
51365
+ case ZodFirstPartyTypeKind.ZodNullable: {
51366
+ const inner = schema._def.innerType;
51367
+ return withSchemaDescription(schema, { anyOf: [zodTypeToJsonSchema(inner), { type: "null" }] });
51368
+ }
51369
+ case ZodFirstPartyTypeKind.ZodObject: {
51370
+ const schemaDef = schema;
51371
+ const shape = schemaDef.shape ?? (typeof schemaDef._def?.shape === "function" ? schemaDef._def.shape() : schemaDef._def?.shape) ?? {};
51372
+ return withSchemaDescription(schema, zodShapeToJsonSchema(shape));
51373
+ }
51374
+ case ZodFirstPartyTypeKind.ZodEffects: {
51375
+ const inner = schema._def.schema;
51376
+ return withSchemaDescription(schema, zodTypeToJsonSchema(inner));
51377
+ }
51378
+ case ZodFirstPartyTypeKind.ZodOptional:
51379
+ case ZodFirstPartyTypeKind.ZodDefault: {
51380
+ const inner = schema._def.innerType;
51381
+ return withSchemaDescription(schema, zodTypeToJsonSchema(inner));
51382
+ }
51383
+ default:
51384
+ return withSchemaDescription(schema, {});
51385
+ }
51386
+ }
51387
+ function zodShapeToJsonSchema(shape = {}) {
51388
+ const properties2 = {};
51389
+ const required2 = [];
51390
+ Object.entries(shape).forEach(([key, schema]) => {
51391
+ properties2[key] = zodTypeToJsonSchema(schema);
51392
+ if (!isOptionalSchema(schema)) {
51393
+ required2.push(key);
51394
+ }
51395
+ });
51396
+ return {
51397
+ type: "object",
51398
+ properties: properties2,
51399
+ ...required2.length ? { required: required2 } : {},
51400
+ additionalProperties: false
51401
+ };
51402
+ }
51403
+ async function registerBuiltinWebMcpTool(options) {
51404
+ const modelContext = getBuiltinModelContext();
51405
+ if (!modelContext) {
51406
+ debugWebMcpLog("register-builtin-skip", { name: options.name, reason: "unsupported" });
51407
+ return false;
51408
+ }
51409
+ if (nativeRegisteredTools.has(options.name)) {
51410
+ debugWebMcpLog("register-builtin-skip", { name: options.name, reason: "already-registered" });
51411
+ return true;
51412
+ }
51413
+ const cleanupLocalRegisterState = () => {
51414
+ nativeToolDisposers.delete(options.name);
51415
+ nativeRegisteredToolDefs.delete(options.name);
51416
+ nativeRegisteredTools.delete(options.name);
51417
+ };
51418
+ debugWebMcpLog("register-builtin-start", { name: options.name });
51419
+ const task = (async () => {
51420
+ const toolDefinition = {
51421
+ name: options.name,
51422
+ description: options.description,
51423
+ inputSchema: zodShapeToJsonSchema(options.inputSchema ?? {}),
51424
+ execute: options.execute
51425
+ };
51426
+ const result = await modelContext.registerTool(toolDefinition);
51427
+ const disposer = resolveBuiltinToolDisposer(result);
51428
+ if (disposer) {
51429
+ nativeToolDisposers.set(options.name, disposer);
51430
+ }
51431
+ nativeRegisteredToolDefs.set(options.name, toolDefinition);
51432
+ nativeRegisteredTools.add(options.name);
51433
+ debugWebMcpLog("register-builtin-success", { name: options.name, hasDisposer: !!disposer });
51434
+ void debugBuiltinToolSnapshot(`register-success:${options.name}`);
51435
+ })();
51436
+ nativeRegisterTasks.set(options.name, task);
51437
+ try {
51438
+ await task;
51439
+ return true;
51440
+ } catch (error) {
51441
+ cleanupLocalRegisterState();
51442
+ debugWebMcpLog("register-builtin-error", {
51443
+ name: options.name,
51444
+ error: error instanceof Error ? error.message : String(error)
51445
+ });
51446
+ return false;
51447
+ } finally {
51448
+ nativeRegisterTasks.delete(options.name);
51449
+ }
51450
+ }
51451
+ async function unregisterBuiltinWebMcpTool(name16) {
51452
+ debugWebMcpLog("unregister-builtin-start", { name: name16 });
51453
+ const cleanup = () => {
51454
+ nativeToolDisposers.delete(name16);
51455
+ nativeRegisteredToolDefs.delete(name16);
51456
+ nativeRegisteredTools.delete(name16);
51457
+ };
51458
+ const pendingRegister = nativeRegisterTasks.get(name16);
51459
+ if (pendingRegister) {
51460
+ try {
51461
+ await pendingRegister;
51462
+ } catch {
51463
+ }
51464
+ }
51465
+ const disposer = nativeToolDisposers.get(name16);
51466
+ if (disposer) {
51467
+ try {
51468
+ await disposer();
51469
+ cleanup();
51470
+ debugWebMcpLog("unregister-builtin-success", { name: name16, method: "disposer" });
51471
+ void debugBuiltinToolSnapshot(`unregister-success:${name16}`);
51472
+ return true;
51473
+ } catch (error) {
51474
+ debugWebMcpLog("unregister-builtin-disposer-error", {
51475
+ name: name16,
51476
+ error: error instanceof Error ? error.message : String(error)
51477
+ });
51478
+ }
51479
+ }
51480
+ const modelContext = getBuiltinModelContext();
51481
+ if (!modelContext) {
51482
+ cleanup();
51483
+ debugWebMcpLog("unregister-builtin-skip", { name: name16, reason: "unsupported" });
51484
+ return false;
51485
+ }
51486
+ if (!modelContext.unregisterTool) {
51487
+ cleanup();
51488
+ debugWebMcpLog("unregister-builtin-skip", { name: name16, reason: "missing-unregister" });
51489
+ return false;
51490
+ }
51491
+ const definition = nativeRegisteredToolDefs.get(name16);
51492
+ const candidates = [name16, { name: name16 }, { toolName: name16 }, { tool: { name: name16 } }, definition].filter(Boolean);
51493
+ for (const candidate of candidates) {
51494
+ try {
51495
+ debugWebMcpLog("unregister-builtin-try", { name: name16, candidate });
51496
+ const result = await modelContext.unregisterTool.call(modelContext, candidate);
51497
+ if (result === false) continue;
51498
+ cleanup();
51499
+ debugWebMcpLog("unregister-builtin-success", { name: name16, method: "unregisterTool", candidate });
51500
+ void debugBuiltinToolSnapshot(`unregister-success:${name16}`);
51501
+ return true;
51502
+ } catch (error) {
51503
+ debugWebMcpLog("unregister-builtin-try-error", {
51504
+ name: name16,
51505
+ candidate,
51506
+ error: error instanceof Error ? error.message : String(error)
51507
+ });
51508
+ }
51509
+ }
51510
+ cleanup();
51511
+ debugWebMcpLog("unregister-builtin-failed", { name: name16 });
51512
+ void debugBuiltinToolSnapshot(`unregister-failed:${name16}`);
51513
+ return false;
51514
+ }
51515
+ function hasBuiltinWebMcpTool(name16) {
51516
+ return nativeRegisteredTools.has(name16);
51517
+ }
51518
+ async function forceResetBuiltinWebMcpTools() {
51519
+ const names2 = Array.from(nativeRegisteredTools);
51520
+ for (const name16 of names2) {
51521
+ try {
51522
+ await unregisterBuiltinWebMcpTool(name16);
51523
+ } catch {
51524
+ }
51525
+ }
51526
+ }
51527
+ async function listBuiltinWebMcpTools() {
51528
+ const testingApi = getBuiltinModelContextTesting();
51529
+ if (!testingApi?.listTools) return [];
51530
+ try {
51531
+ const result = await testingApi.listTools();
51532
+ return Array.isArray(result) ? result : [];
51533
+ } catch {
51534
+ return [];
51535
+ }
51536
+ }
51537
+ async function executeBuiltinWebMcpTool(name16, input) {
51538
+ const testingApi = getBuiltinModelContextTesting();
51539
+ if (!testingApi?.executeTool) {
51540
+ throw new Error("当前浏览器不支持 navigator.modelContextTesting.executeTool。");
51541
+ }
51542
+ return await testingApi.executeTool(name16, JSON.stringify(input ?? {}));
51543
+ }
50526
51544
  let _navigator = null;
50527
51545
  function setNavigator(fn) {
50528
51546
  _navigator = fn;
50529
51547
  }
50530
- function waitForPageReady(path, timeoutMs = 1500) {
51548
+ function isCurrentPathMatched(path) {
51549
+ if (typeof window === "undefined") return false;
51550
+ const target = normalizeRoute(path);
51551
+ const current = normalizeRoute(window.location.pathname);
51552
+ return current === target || current.endsWith(target) && (current.length === target.length || current[current.lastIndexOf(target) - 1] === "/");
51553
+ }
51554
+ function waitForNavigationReady(path, timeoutMs = 1500) {
50531
51555
  if (typeof window === "undefined") {
50532
51556
  return Promise.resolve();
50533
51557
  }
@@ -50541,9 +51565,15 @@ function waitForPageReady(path, timeoutMs = 1500) {
50541
51565
  resolve2();
50542
51566
  };
50543
51567
  const handleMessage = (event) => {
50544
- if (event.source !== window || event.data?.type !== MSG_PAGE_READY) return;
50545
- const route = normalizeRoute(String(event.data.route ?? ""));
50546
- if (route === target) {
51568
+ if (event.source !== window) return;
51569
+ if (event.data?.type === MSG_PAGE_READY) {
51570
+ const route = normalizeRoute(String(event.data.route ?? ""));
51571
+ if (route === target) {
51572
+ cleanup();
51573
+ }
51574
+ return;
51575
+ }
51576
+ if (event.data?.type === MSG_TOOL_CATALOG_CHANGED && isCurrentPathMatched(target)) {
50547
51577
  cleanup();
50548
51578
  }
50549
51579
  };
@@ -50551,63 +51581,144 @@ function waitForPageReady(path, timeoutMs = 1500) {
50551
51581
  setTimeout(cleanup, timeoutMs);
50552
51582
  });
50553
51583
  }
51584
+ function definePageTool(definition) {
51585
+ return definition;
51586
+ }
51587
+ function registerPageTools(server, definitions2) {
51588
+ return definitions2.map(
51589
+ (definition) => server.registerTool(definition.name, definition.config, {
51590
+ route: definition.route,
51591
+ timeout: definition.timeout,
51592
+ invokeEffect: definition.invokeEffect
51593
+ })
51594
+ );
51595
+ }
51596
+ function mountPageTools(options) {
51597
+ return registerPageTool(options);
51598
+ }
51599
+ function registerRuntimePageTools(server, options) {
51600
+ const allTools = options.tools ?? [];
51601
+ if (!allTools.length) {
51602
+ throw new Error("registerRuntimePageTools: tools 不能为空。");
51603
+ }
51604
+ const explicitRoute = options.route ? normalizeRoute(options.route) : null;
51605
+ const routes = new Set(allTools.map((tool2) => normalizeRoute(tool2.route)));
51606
+ if (!explicitRoute && routes.size > 1) {
51607
+ throw new Error("registerRuntimePageTools: tools 包含多个 route,请显式传入 route。");
51608
+ }
51609
+ const mountRoute = explicitRoute ?? Array.from(routes)[0];
51610
+ const routeTools = allTools.filter((tool2) => normalizeRoute(tool2.route) === mountRoute);
51611
+ if (!routeTools.length) {
51612
+ throw new Error(`registerRuntimePageTools: route "${mountRoute}" 下未找到工具定义。`);
51613
+ }
51614
+ routeTools.forEach((definition) => {
51615
+ const route = normalizeRoute(definition.route);
51616
+ const existing = runtimeRegisteredTools.get(definition.name);
51617
+ if (existing) {
51618
+ if (existing.route !== route) {
51619
+ throw new Error(
51620
+ `registerRuntimePageTools: 工具 "${definition.name}" 已绑定路由 "${existing.route}",不能重复绑定到 "${route}"。`
51621
+ );
51622
+ }
51623
+ existing.refCount += 1;
51624
+ return;
51625
+ }
51626
+ const tool2 = server.registerTool(definition.name, definition.config, {
51627
+ route,
51628
+ timeout: definition.timeout,
51629
+ invokeEffect: definition.invokeEffect
51630
+ });
51631
+ runtimeRegisteredTools.set(definition.name, { tool: tool2, route, refCount: 1 });
51632
+ });
51633
+ const cleanupHandlers = registerPageTool({
51634
+ route: mountRoute,
51635
+ tools: routeTools,
51636
+ context: options.context
51637
+ });
51638
+ return () => {
51639
+ cleanupHandlers();
51640
+ if (options.removeOnUnmount === false) return;
51641
+ routeTools.forEach((definition) => {
51642
+ const existing = runtimeRegisteredTools.get(definition.name);
51643
+ if (!existing) return;
51644
+ existing.refCount -= 1;
51645
+ if (existing.refCount > 0) return;
51646
+ runtimeRegisteredTools.delete(definition.name);
51647
+ server.unregisterTool(definition.name);
51648
+ });
51649
+ };
51650
+ }
50554
51651
  function registerNavigateTool(server, options) {
50555
51652
  const name16 = options?.name ?? "navigate_to_page";
50556
51653
  const title2 = options?.title ?? "页面跳转";
50557
51654
  const description2 = options?.description ?? '当需要的工具在当前页面不可用时,使用此工具跳转到特定页面。例如:要查询订单时跳转到 "/orders",要创建价保时跳转到 "/price-protection"。';
50558
51655
  const timeoutMs = options?.timeoutMs ?? 1500;
50559
- return server.registerTool(
51656
+ const inputSchema = {
51657
+ path: stringType().describe('目标页面的路由地址,例如 "/orders"、"/inventory"、"/price-protection" 等。')
51658
+ };
51659
+ const handler = async ({
51660
+ path
51661
+ }) => {
51662
+ if (typeof window === "undefined") {
51663
+ return {
51664
+ content: [{ type: "text", text: "当前环境不支持页面跳转(window 不存在)。" }]
51665
+ };
51666
+ }
51667
+ if (!_navigator) {
51668
+ return {
51669
+ content: [
51670
+ {
51671
+ type: "text",
51672
+ text: "页面跳转失败:尚未在应用入口调用 setNavigator 注册导航函数,无法执行路由跳转。"
51673
+ }
51674
+ ]
51675
+ };
51676
+ }
51677
+ try {
51678
+ if (isCurrentPathMatched(path)) {
51679
+ return {
51680
+ content: [{ type: "text", text: `当前已在页面:${path}。请继续你的下一步操作。` }]
51681
+ };
51682
+ }
51683
+ const readyPromise = waitForNavigationReady(path, timeoutMs);
51684
+ await _navigator(path);
51685
+ await readyPromise;
51686
+ return {
51687
+ content: [{ type: "text", text: `已成功跳转至页面:${path}。请继续你的下一步操作。` }]
51688
+ };
51689
+ } catch (err) {
51690
+ return {
51691
+ content: [
51692
+ {
51693
+ type: "text",
51694
+ text: `页面跳转失败:${err instanceof Error ? err.message : String(err)}。`
51695
+ }
51696
+ ]
51697
+ };
51698
+ }
51699
+ };
51700
+ const registeredTool = server.registerTool(
50560
51701
  name16,
50561
51702
  {
50562
51703
  title: title2,
50563
51704
  description: description2,
50564
- inputSchema: {
50565
- path: stringType().describe('目标页面的路由地址,例如 "/orders"、"/inventory"、"/price-protection" 等。')
50566
- }
51705
+ inputSchema
50567
51706
  },
50568
- async ({ path }) => {
50569
- if (typeof window === "undefined") {
50570
- return {
50571
- content: [{ type: "text", text: "当前环境不支持页面跳转(window 不存在)。" }]
50572
- };
50573
- }
50574
- if (!_navigator) {
50575
- return {
50576
- content: [
50577
- {
50578
- type: "text",
50579
- text: "页面跳转失败:尚未在应用入口调用 setNavigator 注册导航函数,无法执行路由跳转。"
50580
- }
50581
- ]
50582
- };
50583
- }
50584
- try {
50585
- const target = normalizeRoute(path);
50586
- const current = normalizeRoute(window.location.pathname);
50587
- const isAlreadyOnTarget = current === target || current.endsWith(target) && (current.length === target.length || current[current.lastIndexOf(target) - 1] === "/");
50588
- if (isAlreadyOnTarget) {
50589
- return {
50590
- content: [{ type: "text", text: `当前已在页面:${path}。请继续你的下一步操作。` }]
50591
- };
50592
- }
50593
- const readyPromise = waitForPageReady(path, timeoutMs);
50594
- await _navigator(path);
50595
- await readyPromise;
50596
- return {
50597
- content: [{ type: "text", text: `已成功跳转至页面:${path}。请继续你的下一步操作。` }]
50598
- };
50599
- } catch (err) {
50600
- return {
50601
- content: [
50602
- {
50603
- type: "text",
50604
- text: `页面跳转失败:${err instanceof Error ? err.message : String(err)}。`
50605
- }
50606
- ]
50607
- };
50608
- }
50609
- }
51707
+ handler
50610
51708
  );
51709
+ const managedByPageTools = typeof server.unregisterTool === "function";
51710
+ if (!managedByPageTools) {
51711
+ void registerBuiltinWebMcpTool({
51712
+ name: name16,
51713
+ description: description2,
51714
+ inputSchema,
51715
+ execute: async (input) => {
51716
+ return await handler(input);
51717
+ }
51718
+ });
51719
+ return attachBuiltinUnregisterOnRemove(name16, registeredTool);
51720
+ }
51721
+ return registeredTool;
50611
51722
  }
50612
51723
  function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50613
51724
  return (input) => {
@@ -50650,21 +51761,24 @@ function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50650
51761
  if (effectConfig) {
50651
51762
  showToolInvokeEffect(effectConfig);
50652
51763
  }
50653
- if (activePages.get(route)) {
51764
+ if (isToolReadyOnRoute(route, name16)) {
50654
51765
  sendCallOnce();
50655
51766
  return;
50656
51767
  }
50657
51768
  readyHandler = (event) => {
50658
- if (event.source === window && event.data?.type === MSG_PAGE_READY && event.data.route === route) {
50659
- window.removeEventListener("message", readyHandler);
50660
- sendCallOnce();
50661
- }
51769
+ if (event.source !== window || event.data?.type !== MSG_PAGE_READY) return;
51770
+ const readyRoute = normalizeRoute(String(event.data.route ?? ""));
51771
+ if (readyRoute !== route) return;
51772
+ const readyTools = Array.isArray(event.data.toolNames) ? new Set(event.data.toolNames.map((item) => String(item))) : null;
51773
+ if (readyTools && !readyTools.has(name16)) return;
51774
+ window.removeEventListener("message", readyHandler);
51775
+ sendCallOnce();
50662
51776
  };
50663
51777
  window.addEventListener("message", readyHandler);
50664
51778
  if (_navigator) {
50665
51779
  await _navigator(route);
50666
51780
  }
50667
- if (activePages.get(route)) {
51781
+ if (isToolReadyOnRoute(route, name16)) {
50668
51782
  window.removeEventListener("message", readyHandler);
50669
51783
  sendCallOnce();
50670
51784
  }
@@ -50677,31 +51791,125 @@ function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50677
51791
  });
50678
51792
  };
50679
51793
  }
50680
- function withPageTools(server) {
51794
+ function withPageTools(server, options) {
51795
+ const nativeMode = options?.nativeWebMcp?.mode ?? "auto";
51796
+ const shouldRegisterBuiltin = nativeMode !== "disabled";
51797
+ const proxyRegisteredTools = /* @__PURE__ */ new Map();
51798
+ const unregisterByName = (target, name16, silent = false) => {
51799
+ const existing = proxyRegisteredTools.get(name16);
51800
+ const hadTrackedState = !!existing;
51801
+ debugWebMcpLog("proxy-unregister-start", { name: name16, hasExisting: !!existing, silent });
51802
+ tryDirectBuiltinUnregisterByName(name16);
51803
+ proxyRegisteredTools.delete(name16);
51804
+ runtimeRegisteredTools.delete(name16);
51805
+ if (existing) {
51806
+ try {
51807
+ existing.remove();
51808
+ } catch {
51809
+ }
51810
+ }
51811
+ void unregisterBuiltinWebMcpTool(name16);
51812
+ if (!silent && hadTrackedState) {
51813
+ notifyServerToolListChanged(target);
51814
+ broadcastToolCatalogChanged();
51815
+ }
51816
+ debugWebMcpLog("proxy-unregister-done", { name: name16, removed: !!existing, silent });
51817
+ return !!existing;
51818
+ };
50681
51819
  return new Proxy(server, {
50682
51820
  get(target, prop, receiver) {
51821
+ if (prop === "unregisterTool") {
51822
+ return (name16) => unregisterByName(target, name16, false);
51823
+ }
50683
51824
  if (prop === "registerTool") {
50684
51825
  return (name16, config2, handlerOrRoute) => {
51826
+ debugWebMcpLog("proxy-register-start", {
51827
+ name: name16,
51828
+ mode: typeof handlerOrRoute === "function" ? "callback" : "route",
51829
+ shouldRegisterBuiltin
51830
+ });
51831
+ unregisterByName(target, name16, true);
50685
51832
  const rawRegister = target.registerTool.bind(target);
50686
51833
  if (typeof handlerOrRoute === "function") {
50687
- return rawRegister(name16, config2, handlerOrRoute);
51834
+ const registeredTool2 = rawRegister(name16, config2, handlerOrRoute);
51835
+ const wrapped2 = shouldRegisterBuiltin ? attachBuiltinUnregisterOnRemove(name16, registeredTool2) : registeredTool2;
51836
+ proxyRegisteredTools.set(name16, wrapped2);
51837
+ notifyServerToolListChanged(target);
51838
+ broadcastToolCatalogChanged();
51839
+ if (shouldRegisterBuiltin) {
51840
+ void registerBuiltinWebMcpTool({
51841
+ name: name16,
51842
+ description: config2?.description,
51843
+ inputSchema: config2?.inputSchema,
51844
+ execute: async (input) => {
51845
+ return await handlerOrRoute(input);
51846
+ }
51847
+ });
51848
+ }
51849
+ debugWebMcpLog("proxy-register-done", { name: name16, mode: "callback" });
51850
+ return wrapped2;
50688
51851
  }
50689
51852
  const { route, timeout, invokeEffect } = handlerOrRoute;
50690
- toolRouteMap.set(name16, route);
51853
+ const normalizedRoute = normalizeRoute(route);
50691
51854
  const effectConfig = resolveRuntimeEffectConfig(name16, config2?.title, invokeEffect);
50692
- return rawRegister(name16, config2, buildPageHandler(name16, route, timeout, effectConfig));
51855
+ const pageHandler = buildPageHandler(name16, normalizedRoute, timeout, effectConfig);
51856
+ const registeredTool = rawRegister(name16, config2, pageHandler);
51857
+ const wrapped = shouldRegisterBuiltin ? attachBuiltinUnregisterOnRemove(name16, registeredTool) : registeredTool;
51858
+ proxyRegisteredTools.set(name16, wrapped);
51859
+ notifyServerToolListChanged(target);
51860
+ broadcastToolCatalogChanged();
51861
+ if (shouldRegisterBuiltin) {
51862
+ void registerBuiltinWebMcpTool({
51863
+ name: name16,
51864
+ description: config2?.description,
51865
+ inputSchema: config2?.inputSchema,
51866
+ execute: async (input) => {
51867
+ return await pageHandler(input);
51868
+ }
51869
+ });
51870
+ }
51871
+ debugWebMcpLog("proxy-register-done", { name: name16, mode: "route" });
51872
+ return wrapped;
50693
51873
  };
50694
51874
  }
50695
51875
  return Reflect.get(target, prop, receiver);
50696
51876
  }
50697
51877
  });
50698
51878
  }
51879
+ function resolveRouteAndHandlers(options) {
51880
+ if ("handlers" in options) {
51881
+ return {
51882
+ route: normalizeRoute(options.route ?? window.location.pathname),
51883
+ handlers: options.handlers
51884
+ };
51885
+ }
51886
+ const tools = options.tools ?? [];
51887
+ if (!tools.length) {
51888
+ throw new Error("registerPageTool: tools 不能为空。");
51889
+ }
51890
+ const targetRoute = options.route ? normalizeRoute(options.route) : null;
51891
+ const uniqueRoutes = new Set(tools.map((item) => normalizeRoute(item.route)));
51892
+ if (!targetRoute && uniqueRoutes.size > 1) {
51893
+ throw new Error("registerPageTool: tools 包含多个 route,请显式传入 route 参数。");
51894
+ }
51895
+ const route = targetRoute ?? Array.from(uniqueRoutes)[0];
51896
+ const handlers = {};
51897
+ tools.filter((item) => normalizeRoute(item.route) === route).forEach((item) => {
51898
+ if (handlers[item.name]) {
51899
+ throw new Error(`registerPageTool: 工具 "${item.name}" 在 route "${route}" 上重复定义。`);
51900
+ }
51901
+ handlers[item.name] = (input) => item.handler(input, options.context);
51902
+ });
51903
+ if (!Object.keys(handlers).length) {
51904
+ throw new Error(`registerPageTool: route "${route}" 下未找到可激活的工具定义。`);
51905
+ }
51906
+ return { route, handlers };
51907
+ }
50699
51908
  function registerPageTool(options) {
50700
- const { route: routeOption, handlers } = options;
50701
- const normalizeRoute2 = (value) => value.replace(/\/+$/, "") || "/";
50702
- const route = normalizeRoute2(routeOption ?? window.location.pathname);
51909
+ const { route, handlers } = resolveRouteAndHandlers(options);
51910
+ const toolNames = Object.keys(handlers);
50703
51911
  const handleMessage = async (event) => {
50704
- if (event.source !== window || event.data?.type !== MSG_TOOL_CALL || normalizeRoute2(String(event.data?.route ?? "")) !== route || !(event.data.toolName in handlers)) {
51912
+ if (event.source !== window || event.data?.type !== MSG_TOOL_CALL || normalizeRoute(String(event.data?.route ?? "")) !== route || !(event.data.toolName in handlers)) {
50705
51913
  return;
50706
51914
  }
50707
51915
  const { callId, toolName, input } = event.data;
@@ -50719,9 +51927,9 @@ function registerPageTool(options) {
50719
51927
  );
50720
51928
  }
50721
51929
  };
50722
- activePages.set(route, true);
51930
+ activePages.set(route, new Set(toolNames));
50723
51931
  window.addEventListener("message", handleMessage);
50724
- broadcastRouteChange(MSG_PAGE_READY, route);
51932
+ broadcastRouteChange(MSG_PAGE_READY, route, { toolNames });
50725
51933
  return () => {
50726
51934
  activePages.delete(route);
50727
51935
  window.removeEventListener("message", handleMessage);
@@ -50893,6 +52101,7 @@ export {
50893
52101
  MSG_PAGE_LEAVE,
50894
52102
  MSG_REMOTER_READY,
50895
52103
  MSG_ROUTE_STATE_INITIAL,
52104
+ MSG_TOOL_CATALOG_CHANGED,
50896
52105
  QrCode,
50897
52106
  ResourceTemplate,
50898
52107
  UriTemplate,
@@ -50906,8 +52115,12 @@ export {
50906
52115
  createSSEClientTransport,
50907
52116
  createSkillTools,
50908
52117
  createStreamableHTTPClientTransport,
52118
+ definePageTool,
52119
+ executeBuiltinWebMcpTool,
52120
+ forceResetBuiltinWebMcpTools,
50909
52121
  formatSkillsForSystemPrompt,
50910
52122
  getAISDKTools,
52123
+ getActivePageTools,
50911
52124
  getActiveRoutes,
50912
52125
  getDisplayName,
50913
52126
  getMainSkillPathByName,
@@ -50916,16 +52129,24 @@ export {
50916
52129
  getSkillMdPaths,
50917
52130
  getSkillOverviews,
50918
52131
  getToolRouteMap,
52132
+ hasBuiltinWebMcpTool,
52133
+ isBuiltinWebMcpSupported,
50919
52134
  isMcpClient,
50920
52135
  isMcpServer,
50921
52136
  isMessageChannelClientTransport,
50922
52137
  isMessageChannelServerTransport,
50923
52138
  isSSEClientTransport,
50924
52139
  isStreamableHTTPClientTransport,
52140
+ listBuiltinWebMcpTools,
52141
+ mountPageTools,
50925
52142
  parseSkillFrontMatter,
52143
+ registerBuiltinWebMcpTool,
50926
52144
  registerNavigateTool,
50927
52145
  registerPageTool,
52146
+ registerPageTools,
52147
+ registerRuntimePageTools,
50928
52148
  setNavigator,
52149
+ unregisterBuiltinWebMcpTool,
50929
52150
  withPageTools,
50930
52151
  z
50931
52152
  };