@opentiny/next-sdk 0.2.9 → 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() {
@@ -27069,27 +27053,27 @@ class FloatingBlock {
27069
27053
  }
27070
27054
  /**
27071
27055
  * 合并菜单项配置。
27072
- * - sessionId:使用默认菜单 + 用户配置(可定制每一项的 show/text/icon 等)
27073
- * - sessionId:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27056
+ * - 用户明确传入 menuItems:直接使用用户配置,不受 sessionId 限制;未传 icon 时自动补充默认图标
27057
+ * - sessionId 且未传 menuItems:使用默认菜单
27058
+ * - 无 sessionId 且未传 menuItems:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27074
27059
  */
27075
27060
  mergeMenuItems(userMenuItems) {
27061
+ const defaultIcons = {
27062
+ "qr-code": qrCode,
27063
+ "ai-chat": chat,
27064
+ "remote-url": link,
27065
+ "remote-control": scan
27066
+ };
27067
+ if (userMenuItems) {
27068
+ return userMenuItems.map((item) => ({
27069
+ ...item,
27070
+ icon: item.icon ?? defaultIcons[item.action]
27071
+ }));
27072
+ }
27076
27073
  if (!this.options.sessionId) {
27077
27074
  return [];
27078
27075
  }
27079
- if (!userMenuItems) {
27080
- return getDefaultMenuItems(this.options);
27081
- }
27082
- return getDefaultMenuItems(this.options).map((defaultItem) => {
27083
- const userItem = userMenuItems.find((item) => item.action === defaultItem.action);
27084
- if (userItem) {
27085
- return {
27086
- ...defaultItem,
27087
- ...userItem,
27088
- show: userItem.show !== void 0 ? userItem.show : defaultItem.show
27089
- };
27090
- }
27091
- return defaultItem;
27092
- });
27076
+ return getDefaultMenuItems(this.options);
27093
27077
  }
27094
27078
  init() {
27095
27079
  this.createFloatingBlock();
@@ -27120,7 +27104,7 @@ class FloatingBlock {
27120
27104
  <div class="tiny-remoter-dropdown-item__content">
27121
27105
  <div title="${item.tip}">${item.text}</div>
27122
27106
  <div class="tiny-remoter-dropdown-item__desc-wrapper">
27123
- <div class="tiny-remoter-dropdown-item__desc ${item.active ? "tiny-remoter-dropdown-item__desc--active" : ""} ${item.know ? "tiny-remoter-dropdown-item__desc--know" : ""}">${item.desc}</div>
27107
+ <div class="tiny-remoter-dropdown-item__desc ${item.active ? "tiny-remoter-dropdown-item__desc--active" : ""} ${item.know ? "tiny-remoter-dropdown-item__desc--know" : ""}">${item.desc ?? ""}</div>
27124
27108
  <div>
27125
27109
  ${item.showCopyIcon ? `
27126
27110
  <div class="tiny-remoter-copy-icon" id="${item.action}" data-action="${item.action}">
@@ -27228,12 +27212,20 @@ class FloatingBlock {
27228
27212
  this.closeDropdown();
27229
27213
  }
27230
27214
  copyRemoteControl() {
27231
- if (!this.options.sessionId) return;
27232
- this.copyToClipboard(this.options.sessionId.slice(-6));
27215
+ const menuItem = this.menuItems.find((item) => item.action === "remote-control");
27216
+ const codeToCopy = menuItem?.desc || menuItem?.text || (this.options.sessionId ? this.options.sessionId.slice(-6) : "");
27217
+ if (codeToCopy) {
27218
+ this.copyToClipboard(codeToCopy);
27219
+ }
27233
27220
  }
27234
27221
  copyRemoteURL() {
27235
- if (!this.options.sessionId) return;
27236
- this.copyToClipboard(this.options.remoteUrl + this.sessionPrefix + this.options.sessionId);
27222
+ const menuItem = this.menuItems.find((item) => item.action === "remote-url");
27223
+ const sessionUrl = this.options.sessionId ? this.options.remoteUrl + this.sessionPrefix + this.options.sessionId : "";
27224
+ const customDesc = menuItem?.desc && menuItem.desc !== this.options.remoteUrl ? menuItem.desc : void 0;
27225
+ const urlToCopy = customDesc || sessionUrl || menuItem?.text || "";
27226
+ if (urlToCopy) {
27227
+ this.copyToClipboard(urlToCopy);
27228
+ }
27237
27229
  }
27238
27230
  // 实现复制到剪贴板功能
27239
27231
  async copyToClipboard(text2) {
@@ -28383,6 +28375,9 @@ async function downloadBlob(url2, options) {
28383
28375
  const response = await fetch(url2, {
28384
28376
  signal: options == null ? void 0 : options.abortSignal
28385
28377
  });
28378
+ if (response.redirected) {
28379
+ validateDownloadUrl(response.url);
28380
+ }
28386
28381
  if (!response.ok) {
28387
28382
  throw new DownloadError({
28388
28383
  url: url2,
@@ -28544,7 +28539,7 @@ function withUserAgentSuffix$1(headers, ...userAgentSuffixParts) {
28544
28539
  );
28545
28540
  return Object.fromEntries(normalizedHeaders.entries());
28546
28541
  }
28547
- var VERSION$7 = "4.0.19";
28542
+ var VERSION$7 = "4.0.21";
28548
28543
  var getOriginalFetch = () => globalThis.fetch;
28549
28544
  var getFromApi = async ({
28550
28545
  url: url2,
@@ -28768,7 +28763,7 @@ function visit(def) {
28768
28763
  if (typeof def === "boolean") return def;
28769
28764
  return addAdditionalPropertiesToJsonSchema(def);
28770
28765
  }
28771
- var ignoreOverride = Symbol(
28766
+ var ignoreOverride = /* @__PURE__ */ Symbol(
28772
28767
  "Let zodToJsonSchema decide on which parser to use"
28773
28768
  );
28774
28769
  var defaultOptions = {
@@ -29860,7 +29855,7 @@ var zod3ToJsonSchema = (schema, options) => {
29860
29855
  combined.$schema = "http://json-schema.org/draft-07/schema#";
29861
29856
  return combined;
29862
29857
  };
29863
- var schemaSymbol = Symbol.for("vercel.ai.schema");
29858
+ var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
29864
29859
  function lazySchema(createSchema) {
29865
29860
  let schema;
29866
29861
  return () => {
@@ -30968,6 +30963,187 @@ var gatewayCreditsResponseSchema = lazySchema(
30968
30963
  }))
30969
30964
  )
30970
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
+ );
30971
31147
  var GatewayLanguageModel = class {
30972
31148
  constructor(modelId, config2) {
30973
31149
  this.modelId = modelId;
@@ -31692,7 +31868,7 @@ async function getVercelRequestId() {
31692
31868
  var _a92;
31693
31869
  return (_a92 = indexBrowserExports.getContext().headers) == null ? void 0 : _a92["x-vercel-id"];
31694
31870
  }
31695
- var VERSION$6 = "3.0.66";
31871
+ var VERSION$6 = "3.0.83";
31696
31872
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
31697
31873
  function createGatewayProvider(options = {}) {
31698
31874
  var _a92, _b9;
@@ -31792,6 +31968,30 @@ function createGatewayProvider(options = {}) {
31792
31968
  );
31793
31969
  });
31794
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
+ };
31795
31995
  const provider = function(modelId) {
31796
31996
  if (new.target) {
31797
31997
  throw new Error(
@@ -31803,6 +32003,8 @@ function createGatewayProvider(options = {}) {
31803
32003
  provider.specificationVersion = "v3";
31804
32004
  provider.getAvailableModels = getAvailableModels;
31805
32005
  provider.getCredits = getCredits;
32006
+ provider.getSpendReport = getSpendReport;
32007
+ provider.getGenerationInfo = getGenerationInfo;
31806
32008
  provider.imageModel = (modelId) => {
31807
32009
  return new GatewayImageModel(modelId, {
31808
32010
  provider: "gateway",
@@ -33138,7 +33340,7 @@ function detectMediaType({
33138
33340
  }
33139
33341
  return void 0;
33140
33342
  }
33141
- var VERSION$4 = "6.0.116";
33343
+ var VERSION$4 = "6.0.141";
33142
33344
  var download = async ({
33143
33345
  url: url2,
33144
33346
  maxBytes,
@@ -33156,6 +33358,9 @@ var download = async ({
33156
33358
  ),
33157
33359
  signal: abortSignal
33158
33360
  });
33361
+ if (response.redirected) {
33362
+ validateDownloadUrl(response.url);
33363
+ }
33159
33364
  if (!response.ok) {
33160
33365
  throw new DownloadError({
33161
33366
  url: urlText,
@@ -35929,7 +36134,7 @@ async function generateText({
35929
36134
  }),
35930
36135
  tracer,
35931
36136
  fn: async (span) => {
35932
- 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;
35933
36138
  const initialMessages = initialPrompt.messages;
35934
36139
  const responseMessages = [];
35935
36140
  const { approvedToolApprovals, deniedToolApprovals } = collectToolApprovals({ messages: initialMessages });
@@ -36146,6 +36351,7 @@ async function generateText({
36146
36351
  headers: (_g2 = result.response) == null ? void 0 : _g2.headers,
36147
36352
  body: (_h2 = result.response) == null ? void 0 : _h2.body
36148
36353
  };
36354
+ const usage = asLanguageModelUsage(result.usage);
36149
36355
  span2.setAttributes(
36150
36356
  await selectTelemetryAttributes({
36151
36357
  telemetry,
@@ -36169,9 +36375,16 @@ async function generateText({
36169
36375
  "ai.response.providerMetadata": JSON.stringify(
36170
36376
  result.providerMetadata
36171
36377
  ),
36172
- // TODO rename telemetry attributes to inputTokens and outputTokens
36173
- "ai.usage.promptTokens": result.usage.inputTokens.total,
36174
- "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,
36175
36388
  // standardized gen-ai llm span attributes:
36176
36389
  "gen_ai.response.finish_reasons": [
36177
36390
  result.finishReason.unified
@@ -36372,10 +36585,7 @@ async function generateText({
36372
36585
  },
36373
36586
  "ai.response.providerMetadata": JSON.stringify(
36374
36587
  currentModelResponse.providerMetadata
36375
- ),
36376
- // TODO rename telemetry attributes to inputTokens and outputTokens
36377
- "ai.usage.promptTokens": currentModelResponse.usage.inputTokens.total,
36378
- "ai.usage.completionTokens": currentModelResponse.usage.outputTokens.total
36588
+ )
36379
36589
  }
36380
36590
  })
36381
36591
  );
@@ -36392,6 +36602,23 @@ async function generateText({
36392
36602
  cachedInputTokens: void 0
36393
36603
  }
36394
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
+ );
36395
36622
  await notify({
36396
36623
  event: {
36397
36624
  stepNumber: lastStep.stepNumber,
@@ -36619,7 +36846,8 @@ function asContent({
36619
36846
  input: void 0,
36620
36847
  error: part.result,
36621
36848
  providerExecuted: true,
36622
- dynamic: part.dynamic
36849
+ dynamic: part.dynamic,
36850
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36623
36851
  });
36624
36852
  } else {
36625
36853
  contentParts.push({
@@ -36629,7 +36857,8 @@ function asContent({
36629
36857
  input: void 0,
36630
36858
  output: part.result,
36631
36859
  providerExecuted: true,
36632
- dynamic: part.dynamic
36860
+ dynamic: part.dynamic,
36861
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36633
36862
  });
36634
36863
  }
36635
36864
  break;
@@ -36642,7 +36871,8 @@ function asContent({
36642
36871
  input: toolCall.input,
36643
36872
  error: part.result,
36644
36873
  providerExecuted: true,
36645
- dynamic: toolCall.dynamic
36874
+ dynamic: toolCall.dynamic,
36875
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36646
36876
  });
36647
36877
  } else {
36648
36878
  contentParts.push({
@@ -36652,7 +36882,8 @@ function asContent({
36652
36882
  input: toolCall.input,
36653
36883
  output: part.result,
36654
36884
  providerExecuted: true,
36655
- dynamic: toolCall.dynamic
36885
+ dynamic: toolCall.dynamic,
36886
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
36656
36887
  });
36657
36888
  }
36658
36889
  break;
@@ -36883,8 +37114,14 @@ function processUIMessageStream({
36883
37114
  anyPart.title = options.title;
36884
37115
  }
36885
37116
  anyPart.providerExecuted = (_a22 = anyOptions.providerExecuted) != null ? _a22 : part.providerExecuted;
36886
- if (anyOptions.providerMetadata != null) {
36887
- 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
+ }
36888
37125
  }
36889
37126
  } else {
36890
37127
  state.message.parts.push({
@@ -36898,7 +37135,8 @@ function processUIMessageStream({
36898
37135
  errorText: anyOptions.errorText,
36899
37136
  providerExecuted: anyOptions.providerExecuted,
36900
37137
  preliminary: anyOptions.preliminary,
36901
- ...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 } : {}
36902
37140
  });
36903
37141
  }
36904
37142
  }
@@ -36921,8 +37159,14 @@ function processUIMessageStream({
36921
37159
  anyPart.title = options.title;
36922
37160
  }
36923
37161
  anyPart.providerExecuted = (_b22 = anyOptions.providerExecuted) != null ? _b22 : part.providerExecuted;
36924
- if (anyOptions.providerMetadata != null) {
36925
- 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
+ }
36926
37170
  }
36927
37171
  } else {
36928
37172
  state.message.parts.push({
@@ -36936,7 +37180,8 @@ function processUIMessageStream({
36936
37180
  preliminary: anyOptions.preliminary,
36937
37181
  providerExecuted: anyOptions.providerExecuted,
36938
37182
  title: options.title,
36939
- ...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 } : {}
36940
37185
  });
36941
37186
  }
36942
37187
  }
@@ -37220,6 +37465,7 @@ function processUIMessageStream({
37220
37465
  output: chunk.output,
37221
37466
  preliminary: chunk.preliminary,
37222
37467
  providerExecuted: chunk.providerExecuted,
37468
+ providerMetadata: chunk.providerMetadata,
37223
37469
  title: toolInvocation.title
37224
37470
  });
37225
37471
  } else {
@@ -37231,6 +37477,7 @@ function processUIMessageStream({
37231
37477
  output: chunk.output,
37232
37478
  providerExecuted: chunk.providerExecuted,
37233
37479
  preliminary: chunk.preliminary,
37480
+ providerMetadata: chunk.providerMetadata,
37234
37481
  title: toolInvocation.title
37235
37482
  });
37236
37483
  }
@@ -37247,6 +37494,7 @@ function processUIMessageStream({
37247
37494
  input: toolInvocation.input,
37248
37495
  errorText: chunk.errorText,
37249
37496
  providerExecuted: chunk.providerExecuted,
37497
+ providerMetadata: chunk.providerMetadata,
37250
37498
  title: toolInvocation.title
37251
37499
  });
37252
37500
  } else {
@@ -37258,6 +37506,7 @@ function processUIMessageStream({
37258
37506
  rawInput: toolInvocation.rawInput,
37259
37507
  errorText: chunk.errorText,
37260
37508
  providerExecuted: chunk.providerExecuted,
37509
+ providerMetadata: chunk.providerMetadata,
37261
37510
  title: toolInvocation.title
37262
37511
  });
37263
37512
  }
@@ -37830,7 +38079,8 @@ function runToolsTransformation({
37830
38079
  input: toolInputs.get(chunk.toolCallId),
37831
38080
  providerExecuted: true,
37832
38081
  error: chunk.result,
37833
- dynamic: chunk.dynamic
38082
+ dynamic: chunk.dynamic,
38083
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37834
38084
  });
37835
38085
  } else {
37836
38086
  controller.enqueue({
@@ -37840,7 +38090,8 @@ function runToolsTransformation({
37840
38090
  input: toolInputs.get(chunk.toolCallId),
37841
38091
  output: chunk.result,
37842
38092
  providerExecuted: true,
37843
- dynamic: chunk.dynamic
38093
+ dynamic: chunk.dynamic,
38094
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37844
38095
  });
37845
38096
  }
37846
38097
  break;
@@ -38263,6 +38514,7 @@ var DefaultStreamTextResult = class {
38263
38514
  }
38264
38515
  },
38265
38516
  async flush(controller) {
38517
+ var _a21, _b9, _c, _d, _e, _f, _g;
38266
38518
  try {
38267
38519
  if (recordedSteps.length === 0) {
38268
38520
  const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : new NoOutputGeneratedError({
@@ -38326,18 +38578,23 @@ var DefaultStreamTextResult = class {
38326
38578
  },
38327
38579
  "ai.response.toolCalls": {
38328
38580
  output: () => {
38329
- var _a21;
38330
- 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;
38331
38583
  }
38332
38584
  },
38333
38585
  "ai.response.providerMetadata": JSON.stringify(
38334
38586
  finalStep.providerMetadata
38335
38587
  ),
38336
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,
38337
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,
38338
38595
  "ai.usage.totalTokens": totalUsage.totalTokens,
38339
- "ai.usage.reasoningTokens": totalUsage.reasoningTokens,
38340
- "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
38341
38598
  }
38342
38599
  })
38343
38600
  );
@@ -38949,6 +39206,7 @@ var DefaultStreamTextResult = class {
38949
39206
  },
38950
39207
  // invoke onFinish callback and resolve toolResults promise when the stream is about to close:
38951
39208
  async flush(controller) {
39209
+ var _a22, _b22, _c2, _d2, _e2, _f2, _g2;
38952
39210
  const stepToolCallsJson = stepToolCalls.length > 0 ? JSON.stringify(stepToolCalls) : void 0;
38953
39211
  try {
38954
39212
  doStreamSpan.setAttributes(
@@ -38956,29 +39214,22 @@ var DefaultStreamTextResult = class {
38956
39214
  telemetry,
38957
39215
  attributes: {
38958
39216
  "ai.response.finishReason": stepFinishReason,
38959
- "ai.response.text": {
38960
- output: () => activeText
38961
- },
38962
- "ai.response.reasoning": {
38963
- output: () => {
38964
- const reasoningParts = recordedContent.filter(
38965
- (c) => c.type === "reasoning"
38966
- );
38967
- return reasoningParts.length > 0 ? reasoningParts.map((r) => r.text).join("\n") : void 0;
38968
- }
38969
- },
38970
39217
  "ai.response.toolCalls": {
38971
39218
  output: () => stepToolCallsJson
38972
39219
  },
38973
39220
  "ai.response.id": stepResponse.id,
38974
39221
  "ai.response.model": stepResponse.modelId,
38975
39222
  "ai.response.timestamp": stepResponse.timestamp.toISOString(),
38976
- "ai.response.providerMetadata": JSON.stringify(stepProviderMetadata),
38977
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,
38978
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,
38979
39230
  "ai.usage.totalTokens": stepUsage.totalTokens,
38980
- "ai.usage.reasoningTokens": stepUsage.reasoningTokens,
38981
- "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,
38982
39233
  // standardized gen-ai llm span attributes:
38983
39234
  "gen_ai.response.finish_reasons": [
38984
39235
  stepFinishReason
@@ -38991,8 +39242,6 @@ var DefaultStreamTextResult = class {
38991
39242
  })
38992
39243
  );
38993
39244
  } catch (error) {
38994
- } finally {
38995
- doStreamSpan.end();
38996
39245
  }
38997
39246
  controller.enqueue({
38998
39247
  type: "finish-step",
@@ -39010,6 +39259,28 @@ var DefaultStreamTextResult = class {
39010
39259
  stepUsage
39011
39260
  );
39012
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
+ }
39013
39284
  const clientToolCalls = stepToolCalls.filter(
39014
39285
  (toolCall) => toolCall.providerExecuted !== true
39015
39286
  );
@@ -39440,6 +39711,7 @@ var DefaultStreamTextResult = class {
39440
39711
  toolCallId: part.toolCallId,
39441
39712
  output: part.output,
39442
39713
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
39714
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
39443
39715
  ...part.preliminary != null ? { preliminary: part.preliminary } : {},
39444
39716
  ...dynamic != null ? { dynamic } : {}
39445
39717
  });
@@ -39450,8 +39722,9 @@ var DefaultStreamTextResult = class {
39450
39722
  controller.enqueue({
39451
39723
  type: "tool-output-error",
39452
39724
  toolCallId: part.toolCallId,
39453
- errorText: onError(part.error),
39725
+ errorText: part.providerExecuted ? typeof part.error === "string" ? part.error : JSON.stringify(part.error) : onError(part.error),
39454
39726
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
39727
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
39455
39728
  ...dynamic != null ? { dynamic } : {}
39456
39729
  });
39457
39730
  break;
@@ -39624,9 +39897,10 @@ var MCPClientError = class extends (_b = AISDKError$1, _a$1 = symbol$1, _b) {
39624
39897
  return AISDKError$1.hasMarker(error, marker$1);
39625
39898
  }
39626
39899
  };
39627
- var LATEST_PROTOCOL_VERSION = "2025-06-18";
39900
+ var LATEST_PROTOCOL_VERSION = "2025-11-25";
39628
39901
  var SUPPORTED_PROTOCOL_VERSIONS = [
39629
39902
  LATEST_PROTOCOL_VERSION,
39903
+ "2025-06-18",
39630
39904
  "2025-03-26",
39631
39905
  "2024-11-05"
39632
39906
  ];
@@ -40481,6 +40755,7 @@ async function selectResourceURL(serverUrl, provider, resourceMetadata) {
40481
40755
  async function authInternal(provider, {
40482
40756
  serverUrl,
40483
40757
  authorizationCode,
40758
+ callbackState,
40484
40759
  scope: scope2,
40485
40760
  resourceMetadataUrl,
40486
40761
  fetchFn
@@ -40533,6 +40808,14 @@ async function authInternal(provider, {
40533
40808
  clientInformation = fullInformation;
40534
40809
  }
40535
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
+ }
40536
40819
  const codeVerifier2 = await provider.codeVerifier();
40537
40820
  const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
40538
40821
  metadata: metadata2,
@@ -40571,6 +40854,9 @@ async function authInternal(provider, {
40571
40854
  }
40572
40855
  }
40573
40856
  const state = provider.state ? await provider.state() : void 0;
40857
+ if (state && provider.saveState) {
40858
+ await provider.saveState(state);
40859
+ }
40574
40860
  const { authorizationUrl, codeVerifier } = await startAuthorization(
40575
40861
  authorizationServerUrl,
40576
40862
  {
@@ -40590,12 +40876,14 @@ var SseMCPTransport = class {
40590
40876
  constructor({
40591
40877
  url: url2,
40592
40878
  headers,
40593
- authProvider
40879
+ authProvider,
40880
+ redirect = "follow"
40594
40881
  }) {
40595
40882
  this.connected = false;
40596
40883
  this.url = new URL(url2);
40597
40884
  this.headers = headers;
40598
40885
  this.authProvider = authProvider;
40886
+ this.redirectMode = redirect;
40599
40887
  }
40600
40888
  async commonHeaders(base) {
40601
40889
  const headers = {
@@ -40629,7 +40917,8 @@ var SseMCPTransport = class {
40629
40917
  });
40630
40918
  const response = await fetch(this.url.href, {
40631
40919
  headers,
40632
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
40920
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
40921
+ redirect: this.redirectMode
40633
40922
  });
40634
40923
  if (response.status === 401 && this.authProvider && !triedAuth) {
40635
40924
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
@@ -40748,7 +41037,8 @@ var SseMCPTransport = class {
40748
41037
  method: "POST",
40749
41038
  headers,
40750
41039
  body: JSON.stringify(message),
40751
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41040
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41041
+ redirect: this.redirectMode
40752
41042
  };
40753
41043
  const response = await fetch(endpoint, init);
40754
41044
  if (response.status === 401 && this.authProvider && !triedAuth) {
@@ -40789,7 +41079,8 @@ var HttpMCPTransport = class {
40789
41079
  constructor({
40790
41080
  url: url2,
40791
41081
  headers,
40792
- authProvider
41082
+ authProvider,
41083
+ redirect = "follow"
40793
41084
  }) {
40794
41085
  this.inboundReconnectAttempts = 0;
40795
41086
  this.reconnectionOptions = {
@@ -40801,6 +41092,7 @@ var HttpMCPTransport = class {
40801
41092
  this.url = new URL(url2);
40802
41093
  this.headers = headers;
40803
41094
  this.authProvider = authProvider;
41095
+ this.redirectMode = redirect;
40804
41096
  }
40805
41097
  async commonHeaders(base) {
40806
41098
  const headers = {
@@ -40841,7 +41133,8 @@ var HttpMCPTransport = class {
40841
41133
  await fetch(this.url, {
40842
41134
  method: "DELETE",
40843
41135
  headers,
40844
- signal: this.abortController.signal
41136
+ signal: this.abortController.signal,
41137
+ redirect: this.redirectMode
40845
41138
  }).catch(() => void 0);
40846
41139
  }
40847
41140
  } catch (e) {
@@ -40861,7 +41154,8 @@ var HttpMCPTransport = class {
40861
41154
  method: "POST",
40862
41155
  headers,
40863
41156
  body: JSON.stringify(message),
40864
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41157
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41158
+ redirect: this.redirectMode
40865
41159
  };
40866
41160
  const response = await fetch(this.url, init);
40867
41161
  const sessionId = response.headers.get("mcp-session-id");
@@ -41010,7 +41304,8 @@ var HttpMCPTransport = class {
41010
41304
  const response = await fetch(this.url.href, {
41011
41305
  method: "GET",
41012
41306
  headers,
41013
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41307
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41308
+ redirect: this.redirectMode
41014
41309
  });
41015
41310
  const sessionId = response.headers.get("mcp-session-id");
41016
41311
  if (sessionId) {
@@ -41671,9 +41966,9 @@ var openaiFailedResponseHandler = createJsonErrorResponseHandler$1({
41671
41966
  });
41672
41967
  function getOpenAILanguageModelCapabilities(modelId) {
41673
41968
  const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41674
- 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");
41675
41970
  const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41676
- 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");
41677
41972
  const systemMessageMode = isReasoningModel ? "developer" : "system";
41678
41973
  return {
41679
41974
  supportsFlexProcessing,
@@ -43794,6 +44089,36 @@ var shell = createProviderToolFactoryWithOutputSchema({
43794
44089
  inputSchema: shellInputSchema,
43795
44090
  outputSchema: shellOutputSchema
43796
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);
43797
44122
  var webSearchArgsSchema = lazySchema(
43798
44123
  () => zodSchema(
43799
44124
  object$2({
@@ -44050,7 +44375,17 @@ var openaiTools = {
44050
44375
  * @param serverDescription - Optional description of the server.
44051
44376
  * @param serverUrl - URL for the MCP server.
44052
44377
  */
44053
- 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
44054
44389
  };
44055
44390
  function convertOpenAIResponsesUsage(usage) {
44056
44391
  var _a10, _b9, _c, _d;
@@ -44106,8 +44441,8 @@ async function convertToOpenAIResponsesInput({
44106
44441
  hasApplyPatchTool = false,
44107
44442
  customProviderToolNames
44108
44443
  }) {
44109
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
44110
- const input = [];
44444
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
44445
+ let input = [];
44111
44446
  const warnings = [];
44112
44447
  const processedApprovalIds = /* @__PURE__ */ new Set();
44113
44448
  for (const { role, content } of prompt) {
@@ -44210,6 +44545,32 @@ async function convertToOpenAIResponsesInput({
44210
44545
  if (hasConversation && id2 != null) {
44211
44546
  break;
44212
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
+ }
44213
44574
  if (part.providerExecuted) {
44214
44575
  if (store && id2 != null) {
44215
44576
  input.push({ type: "item_reference", id: id2 });
@@ -44220,9 +44581,6 @@ async function convertToOpenAIResponsesInput({
44220
44581
  input.push({ type: "item_reference", id: id2 });
44221
44582
  break;
44222
44583
  }
44223
- const resolvedToolName = toolNameMapping.toProviderToolName(
44224
- part.toolName
44225
- );
44226
44584
  if (hasLocalShellTool && resolvedToolName === "local_shell") {
44227
44585
  const parsedInput = await validateTypes$1({
44228
44586
  value: part.input,
@@ -44305,6 +44663,26 @@ async function convertToOpenAIResponsesInput({
44305
44663
  const resolvedResultToolName = toolNameMapping.toProviderToolName(
44306
44664
  part.toolName
44307
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
+ }
44308
44686
  if (hasShellTool && resolvedResultToolName === "shell") {
44309
44687
  if (part.output.type === "json") {
44310
44688
  const parsedOutput = await validateTypes$1({
@@ -44327,7 +44705,7 @@ async function convertToOpenAIResponsesInput({
44327
44705
  break;
44328
44706
  }
44329
44707
  if (store) {
44330
- 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;
44331
44709
  input.push({ type: "item_reference", id: itemId });
44332
44710
  } else {
44333
44711
  warnings.push({
@@ -44437,7 +44815,7 @@ async function convertToOpenAIResponsesInput({
44437
44815
  }
44438
44816
  const output = part.output;
44439
44817
  if (output.type === "execution-denied") {
44440
- 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;
44441
44819
  if (approvalId) {
44442
44820
  continue;
44443
44821
  }
@@ -44445,6 +44823,20 @@ async function convertToOpenAIResponsesInput({
44445
44823
  const resolvedToolName = toolNameMapping.toProviderToolName(
44446
44824
  part.toolName
44447
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
+ }
44448
44840
  if (hasLocalShellTool && resolvedToolName === "local_shell" && output.type === "json") {
44449
44841
  const parsedOutput = await validateTypes$1({
44450
44842
  value: output.value,
@@ -44497,7 +44889,7 @@ async function convertToOpenAIResponsesInput({
44497
44889
  outputValue = output.value;
44498
44890
  break;
44499
44891
  case "execution-denied":
44500
- outputValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
44892
+ outputValue = (_p = output.reason) != null ? _p : "Tool execution denied.";
44501
44893
  break;
44502
44894
  case "json":
44503
44895
  case "error-json":
@@ -44551,7 +44943,7 @@ async function convertToOpenAIResponsesInput({
44551
44943
  contentValue = output.value;
44552
44944
  break;
44553
44945
  case "execution-denied":
44554
- contentValue = (_m = output.reason) != null ? _m : "Tool execution denied.";
44946
+ contentValue = (_q = output.reason) != null ? _q : "Tool execution denied.";
44555
44947
  break;
44556
44948
  case "json":
44557
44949
  case "error-json":
@@ -44608,6 +45000,17 @@ async function convertToOpenAIResponsesInput({
44608
45000
  }
44609
45001
  }
44610
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
+ }
44611
45014
  return { input, warnings };
44612
45015
  }
44613
45016
  var openaiResponsesReasoningProviderOptionsSchema = object$2({
@@ -44630,6 +45033,16 @@ function mapOpenAIResponseFinishReason({
44630
45033
  return hasFunctionCall ? "tool-calls" : "other";
44631
45034
  }
44632
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
+ );
44633
45046
  var openaiResponsesChunkSchema = lazySchema(
44634
45047
  () => zodSchema(
44635
45048
  union([
@@ -44663,6 +45076,23 @@ var openaiResponsesChunkSchema = lazySchema(
44663
45076
  service_tier: string().nullish()
44664
45077
  })
44665
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
+ }),
44666
45096
  object$2({
44667
45097
  type: literal("response.created"),
44668
45098
  response: object$2({
@@ -44794,6 +45224,22 @@ var openaiResponsesChunkSchema = lazySchema(
44794
45224
  ])
44795
45225
  })
44796
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()))
44797
45243
  })
44798
45244
  ])
44799
45245
  }),
@@ -45001,6 +45447,22 @@ var openaiResponsesChunkSchema = lazySchema(
45001
45447
  ])
45002
45448
  })
45003
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()))
45004
45466
  })
45005
45467
  ])
45006
45468
  }),
@@ -45382,6 +45844,22 @@ var openaiResponsesResponseSchema = lazySchema(
45382
45844
  ])
45383
45845
  })
45384
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()))
45385
45863
  })
45386
45864
  ])
45387
45865
  ).optional(),
@@ -45557,7 +46035,7 @@ async function prepareResponsesTools({
45557
46035
  toolNameMapping,
45558
46036
  customProviderToolNames
45559
46037
  }) {
45560
- var _a10;
46038
+ var _a10, _b9;
45561
46039
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
45562
46040
  const toolWarnings = [];
45563
46041
  if (tools == null) {
@@ -45567,15 +46045,19 @@ async function prepareResponsesTools({
45567
46045
  const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
45568
46046
  for (const tool2 of tools) {
45569
46047
  switch (tool2.type) {
45570
- 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;
45571
46051
  openaiTools2.push({
45572
46052
  type: "function",
45573
46053
  name: tool2.name,
45574
46054
  description: tool2.description,
45575
46055
  parameters: tool2.inputSchema,
45576
- ...tool2.strict != null ? { strict: tool2.strict } : {}
46056
+ ...tool2.strict != null ? { strict: tool2.strict } : {},
46057
+ ...deferLoading != null ? { defer_loading: deferLoading } : {}
45577
46058
  });
45578
46059
  break;
46060
+ }
45579
46061
  case "provider": {
45580
46062
  switch (tool2.id) {
45581
46063
  case "openai.file_search": {
@@ -45720,6 +46202,19 @@ async function prepareResponsesTools({
45720
46202
  resolvedCustomProviderToolNames.add(args.name);
45721
46203
  break;
45722
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
+ }
45723
46218
  }
45724
46219
  break;
45725
46220
  }
@@ -45741,7 +46236,7 @@ async function prepareResponsesTools({
45741
46236
  case "required":
45742
46237
  return { tools: openaiTools2, toolChoice: type2, toolWarnings };
45743
46238
  case "tool": {
45744
- 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;
45745
46240
  return {
45746
46241
  tools: openaiTools2,
45747
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 },
@@ -45895,7 +46390,8 @@ var OpenAIResponsesLanguageModel = class {
45895
46390
  "openai.web_search": "web_search",
45896
46391
  "openai.web_search_preview": "web_search_preview",
45897
46392
  "openai.mcp": "mcp",
45898
- "openai.apply_patch": "apply_patch"
46393
+ "openai.apply_patch": "apply_patch",
46394
+ "openai.tool_search": "tool_search"
45899
46395
  },
45900
46396
  resolveProviderToolName: (tool2) => tool2.id === "openai.custom" ? tool2.args.name : void 0
45901
46397
  });
@@ -46073,7 +46569,7 @@ var OpenAIResponsesLanguageModel = class {
46073
46569
  };
46074
46570
  }
46075
46571
  async doGenerate(options) {
46076
- 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;
46077
46573
  const {
46078
46574
  args: body,
46079
46575
  warnings,
@@ -46116,6 +46612,7 @@ var OpenAIResponsesLanguageModel = class {
46116
46612
  const content = [];
46117
46613
  const logprobs = [];
46118
46614
  let hasFunctionCall = false;
46615
+ const hostedToolSearchCallIds = [];
46119
46616
  for (const part of response.output) {
46120
46617
  switch (part.type) {
46121
46618
  case "reasoning": {
@@ -46154,6 +46651,46 @@ var OpenAIResponsesLanguageModel = class {
46154
46651
  });
46155
46652
  break;
46156
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
+ }
46157
46694
  case "local_shell_call": {
46158
46695
  content.push({
46159
46696
  type: "tool-call",
@@ -46209,7 +46746,7 @@ var OpenAIResponsesLanguageModel = class {
46209
46746
  }
46210
46747
  case "message": {
46211
46748
  for (const contentPart of part.content) {
46212
- 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) {
46213
46750
  logprobs.push(contentPart.logprobs);
46214
46751
  }
46215
46752
  const providerMetadata2 = {
@@ -46231,7 +46768,7 @@ var OpenAIResponsesLanguageModel = class {
46231
46768
  content.push({
46232
46769
  type: "source",
46233
46770
  sourceType: "url",
46234
- 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(),
46235
46772
  url: annotation.url,
46236
46773
  title: annotation.title
46237
46774
  });
@@ -46239,7 +46776,7 @@ var OpenAIResponsesLanguageModel = class {
46239
46776
  content.push({
46240
46777
  type: "source",
46241
46778
  sourceType: "document",
46242
- 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(),
46243
46780
  mediaType: "text/plain",
46244
46781
  title: annotation.filename,
46245
46782
  filename: annotation.filename,
@@ -46255,7 +46792,7 @@ var OpenAIResponsesLanguageModel = class {
46255
46792
  content.push({
46256
46793
  type: "source",
46257
46794
  sourceType: "document",
46258
- 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(),
46259
46796
  mediaType: "text/plain",
46260
46797
  title: annotation.filename,
46261
46798
  filename: annotation.filename,
@@ -46271,7 +46808,7 @@ var OpenAIResponsesLanguageModel = class {
46271
46808
  content.push({
46272
46809
  type: "source",
46273
46810
  sourceType: "document",
46274
- 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(),
46275
46812
  mediaType: "application/octet-stream",
46276
46813
  title: annotation.file_id,
46277
46814
  filename: annotation.file_id,
@@ -46340,7 +46877,7 @@ var OpenAIResponsesLanguageModel = class {
46340
46877
  break;
46341
46878
  }
46342
46879
  case "mcp_call": {
46343
- 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;
46344
46881
  const toolName = `mcp.${part.name}`;
46345
46882
  content.push({
46346
46883
  type: "tool-call",
@@ -46374,8 +46911,8 @@ var OpenAIResponsesLanguageModel = class {
46374
46911
  break;
46375
46912
  }
46376
46913
  case "mcp_approval_request": {
46377
- const approvalRequestId = (_q = part.approval_request_id) != null ? _q : part.id;
46378
- 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();
46379
46916
  const toolName = `mcp.${part.name}`;
46380
46917
  content.push({
46381
46918
  type: "tool-call",
@@ -46425,13 +46962,13 @@ var OpenAIResponsesLanguageModel = class {
46425
46962
  toolName: toolNameMapping.toCustomToolName("file_search"),
46426
46963
  result: {
46427
46964
  queries: part.queries,
46428
- results: (_v = (_u = part.results) == null ? void 0 : _u.map((result) => ({
46965
+ results: (_y = (_x = part.results) == null ? void 0 : _x.map((result) => ({
46429
46966
  attributes: result.attributes,
46430
46967
  fileId: result.file_id,
46431
46968
  filename: result.filename,
46432
46969
  score: result.score,
46433
46970
  text: result.text
46434
- }))) != null ? _v : null
46971
+ }))) != null ? _y : null
46435
46972
  }
46436
46973
  });
46437
46974
  break;
@@ -46488,10 +47025,10 @@ var OpenAIResponsesLanguageModel = class {
46488
47025
  content,
46489
47026
  finishReason: {
46490
47027
  unified: mapOpenAIResponseFinishReason({
46491
- finishReason: (_w = response.incomplete_details) == null ? void 0 : _w.reason,
47028
+ finishReason: (_z = response.incomplete_details) == null ? void 0 : _z.reason,
46492
47029
  hasFunctionCall
46493
47030
  }),
46494
- 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
46495
47032
  },
46496
47033
  usage: convertOpenAIResponsesUsage(usage),
46497
47034
  request: { body },
@@ -46549,6 +47086,7 @@ var OpenAIResponsesLanguageModel = class {
46549
47086
  let hasFunctionCall = false;
46550
47087
  const activeReasoning = {};
46551
47088
  let serviceTier;
47089
+ const hostedToolSearchCallIds = [];
46552
47090
  return {
46553
47091
  stream: response.pipeThrough(
46554
47092
  new TransformStream({
@@ -46556,7 +47094,7 @@ var OpenAIResponsesLanguageModel = class {
46556
47094
  controller.enqueue({ type: "stream-start", warnings });
46557
47095
  },
46558
47096
  transform(chunk, controller) {
46559
- 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;
46560
47098
  if (options.includeRawChunks) {
46561
47099
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
46562
47100
  }
@@ -46664,7 +47202,25 @@ var OpenAIResponsesLanguageModel = class {
46664
47202
  input: "{}",
46665
47203
  providerExecuted: true
46666
47204
  });
46667
- } 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") ;
46668
47224
  else if (value.item.type === "apply_patch_call") {
46669
47225
  const { call_id: callId, operation } = value.item;
46670
47226
  ongoingToolCalls[value.output_index] = {
@@ -46710,7 +47266,7 @@ var OpenAIResponsesLanguageModel = class {
46710
47266
  } else if (value.item.type === "shell_call_output") ;
46711
47267
  else if (value.item.type === "message") {
46712
47268
  ongoingAnnotations.splice(0, ongoingAnnotations.length);
46713
- activeMessagePhase = (_a10 = value.item.phase) != null ? _a10 : void 0;
47269
+ activeMessagePhase = (_b9 = value.item.phase) != null ? _b9 : void 0;
46714
47270
  controller.enqueue({
46715
47271
  type: "text-start",
46716
47272
  id: value.item.id,
@@ -46734,14 +47290,14 @@ var OpenAIResponsesLanguageModel = class {
46734
47290
  providerMetadata: {
46735
47291
  [providerOptionsName]: {
46736
47292
  itemId: value.item.id,
46737
- reasoningEncryptedContent: (_b9 = value.item.encrypted_content) != null ? _b9 : null
47293
+ reasoningEncryptedContent: (_c = value.item.encrypted_content) != null ? _c : null
46738
47294
  }
46739
47295
  }
46740
47296
  });
46741
47297
  }
46742
47298
  } else if (isResponseOutputItemDoneChunk(value)) {
46743
47299
  if (value.item.type === "message") {
46744
- const phase = (_c = value.item.phase) != null ? _c : activeMessagePhase;
47300
+ const phase = (_d = value.item.phase) != null ? _d : activeMessagePhase;
46745
47301
  activeMessagePhase = void 0;
46746
47302
  controller.enqueue({
46747
47303
  type: "text-end",
@@ -46835,13 +47391,13 @@ var OpenAIResponsesLanguageModel = class {
46835
47391
  toolName: toolNameMapping.toCustomToolName("file_search"),
46836
47392
  result: {
46837
47393
  queries: value.item.queries,
46838
- 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) => ({
46839
47395
  attributes: result.attributes,
46840
47396
  fileId: result.file_id,
46841
47397
  filename: result.filename,
46842
47398
  score: result.score,
46843
47399
  text: result.text
46844
- }))) != null ? _e : null
47400
+ }))) != null ? _f : null
46845
47401
  }
46846
47402
  });
46847
47403
  } else if (value.item.type === "code_interpreter_call") {
@@ -46863,12 +47419,62 @@ var OpenAIResponsesLanguageModel = class {
46863
47419
  result: value.item.result
46864
47420
  }
46865
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
+ });
46866
47472
  } else if (value.item.type === "mcp_call") {
46867
47473
  ongoingToolCalls[value.output_index] = void 0;
46868
- const approvalRequestId = (_f = value.item.approval_request_id) != null ? _f : void 0;
46869
- 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(
46870
47476
  approvalRequestId
46871
- )) != 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;
46872
47478
  const toolName = `mcp.${value.item.name}`;
46873
47479
  controller.enqueue({
46874
47480
  type: "tool-call",
@@ -46938,8 +47544,8 @@ var OpenAIResponsesLanguageModel = class {
46938
47544
  ongoingToolCalls[value.output_index] = void 0;
46939
47545
  } else if (value.item.type === "mcp_approval_request") {
46940
47546
  ongoingToolCalls[value.output_index] = void 0;
46941
- const dummyToolCallId = (_k = (_j = (_i = self2.config).generateId) == null ? void 0 : _j.call(_i)) != null ? _k : generateId$1();
46942
- 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;
46943
47549
  approvalRequestIdToDummyToolCallIdFromStream.set(
46944
47550
  approvalRequestId,
46945
47551
  dummyToolCallId
@@ -47028,7 +47634,7 @@ var OpenAIResponsesLanguageModel = class {
47028
47634
  providerMetadata: {
47029
47635
  [providerOptionsName]: {
47030
47636
  itemId: value.item.id,
47031
- reasoningEncryptedContent: (_m = value.item.encrypted_content) != null ? _m : null
47637
+ reasoningEncryptedContent: (_q = value.item.encrypted_content) != null ? _q : null
47032
47638
  }
47033
47639
  }
47034
47640
  });
@@ -47141,7 +47747,7 @@ var OpenAIResponsesLanguageModel = class {
47141
47747
  id: value.item_id,
47142
47748
  delta: value.delta
47143
47749
  });
47144
- 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) {
47145
47751
  logprobs.push(value.logprobs);
47146
47752
  }
47147
47753
  } else if (value.type === "response.reasoning_summary_part.added") {
@@ -47170,7 +47776,7 @@ var OpenAIResponsesLanguageModel = class {
47170
47776
  providerMetadata: {
47171
47777
  [providerOptionsName]: {
47172
47778
  itemId: value.item_id,
47173
- 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
47174
47780
  }
47175
47781
  }
47176
47782
  });
@@ -47204,22 +47810,32 @@ var OpenAIResponsesLanguageModel = class {
47204
47810
  } else if (isResponseFinishedChunk(value)) {
47205
47811
  finishReason = {
47206
47812
  unified: mapOpenAIResponseFinishReason({
47207
- finishReason: (_r = value.response.incomplete_details) == null ? void 0 : _r.reason,
47813
+ finishReason: (_v = value.response.incomplete_details) == null ? void 0 : _v.reason,
47208
47814
  hasFunctionCall
47209
47815
  }),
47210
- 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
47211
47817
  };
47212
47818
  usage = value.response.usage;
47213
47819
  if (typeof value.response.service_tier === "string") {
47214
47820
  serviceTier = value.response.service_tier;
47215
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;
47216
47832
  } else if (isResponseAnnotationAddedChunk(value)) {
47217
47833
  ongoingAnnotations.push(value.annotation);
47218
47834
  if (value.annotation.type === "url_citation") {
47219
47835
  controller.enqueue({
47220
47836
  type: "source",
47221
47837
  sourceType: "url",
47222
- 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(),
47223
47839
  url: value.annotation.url,
47224
47840
  title: value.annotation.title
47225
47841
  });
@@ -47227,7 +47843,7 @@ var OpenAIResponsesLanguageModel = class {
47227
47843
  controller.enqueue({
47228
47844
  type: "source",
47229
47845
  sourceType: "document",
47230
- 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(),
47231
47847
  mediaType: "text/plain",
47232
47848
  title: value.annotation.filename,
47233
47849
  filename: value.annotation.filename,
@@ -47243,7 +47859,7 @@ var OpenAIResponsesLanguageModel = class {
47243
47859
  controller.enqueue({
47244
47860
  type: "source",
47245
47861
  sourceType: "document",
47246
- 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(),
47247
47863
  mediaType: "text/plain",
47248
47864
  title: value.annotation.filename,
47249
47865
  filename: value.annotation.filename,
@@ -47259,7 +47875,7 @@ var OpenAIResponsesLanguageModel = class {
47259
47875
  controller.enqueue({
47260
47876
  type: "source",
47261
47877
  sourceType: "document",
47262
- 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(),
47263
47879
  mediaType: "application/octet-stream",
47264
47880
  title: value.annotation.file_id,
47265
47881
  filename: value.annotation.file_id,
@@ -47307,6 +47923,9 @@ function isResponseOutputItemDoneChunk(chunk) {
47307
47923
  function isResponseFinishedChunk(chunk) {
47308
47924
  return chunk.type === "response.completed" || chunk.type === "response.incomplete";
47309
47925
  }
47926
+ function isResponseFailedChunk(chunk) {
47927
+ return chunk.type === "response.failed";
47928
+ }
47310
47929
  function isResponseCreatedChunk(chunk) {
47311
47930
  return chunk.type === "response.created";
47312
47931
  }
@@ -47697,7 +48316,7 @@ var OpenAITranscriptionModel = class {
47697
48316
  };
47698
48317
  }
47699
48318
  };
47700
- var VERSION$2 = "3.0.41";
48319
+ var VERSION$2 = "3.0.48";
47701
48320
  function createOpenAI(options = {}) {
47702
48321
  var _a10, _b9;
47703
48322
  const baseURL = (_a10 = withoutTrailingSlash$1(
@@ -49629,7 +50248,13 @@ class AgentModelProvider {
49629
50248
  try {
49630
50249
  let transport;
49631
50250
  if ("type" in serverConfig && serverConfig.type.toLocaleLowerCase() === "streamablehttp") {
49632
- transport = new StreamableHTTPClientTransport(new URL(serverConfig.url));
50251
+ const configWithHeaders = serverConfig;
50252
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
50253
+ transport = new StreamableHTTPClientTransport(new URL(configWithHeaders.url), { requestInit });
50254
+ } else if ("type" in serverConfig && serverConfig.type === "sse") {
50255
+ const configWithHeaders = serverConfig;
50256
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
50257
+ transport = new SSEClientTransport(new URL(configWithHeaders.url), { requestInit });
49633
50258
  } else if ("type" in serverConfig && serverConfig.type === "extension") {
49634
50259
  transport = new ExtensionClientTransport(serverConfig.sessionId);
49635
50260
  } else if ("transport" in serverConfig) {
@@ -49741,6 +50366,11 @@ class AgentModelProvider {
49741
50366
  await this._createMpcTools();
49742
50367
  this.onUpdatedTools?.();
49743
50368
  }
50369
+ /** 仅刷新已连接 clients 的 tools(不重建 client,适合工具目录动态变化场景) */
50370
+ async refreshTools() {
50371
+ await this._createMpcTools();
50372
+ this.onUpdatedTools?.();
50373
+ }
49744
50374
  /** 全量更新所有的 mcpServers */
49745
50375
  async updateMcpServers(mcpServers) {
49746
50376
  await this.closeAll();
@@ -50146,13 +50776,37 @@ ${observationText}
50146
50776
  throw new Error("LLM is not initialized");
50147
50777
  }
50148
50778
  await this.initClientsAndTools();
50149
- 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
+ };
50150
50803
  const chatOptions = {
50151
50804
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
50152
50805
  model: this.llm(model),
50153
50806
  stopWhen: stepCountIs(maxSteps),
50154
50807
  ...options,
50155
50808
  tools: allTools,
50809
+ prepareStep: wrappedPrepareStep,
50156
50810
  activeTools: this._getActiveToolNames(allTools)
50157
50811
  };
50158
50812
  let lastUserMessage = null;
@@ -50465,6 +51119,7 @@ const MSG_PAGE_READY = "next-sdk:page-ready";
50465
51119
  const MSG_PAGE_LEAVE = "next-sdk:page-leave";
50466
51120
  const MSG_REMOTER_READY = "next-sdk:remoter-ready";
50467
51121
  const MSG_ROUTE_STATE_INITIAL = "next-sdk:route-state-initial";
51122
+ const MSG_TOOL_CATALOG_CHANGED = "next-sdk:tool-catalog-changed";
50468
51123
  const activePages = /* @__PURE__ */ new Map();
50469
51124
  const normalizeRoute = (value) => value.replace(/\/+$/, "") || "/";
50470
51125
  const broadcastTargets = /* @__PURE__ */ new Set();
@@ -50474,8 +51129,8 @@ function initBroadcastTargets() {
50474
51129
  }
50475
51130
  }
50476
51131
  initBroadcastTargets();
50477
- function broadcastRouteChange(type2, route) {
50478
- const msg = { type: type2, route };
51132
+ function broadcastRouteChange(type2, route, extra = {}) {
51133
+ const msg = { type: type2, route, ...extra };
50479
51134
  broadcastTargets.forEach(({ win, origin }) => {
50480
51135
  try {
50481
51136
  win.postMessage(msg, origin);
@@ -50490,30 +51145,413 @@ function setupIframeRemoterBridge() {
50490
51145
  if (event.origin !== window.location.origin) return;
50491
51146
  const target = event.source;
50492
51147
  broadcastTargets.add({ win: target, origin: event.origin || "*" });
50493
- const payload = {
50494
- type: MSG_ROUTE_STATE_INITIAL,
50495
- toolRouteMap: Array.from(toolRouteMap.entries()),
50496
- activeRoutes: Array.from(activePages.keys())
50497
- };
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 }) => {
50498
51158
  try {
50499
- target.postMessage(payload, event.origin || "*");
51159
+ win.postMessage(payload, origin);
50500
51160
  } catch {
50501
51161
  }
50502
51162
  });
50503
51163
  }
50504
- setupIframeRemoterBridge();
50505
- const toolRouteMap = /* @__PURE__ */ new Map();
51164
+ function notifyServerToolListChanged(server) {
51165
+ const maybeServer = server;
51166
+ try {
51167
+ maybeServer.sendToolListChanged?.();
51168
+ } catch {
51169
+ }
51170
+ }
50506
51171
  function getToolRouteMap() {
50507
- return new Map(toolRouteMap);
51172
+ return /* @__PURE__ */ new Map();
50508
51173
  }
50509
51174
  function getActiveRoutes() {
50510
51175
  return new Set(activePages.keys());
50511
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
+ }
50512
51544
  let _navigator = null;
50513
51545
  function setNavigator(fn) {
50514
51546
  _navigator = fn;
50515
51547
  }
50516
- 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) {
50517
51555
  if (typeof window === "undefined") {
50518
51556
  return Promise.resolve();
50519
51557
  }
@@ -50527,9 +51565,15 @@ function waitForPageReady(path, timeoutMs = 1500) {
50527
51565
  resolve2();
50528
51566
  };
50529
51567
  const handleMessage = (event) => {
50530
- if (event.source !== window || event.data?.type !== MSG_PAGE_READY) return;
50531
- const route = normalizeRoute(String(event.data.route ?? ""));
50532
- 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)) {
50533
51577
  cleanup();
50534
51578
  }
50535
51579
  };
@@ -50537,63 +51581,144 @@ function waitForPageReady(path, timeoutMs = 1500) {
50537
51581
  setTimeout(cleanup, timeoutMs);
50538
51582
  });
50539
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
+ }
50540
51651
  function registerNavigateTool(server, options) {
50541
51652
  const name16 = options?.name ?? "navigate_to_page";
50542
51653
  const title2 = options?.title ?? "页面跳转";
50543
51654
  const description2 = options?.description ?? '当需要的工具在当前页面不可用时,使用此工具跳转到特定页面。例如:要查询订单时跳转到 "/orders",要创建价保时跳转到 "/price-protection"。';
50544
51655
  const timeoutMs = options?.timeoutMs ?? 1500;
50545
- 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(
50546
51701
  name16,
50547
51702
  {
50548
51703
  title: title2,
50549
51704
  description: description2,
50550
- inputSchema: {
50551
- path: stringType().describe('目标页面的路由地址,例如 "/orders"、"/inventory"、"/price-protection" 等。')
50552
- }
51705
+ inputSchema
50553
51706
  },
50554
- async ({ path }) => {
50555
- if (typeof window === "undefined") {
50556
- return {
50557
- content: [{ type: "text", text: "当前环境不支持页面跳转(window 不存在)。" }]
50558
- };
50559
- }
50560
- if (!_navigator) {
50561
- return {
50562
- content: [
50563
- {
50564
- type: "text",
50565
- text: "页面跳转失败:尚未在应用入口调用 setNavigator 注册导航函数,无法执行路由跳转。"
50566
- }
50567
- ]
50568
- };
50569
- }
50570
- try {
50571
- const target = normalizeRoute(path);
50572
- const current = normalizeRoute(window.location.pathname);
50573
- const isAlreadyOnTarget = current === target || current.endsWith(target) && (current.length === target.length || current[current.lastIndexOf(target) - 1] === "/");
50574
- if (isAlreadyOnTarget) {
50575
- return {
50576
- content: [{ type: "text", text: `当前已在页面:${path}。请继续你的下一步操作。` }]
50577
- };
50578
- }
50579
- const readyPromise = waitForPageReady(path, timeoutMs);
50580
- await _navigator(path);
50581
- await readyPromise;
50582
- return {
50583
- content: [{ type: "text", text: `已成功跳转至页面:${path}。请继续你的下一步操作。` }]
50584
- };
50585
- } catch (err) {
50586
- return {
50587
- content: [
50588
- {
50589
- type: "text",
50590
- text: `页面跳转失败:${err instanceof Error ? err.message : String(err)}。`
50591
- }
50592
- ]
50593
- };
50594
- }
50595
- }
51707
+ handler
50596
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;
50597
51722
  }
50598
51723
  function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50599
51724
  return (input) => {
@@ -50636,21 +51761,24 @@ function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50636
51761
  if (effectConfig) {
50637
51762
  showToolInvokeEffect(effectConfig);
50638
51763
  }
50639
- if (activePages.get(route)) {
51764
+ if (isToolReadyOnRoute(route, name16)) {
50640
51765
  sendCallOnce();
50641
51766
  return;
50642
51767
  }
50643
51768
  readyHandler = (event) => {
50644
- if (event.source === window && event.data?.type === MSG_PAGE_READY && event.data.route === route) {
50645
- window.removeEventListener("message", readyHandler);
50646
- sendCallOnce();
50647
- }
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();
50648
51776
  };
50649
51777
  window.addEventListener("message", readyHandler);
50650
51778
  if (_navigator) {
50651
51779
  await _navigator(route);
50652
51780
  }
50653
- if (activePages.get(route)) {
51781
+ if (isToolReadyOnRoute(route, name16)) {
50654
51782
  window.removeEventListener("message", readyHandler);
50655
51783
  sendCallOnce();
50656
51784
  }
@@ -50663,31 +51791,125 @@ function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50663
51791
  });
50664
51792
  };
50665
51793
  }
50666
- 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
+ };
50667
51819
  return new Proxy(server, {
50668
51820
  get(target, prop, receiver) {
51821
+ if (prop === "unregisterTool") {
51822
+ return (name16) => unregisterByName(target, name16, false);
51823
+ }
50669
51824
  if (prop === "registerTool") {
50670
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);
50671
51832
  const rawRegister = target.registerTool.bind(target);
50672
51833
  if (typeof handlerOrRoute === "function") {
50673
- 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;
50674
51851
  }
50675
51852
  const { route, timeout, invokeEffect } = handlerOrRoute;
50676
- toolRouteMap.set(name16, route);
51853
+ const normalizedRoute = normalizeRoute(route);
50677
51854
  const effectConfig = resolveRuntimeEffectConfig(name16, config2?.title, invokeEffect);
50678
- 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;
50679
51873
  };
50680
51874
  }
50681
51875
  return Reflect.get(target, prop, receiver);
50682
51876
  }
50683
51877
  });
50684
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
+ }
50685
51908
  function registerPageTool(options) {
50686
- const { route: routeOption, handlers } = options;
50687
- const normalizeRoute2 = (value) => value.replace(/\/+$/, "") || "/";
50688
- const route = normalizeRoute2(routeOption ?? window.location.pathname);
51909
+ const { route, handlers } = resolveRouteAndHandlers(options);
51910
+ const toolNames = Object.keys(handlers);
50689
51911
  const handleMessage = async (event) => {
50690
- 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)) {
50691
51913
  return;
50692
51914
  }
50693
51915
  const { callId, toolName, input } = event.data;
@@ -50705,9 +51927,9 @@ function registerPageTool(options) {
50705
51927
  );
50706
51928
  }
50707
51929
  };
50708
- activePages.set(route, true);
51930
+ activePages.set(route, new Set(toolNames));
50709
51931
  window.addEventListener("message", handleMessage);
50710
- broadcastRouteChange(MSG_PAGE_READY, route);
51932
+ broadcastRouteChange(MSG_PAGE_READY, route, { toolNames });
50711
51933
  return () => {
50712
51934
  activePages.delete(route);
50713
51935
  window.removeEventListener("message", handleMessage);
@@ -50879,6 +52101,7 @@ export {
50879
52101
  MSG_PAGE_LEAVE,
50880
52102
  MSG_REMOTER_READY,
50881
52103
  MSG_ROUTE_STATE_INITIAL,
52104
+ MSG_TOOL_CATALOG_CHANGED,
50882
52105
  QrCode,
50883
52106
  ResourceTemplate,
50884
52107
  UriTemplate,
@@ -50892,8 +52115,12 @@ export {
50892
52115
  createSSEClientTransport,
50893
52116
  createSkillTools,
50894
52117
  createStreamableHTTPClientTransport,
52118
+ definePageTool,
52119
+ executeBuiltinWebMcpTool,
52120
+ forceResetBuiltinWebMcpTools,
50895
52121
  formatSkillsForSystemPrompt,
50896
52122
  getAISDKTools,
52123
+ getActivePageTools,
50897
52124
  getActiveRoutes,
50898
52125
  getDisplayName,
50899
52126
  getMainSkillPathByName,
@@ -50902,16 +52129,24 @@ export {
50902
52129
  getSkillMdPaths,
50903
52130
  getSkillOverviews,
50904
52131
  getToolRouteMap,
52132
+ hasBuiltinWebMcpTool,
52133
+ isBuiltinWebMcpSupported,
50905
52134
  isMcpClient,
50906
52135
  isMcpServer,
50907
52136
  isMessageChannelClientTransport,
50908
52137
  isMessageChannelServerTransport,
50909
52138
  isSSEClientTransport,
50910
52139
  isStreamableHTTPClientTransport,
52140
+ listBuiltinWebMcpTools,
52141
+ mountPageTools,
50911
52142
  parseSkillFrontMatter,
52143
+ registerBuiltinWebMcpTool,
50912
52144
  registerNavigateTool,
50913
52145
  registerPageTool,
52146
+ registerPageTools,
52147
+ registerRuntimePageTools,
50914
52148
  setNavigator,
52149
+ unregisterBuiltinWebMcpTool,
50915
52150
  withPageTools,
50916
52151
  z
50917
52152
  };