@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.
@@ -16200,7 +16200,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16200
16200
  }
16201
16201
  return String(error);
16202
16202
  }
16203
- function getSchemaDescription(schema) {
16203
+ function getSchemaDescription$1(schema) {
16204
16204
  return schema.description;
16205
16205
  }
16206
16206
  function isSchemaOptional(schema) {
@@ -23674,7 +23674,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
23674
23674
  if (!shape)
23675
23675
  return [];
23676
23676
  return Object.entries(shape).map(([name16, field]) => {
23677
- const description2 = getSchemaDescription(field);
23677
+ const description2 = getSchemaDescription$1(field);
23678
23678
  const isOptional = isSchemaOptional(field);
23679
23679
  return {
23680
23680
  name: name16,
@@ -24323,7 +24323,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24323
24323
  console.log("【Client Transport】处理server消息错误:", error);
24324
24324
  }
24325
24325
  },
24326
- "content->side"
24326
+ "content->bg"
24327
24327
  );
24328
24328
  }
24329
24329
  // 是否已关闭
@@ -24346,13 +24346,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24346
24346
  async send(message, _options) {
24347
24347
  this._throwError(() => !this._isStarted, "【Client Transport】 未启动,无法发送消息");
24348
24348
  this._throwError(() => this._isClosed, "【Client Transport】 已关闭,无法发送消息");
24349
- const sessionInfo = chrome.sessionRegistry.get(this.targetSessionId);
24350
- this._throwError(() => !sessionInfo, `【Client Transport】sessionRegistry中未找到${this.targetSessionId}`);
24351
- const tabId = sessionInfo.tabIds[sessionInfo.tabIds.length - 1];
24349
+ let tabId;
24350
+ if (chrome.sessionRegistry) {
24351
+ const sessionInfo = chrome.sessionRegistry.get(this.targetSessionId);
24352
+ if (sessionInfo && sessionInfo.tabIds.length > 0) {
24353
+ tabId = sessionInfo.tabIds[sessionInfo.tabIds.length - 1];
24354
+ }
24355
+ }
24356
+ if (tabId == null) {
24357
+ tabId = await chrome.runtime.sendMessage({ type: "get-session-tab-id", sessionId: this.targetSessionId });
24358
+ }
24359
+ this._throwError(() => tabId == null, `【Client Transport】后台未找到活动的tabId用于${this.targetSessionId}`);
24352
24360
  sendRuntimeMessage(
24353
24361
  "mcp-client-to-server",
24354
24362
  { sessionId: this.targetSessionId, tabId, mcpMessage: message },
24355
- "side->content"
24363
+ "bg->content"
24356
24364
  );
24357
24365
  }
24358
24366
  /** 关闭 transport */
@@ -24384,17 +24392,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24384
24392
  this._isClosed = false;
24385
24393
  this._lastRegistration = null;
24386
24394
  this.sessionId = sessionId || randomUUID();
24387
- this._messageListener1 = onWindowMessage(
24388
- "sidepanel-ready-to-page",
24389
- () => {
24390
- if (this._lastRegistration && this._isStarted) {
24391
- this.notifyRegistration(this._lastRegistration).catch((error) => {
24392
- console.error("【Page Svr Transport】 notifyRegistration失败:", error);
24393
- });
24394
- }
24395
- },
24396
- "content->page"
24397
- );
24398
24395
  this._messageListener2 = onWindowMessage(
24399
24396
  "mcp-client-to-server-to-page",
24400
24397
  (data) => {
@@ -24477,7 +24474,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24477
24474
  async close() {
24478
24475
  if (this._isClosed) return;
24479
24476
  try {
24480
- this._messageListener1 && this._messageListener1();
24481
24477
  this._messageListener2 && this._messageListener2();
24482
24478
  this._isClosed = true;
24483
24479
  this._isStarted = false;
@@ -24494,18 +24490,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24494
24490
  this._lastRegistration = null;
24495
24491
  this.sessionId = sessionId || randomUUID();
24496
24492
  this.tabId = tabId;
24497
- onRuntimeMessage(
24498
- "sidepanel-ready",
24499
- () => {
24500
- if (this._lastRegistration && this._isStarted) {
24501
- this.notifyRegistration(this._lastRegistration).catch((error) => {
24502
- console.log("【Content Svr Transport】 notifyRegistration 失败", error);
24503
- });
24504
- }
24505
- },
24506
- "side->content",
24507
- this.tabId
24508
- );
24509
24493
  }
24510
24494
  // 最后一次注册信息(用于 Sidepanel 刷新后重新注册)
24511
24495
  _throwError(whenFn, message) {
@@ -24544,7 +24528,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24544
24528
  console.log("【Content Svr Transport】 处理消息时发生错误:", error);
24545
24529
  }
24546
24530
  },
24547
- "side->content",
24531
+ "bg->content",
24548
24532
  this.tabId
24549
24533
  );
24550
24534
  this._isStarted = true;
@@ -24561,7 +24545,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24561
24545
  sessionId: this.sessionId,
24562
24546
  mcpMessage: message
24563
24547
  },
24564
- "content->side"
24548
+ "content->bg"
24565
24549
  );
24566
24550
  if ("result" in message && message.result?.content) {
24567
24551
  sendWindowMessage(
@@ -24589,7 +24573,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
24589
24573
  title: document.title
24590
24574
  }
24591
24575
  },
24592
- "content->side"
24576
+ "content->bg"
24593
24577
  );
24594
24578
  }
24595
24579
  async close() {
@@ -27073,27 +27057,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27073
27057
  }
27074
27058
  /**
27075
27059
  * 合并菜单项配置。
27076
- * - sessionId:使用默认菜单 + 用户配置(可定制每一项的 show/text/icon 等)
27077
- * - sessionId:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27060
+ * - 用户明确传入 menuItems:直接使用用户配置,不受 sessionId 限制;未传 icon 时自动补充默认图标
27061
+ * - sessionId 且未传 menuItems:使用默认菜单
27062
+ * - 无 sessionId 且未传 menuItems:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27078
27063
  */
27079
27064
  mergeMenuItems(userMenuItems) {
27065
+ const defaultIcons = {
27066
+ "qr-code": qrCode,
27067
+ "ai-chat": chat,
27068
+ "remote-url": link,
27069
+ "remote-control": scan
27070
+ };
27071
+ if (userMenuItems) {
27072
+ return userMenuItems.map((item) => ({
27073
+ ...item,
27074
+ icon: item.icon ?? defaultIcons[item.action]
27075
+ }));
27076
+ }
27080
27077
  if (!this.options.sessionId) {
27081
27078
  return [];
27082
27079
  }
27083
- if (!userMenuItems) {
27084
- return getDefaultMenuItems(this.options);
27085
- }
27086
- return getDefaultMenuItems(this.options).map((defaultItem) => {
27087
- const userItem = userMenuItems.find((item) => item.action === defaultItem.action);
27088
- if (userItem) {
27089
- return {
27090
- ...defaultItem,
27091
- ...userItem,
27092
- show: userItem.show !== void 0 ? userItem.show : defaultItem.show
27093
- };
27094
- }
27095
- return defaultItem;
27096
- });
27080
+ return getDefaultMenuItems(this.options);
27097
27081
  }
27098
27082
  init() {
27099
27083
  this.createFloatingBlock();
@@ -27124,7 +27108,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27124
27108
  <div class="tiny-remoter-dropdown-item__content">
27125
27109
  <div title="${item.tip}">${item.text}</div>
27126
27110
  <div class="tiny-remoter-dropdown-item__desc-wrapper">
27127
- <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>
27111
+ <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>
27128
27112
  <div>
27129
27113
  ${item.showCopyIcon ? `
27130
27114
  <div class="tiny-remoter-copy-icon" id="${item.action}" data-action="${item.action}">
@@ -27232,12 +27216,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27232
27216
  this.closeDropdown();
27233
27217
  }
27234
27218
  copyRemoteControl() {
27235
- if (!this.options.sessionId) return;
27236
- this.copyToClipboard(this.options.sessionId.slice(-6));
27219
+ const menuItem = this.menuItems.find((item) => item.action === "remote-control");
27220
+ const codeToCopy = menuItem?.desc || menuItem?.text || (this.options.sessionId ? this.options.sessionId.slice(-6) : "");
27221
+ if (codeToCopy) {
27222
+ this.copyToClipboard(codeToCopy);
27223
+ }
27237
27224
  }
27238
27225
  copyRemoteURL() {
27239
- if (!this.options.sessionId) return;
27240
- this.copyToClipboard(this.options.remoteUrl + this.sessionPrefix + this.options.sessionId);
27226
+ const menuItem = this.menuItems.find((item) => item.action === "remote-url");
27227
+ const sessionUrl = this.options.sessionId ? this.options.remoteUrl + this.sessionPrefix + this.options.sessionId : "";
27228
+ const customDesc = menuItem?.desc && menuItem.desc !== this.options.remoteUrl ? menuItem.desc : void 0;
27229
+ const urlToCopy = customDesc || sessionUrl || menuItem?.text || "";
27230
+ if (urlToCopy) {
27231
+ this.copyToClipboard(urlToCopy);
27232
+ }
27241
27233
  }
27242
27234
  // 实现复制到剪贴板功能
27243
27235
  async copyToClipboard(text2) {
@@ -28387,6 +28379,9 @@ Error message: ${getErrorMessage$2(cause)}`,
28387
28379
  const response = await fetch(url2, {
28388
28380
  signal: options == null ? void 0 : options.abortSignal
28389
28381
  });
28382
+ if (response.redirected) {
28383
+ validateDownloadUrl(response.url);
28384
+ }
28390
28385
  if (!response.ok) {
28391
28386
  throw new DownloadError({
28392
28387
  url: url2,
@@ -28548,7 +28543,7 @@ Error message: ${getErrorMessage$2(cause)}`,
28548
28543
  );
28549
28544
  return Object.fromEntries(normalizedHeaders.entries());
28550
28545
  }
28551
- var VERSION$7 = "4.0.19";
28546
+ var VERSION$7 = "4.0.21";
28552
28547
  var getOriginalFetch = () => globalThis.fetch;
28553
28548
  var getFromApi = async ({
28554
28549
  url: url2,
@@ -28772,7 +28767,7 @@ Error message: ${getErrorMessage$2(cause)}`,
28772
28767
  if (typeof def === "boolean") return def;
28773
28768
  return addAdditionalPropertiesToJsonSchema(def);
28774
28769
  }
28775
- var ignoreOverride = Symbol(
28770
+ var ignoreOverride = /* @__PURE__ */ Symbol(
28776
28771
  "Let zodToJsonSchema decide on which parser to use"
28777
28772
  );
28778
28773
  var defaultOptions = {
@@ -29864,7 +29859,7 @@ Error message: ${getErrorMessage$2(cause)}`,
29864
29859
  combined.$schema = "http://json-schema.org/draft-07/schema#";
29865
29860
  return combined;
29866
29861
  };
29867
- var schemaSymbol = Symbol.for("vercel.ai.schema");
29862
+ var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
29868
29863
  function lazySchema(createSchema) {
29869
29864
  let schema;
29870
29865
  return () => {
@@ -30972,6 +30967,187 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
30972
30967
  }))
30973
30968
  )
30974
30969
  );
30970
+ var GatewaySpendReport = class {
30971
+ constructor(config2) {
30972
+ this.config = config2;
30973
+ }
30974
+ async getSpendReport(params) {
30975
+ try {
30976
+ const baseUrl = new URL(this.config.baseURL);
30977
+ const searchParams = new URLSearchParams();
30978
+ searchParams.set("start_date", params.startDate);
30979
+ searchParams.set("end_date", params.endDate);
30980
+ if (params.groupBy) {
30981
+ searchParams.set("group_by", params.groupBy);
30982
+ }
30983
+ if (params.datePart) {
30984
+ searchParams.set("date_part", params.datePart);
30985
+ }
30986
+ if (params.userId) {
30987
+ searchParams.set("user_id", params.userId);
30988
+ }
30989
+ if (params.model) {
30990
+ searchParams.set("model", params.model);
30991
+ }
30992
+ if (params.provider) {
30993
+ searchParams.set("provider", params.provider);
30994
+ }
30995
+ if (params.credentialType) {
30996
+ searchParams.set("credential_type", params.credentialType);
30997
+ }
30998
+ if (params.tags && params.tags.length > 0) {
30999
+ searchParams.set("tags", params.tags.join(","));
31000
+ }
31001
+ const { value } = await getFromApi({
31002
+ url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`,
31003
+ headers: await resolve(this.config.headers()),
31004
+ successfulResponseHandler: createJsonResponseHandler$1(
31005
+ gatewaySpendReportResponseSchema
31006
+ ),
31007
+ failedResponseHandler: createJsonErrorResponseHandler$1({
31008
+ errorSchema: any(),
31009
+ errorToMessage: (data) => data
31010
+ }),
31011
+ fetch: this.config.fetch
31012
+ });
31013
+ return value;
31014
+ } catch (error) {
31015
+ throw await asGatewayError(error);
31016
+ }
31017
+ }
31018
+ };
31019
+ var gatewaySpendReportResponseSchema = lazySchema(
31020
+ () => zodSchema(
31021
+ object$2({
31022
+ results: array$1(
31023
+ object$2({
31024
+ day: string().optional(),
31025
+ hour: string().optional(),
31026
+ user: string().optional(),
31027
+ model: string().optional(),
31028
+ tag: string().optional(),
31029
+ provider: string().optional(),
31030
+ credential_type: _enum(["byok", "system"]).optional(),
31031
+ total_cost: number$1(),
31032
+ market_cost: number$1().optional(),
31033
+ input_tokens: number$1().optional(),
31034
+ output_tokens: number$1().optional(),
31035
+ cached_input_tokens: number$1().optional(),
31036
+ cache_creation_input_tokens: number$1().optional(),
31037
+ reasoning_tokens: number$1().optional(),
31038
+ request_count: number$1().optional()
31039
+ }).transform(
31040
+ ({
31041
+ credential_type,
31042
+ total_cost,
31043
+ market_cost,
31044
+ input_tokens,
31045
+ output_tokens,
31046
+ cached_input_tokens,
31047
+ cache_creation_input_tokens,
31048
+ reasoning_tokens,
31049
+ request_count,
31050
+ ...rest
31051
+ }) => ({
31052
+ ...rest,
31053
+ ...credential_type !== void 0 ? { credentialType: credential_type } : {},
31054
+ totalCost: total_cost,
31055
+ ...market_cost !== void 0 ? { marketCost: market_cost } : {},
31056
+ ...input_tokens !== void 0 ? { inputTokens: input_tokens } : {},
31057
+ ...output_tokens !== void 0 ? { outputTokens: output_tokens } : {},
31058
+ ...cached_input_tokens !== void 0 ? { cachedInputTokens: cached_input_tokens } : {},
31059
+ ...cache_creation_input_tokens !== void 0 ? { cacheCreationInputTokens: cache_creation_input_tokens } : {},
31060
+ ...reasoning_tokens !== void 0 ? { reasoningTokens: reasoning_tokens } : {},
31061
+ ...request_count !== void 0 ? { requestCount: request_count } : {}
31062
+ })
31063
+ )
31064
+ )
31065
+ })
31066
+ )
31067
+ );
31068
+ var GatewayGenerationInfoFetcher = class {
31069
+ constructor(config2) {
31070
+ this.config = config2;
31071
+ }
31072
+ async getGenerationInfo(params) {
31073
+ try {
31074
+ const baseUrl = new URL(this.config.baseURL);
31075
+ const { value } = await getFromApi({
31076
+ url: `${baseUrl.origin}/v1/generation?id=${encodeURIComponent(params.id)}`,
31077
+ headers: await resolve(this.config.headers()),
31078
+ successfulResponseHandler: createJsonResponseHandler$1(
31079
+ gatewayGenerationInfoResponseSchema
31080
+ ),
31081
+ failedResponseHandler: createJsonErrorResponseHandler$1({
31082
+ errorSchema: any(),
31083
+ errorToMessage: (data) => data
31084
+ }),
31085
+ fetch: this.config.fetch
31086
+ });
31087
+ return value;
31088
+ } catch (error) {
31089
+ throw await asGatewayError(error);
31090
+ }
31091
+ }
31092
+ };
31093
+ var gatewayGenerationInfoResponseSchema = lazySchema(
31094
+ () => zodSchema(
31095
+ object$2({
31096
+ data: object$2({
31097
+ id: string(),
31098
+ total_cost: number$1(),
31099
+ upstream_inference_cost: number$1(),
31100
+ usage: number$1(),
31101
+ created_at: string(),
31102
+ model: string(),
31103
+ is_byok: boolean(),
31104
+ provider_name: string(),
31105
+ streamed: boolean(),
31106
+ finish_reason: string(),
31107
+ latency: number$1(),
31108
+ generation_time: number$1(),
31109
+ native_tokens_prompt: number$1(),
31110
+ native_tokens_completion: number$1(),
31111
+ native_tokens_reasoning: number$1(),
31112
+ native_tokens_cached: number$1(),
31113
+ native_tokens_cache_creation: number$1(),
31114
+ billable_web_search_calls: number$1()
31115
+ }).transform(
31116
+ ({
31117
+ total_cost,
31118
+ upstream_inference_cost,
31119
+ created_at,
31120
+ is_byok,
31121
+ provider_name,
31122
+ finish_reason,
31123
+ generation_time,
31124
+ native_tokens_prompt,
31125
+ native_tokens_completion,
31126
+ native_tokens_reasoning,
31127
+ native_tokens_cached,
31128
+ native_tokens_cache_creation,
31129
+ billable_web_search_calls,
31130
+ ...rest
31131
+ }) => ({
31132
+ ...rest,
31133
+ totalCost: total_cost,
31134
+ upstreamInferenceCost: upstream_inference_cost,
31135
+ createdAt: created_at,
31136
+ isByok: is_byok,
31137
+ providerName: provider_name,
31138
+ finishReason: finish_reason,
31139
+ generationTime: generation_time,
31140
+ promptTokens: native_tokens_prompt,
31141
+ completionTokens: native_tokens_completion,
31142
+ reasoningTokens: native_tokens_reasoning,
31143
+ cachedTokens: native_tokens_cached,
31144
+ cacheCreationTokens: native_tokens_cache_creation,
31145
+ billableWebSearchCalls: billable_web_search_calls
31146
+ })
31147
+ )
31148
+ }).transform(({ data }) => data)
31149
+ )
31150
+ );
30975
31151
  var GatewayLanguageModel = class {
30976
31152
  constructor(modelId, config2) {
30977
31153
  this.modelId = modelId;
@@ -31696,7 +31872,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
31696
31872
  var _a92;
31697
31873
  return (_a92 = indexBrowserExports.getContext().headers) == null ? void 0 : _a92["x-vercel-id"];
31698
31874
  }
31699
- var VERSION$6 = "3.0.66";
31875
+ var VERSION$6 = "3.0.83";
31700
31876
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
31701
31877
  function createGatewayProvider(options = {}) {
31702
31878
  var _a92, _b9;
@@ -31796,6 +31972,30 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
31796
31972
  );
31797
31973
  });
31798
31974
  };
31975
+ const getSpendReport = async (params) => {
31976
+ return new GatewaySpendReport({
31977
+ baseURL,
31978
+ headers: getHeaders,
31979
+ fetch: options.fetch
31980
+ }).getSpendReport(params).catch(async (error) => {
31981
+ throw await asGatewayError(
31982
+ error,
31983
+ await parseAuthMethod(await getHeaders())
31984
+ );
31985
+ });
31986
+ };
31987
+ const getGenerationInfo = async (params) => {
31988
+ return new GatewayGenerationInfoFetcher({
31989
+ baseURL,
31990
+ headers: getHeaders,
31991
+ fetch: options.fetch
31992
+ }).getGenerationInfo(params).catch(async (error) => {
31993
+ throw await asGatewayError(
31994
+ error,
31995
+ await parseAuthMethod(await getHeaders())
31996
+ );
31997
+ });
31998
+ };
31799
31999
  const provider = function(modelId) {
31800
32000
  if (new.target) {
31801
32001
  throw new Error(
@@ -31807,6 +32007,8 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
31807
32007
  provider.specificationVersion = "v3";
31808
32008
  provider.getAvailableModels = getAvailableModels;
31809
32009
  provider.getCredits = getCredits;
32010
+ provider.getSpendReport = getSpendReport;
32011
+ provider.getGenerationInfo = getGenerationInfo;
31810
32012
  provider.imageModel = (modelId) => {
31811
32013
  return new GatewayImageModel(modelId, {
31812
32014
  provider: "gateway",
@@ -33531,7 +33733,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33531
33733
  }
33532
33734
  return void 0;
33533
33735
  }
33534
- var VERSION$4 = "6.0.116";
33736
+ var VERSION$4 = "6.0.141";
33535
33737
  var download = async ({
33536
33738
  url: url2,
33537
33739
  maxBytes,
@@ -33549,6 +33751,9 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33549
33751
  ),
33550
33752
  signal: abortSignal
33551
33753
  });
33754
+ if (response.redirected) {
33755
+ validateDownloadUrl(response.url);
33756
+ }
33552
33757
  if (!response.ok) {
33553
33758
  throw new DownloadError({
33554
33759
  url: urlText,
@@ -36322,7 +36527,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36322
36527
  }),
36323
36528
  tracer,
36324
36529
  fn: async (span) => {
36325
- var _a21, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
36530
+ var _a21, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
36326
36531
  const initialMessages = initialPrompt.messages;
36327
36532
  const responseMessages = [];
36328
36533
  const { approvedToolApprovals, deniedToolApprovals } = collectToolApprovals({ messages: initialMessages });
@@ -36539,6 +36744,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36539
36744
  headers: (_g2 = result.response) == null ? void 0 : _g2.headers,
36540
36745
  body: (_h2 = result.response) == null ? void 0 : _h2.body
36541
36746
  };
36747
+ const usage = asLanguageModelUsage(result.usage);
36542
36748
  span2.setAttributes(
36543
36749
  await selectTelemetryAttributes({
36544
36750
  telemetry,
@@ -36562,9 +36768,16 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36562
36768
  "ai.response.providerMetadata": JSON.stringify(
36563
36769
  result.providerMetadata
36564
36770
  ),
36565
- // TODO rename telemetry attributes to inputTokens and outputTokens
36566
- "ai.usage.promptTokens": result.usage.inputTokens.total,
36567
- "ai.usage.completionTokens": result.usage.outputTokens.total,
36771
+ "ai.usage.inputTokens": result.usage.inputTokens.total,
36772
+ "ai.usage.inputTokenDetails.noCacheTokens": result.usage.inputTokens.noCache,
36773
+ "ai.usage.inputTokenDetails.cacheReadTokens": result.usage.inputTokens.cacheRead,
36774
+ "ai.usage.inputTokenDetails.cacheWriteTokens": result.usage.inputTokens.cacheWrite,
36775
+ "ai.usage.outputTokens": result.usage.outputTokens.total,
36776
+ "ai.usage.outputTokenDetails.textTokens": result.usage.outputTokens.text,
36777
+ "ai.usage.outputTokenDetails.reasoningTokens": result.usage.outputTokens.reasoning,
36778
+ "ai.usage.totalTokens": usage.totalTokens,
36779
+ "ai.usage.reasoningTokens": result.usage.outputTokens.reasoning,
36780
+ "ai.usage.cachedInputTokens": result.usage.inputTokens.cacheRead,
36568
36781
  // standardized gen-ai llm span attributes:
36569
36782
  "gen_ai.response.finish_reasons": [
36570
36783
  result.finishReason.unified
@@ -36765,10 +36978,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36765
36978
  },
36766
36979
  "ai.response.providerMetadata": JSON.stringify(
36767
36980
  currentModelResponse.providerMetadata
36768
- ),
36769
- // TODO rename telemetry attributes to inputTokens and outputTokens
36770
- "ai.usage.promptTokens": currentModelResponse.usage.inputTokens.total,
36771
- "ai.usage.completionTokens": currentModelResponse.usage.outputTokens.total
36981
+ )
36772
36982
  }
36773
36983
  })
36774
36984
  );
@@ -36785,6 +36995,23 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36785
36995
  cachedInputTokens: void 0
36786
36996
  }
36787
36997
  );
36998
+ span.setAttributes(
36999
+ await selectTelemetryAttributes({
37000
+ telemetry,
37001
+ attributes: {
37002
+ "ai.usage.inputTokens": totalUsage.inputTokens,
37003
+ "ai.usage.inputTokenDetails.noCacheTokens": (_n = totalUsage.inputTokenDetails) == null ? void 0 : _n.noCacheTokens,
37004
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_o = totalUsage.inputTokenDetails) == null ? void 0 : _o.cacheReadTokens,
37005
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_p = totalUsage.inputTokenDetails) == null ? void 0 : _p.cacheWriteTokens,
37006
+ "ai.usage.outputTokens": totalUsage.outputTokens,
37007
+ "ai.usage.outputTokenDetails.textTokens": (_q = totalUsage.outputTokenDetails) == null ? void 0 : _q.textTokens,
37008
+ "ai.usage.outputTokenDetails.reasoningTokens": (_r = totalUsage.outputTokenDetails) == null ? void 0 : _r.reasoningTokens,
37009
+ "ai.usage.totalTokens": totalUsage.totalTokens,
37010
+ "ai.usage.reasoningTokens": (_s = totalUsage.outputTokenDetails) == null ? void 0 : _s.reasoningTokens,
37011
+ "ai.usage.cachedInputTokens": (_t = totalUsage.inputTokenDetails) == null ? void 0 : _t.cacheReadTokens
37012
+ }
37013
+ })
37014
+ );
36788
37015
  await notify({
36789
37016
  event: {
36790
37017
  stepNumber: lastStep.stepNumber,
@@ -37012,7 +37239,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37012
37239
  input: void 0,
37013
37240
  error: part.result,
37014
37241
  providerExecuted: true,
37015
- dynamic: part.dynamic
37242
+ dynamic: part.dynamic,
37243
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37016
37244
  });
37017
37245
  } else {
37018
37246
  contentParts.push({
@@ -37022,7 +37250,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37022
37250
  input: void 0,
37023
37251
  output: part.result,
37024
37252
  providerExecuted: true,
37025
- dynamic: part.dynamic
37253
+ dynamic: part.dynamic,
37254
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37026
37255
  });
37027
37256
  }
37028
37257
  break;
@@ -37035,7 +37264,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37035
37264
  input: toolCall.input,
37036
37265
  error: part.result,
37037
37266
  providerExecuted: true,
37038
- dynamic: toolCall.dynamic
37267
+ dynamic: toolCall.dynamic,
37268
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37039
37269
  });
37040
37270
  } else {
37041
37271
  contentParts.push({
@@ -37045,7 +37275,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37045
37275
  input: toolCall.input,
37046
37276
  output: part.result,
37047
37277
  providerExecuted: true,
37048
- dynamic: toolCall.dynamic
37278
+ dynamic: toolCall.dynamic,
37279
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
37049
37280
  });
37050
37281
  }
37051
37282
  break;
@@ -37276,8 +37507,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37276
37507
  anyPart.title = options.title;
37277
37508
  }
37278
37509
  anyPart.providerExecuted = (_a22 = anyOptions.providerExecuted) != null ? _a22 : part.providerExecuted;
37279
- if (anyOptions.providerMetadata != null) {
37280
- part.callProviderMetadata = anyOptions.providerMetadata;
37510
+ const providerMetadata = anyOptions.providerMetadata;
37511
+ if (providerMetadata != null) {
37512
+ if (options.state === "output-available" || options.state === "output-error") {
37513
+ const resultPart = part;
37514
+ resultPart.resultProviderMetadata = providerMetadata;
37515
+ } else {
37516
+ part.callProviderMetadata = providerMetadata;
37517
+ }
37281
37518
  }
37282
37519
  } else {
37283
37520
  state.message.parts.push({
@@ -37291,7 +37528,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37291
37528
  errorText: anyOptions.errorText,
37292
37529
  providerExecuted: anyOptions.providerExecuted,
37293
37530
  preliminary: anyOptions.preliminary,
37294
- ...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37531
+ ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {},
37532
+ ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37295
37533
  });
37296
37534
  }
37297
37535
  }
@@ -37314,8 +37552,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37314
37552
  anyPart.title = options.title;
37315
37553
  }
37316
37554
  anyPart.providerExecuted = (_b22 = anyOptions.providerExecuted) != null ? _b22 : part.providerExecuted;
37317
- if (anyOptions.providerMetadata != null) {
37318
- part.callProviderMetadata = anyOptions.providerMetadata;
37555
+ const providerMetadata = anyOptions.providerMetadata;
37556
+ if (providerMetadata != null) {
37557
+ if (options.state === "output-available" || options.state === "output-error") {
37558
+ const resultPart = part;
37559
+ resultPart.resultProviderMetadata = providerMetadata;
37560
+ } else {
37561
+ part.callProviderMetadata = providerMetadata;
37562
+ }
37319
37563
  }
37320
37564
  } else {
37321
37565
  state.message.parts.push({
@@ -37329,7 +37573,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37329
37573
  preliminary: anyOptions.preliminary,
37330
37574
  providerExecuted: anyOptions.providerExecuted,
37331
37575
  title: options.title,
37332
- ...anyOptions.providerMetadata != null ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37576
+ ...anyOptions.providerMetadata != null && (options.state === "output-available" || options.state === "output-error") ? { resultProviderMetadata: anyOptions.providerMetadata } : {},
37577
+ ...anyOptions.providerMetadata != null && !(options.state === "output-available" || options.state === "output-error") ? { callProviderMetadata: anyOptions.providerMetadata } : {}
37333
37578
  });
37334
37579
  }
37335
37580
  }
@@ -37613,6 +37858,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37613
37858
  output: chunk.output,
37614
37859
  preliminary: chunk.preliminary,
37615
37860
  providerExecuted: chunk.providerExecuted,
37861
+ providerMetadata: chunk.providerMetadata,
37616
37862
  title: toolInvocation.title
37617
37863
  });
37618
37864
  } else {
@@ -37624,6 +37870,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37624
37870
  output: chunk.output,
37625
37871
  providerExecuted: chunk.providerExecuted,
37626
37872
  preliminary: chunk.preliminary,
37873
+ providerMetadata: chunk.providerMetadata,
37627
37874
  title: toolInvocation.title
37628
37875
  });
37629
37876
  }
@@ -37640,6 +37887,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37640
37887
  input: toolInvocation.input,
37641
37888
  errorText: chunk.errorText,
37642
37889
  providerExecuted: chunk.providerExecuted,
37890
+ providerMetadata: chunk.providerMetadata,
37643
37891
  title: toolInvocation.title
37644
37892
  });
37645
37893
  } else {
@@ -37651,6 +37899,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37651
37899
  rawInput: toolInvocation.rawInput,
37652
37900
  errorText: chunk.errorText,
37653
37901
  providerExecuted: chunk.providerExecuted,
37902
+ providerMetadata: chunk.providerMetadata,
37654
37903
  title: toolInvocation.title
37655
37904
  });
37656
37905
  }
@@ -38223,7 +38472,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38223
38472
  input: toolInputs.get(chunk.toolCallId),
38224
38473
  providerExecuted: true,
38225
38474
  error: chunk.result,
38226
- dynamic: chunk.dynamic
38475
+ dynamic: chunk.dynamic,
38476
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
38227
38477
  });
38228
38478
  } else {
38229
38479
  controller.enqueue({
@@ -38233,7 +38483,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38233
38483
  input: toolInputs.get(chunk.toolCallId),
38234
38484
  output: chunk.result,
38235
38485
  providerExecuted: true,
38236
- dynamic: chunk.dynamic
38486
+ dynamic: chunk.dynamic,
38487
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
38237
38488
  });
38238
38489
  }
38239
38490
  break;
@@ -38656,6 +38907,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38656
38907
  }
38657
38908
  },
38658
38909
  async flush(controller) {
38910
+ var _a21, _b9, _c, _d, _e, _f, _g;
38659
38911
  try {
38660
38912
  if (recordedSteps.length === 0) {
38661
38913
  const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : new NoOutputGeneratedError({
@@ -38719,18 +38971,23 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38719
38971
  },
38720
38972
  "ai.response.toolCalls": {
38721
38973
  output: () => {
38722
- var _a21;
38723
- return ((_a21 = finalStep.toolCalls) == null ? void 0 : _a21.length) ? JSON.stringify(finalStep.toolCalls) : void 0;
38974
+ var _a22;
38975
+ return ((_a22 = finalStep.toolCalls) == null ? void 0 : _a22.length) ? JSON.stringify(finalStep.toolCalls) : void 0;
38724
38976
  }
38725
38977
  },
38726
38978
  "ai.response.providerMetadata": JSON.stringify(
38727
38979
  finalStep.providerMetadata
38728
38980
  ),
38729
38981
  "ai.usage.inputTokens": totalUsage.inputTokens,
38982
+ "ai.usage.inputTokenDetails.noCacheTokens": (_a21 = totalUsage.inputTokenDetails) == null ? void 0 : _a21.noCacheTokens,
38983
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_b9 = totalUsage.inputTokenDetails) == null ? void 0 : _b9.cacheReadTokens,
38984
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_c = totalUsage.inputTokenDetails) == null ? void 0 : _c.cacheWriteTokens,
38730
38985
  "ai.usage.outputTokens": totalUsage.outputTokens,
38986
+ "ai.usage.outputTokenDetails.textTokens": (_d = totalUsage.outputTokenDetails) == null ? void 0 : _d.textTokens,
38987
+ "ai.usage.outputTokenDetails.reasoningTokens": (_e = totalUsage.outputTokenDetails) == null ? void 0 : _e.reasoningTokens,
38731
38988
  "ai.usage.totalTokens": totalUsage.totalTokens,
38732
- "ai.usage.reasoningTokens": totalUsage.reasoningTokens,
38733
- "ai.usage.cachedInputTokens": totalUsage.cachedInputTokens
38989
+ "ai.usage.reasoningTokens": (_f = totalUsage.outputTokenDetails) == null ? void 0 : _f.reasoningTokens,
38990
+ "ai.usage.cachedInputTokens": (_g = totalUsage.inputTokenDetails) == null ? void 0 : _g.cacheReadTokens
38734
38991
  }
38735
38992
  })
38736
38993
  );
@@ -39342,6 +39599,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39342
39599
  },
39343
39600
  // invoke onFinish callback and resolve toolResults promise when the stream is about to close:
39344
39601
  async flush(controller) {
39602
+ var _a22, _b22, _c2, _d2, _e2, _f2, _g2;
39345
39603
  const stepToolCallsJson = stepToolCalls.length > 0 ? JSON.stringify(stepToolCalls) : void 0;
39346
39604
  try {
39347
39605
  doStreamSpan.setAttributes(
@@ -39349,29 +39607,22 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39349
39607
  telemetry,
39350
39608
  attributes: {
39351
39609
  "ai.response.finishReason": stepFinishReason,
39352
- "ai.response.text": {
39353
- output: () => activeText
39354
- },
39355
- "ai.response.reasoning": {
39356
- output: () => {
39357
- const reasoningParts = recordedContent.filter(
39358
- (c) => c.type === "reasoning"
39359
- );
39360
- return reasoningParts.length > 0 ? reasoningParts.map((r) => r.text).join("\n") : void 0;
39361
- }
39362
- },
39363
39610
  "ai.response.toolCalls": {
39364
39611
  output: () => stepToolCallsJson
39365
39612
  },
39366
39613
  "ai.response.id": stepResponse.id,
39367
39614
  "ai.response.model": stepResponse.modelId,
39368
39615
  "ai.response.timestamp": stepResponse.timestamp.toISOString(),
39369
- "ai.response.providerMetadata": JSON.stringify(stepProviderMetadata),
39370
39616
  "ai.usage.inputTokens": stepUsage.inputTokens,
39617
+ "ai.usage.inputTokenDetails.noCacheTokens": (_a22 = stepUsage.inputTokenDetails) == null ? void 0 : _a22.noCacheTokens,
39618
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_b22 = stepUsage.inputTokenDetails) == null ? void 0 : _b22.cacheReadTokens,
39619
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_c2 = stepUsage.inputTokenDetails) == null ? void 0 : _c2.cacheWriteTokens,
39371
39620
  "ai.usage.outputTokens": stepUsage.outputTokens,
39621
+ "ai.usage.outputTokenDetails.textTokens": (_d2 = stepUsage.outputTokenDetails) == null ? void 0 : _d2.textTokens,
39622
+ "ai.usage.outputTokenDetails.reasoningTokens": (_e2 = stepUsage.outputTokenDetails) == null ? void 0 : _e2.reasoningTokens,
39372
39623
  "ai.usage.totalTokens": stepUsage.totalTokens,
39373
- "ai.usage.reasoningTokens": stepUsage.reasoningTokens,
39374
- "ai.usage.cachedInputTokens": stepUsage.cachedInputTokens,
39624
+ "ai.usage.reasoningTokens": (_f2 = stepUsage.outputTokenDetails) == null ? void 0 : _f2.reasoningTokens,
39625
+ "ai.usage.cachedInputTokens": (_g2 = stepUsage.inputTokenDetails) == null ? void 0 : _g2.cacheReadTokens,
39375
39626
  // standardized gen-ai llm span attributes:
39376
39627
  "gen_ai.response.finish_reasons": [
39377
39628
  stepFinishReason
@@ -39384,8 +39635,6 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39384
39635
  })
39385
39636
  );
39386
39637
  } catch (error) {
39387
- } finally {
39388
- doStreamSpan.end();
39389
39638
  }
39390
39639
  controller.enqueue({
39391
39640
  type: "finish-step",
@@ -39403,6 +39652,28 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39403
39652
  stepUsage
39404
39653
  );
39405
39654
  await stepFinish.promise;
39655
+ const processedStep = recordedSteps[recordedSteps.length - 1];
39656
+ try {
39657
+ doStreamSpan.setAttributes(
39658
+ await selectTelemetryAttributes({
39659
+ telemetry,
39660
+ attributes: {
39661
+ "ai.response.text": {
39662
+ output: () => processedStep.text
39663
+ },
39664
+ "ai.response.reasoning": {
39665
+ output: () => processedStep.reasoningText
39666
+ },
39667
+ "ai.response.providerMetadata": JSON.stringify(
39668
+ processedStep.providerMetadata
39669
+ )
39670
+ }
39671
+ })
39672
+ );
39673
+ } catch (error) {
39674
+ } finally {
39675
+ doStreamSpan.end();
39676
+ }
39406
39677
  const clientToolCalls = stepToolCalls.filter(
39407
39678
  (toolCall) => toolCall.providerExecuted !== true
39408
39679
  );
@@ -39833,6 +40104,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39833
40104
  toolCallId: part.toolCallId,
39834
40105
  output: part.output,
39835
40106
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
40107
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
39836
40108
  ...part.preliminary != null ? { preliminary: part.preliminary } : {},
39837
40109
  ...dynamic != null ? { dynamic } : {}
39838
40110
  });
@@ -39843,8 +40115,9 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39843
40115
  controller.enqueue({
39844
40116
  type: "tool-output-error",
39845
40117
  toolCallId: part.toolCallId,
39846
- errorText: onError(part.error),
40118
+ errorText: part.providerExecuted ? typeof part.error === "string" ? part.error : JSON.stringify(part.error) : onError(part.error),
39847
40119
  ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
40120
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
39848
40121
  ...dynamic != null ? { dynamic } : {}
39849
40122
  });
39850
40123
  break;
@@ -40017,9 +40290,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
40017
40290
  return AISDKError$1.hasMarker(error, marker$1);
40018
40291
  }
40019
40292
  };
40020
- var LATEST_PROTOCOL_VERSION = "2025-06-18";
40293
+ var LATEST_PROTOCOL_VERSION = "2025-11-25";
40021
40294
  var SUPPORTED_PROTOCOL_VERSIONS = [
40022
40295
  LATEST_PROTOCOL_VERSION,
40296
+ "2025-06-18",
40023
40297
  "2025-03-26",
40024
40298
  "2024-11-05"
40025
40299
  ];
@@ -40874,6 +41148,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
40874
41148
  async function authInternal(provider, {
40875
41149
  serverUrl,
40876
41150
  authorizationCode,
41151
+ callbackState,
40877
41152
  scope: scope2,
40878
41153
  resourceMetadataUrl,
40879
41154
  fetchFn
@@ -40926,6 +41201,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
40926
41201
  clientInformation = fullInformation;
40927
41202
  }
40928
41203
  if (authorizationCode !== void 0) {
41204
+ if (provider.storedState) {
41205
+ const expectedState = await provider.storedState();
41206
+ if (expectedState !== void 0 && expectedState !== callbackState) {
41207
+ throw new Error(
41208
+ "OAuth state parameter mismatch - possible CSRF attack"
41209
+ );
41210
+ }
41211
+ }
40929
41212
  const codeVerifier2 = await provider.codeVerifier();
40930
41213
  const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
40931
41214
  metadata: metadata2,
@@ -40964,6 +41247,9 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
40964
41247
  }
40965
41248
  }
40966
41249
  const state = provider.state ? await provider.state() : void 0;
41250
+ if (state && provider.saveState) {
41251
+ await provider.saveState(state);
41252
+ }
40967
41253
  const { authorizationUrl, codeVerifier } = await startAuthorization(
40968
41254
  authorizationServerUrl,
40969
41255
  {
@@ -40983,12 +41269,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
40983
41269
  constructor({
40984
41270
  url: url2,
40985
41271
  headers,
40986
- authProvider
41272
+ authProvider,
41273
+ redirect = "follow"
40987
41274
  }) {
40988
41275
  this.connected = false;
40989
41276
  this.url = new URL(url2);
40990
41277
  this.headers = headers;
40991
41278
  this.authProvider = authProvider;
41279
+ this.redirectMode = redirect;
40992
41280
  }
40993
41281
  async commonHeaders(base) {
40994
41282
  const headers = {
@@ -41022,7 +41310,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41022
41310
  });
41023
41311
  const response = await fetch(this.url.href, {
41024
41312
  headers,
41025
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41313
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41314
+ redirect: this.redirectMode
41026
41315
  });
41027
41316
  if (response.status === 401 && this.authProvider && !triedAuth) {
41028
41317
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
@@ -41141,7 +41430,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41141
41430
  method: "POST",
41142
41431
  headers,
41143
41432
  body: JSON.stringify(message),
41144
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41433
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41434
+ redirect: this.redirectMode
41145
41435
  };
41146
41436
  const response = await fetch(endpoint, init);
41147
41437
  if (response.status === 401 && this.authProvider && !triedAuth) {
@@ -41182,7 +41472,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41182
41472
  constructor({
41183
41473
  url: url2,
41184
41474
  headers,
41185
- authProvider
41475
+ authProvider,
41476
+ redirect = "follow"
41186
41477
  }) {
41187
41478
  this.inboundReconnectAttempts = 0;
41188
41479
  this.reconnectionOptions = {
@@ -41194,6 +41485,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41194
41485
  this.url = new URL(url2);
41195
41486
  this.headers = headers;
41196
41487
  this.authProvider = authProvider;
41488
+ this.redirectMode = redirect;
41197
41489
  }
41198
41490
  async commonHeaders(base) {
41199
41491
  const headers = {
@@ -41234,7 +41526,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41234
41526
  await fetch(this.url, {
41235
41527
  method: "DELETE",
41236
41528
  headers,
41237
- signal: this.abortController.signal
41529
+ signal: this.abortController.signal,
41530
+ redirect: this.redirectMode
41238
41531
  }).catch(() => void 0);
41239
41532
  }
41240
41533
  } catch (e) {
@@ -41254,7 +41547,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41254
41547
  method: "POST",
41255
41548
  headers,
41256
41549
  body: JSON.stringify(message),
41257
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41550
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41551
+ redirect: this.redirectMode
41258
41552
  };
41259
41553
  const response = await fetch(this.url, init);
41260
41554
  const sessionId = response.headers.get("mcp-session-id");
@@ -41403,7 +41697,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41403
41697
  const response = await fetch(this.url.href, {
41404
41698
  method: "GET",
41405
41699
  headers,
41406
- signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal
41700
+ signal: (_a32 = this.abortController) == null ? void 0 : _a32.signal,
41701
+ redirect: this.redirectMode
41407
41702
  });
41408
41703
  const sessionId = response.headers.get("mcp-session-id");
41409
41704
  if (sessionId) {
@@ -42064,9 +42359,9 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
42064
42359
  });
42065
42360
  function getOpenAILanguageModelCapabilities(modelId) {
42066
42361
  const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
42067
- 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");
42362
+ 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");
42068
42363
  const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
42069
- const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2");
42364
+ const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2") || modelId.startsWith("gpt-5.3") || modelId.startsWith("gpt-5.4");
42070
42365
  const systemMessageMode = isReasoningModel ? "developer" : "system";
42071
42366
  return {
42072
42367
  supportsFlexProcessing,
@@ -44187,6 +44482,36 @@ ${user}:`]
44187
44482
  inputSchema: shellInputSchema,
44188
44483
  outputSchema: shellOutputSchema
44189
44484
  });
44485
+ var toolSearchArgsSchema = lazySchema(
44486
+ () => zodSchema(
44487
+ object$2({
44488
+ execution: _enum(["server", "client"]).optional(),
44489
+ description: string().optional(),
44490
+ parameters: record(string(), unknown()).optional()
44491
+ })
44492
+ )
44493
+ );
44494
+ var toolSearchInputSchema = lazySchema(
44495
+ () => zodSchema(
44496
+ object$2({
44497
+ arguments: unknown().optional(),
44498
+ call_id: string().nullish()
44499
+ })
44500
+ )
44501
+ );
44502
+ var toolSearchOutputSchema = lazySchema(
44503
+ () => zodSchema(
44504
+ object$2({
44505
+ tools: array$1(record(string(), unknown()))
44506
+ })
44507
+ )
44508
+ );
44509
+ var toolSearchToolFactory = createProviderToolFactoryWithOutputSchema({
44510
+ id: "openai.tool_search",
44511
+ inputSchema: toolSearchInputSchema,
44512
+ outputSchema: toolSearchOutputSchema
44513
+ });
44514
+ var toolSearch = (args = {}) => toolSearchToolFactory(args);
44190
44515
  var webSearchArgsSchema = lazySchema(
44191
44516
  () => zodSchema(
44192
44517
  object$2({
@@ -44443,7 +44768,17 @@ ${user}:`]
44443
44768
  * @param serverDescription - Optional description of the server.
44444
44769
  * @param serverUrl - URL for the MCP server.
44445
44770
  */
44446
- mcp
44771
+ mcp,
44772
+ /**
44773
+ * Tool search allows the model to dynamically search for and load deferred
44774
+ * tools into the model's context as needed. This helps reduce overall token
44775
+ * usage, cost, and latency by only loading tools when the model needs them.
44776
+ *
44777
+ * To use tool search, mark functions or namespaces with `defer_loading: true`
44778
+ * in the tools array. The model will use tool search to load these tools
44779
+ * when it determines they are needed.
44780
+ */
44781
+ toolSearch
44447
44782
  };
44448
44783
  function convertOpenAIResponsesUsage(usage) {
44449
44784
  var _a10, _b9, _c, _d;
@@ -44499,8 +44834,8 @@ ${user}:`]
44499
44834
  hasApplyPatchTool = false,
44500
44835
  customProviderToolNames
44501
44836
  }) {
44502
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
44503
- const input = [];
44837
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
44838
+ let input = [];
44504
44839
  const warnings = [];
44505
44840
  const processedApprovalIds = /* @__PURE__ */ new Set();
44506
44841
  for (const { role, content } of prompt) {
@@ -44603,6 +44938,32 @@ ${user}:`]
44603
44938
  if (hasConversation && id2 != null) {
44604
44939
  break;
44605
44940
  }
44941
+ const resolvedToolName = toolNameMapping.toProviderToolName(
44942
+ part.toolName
44943
+ );
44944
+ if (resolvedToolName === "tool_search") {
44945
+ if (store && id2 != null) {
44946
+ input.push({ type: "item_reference", id: id2 });
44947
+ break;
44948
+ }
44949
+ const parsedInput = typeof part.input === "string" ? await parseJSON$1({
44950
+ text: part.input,
44951
+ schema: toolSearchInputSchema
44952
+ }) : await validateTypes$1({
44953
+ value: part.input,
44954
+ schema: toolSearchInputSchema
44955
+ });
44956
+ const execution = parsedInput.call_id != null ? "client" : "server";
44957
+ input.push({
44958
+ type: "tool_search_call",
44959
+ id: id2 != null ? id2 : part.toolCallId,
44960
+ execution,
44961
+ call_id: (_g = parsedInput.call_id) != null ? _g : null,
44962
+ status: "completed",
44963
+ arguments: parsedInput.arguments
44964
+ });
44965
+ break;
44966
+ }
44606
44967
  if (part.providerExecuted) {
44607
44968
  if (store && id2 != null) {
44608
44969
  input.push({ type: "item_reference", id: id2 });
@@ -44613,9 +44974,6 @@ ${user}:`]
44613
44974
  input.push({ type: "item_reference", id: id2 });
44614
44975
  break;
44615
44976
  }
44616
- const resolvedToolName = toolNameMapping.toProviderToolName(
44617
- part.toolName
44618
- );
44619
44977
  if (hasLocalShellTool && resolvedToolName === "local_shell") {
44620
44978
  const parsedInput = await validateTypes$1({
44621
44979
  value: part.input,
@@ -44698,6 +45056,26 @@ ${user}:`]
44698
45056
  const resolvedResultToolName = toolNameMapping.toProviderToolName(
44699
45057
  part.toolName
44700
45058
  );
45059
+ if (resolvedResultToolName === "tool_search") {
45060
+ const itemId = (_j = (_i = (_h = part.providerOptions) == null ? void 0 : _h[providerOptionsName]) == null ? void 0 : _i.itemId) != null ? _j : part.toolCallId;
45061
+ if (store) {
45062
+ input.push({ type: "item_reference", id: itemId });
45063
+ } else if (part.output.type === "json") {
45064
+ const parsedOutput = await validateTypes$1({
45065
+ value: part.output.value,
45066
+ schema: toolSearchOutputSchema
45067
+ });
45068
+ input.push({
45069
+ type: "tool_search_output",
45070
+ id: itemId,
45071
+ execution: "server",
45072
+ call_id: null,
45073
+ status: "completed",
45074
+ tools: parsedOutput.tools
45075
+ });
45076
+ }
45077
+ break;
45078
+ }
44701
45079
  if (hasShellTool && resolvedResultToolName === "shell") {
44702
45080
  if (part.output.type === "json") {
44703
45081
  const parsedOutput = await validateTypes$1({
@@ -44720,7 +45098,7 @@ ${user}:`]
44720
45098
  break;
44721
45099
  }
44722
45100
  if (store) {
44723
- const itemId = (_i = (_h = (_g = part.providerOptions) == null ? void 0 : _g[providerOptionsName]) == null ? void 0 : _h.itemId) != null ? _i : part.toolCallId;
45101
+ const itemId = (_m = (_l = (_k = part.providerOptions) == null ? void 0 : _k[providerOptionsName]) == null ? void 0 : _l.itemId) != null ? _m : part.toolCallId;
44724
45102
  input.push({ type: "item_reference", id: itemId });
44725
45103
  } else {
44726
45104
  warnings.push({
@@ -44830,7 +45208,7 @@ ${user}:`]
44830
45208
  }
44831
45209
  const output = part.output;
44832
45210
  if (output.type === "execution-denied") {
44833
- const approvalId = (_k = (_j = output.providerOptions) == null ? void 0 : _j.openai) == null ? void 0 : _k.approvalId;
45211
+ const approvalId = (_o = (_n = output.providerOptions) == null ? void 0 : _n.openai) == null ? void 0 : _o.approvalId;
44834
45212
  if (approvalId) {
44835
45213
  continue;
44836
45214
  }
@@ -44838,6 +45216,20 @@ ${user}:`]
44838
45216
  const resolvedToolName = toolNameMapping.toProviderToolName(
44839
45217
  part.toolName
44840
45218
  );
45219
+ if (resolvedToolName === "tool_search" && output.type === "json") {
45220
+ const parsedOutput = await validateTypes$1({
45221
+ value: output.value,
45222
+ schema: toolSearchOutputSchema
45223
+ });
45224
+ input.push({
45225
+ type: "tool_search_output",
45226
+ execution: "client",
45227
+ call_id: part.toolCallId,
45228
+ status: "completed",
45229
+ tools: parsedOutput.tools
45230
+ });
45231
+ continue;
45232
+ }
44841
45233
  if (hasLocalShellTool && resolvedToolName === "local_shell" && output.type === "json") {
44842
45234
  const parsedOutput = await validateTypes$1({
44843
45235
  value: output.value,
@@ -44890,7 +45282,7 @@ ${user}:`]
44890
45282
  outputValue = output.value;
44891
45283
  break;
44892
45284
  case "execution-denied":
44893
- outputValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
45285
+ outputValue = (_p = output.reason) != null ? _p : "Tool execution denied.";
44894
45286
  break;
44895
45287
  case "json":
44896
45288
  case "error-json":
@@ -44944,7 +45336,7 @@ ${user}:`]
44944
45336
  contentValue = output.value;
44945
45337
  break;
44946
45338
  case "execution-denied":
44947
- contentValue = (_m = output.reason) != null ? _m : "Tool execution denied.";
45339
+ contentValue = (_q = output.reason) != null ? _q : "Tool execution denied.";
44948
45340
  break;
44949
45341
  case "json":
44950
45342
  case "error-json":
@@ -45001,6 +45393,17 @@ ${user}:`]
45001
45393
  }
45002
45394
  }
45003
45395
  }
45396
+ if (!store && input.some(
45397
+ (item) => "type" in item && item.type === "reasoning" && item.encrypted_content == null
45398
+ )) {
45399
+ warnings.push({
45400
+ type: "other",
45401
+ message: "Reasoning parts without encrypted content are not supported when store is false. Skipping reasoning parts."
45402
+ });
45403
+ input = input.filter(
45404
+ (item) => !("type" in item) || item.type !== "reasoning" || item.encrypted_content != null
45405
+ );
45406
+ }
45004
45407
  return { input, warnings };
45005
45408
  }
45006
45409
  var openaiResponsesReasoningProviderOptionsSchema = object$2({
@@ -45023,6 +45426,16 @@ ${user}:`]
45023
45426
  return hasFunctionCall ? "tool-calls" : "other";
45024
45427
  }
45025
45428
  }
45429
+ var jsonValueSchema2 = lazy(
45430
+ () => union([
45431
+ string(),
45432
+ number$1(),
45433
+ boolean(),
45434
+ _null(),
45435
+ array$1(jsonValueSchema2),
45436
+ record(string(), jsonValueSchema2.optional())
45437
+ ])
45438
+ );
45026
45439
  var openaiResponsesChunkSchema = lazySchema(
45027
45440
  () => zodSchema(
45028
45441
  union([
@@ -45056,6 +45469,23 @@ ${user}:`]
45056
45469
  service_tier: string().nullish()
45057
45470
  })
45058
45471
  }),
45472
+ object$2({
45473
+ type: literal("response.failed"),
45474
+ response: object$2({
45475
+ error: object$2({
45476
+ code: string().nullish(),
45477
+ message: string()
45478
+ }).nullish(),
45479
+ incomplete_details: object$2({ reason: string() }).nullish(),
45480
+ usage: object$2({
45481
+ input_tokens: number$1(),
45482
+ input_tokens_details: object$2({ cached_tokens: number$1().nullish() }).nullish(),
45483
+ output_tokens: number$1(),
45484
+ output_tokens_details: object$2({ reasoning_tokens: number$1().nullish() }).nullish()
45485
+ }).nullish(),
45486
+ service_tier: string().nullish()
45487
+ })
45488
+ }),
45059
45489
  object$2({
45060
45490
  type: literal("response.created"),
45061
45491
  response: object$2({
@@ -45187,6 +45617,22 @@ ${user}:`]
45187
45617
  ])
45188
45618
  })
45189
45619
  )
45620
+ }),
45621
+ object$2({
45622
+ type: literal("tool_search_call"),
45623
+ id: string(),
45624
+ execution: _enum(["server", "client"]),
45625
+ call_id: string().nullable(),
45626
+ status: _enum(["in_progress", "completed", "incomplete"]),
45627
+ arguments: unknown()
45628
+ }),
45629
+ object$2({
45630
+ type: literal("tool_search_output"),
45631
+ id: string(),
45632
+ execution: _enum(["server", "client"]),
45633
+ call_id: string().nullable(),
45634
+ status: _enum(["in_progress", "completed", "incomplete"]),
45635
+ tools: array$1(record(string(), jsonValueSchema2.optional()))
45190
45636
  })
45191
45637
  ])
45192
45638
  }),
@@ -45394,6 +45840,22 @@ ${user}:`]
45394
45840
  ])
45395
45841
  })
45396
45842
  )
45843
+ }),
45844
+ object$2({
45845
+ type: literal("tool_search_call"),
45846
+ id: string(),
45847
+ execution: _enum(["server", "client"]),
45848
+ call_id: string().nullable(),
45849
+ status: _enum(["in_progress", "completed", "incomplete"]),
45850
+ arguments: unknown()
45851
+ }),
45852
+ object$2({
45853
+ type: literal("tool_search_output"),
45854
+ id: string(),
45855
+ execution: _enum(["server", "client"]),
45856
+ call_id: string().nullable(),
45857
+ status: _enum(["in_progress", "completed", "incomplete"]),
45858
+ tools: array$1(record(string(), jsonValueSchema2.optional()))
45397
45859
  })
45398
45860
  ])
45399
45861
  }),
@@ -45775,6 +46237,22 @@ ${user}:`]
45775
46237
  ])
45776
46238
  })
45777
46239
  )
46240
+ }),
46241
+ object$2({
46242
+ type: literal("tool_search_call"),
46243
+ id: string(),
46244
+ execution: _enum(["server", "client"]),
46245
+ call_id: string().nullable(),
46246
+ status: _enum(["in_progress", "completed", "incomplete"]),
46247
+ arguments: unknown()
46248
+ }),
46249
+ object$2({
46250
+ type: literal("tool_search_output"),
46251
+ id: string(),
46252
+ execution: _enum(["server", "client"]),
46253
+ call_id: string().nullable(),
46254
+ status: _enum(["in_progress", "completed", "incomplete"]),
46255
+ tools: array$1(record(string(), jsonValueSchema2.optional()))
45778
46256
  })
45779
46257
  ])
45780
46258
  ).optional(),
@@ -45950,7 +46428,7 @@ ${user}:`]
45950
46428
  toolNameMapping,
45951
46429
  customProviderToolNames
45952
46430
  }) {
45953
- var _a10;
46431
+ var _a10, _b9;
45954
46432
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
45955
46433
  const toolWarnings = [];
45956
46434
  if (tools == null) {
@@ -45960,15 +46438,19 @@ ${user}:`]
45960
46438
  const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
45961
46439
  for (const tool2 of tools) {
45962
46440
  switch (tool2.type) {
45963
- case "function":
46441
+ case "function": {
46442
+ const openaiOptions = (_a10 = tool2.providerOptions) == null ? void 0 : _a10.openai;
46443
+ const deferLoading = openaiOptions == null ? void 0 : openaiOptions.deferLoading;
45964
46444
  openaiTools2.push({
45965
46445
  type: "function",
45966
46446
  name: tool2.name,
45967
46447
  description: tool2.description,
45968
46448
  parameters: tool2.inputSchema,
45969
- ...tool2.strict != null ? { strict: tool2.strict } : {}
46449
+ ...tool2.strict != null ? { strict: tool2.strict } : {},
46450
+ ...deferLoading != null ? { defer_loading: deferLoading } : {}
45970
46451
  });
45971
46452
  break;
46453
+ }
45972
46454
  case "provider": {
45973
46455
  switch (tool2.id) {
45974
46456
  case "openai.file_search": {
@@ -46113,6 +46595,19 @@ ${user}:`]
46113
46595
  resolvedCustomProviderToolNames.add(args.name);
46114
46596
  break;
46115
46597
  }
46598
+ case "openai.tool_search": {
46599
+ const args = await validateTypes$1({
46600
+ value: tool2.args,
46601
+ schema: toolSearchArgsSchema
46602
+ });
46603
+ openaiTools2.push({
46604
+ type: "tool_search",
46605
+ ...args.execution != null ? { execution: args.execution } : {},
46606
+ ...args.description != null ? { description: args.description } : {},
46607
+ ...args.parameters != null ? { parameters: args.parameters } : {}
46608
+ });
46609
+ break;
46610
+ }
46116
46611
  }
46117
46612
  break;
46118
46613
  }
@@ -46134,7 +46629,7 @@ ${user}:`]
46134
46629
  case "required":
46135
46630
  return { tools: openaiTools2, toolChoice: type2, toolWarnings };
46136
46631
  case "tool": {
46137
- const resolvedToolName = (_a10 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _a10 : toolChoice.toolName;
46632
+ const resolvedToolName = (_b9 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _b9 : toolChoice.toolName;
46138
46633
  return {
46139
46634
  tools: openaiTools2,
46140
46635
  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 },
@@ -46288,7 +46783,8 @@ ${user}:`]
46288
46783
  "openai.web_search": "web_search",
46289
46784
  "openai.web_search_preview": "web_search_preview",
46290
46785
  "openai.mcp": "mcp",
46291
- "openai.apply_patch": "apply_patch"
46786
+ "openai.apply_patch": "apply_patch",
46787
+ "openai.tool_search": "tool_search"
46292
46788
  },
46293
46789
  resolveProviderToolName: (tool2) => tool2.id === "openai.custom" ? tool2.args.name : void 0
46294
46790
  });
@@ -46466,7 +46962,7 @@ ${user}:`]
46466
46962
  };
46467
46963
  }
46468
46964
  async doGenerate(options) {
46469
- 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;
46965
+ 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;
46470
46966
  const {
46471
46967
  args: body,
46472
46968
  warnings,
@@ -46509,6 +47005,7 @@ ${user}:`]
46509
47005
  const content = [];
46510
47006
  const logprobs = [];
46511
47007
  let hasFunctionCall = false;
47008
+ const hostedToolSearchCallIds = [];
46512
47009
  for (const part of response.output) {
46513
47010
  switch (part.type) {
46514
47011
  case "reasoning": {
@@ -46547,6 +47044,46 @@ ${user}:`]
46547
47044
  });
46548
47045
  break;
46549
47046
  }
47047
+ case "tool_search_call": {
47048
+ const toolCallId = (_b9 = part.call_id) != null ? _b9 : part.id;
47049
+ const isHosted = part.execution === "server";
47050
+ if (isHosted) {
47051
+ hostedToolSearchCallIds.push(toolCallId);
47052
+ }
47053
+ content.push({
47054
+ type: "tool-call",
47055
+ toolCallId,
47056
+ toolName: toolNameMapping.toCustomToolName("tool_search"),
47057
+ input: JSON.stringify({
47058
+ arguments: part.arguments,
47059
+ call_id: part.call_id
47060
+ }),
47061
+ ...isHosted ? { providerExecuted: true } : {},
47062
+ providerMetadata: {
47063
+ [providerOptionsName]: {
47064
+ itemId: part.id
47065
+ }
47066
+ }
47067
+ });
47068
+ break;
47069
+ }
47070
+ case "tool_search_output": {
47071
+ const toolCallId = (_d = (_c = part.call_id) != null ? _c : hostedToolSearchCallIds.shift()) != null ? _d : part.id;
47072
+ content.push({
47073
+ type: "tool-result",
47074
+ toolCallId,
47075
+ toolName: toolNameMapping.toCustomToolName("tool_search"),
47076
+ result: {
47077
+ tools: part.tools
47078
+ },
47079
+ providerMetadata: {
47080
+ [providerOptionsName]: {
47081
+ itemId: part.id
47082
+ }
47083
+ }
47084
+ });
47085
+ break;
47086
+ }
46550
47087
  case "local_shell_call": {
46551
47088
  content.push({
46552
47089
  type: "tool-call",
@@ -46602,7 +47139,7 @@ ${user}:`]
46602
47139
  }
46603
47140
  case "message": {
46604
47141
  for (const contentPart of part.content) {
46605
- if (((_c = (_b9 = options.providerOptions) == null ? void 0 : _b9[providerOptionsName]) == null ? void 0 : _c.logprobs) && contentPart.logprobs) {
47142
+ if (((_f = (_e = options.providerOptions) == null ? void 0 : _e[providerOptionsName]) == null ? void 0 : _f.logprobs) && contentPart.logprobs) {
46606
47143
  logprobs.push(contentPart.logprobs);
46607
47144
  }
46608
47145
  const providerMetadata2 = {
@@ -46624,7 +47161,7 @@ ${user}:`]
46624
47161
  content.push({
46625
47162
  type: "source",
46626
47163
  sourceType: "url",
46627
- id: (_f = (_e = (_d = this.config).generateId) == null ? void 0 : _e.call(_d)) != null ? _f : generateId$1(),
47164
+ id: (_i = (_h = (_g = this.config).generateId) == null ? void 0 : _h.call(_g)) != null ? _i : generateId$1(),
46628
47165
  url: annotation.url,
46629
47166
  title: annotation.title
46630
47167
  });
@@ -46632,7 +47169,7 @@ ${user}:`]
46632
47169
  content.push({
46633
47170
  type: "source",
46634
47171
  sourceType: "document",
46635
- id: (_i = (_h = (_g = this.config).generateId) == null ? void 0 : _h.call(_g)) != null ? _i : generateId$1(),
47172
+ id: (_l = (_k = (_j = this.config).generateId) == null ? void 0 : _k.call(_j)) != null ? _l : generateId$1(),
46636
47173
  mediaType: "text/plain",
46637
47174
  title: annotation.filename,
46638
47175
  filename: annotation.filename,
@@ -46648,7 +47185,7 @@ ${user}:`]
46648
47185
  content.push({
46649
47186
  type: "source",
46650
47187
  sourceType: "document",
46651
- id: (_l = (_k = (_j = this.config).generateId) == null ? void 0 : _k.call(_j)) != null ? _l : generateId$1(),
47188
+ id: (_o = (_n = (_m = this.config).generateId) == null ? void 0 : _n.call(_m)) != null ? _o : generateId$1(),
46652
47189
  mediaType: "text/plain",
46653
47190
  title: annotation.filename,
46654
47191
  filename: annotation.filename,
@@ -46664,7 +47201,7 @@ ${user}:`]
46664
47201
  content.push({
46665
47202
  type: "source",
46666
47203
  sourceType: "document",
46667
- id: (_o = (_n = (_m = this.config).generateId) == null ? void 0 : _n.call(_m)) != null ? _o : generateId$1(),
47204
+ id: (_r = (_q = (_p = this.config).generateId) == null ? void 0 : _q.call(_p)) != null ? _r : generateId$1(),
46668
47205
  mediaType: "application/octet-stream",
46669
47206
  title: annotation.file_id,
46670
47207
  filename: annotation.file_id,
@@ -46733,7 +47270,7 @@ ${user}:`]
46733
47270
  break;
46734
47271
  }
46735
47272
  case "mcp_call": {
46736
- const toolCallId = part.approval_request_id != null ? (_p = approvalRequestIdToDummyToolCallIdFromPrompt[part.approval_request_id]) != null ? _p : part.id : part.id;
47273
+ const toolCallId = part.approval_request_id != null ? (_s = approvalRequestIdToDummyToolCallIdFromPrompt[part.approval_request_id]) != null ? _s : part.id : part.id;
46737
47274
  const toolName = `mcp.${part.name}`;
46738
47275
  content.push({
46739
47276
  type: "tool-call",
@@ -46767,8 +47304,8 @@ ${user}:`]
46767
47304
  break;
46768
47305
  }
46769
47306
  case "mcp_approval_request": {
46770
- const approvalRequestId = (_q = part.approval_request_id) != null ? _q : part.id;
46771
- const dummyToolCallId = (_t = (_s = (_r = this.config).generateId) == null ? void 0 : _s.call(_r)) != null ? _t : generateId$1();
47307
+ const approvalRequestId = (_t = part.approval_request_id) != null ? _t : part.id;
47308
+ const dummyToolCallId = (_w = (_v = (_u = this.config).generateId) == null ? void 0 : _v.call(_u)) != null ? _w : generateId$1();
46772
47309
  const toolName = `mcp.${part.name}`;
46773
47310
  content.push({
46774
47311
  type: "tool-call",
@@ -46818,13 +47355,13 @@ ${user}:`]
46818
47355
  toolName: toolNameMapping.toCustomToolName("file_search"),
46819
47356
  result: {
46820
47357
  queries: part.queries,
46821
- results: (_v = (_u = part.results) == null ? void 0 : _u.map((result) => ({
47358
+ results: (_y = (_x = part.results) == null ? void 0 : _x.map((result) => ({
46822
47359
  attributes: result.attributes,
46823
47360
  fileId: result.file_id,
46824
47361
  filename: result.filename,
46825
47362
  score: result.score,
46826
47363
  text: result.text
46827
- }))) != null ? _v : null
47364
+ }))) != null ? _y : null
46828
47365
  }
46829
47366
  });
46830
47367
  break;
@@ -46881,10 +47418,10 @@ ${user}:`]
46881
47418
  content,
46882
47419
  finishReason: {
46883
47420
  unified: mapOpenAIResponseFinishReason({
46884
- finishReason: (_w = response.incomplete_details) == null ? void 0 : _w.reason,
47421
+ finishReason: (_z = response.incomplete_details) == null ? void 0 : _z.reason,
46885
47422
  hasFunctionCall
46886
47423
  }),
46887
- raw: (_y = (_x = response.incomplete_details) == null ? void 0 : _x.reason) != null ? _y : void 0
47424
+ raw: (_B = (_A = response.incomplete_details) == null ? void 0 : _A.reason) != null ? _B : void 0
46888
47425
  },
46889
47426
  usage: convertOpenAIResponsesUsage(usage),
46890
47427
  request: { body },
@@ -46942,6 +47479,7 @@ ${user}:`]
46942
47479
  let hasFunctionCall = false;
46943
47480
  const activeReasoning = {};
46944
47481
  let serviceTier;
47482
+ const hostedToolSearchCallIds = [];
46945
47483
  return {
46946
47484
  stream: response.pipeThrough(
46947
47485
  new TransformStream({
@@ -46949,7 +47487,7 @@ ${user}:`]
46949
47487
  controller.enqueue({ type: "stream-start", warnings });
46950
47488
  },
46951
47489
  transform(chunk, controller) {
46952
- 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;
47490
+ 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;
46953
47491
  if (options.includeRawChunks) {
46954
47492
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
46955
47493
  }
@@ -47057,7 +47595,25 @@ ${user}:`]
47057
47595
  input: "{}",
47058
47596
  providerExecuted: true
47059
47597
  });
47060
- } else if (value.item.type === "mcp_call" || value.item.type === "mcp_list_tools" || value.item.type === "mcp_approval_request") ;
47598
+ } else if (value.item.type === "tool_search_call") {
47599
+ const toolCallId = value.item.id;
47600
+ const toolName = toolNameMapping.toCustomToolName("tool_search");
47601
+ const isHosted = value.item.execution === "server";
47602
+ ongoingToolCalls[value.output_index] = {
47603
+ toolName,
47604
+ toolCallId,
47605
+ toolSearchExecution: (_a10 = value.item.execution) != null ? _a10 : "server"
47606
+ };
47607
+ if (isHosted) {
47608
+ controller.enqueue({
47609
+ type: "tool-input-start",
47610
+ id: toolCallId,
47611
+ toolName,
47612
+ providerExecuted: true
47613
+ });
47614
+ }
47615
+ } else if (value.item.type === "tool_search_output") ;
47616
+ else if (value.item.type === "mcp_call" || value.item.type === "mcp_list_tools" || value.item.type === "mcp_approval_request") ;
47061
47617
  else if (value.item.type === "apply_patch_call") {
47062
47618
  const { call_id: callId, operation } = value.item;
47063
47619
  ongoingToolCalls[value.output_index] = {
@@ -47103,7 +47659,7 @@ ${user}:`]
47103
47659
  } else if (value.item.type === "shell_call_output") ;
47104
47660
  else if (value.item.type === "message") {
47105
47661
  ongoingAnnotations.splice(0, ongoingAnnotations.length);
47106
- activeMessagePhase = (_a10 = value.item.phase) != null ? _a10 : void 0;
47662
+ activeMessagePhase = (_b9 = value.item.phase) != null ? _b9 : void 0;
47107
47663
  controller.enqueue({
47108
47664
  type: "text-start",
47109
47665
  id: value.item.id,
@@ -47127,14 +47683,14 @@ ${user}:`]
47127
47683
  providerMetadata: {
47128
47684
  [providerOptionsName]: {
47129
47685
  itemId: value.item.id,
47130
- reasoningEncryptedContent: (_b9 = value.item.encrypted_content) != null ? _b9 : null
47686
+ reasoningEncryptedContent: (_c = value.item.encrypted_content) != null ? _c : null
47131
47687
  }
47132
47688
  }
47133
47689
  });
47134
47690
  }
47135
47691
  } else if (isResponseOutputItemDoneChunk(value)) {
47136
47692
  if (value.item.type === "message") {
47137
- const phase = (_c = value.item.phase) != null ? _c : activeMessagePhase;
47693
+ const phase = (_d = value.item.phase) != null ? _d : activeMessagePhase;
47138
47694
  activeMessagePhase = void 0;
47139
47695
  controller.enqueue({
47140
47696
  type: "text-end",
@@ -47228,13 +47784,13 @@ ${user}:`]
47228
47784
  toolName: toolNameMapping.toCustomToolName("file_search"),
47229
47785
  result: {
47230
47786
  queries: value.item.queries,
47231
- results: (_e = (_d = value.item.results) == null ? void 0 : _d.map((result) => ({
47787
+ results: (_f = (_e = value.item.results) == null ? void 0 : _e.map((result) => ({
47232
47788
  attributes: result.attributes,
47233
47789
  fileId: result.file_id,
47234
47790
  filename: result.filename,
47235
47791
  score: result.score,
47236
47792
  text: result.text
47237
- }))) != null ? _e : null
47793
+ }))) != null ? _f : null
47238
47794
  }
47239
47795
  });
47240
47796
  } else if (value.item.type === "code_interpreter_call") {
@@ -47256,12 +47812,62 @@ ${user}:`]
47256
47812
  result: value.item.result
47257
47813
  }
47258
47814
  });
47815
+ } else if (value.item.type === "tool_search_call") {
47816
+ const toolCall = ongoingToolCalls[value.output_index];
47817
+ const isHosted = value.item.execution === "server";
47818
+ if (toolCall != null) {
47819
+ const toolCallId = isHosted ? toolCall.toolCallId : (_g = value.item.call_id) != null ? _g : value.item.id;
47820
+ if (isHosted) {
47821
+ hostedToolSearchCallIds.push(toolCallId);
47822
+ } else {
47823
+ controller.enqueue({
47824
+ type: "tool-input-start",
47825
+ id: toolCallId,
47826
+ toolName: toolCall.toolName
47827
+ });
47828
+ }
47829
+ controller.enqueue({
47830
+ type: "tool-input-end",
47831
+ id: toolCallId
47832
+ });
47833
+ controller.enqueue({
47834
+ type: "tool-call",
47835
+ toolCallId,
47836
+ toolName: toolCall.toolName,
47837
+ input: JSON.stringify({
47838
+ arguments: value.item.arguments,
47839
+ call_id: isHosted ? null : toolCallId
47840
+ }),
47841
+ ...isHosted ? { providerExecuted: true } : {},
47842
+ providerMetadata: {
47843
+ [providerOptionsName]: {
47844
+ itemId: value.item.id
47845
+ }
47846
+ }
47847
+ });
47848
+ }
47849
+ ongoingToolCalls[value.output_index] = void 0;
47850
+ } else if (value.item.type === "tool_search_output") {
47851
+ const toolCallId = (_i = (_h = value.item.call_id) != null ? _h : hostedToolSearchCallIds.shift()) != null ? _i : value.item.id;
47852
+ controller.enqueue({
47853
+ type: "tool-result",
47854
+ toolCallId,
47855
+ toolName: toolNameMapping.toCustomToolName("tool_search"),
47856
+ result: {
47857
+ tools: value.item.tools
47858
+ },
47859
+ providerMetadata: {
47860
+ [providerOptionsName]: {
47861
+ itemId: value.item.id
47862
+ }
47863
+ }
47864
+ });
47259
47865
  } else if (value.item.type === "mcp_call") {
47260
47866
  ongoingToolCalls[value.output_index] = void 0;
47261
- const approvalRequestId = (_f = value.item.approval_request_id) != null ? _f : void 0;
47262
- const aliasedToolCallId = approvalRequestId != null ? (_h = (_g = approvalRequestIdToDummyToolCallIdFromStream.get(
47867
+ const approvalRequestId = (_j = value.item.approval_request_id) != null ? _j : void 0;
47868
+ const aliasedToolCallId = approvalRequestId != null ? (_l = (_k = approvalRequestIdToDummyToolCallIdFromStream.get(
47263
47869
  approvalRequestId
47264
- )) != null ? _g : approvalRequestIdToDummyToolCallIdFromPrompt[approvalRequestId]) != null ? _h : value.item.id : value.item.id;
47870
+ )) != null ? _k : approvalRequestIdToDummyToolCallIdFromPrompt[approvalRequestId]) != null ? _l : value.item.id : value.item.id;
47265
47871
  const toolName = `mcp.${value.item.name}`;
47266
47872
  controller.enqueue({
47267
47873
  type: "tool-call",
@@ -47331,8 +47937,8 @@ ${user}:`]
47331
47937
  ongoingToolCalls[value.output_index] = void 0;
47332
47938
  } else if (value.item.type === "mcp_approval_request") {
47333
47939
  ongoingToolCalls[value.output_index] = void 0;
47334
- const dummyToolCallId = (_k = (_j = (_i = self2.config).generateId) == null ? void 0 : _j.call(_i)) != null ? _k : generateId$1();
47335
- const approvalRequestId = (_l = value.item.approval_request_id) != null ? _l : value.item.id;
47940
+ const dummyToolCallId = (_o = (_n = (_m = self2.config).generateId) == null ? void 0 : _n.call(_m)) != null ? _o : generateId$1();
47941
+ const approvalRequestId = (_p = value.item.approval_request_id) != null ? _p : value.item.id;
47336
47942
  approvalRequestIdToDummyToolCallIdFromStream.set(
47337
47943
  approvalRequestId,
47338
47944
  dummyToolCallId
@@ -47421,7 +48027,7 @@ ${user}:`]
47421
48027
  providerMetadata: {
47422
48028
  [providerOptionsName]: {
47423
48029
  itemId: value.item.id,
47424
- reasoningEncryptedContent: (_m = value.item.encrypted_content) != null ? _m : null
48030
+ reasoningEncryptedContent: (_q = value.item.encrypted_content) != null ? _q : null
47425
48031
  }
47426
48032
  }
47427
48033
  });
@@ -47534,7 +48140,7 @@ ${user}:`]
47534
48140
  id: value.item_id,
47535
48141
  delta: value.delta
47536
48142
  });
47537
- if (((_o = (_n = options.providerOptions) == null ? void 0 : _n[providerOptionsName]) == null ? void 0 : _o.logprobs) && value.logprobs) {
48143
+ if (((_s = (_r = options.providerOptions) == null ? void 0 : _r[providerOptionsName]) == null ? void 0 : _s.logprobs) && value.logprobs) {
47538
48144
  logprobs.push(value.logprobs);
47539
48145
  }
47540
48146
  } else if (value.type === "response.reasoning_summary_part.added") {
@@ -47563,7 +48169,7 @@ ${user}:`]
47563
48169
  providerMetadata: {
47564
48170
  [providerOptionsName]: {
47565
48171
  itemId: value.item_id,
47566
- reasoningEncryptedContent: (_q = (_p = activeReasoning[value.item_id]) == null ? void 0 : _p.encryptedContent) != null ? _q : null
48172
+ reasoningEncryptedContent: (_u = (_t = activeReasoning[value.item_id]) == null ? void 0 : _t.encryptedContent) != null ? _u : null
47567
48173
  }
47568
48174
  }
47569
48175
  });
@@ -47597,22 +48203,32 @@ ${user}:`]
47597
48203
  } else if (isResponseFinishedChunk(value)) {
47598
48204
  finishReason = {
47599
48205
  unified: mapOpenAIResponseFinishReason({
47600
- finishReason: (_r = value.response.incomplete_details) == null ? void 0 : _r.reason,
48206
+ finishReason: (_v = value.response.incomplete_details) == null ? void 0 : _v.reason,
47601
48207
  hasFunctionCall
47602
48208
  }),
47603
- raw: (_t = (_s = value.response.incomplete_details) == null ? void 0 : _s.reason) != null ? _t : void 0
48209
+ raw: (_x = (_w = value.response.incomplete_details) == null ? void 0 : _w.reason) != null ? _x : void 0
47604
48210
  };
47605
48211
  usage = value.response.usage;
47606
48212
  if (typeof value.response.service_tier === "string") {
47607
48213
  serviceTier = value.response.service_tier;
47608
48214
  }
48215
+ } else if (isResponseFailedChunk(value)) {
48216
+ const incompleteReason = (_y = value.response.incomplete_details) == null ? void 0 : _y.reason;
48217
+ finishReason = {
48218
+ unified: incompleteReason ? mapOpenAIResponseFinishReason({
48219
+ finishReason: incompleteReason,
48220
+ hasFunctionCall
48221
+ }) : "error",
48222
+ raw: incompleteReason != null ? incompleteReason : "error"
48223
+ };
48224
+ usage = (_z = value.response.usage) != null ? _z : void 0;
47609
48225
  } else if (isResponseAnnotationAddedChunk(value)) {
47610
48226
  ongoingAnnotations.push(value.annotation);
47611
48227
  if (value.annotation.type === "url_citation") {
47612
48228
  controller.enqueue({
47613
48229
  type: "source",
47614
48230
  sourceType: "url",
47615
- id: (_w = (_v = (_u = self2.config).generateId) == null ? void 0 : _v.call(_u)) != null ? _w : generateId$1(),
48231
+ id: (_C = (_B = (_A = self2.config).generateId) == null ? void 0 : _B.call(_A)) != null ? _C : generateId$1(),
47616
48232
  url: value.annotation.url,
47617
48233
  title: value.annotation.title
47618
48234
  });
@@ -47620,7 +48236,7 @@ ${user}:`]
47620
48236
  controller.enqueue({
47621
48237
  type: "source",
47622
48238
  sourceType: "document",
47623
- id: (_z = (_y = (_x = self2.config).generateId) == null ? void 0 : _y.call(_x)) != null ? _z : generateId$1(),
48239
+ id: (_F = (_E = (_D = self2.config).generateId) == null ? void 0 : _E.call(_D)) != null ? _F : generateId$1(),
47624
48240
  mediaType: "text/plain",
47625
48241
  title: value.annotation.filename,
47626
48242
  filename: value.annotation.filename,
@@ -47636,7 +48252,7 @@ ${user}:`]
47636
48252
  controller.enqueue({
47637
48253
  type: "source",
47638
48254
  sourceType: "document",
47639
- id: (_C = (_B = (_A = self2.config).generateId) == null ? void 0 : _B.call(_A)) != null ? _C : generateId$1(),
48255
+ id: (_I = (_H = (_G = self2.config).generateId) == null ? void 0 : _H.call(_G)) != null ? _I : generateId$1(),
47640
48256
  mediaType: "text/plain",
47641
48257
  title: value.annotation.filename,
47642
48258
  filename: value.annotation.filename,
@@ -47652,7 +48268,7 @@ ${user}:`]
47652
48268
  controller.enqueue({
47653
48269
  type: "source",
47654
48270
  sourceType: "document",
47655
- id: (_F = (_E = (_D = self2.config).generateId) == null ? void 0 : _E.call(_D)) != null ? _F : generateId$1(),
48271
+ id: (_L = (_K = (_J = self2.config).generateId) == null ? void 0 : _K.call(_J)) != null ? _L : generateId$1(),
47656
48272
  mediaType: "application/octet-stream",
47657
48273
  title: value.annotation.file_id,
47658
48274
  filename: value.annotation.file_id,
@@ -47700,6 +48316,9 @@ ${user}:`]
47700
48316
  function isResponseFinishedChunk(chunk) {
47701
48317
  return chunk.type === "response.completed" || chunk.type === "response.incomplete";
47702
48318
  }
48319
+ function isResponseFailedChunk(chunk) {
48320
+ return chunk.type === "response.failed";
48321
+ }
47703
48322
  function isResponseCreatedChunk(chunk) {
47704
48323
  return chunk.type === "response.created";
47705
48324
  }
@@ -48090,7 +48709,7 @@ ${user}:`]
48090
48709
  };
48091
48710
  }
48092
48711
  };
48093
- var VERSION$2 = "3.0.41";
48712
+ var VERSION$2 = "3.0.48";
48094
48713
  function createOpenAI(options = {}) {
48095
48714
  var _a10, _b9;
48096
48715
  const baseURL = (_a10 = withoutTrailingSlash$1(
@@ -50022,7 +50641,13 @@ Thought: 用户想要获取今天的日期,我需要调用日期相关的工
50022
50641
  try {
50023
50642
  let transport;
50024
50643
  if ("type" in serverConfig && serverConfig.type.toLocaleLowerCase() === "streamablehttp") {
50025
- transport = new StreamableHTTPClientTransport(new URL(serverConfig.url));
50644
+ const configWithHeaders = serverConfig;
50645
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
50646
+ transport = new StreamableHTTPClientTransport(new URL(configWithHeaders.url), { requestInit });
50647
+ } else if ("type" in serverConfig && serverConfig.type === "sse") {
50648
+ const configWithHeaders = serverConfig;
50649
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
50650
+ transport = new SSEClientTransport(new URL(configWithHeaders.url), { requestInit });
50026
50651
  } else if ("type" in serverConfig && serverConfig.type === "extension") {
50027
50652
  transport = new ExtensionClientTransport(serverConfig.sessionId);
50028
50653
  } else if ("transport" in serverConfig) {
@@ -50134,6 +50759,11 @@ Thought: 用户想要获取今天的日期,我需要调用日期相关的工
50134
50759
  await this._createMpcTools();
50135
50760
  this.onUpdatedTools?.();
50136
50761
  }
50762
+ /** 仅刷新已连接 clients 的 tools(不重建 client,适合工具目录动态变化场景) */
50763
+ async refreshTools() {
50764
+ await this._createMpcTools();
50765
+ this.onUpdatedTools?.();
50766
+ }
50137
50767
  /** 全量更新所有的 mcpServers */
50138
50768
  async updateMcpServers(mcpServers) {
50139
50769
  await this.closeAll();
@@ -50539,13 +51169,37 @@ ${observationText}
50539
51169
  throw new Error("LLM is not initialized");
50540
51170
  }
50541
51171
  await this.initClientsAndTools();
50542
- const allTools = this._tempMergeTools(options.tools, false);
51172
+ const extraTools = options.tools || {};
51173
+ const allTools = this._tempMergeTools(extraTools, false);
51174
+ const syncToolsForStep = () => {
51175
+ const latestTools = this._tempMergeTools(extraTools, false);
51176
+ Object.entries(latestTools).forEach(([name16, tool2]) => {
51177
+ allTools[name16] = tool2;
51178
+ });
51179
+ Object.keys(allTools).forEach((name16) => {
51180
+ if (!(name16 in latestTools)) {
51181
+ delete allTools[name16];
51182
+ }
51183
+ });
51184
+ };
51185
+ const userPrepareStep = options.prepareStep;
51186
+ const wrappedPrepareStep = async (stepOptions) => {
51187
+ syncToolsForStep();
51188
+ const latestActiveTools = this._getActiveToolNames(allTools);
51189
+ const userStepPatch = typeof userPrepareStep === "function" ? await userPrepareStep(stepOptions) : void 0;
51190
+ const safeUserStepPatch = userStepPatch && typeof userStepPatch === "object" ? userStepPatch : {};
51191
+ return {
51192
+ ...safeUserStepPatch,
51193
+ activeTools: Array.isArray(safeUserStepPatch.activeTools) ? safeUserStepPatch.activeTools.filter((name16) => latestActiveTools.includes(name16)) : latestActiveTools
51194
+ };
51195
+ };
50543
51196
  const chatOptions = {
50544
51197
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
50545
51198
  model: this.llm(model),
50546
51199
  stopWhen: stepCountIs(maxSteps),
50547
51200
  ...options,
50548
51201
  tools: allTools,
51202
+ prepareStep: wrappedPrepareStep,
50549
51203
  activeTools: this._getActiveToolNames(allTools)
50550
51204
  };
50551
51205
  let lastUserMessage = null;
@@ -50858,6 +51512,7 @@ ${observationText}
50858
51512
  const MSG_PAGE_LEAVE = "next-sdk:page-leave";
50859
51513
  const MSG_REMOTER_READY = "next-sdk:remoter-ready";
50860
51514
  const MSG_ROUTE_STATE_INITIAL = "next-sdk:route-state-initial";
51515
+ const MSG_TOOL_CATALOG_CHANGED = "next-sdk:tool-catalog-changed";
50861
51516
  const activePages = /* @__PURE__ */ new Map();
50862
51517
  const normalizeRoute = (value) => value.replace(/\/+$/, "") || "/";
50863
51518
  const broadcastTargets = /* @__PURE__ */ new Set();
@@ -50867,8 +51522,8 @@ ${observationText}
50867
51522
  }
50868
51523
  }
50869
51524
  initBroadcastTargets();
50870
- function broadcastRouteChange(type2, route) {
50871
- const msg = { type: type2, route };
51525
+ function broadcastRouteChange(type2, route, extra = {}) {
51526
+ const msg = { type: type2, route, ...extra };
50872
51527
  broadcastTargets.forEach(({ win, origin }) => {
50873
51528
  try {
50874
51529
  win.postMessage(msg, origin);
@@ -50883,30 +51538,413 @@ ${observationText}
50883
51538
  if (event.origin !== window.location.origin) return;
50884
51539
  const target = event.source;
50885
51540
  broadcastTargets.add({ win: target, origin: event.origin || "*" });
50886
- const payload = {
50887
- type: MSG_ROUTE_STATE_INITIAL,
50888
- toolRouteMap: Array.from(toolRouteMap.entries()),
50889
- activeRoutes: Array.from(activePages.keys())
50890
- };
51541
+ });
51542
+ }
51543
+ setupIframeRemoterBridge();
51544
+ const runtimeRegisteredTools = /* @__PURE__ */ new Map();
51545
+ function broadcastToolCatalogChanged() {
51546
+ if (typeof window === "undefined") return;
51547
+ const payload = {
51548
+ type: MSG_TOOL_CATALOG_CHANGED
51549
+ };
51550
+ broadcastTargets.forEach(({ win, origin }) => {
50891
51551
  try {
50892
- target.postMessage(payload, event.origin || "*");
51552
+ win.postMessage(payload, origin);
50893
51553
  } catch {
50894
51554
  }
50895
51555
  });
50896
51556
  }
50897
- setupIframeRemoterBridge();
50898
- const toolRouteMap = /* @__PURE__ */ new Map();
51557
+ function notifyServerToolListChanged(server) {
51558
+ const maybeServer = server;
51559
+ try {
51560
+ maybeServer.sendToolListChanged?.();
51561
+ } catch {
51562
+ }
51563
+ }
50899
51564
  function getToolRouteMap() {
50900
- return new Map(toolRouteMap);
51565
+ return /* @__PURE__ */ new Map();
50901
51566
  }
50902
51567
  function getActiveRoutes() {
50903
51568
  return new Set(activePages.keys());
50904
51569
  }
51570
+ function getActivePageTools() {
51571
+ const snapshot = /* @__PURE__ */ new Map();
51572
+ activePages.forEach((toolNames, route) => {
51573
+ snapshot.set(route, Array.from(toolNames));
51574
+ });
51575
+ return snapshot;
51576
+ }
51577
+ function isToolReadyOnRoute(route, toolName) {
51578
+ const toolNames = activePages.get(route);
51579
+ return !!toolNames && toolNames.has(toolName);
51580
+ }
51581
+ const nativeRegisteredTools = /* @__PURE__ */ new Set();
51582
+ const nativeToolDisposers = /* @__PURE__ */ new Map();
51583
+ const nativeRegisteredToolDefs = /* @__PURE__ */ new Map();
51584
+ const nativeRegisterTasks = /* @__PURE__ */ new Map();
51585
+ const BUILTIN_REMOVE_PATCH_SYMBOL = Symbol("builtin-remove-patched");
51586
+ function attachBuiltinUnregisterOnRemove(name16, tool2) {
51587
+ const mutableTool = tool2;
51588
+ if (mutableTool[BUILTIN_REMOVE_PATCH_SYMBOL]) return tool2;
51589
+ if (typeof mutableTool.remove !== "function") return tool2;
51590
+ const originalRemove = mutableTool.remove.bind(mutableTool);
51591
+ mutableTool.remove = () => {
51592
+ try {
51593
+ originalRemove();
51594
+ } finally {
51595
+ void unregisterBuiltinWebMcpTool(name16);
51596
+ }
51597
+ };
51598
+ mutableTool[BUILTIN_REMOVE_PATCH_SYMBOL] = true;
51599
+ return mutableTool;
51600
+ }
51601
+ function getBuiltinModelContext() {
51602
+ if (typeof navigator === "undefined") return null;
51603
+ const nav = navigator;
51604
+ if (!nav.modelContext?.registerTool) return null;
51605
+ return nav.modelContext;
51606
+ }
51607
+ function getBuiltinModelContextTesting() {
51608
+ if (typeof navigator === "undefined") return null;
51609
+ const nav = navigator;
51610
+ return nav.modelContextTesting ?? null;
51611
+ }
51612
+ function isWebMcpDebugEnabled() {
51613
+ if (typeof window === "undefined") return false;
51614
+ const w = window;
51615
+ if (w.__NEXT_SDK_WEBMCP_DEBUG__ === true) return true;
51616
+ try {
51617
+ return window.localStorage?.getItem("next-sdk:webmcp-debug") === "1";
51618
+ } catch {
51619
+ return false;
51620
+ }
51621
+ }
51622
+ function debugWebMcpLog(event, payload = {}) {
51623
+ if (!isWebMcpDebugEnabled()) return;
51624
+ try {
51625
+ console.info("[next-sdk/webmcp]", event, payload);
51626
+ } catch {
51627
+ }
51628
+ }
51629
+ async function debugBuiltinToolSnapshot(event) {
51630
+ if (!isWebMcpDebugEnabled()) return;
51631
+ const testingApi = getBuiltinModelContextTesting();
51632
+ if (!testingApi) {
51633
+ debugWebMcpLog(`${event}:snapshot`, { available: false });
51634
+ return;
51635
+ }
51636
+ try {
51637
+ const list = testingApi.listTools ?? testingApi.getTools;
51638
+ if (!list) {
51639
+ debugWebMcpLog(`${event}:snapshot`, { available: false, reason: "no-list-method" });
51640
+ return;
51641
+ }
51642
+ const result = await list();
51643
+ const tools = Array.isArray(result) ? result : [];
51644
+ const names2 = tools.map((item) => {
51645
+ if (!item || typeof item !== "object") return "";
51646
+ return String(item.name ?? "");
51647
+ }).filter(Boolean);
51648
+ debugWebMcpLog(`${event}:snapshot`, { count: names2.length, names: names2 });
51649
+ } catch (error) {
51650
+ debugWebMcpLog(`${event}:snapshot-error`, { error: error instanceof Error ? error.message : String(error) });
51651
+ }
51652
+ }
51653
+ function tryDirectBuiltinUnregisterByName(name16) {
51654
+ const modelContext = getBuiltinModelContext();
51655
+ if (!modelContext?.unregisterTool) {
51656
+ debugWebMcpLog("direct-unregister-skip", { name: name16, reason: "missing-unregister" });
51657
+ return;
51658
+ }
51659
+ debugWebMcpLog("direct-unregister-start", { name: name16 });
51660
+ try {
51661
+ const result = modelContext.unregisterTool.call(modelContext, name16);
51662
+ if (result && typeof result === "object" && "then" in result) {
51663
+ void result.then(() => {
51664
+ debugWebMcpLog("direct-unregister-done", { name: name16, async: true });
51665
+ void debugBuiltinToolSnapshot(`direct-unregister-done:${name16}`);
51666
+ }).catch((error) => {
51667
+ debugWebMcpLog("direct-unregister-error", { name: name16, async: true, error: error instanceof Error ? error.message : String(error) });
51668
+ });
51669
+ return;
51670
+ }
51671
+ debugWebMcpLog("direct-unregister-done", { name: name16, async: false });
51672
+ void debugBuiltinToolSnapshot(`direct-unregister-done:${name16}`);
51673
+ } catch {
51674
+ debugWebMcpLog("direct-unregister-error", { name: name16, async: false });
51675
+ }
51676
+ }
51677
+ function resolveBuiltinToolDisposer(result) {
51678
+ if (typeof result === "function") {
51679
+ return result;
51680
+ }
51681
+ if (!result || typeof result !== "object") {
51682
+ return null;
51683
+ }
51684
+ const value = result;
51685
+ if (typeof value.unregister === "function") return value.unregister.bind(value);
51686
+ if (typeof value.remove === "function") return value.remove.bind(value);
51687
+ if (typeof value.dispose === "function") return value.dispose.bind(value);
51688
+ if (typeof value.close === "function") return value.close.bind(value);
51689
+ return null;
51690
+ }
51691
+ function isBuiltinWebMcpSupported() {
51692
+ return !!getBuiltinModelContext();
51693
+ }
51694
+ function getSchemaTypeName(schema) {
51695
+ return schema._def?.typeName;
51696
+ }
51697
+ function getSchemaDescription(schema) {
51698
+ return schema.description;
51699
+ }
51700
+ function withSchemaDescription(schema, base) {
51701
+ const description2 = getSchemaDescription(schema);
51702
+ return description2 ? { ...base, description: description2 } : base;
51703
+ }
51704
+ function isOptionalSchema(schema) {
51705
+ const typeName = getSchemaTypeName(schema);
51706
+ if (typeName === ZodFirstPartyTypeKind.ZodOptional || typeName === ZodFirstPartyTypeKind.ZodDefault) {
51707
+ return true;
51708
+ }
51709
+ if (typeName === ZodFirstPartyTypeKind.ZodEffects) {
51710
+ const inner = schema._def.schema;
51711
+ return isOptionalSchema(inner);
51712
+ }
51713
+ return false;
51714
+ }
51715
+ function toPrimitiveJsonType(value) {
51716
+ if (typeof value === "string") return "string";
51717
+ if (typeof value === "number") return "number";
51718
+ if (typeof value === "boolean") return "boolean";
51719
+ if (value === null) return "null";
51720
+ return void 0;
51721
+ }
51722
+ function zodTypeToJsonSchema(schema) {
51723
+ const typeName = getSchemaTypeName(schema);
51724
+ switch (typeName) {
51725
+ case ZodFirstPartyTypeKind.ZodString:
51726
+ return withSchemaDescription(schema, { type: "string" });
51727
+ case ZodFirstPartyTypeKind.ZodNumber:
51728
+ return withSchemaDescription(schema, { type: "number" });
51729
+ case ZodFirstPartyTypeKind.ZodBoolean:
51730
+ return withSchemaDescription(schema, { type: "boolean" });
51731
+ case ZodFirstPartyTypeKind.ZodArray: {
51732
+ const itemSchema = schema._def.type;
51733
+ return withSchemaDescription(schema, { type: "array", items: zodTypeToJsonSchema(itemSchema) });
51734
+ }
51735
+ case ZodFirstPartyTypeKind.ZodEnum: {
51736
+ const values = schema.options ?? [];
51737
+ return withSchemaDescription(schema, { type: "string", enum: values });
51738
+ }
51739
+ case ZodFirstPartyTypeKind.ZodNativeEnum: {
51740
+ const rawValues = Object.values(schema._def.values);
51741
+ const enumValues = rawValues.filter(
51742
+ (value) => typeof value === "string" || typeof value === "number"
51743
+ );
51744
+ return withSchemaDescription(schema, { enum: enumValues });
51745
+ }
51746
+ case ZodFirstPartyTypeKind.ZodLiteral: {
51747
+ const literalValue = schema._def.value;
51748
+ const primitiveType = toPrimitiveJsonType(literalValue);
51749
+ return withSchemaDescription(schema, {
51750
+ ...primitiveType ? { type: primitiveType } : {},
51751
+ const: literalValue ?? null
51752
+ });
51753
+ }
51754
+ case ZodFirstPartyTypeKind.ZodUnion: {
51755
+ const options = schema._def.options ?? [];
51756
+ return withSchemaDescription(schema, { anyOf: options.map((item) => zodTypeToJsonSchema(item)) });
51757
+ }
51758
+ case ZodFirstPartyTypeKind.ZodNullable: {
51759
+ const inner = schema._def.innerType;
51760
+ return withSchemaDescription(schema, { anyOf: [zodTypeToJsonSchema(inner), { type: "null" }] });
51761
+ }
51762
+ case ZodFirstPartyTypeKind.ZodObject: {
51763
+ const schemaDef = schema;
51764
+ const shape = schemaDef.shape ?? (typeof schemaDef._def?.shape === "function" ? schemaDef._def.shape() : schemaDef._def?.shape) ?? {};
51765
+ return withSchemaDescription(schema, zodShapeToJsonSchema(shape));
51766
+ }
51767
+ case ZodFirstPartyTypeKind.ZodEffects: {
51768
+ const inner = schema._def.schema;
51769
+ return withSchemaDescription(schema, zodTypeToJsonSchema(inner));
51770
+ }
51771
+ case ZodFirstPartyTypeKind.ZodOptional:
51772
+ case ZodFirstPartyTypeKind.ZodDefault: {
51773
+ const inner = schema._def.innerType;
51774
+ return withSchemaDescription(schema, zodTypeToJsonSchema(inner));
51775
+ }
51776
+ default:
51777
+ return withSchemaDescription(schema, {});
51778
+ }
51779
+ }
51780
+ function zodShapeToJsonSchema(shape = {}) {
51781
+ const properties2 = {};
51782
+ const required2 = [];
51783
+ Object.entries(shape).forEach(([key, schema]) => {
51784
+ properties2[key] = zodTypeToJsonSchema(schema);
51785
+ if (!isOptionalSchema(schema)) {
51786
+ required2.push(key);
51787
+ }
51788
+ });
51789
+ return {
51790
+ type: "object",
51791
+ properties: properties2,
51792
+ ...required2.length ? { required: required2 } : {},
51793
+ additionalProperties: false
51794
+ };
51795
+ }
51796
+ async function registerBuiltinWebMcpTool(options) {
51797
+ const modelContext = getBuiltinModelContext();
51798
+ if (!modelContext) {
51799
+ debugWebMcpLog("register-builtin-skip", { name: options.name, reason: "unsupported" });
51800
+ return false;
51801
+ }
51802
+ if (nativeRegisteredTools.has(options.name)) {
51803
+ debugWebMcpLog("register-builtin-skip", { name: options.name, reason: "already-registered" });
51804
+ return true;
51805
+ }
51806
+ const cleanupLocalRegisterState = () => {
51807
+ nativeToolDisposers.delete(options.name);
51808
+ nativeRegisteredToolDefs.delete(options.name);
51809
+ nativeRegisteredTools.delete(options.name);
51810
+ };
51811
+ debugWebMcpLog("register-builtin-start", { name: options.name });
51812
+ const task = (async () => {
51813
+ const toolDefinition = {
51814
+ name: options.name,
51815
+ description: options.description,
51816
+ inputSchema: zodShapeToJsonSchema(options.inputSchema ?? {}),
51817
+ execute: options.execute
51818
+ };
51819
+ const result = await modelContext.registerTool(toolDefinition);
51820
+ const disposer = resolveBuiltinToolDisposer(result);
51821
+ if (disposer) {
51822
+ nativeToolDisposers.set(options.name, disposer);
51823
+ }
51824
+ nativeRegisteredToolDefs.set(options.name, toolDefinition);
51825
+ nativeRegisteredTools.add(options.name);
51826
+ debugWebMcpLog("register-builtin-success", { name: options.name, hasDisposer: !!disposer });
51827
+ void debugBuiltinToolSnapshot(`register-success:${options.name}`);
51828
+ })();
51829
+ nativeRegisterTasks.set(options.name, task);
51830
+ try {
51831
+ await task;
51832
+ return true;
51833
+ } catch (error) {
51834
+ cleanupLocalRegisterState();
51835
+ debugWebMcpLog("register-builtin-error", {
51836
+ name: options.name,
51837
+ error: error instanceof Error ? error.message : String(error)
51838
+ });
51839
+ return false;
51840
+ } finally {
51841
+ nativeRegisterTasks.delete(options.name);
51842
+ }
51843
+ }
51844
+ async function unregisterBuiltinWebMcpTool(name16) {
51845
+ debugWebMcpLog("unregister-builtin-start", { name: name16 });
51846
+ const cleanup = () => {
51847
+ nativeToolDisposers.delete(name16);
51848
+ nativeRegisteredToolDefs.delete(name16);
51849
+ nativeRegisteredTools.delete(name16);
51850
+ };
51851
+ const pendingRegister = nativeRegisterTasks.get(name16);
51852
+ if (pendingRegister) {
51853
+ try {
51854
+ await pendingRegister;
51855
+ } catch {
51856
+ }
51857
+ }
51858
+ const disposer = nativeToolDisposers.get(name16);
51859
+ if (disposer) {
51860
+ try {
51861
+ await disposer();
51862
+ cleanup();
51863
+ debugWebMcpLog("unregister-builtin-success", { name: name16, method: "disposer" });
51864
+ void debugBuiltinToolSnapshot(`unregister-success:${name16}`);
51865
+ return true;
51866
+ } catch (error) {
51867
+ debugWebMcpLog("unregister-builtin-disposer-error", {
51868
+ name: name16,
51869
+ error: error instanceof Error ? error.message : String(error)
51870
+ });
51871
+ }
51872
+ }
51873
+ const modelContext = getBuiltinModelContext();
51874
+ if (!modelContext) {
51875
+ cleanup();
51876
+ debugWebMcpLog("unregister-builtin-skip", { name: name16, reason: "unsupported" });
51877
+ return false;
51878
+ }
51879
+ if (!modelContext.unregisterTool) {
51880
+ cleanup();
51881
+ debugWebMcpLog("unregister-builtin-skip", { name: name16, reason: "missing-unregister" });
51882
+ return false;
51883
+ }
51884
+ const definition = nativeRegisteredToolDefs.get(name16);
51885
+ const candidates = [name16, { name: name16 }, { toolName: name16 }, { tool: { name: name16 } }, definition].filter(Boolean);
51886
+ for (const candidate of candidates) {
51887
+ try {
51888
+ debugWebMcpLog("unregister-builtin-try", { name: name16, candidate });
51889
+ const result = await modelContext.unregisterTool.call(modelContext, candidate);
51890
+ if (result === false) continue;
51891
+ cleanup();
51892
+ debugWebMcpLog("unregister-builtin-success", { name: name16, method: "unregisterTool", candidate });
51893
+ void debugBuiltinToolSnapshot(`unregister-success:${name16}`);
51894
+ return true;
51895
+ } catch (error) {
51896
+ debugWebMcpLog("unregister-builtin-try-error", {
51897
+ name: name16,
51898
+ candidate,
51899
+ error: error instanceof Error ? error.message : String(error)
51900
+ });
51901
+ }
51902
+ }
51903
+ cleanup();
51904
+ debugWebMcpLog("unregister-builtin-failed", { name: name16 });
51905
+ void debugBuiltinToolSnapshot(`unregister-failed:${name16}`);
51906
+ return false;
51907
+ }
51908
+ function hasBuiltinWebMcpTool(name16) {
51909
+ return nativeRegisteredTools.has(name16);
51910
+ }
51911
+ async function forceResetBuiltinWebMcpTools() {
51912
+ const names2 = Array.from(nativeRegisteredTools);
51913
+ for (const name16 of names2) {
51914
+ try {
51915
+ await unregisterBuiltinWebMcpTool(name16);
51916
+ } catch {
51917
+ }
51918
+ }
51919
+ }
51920
+ async function listBuiltinWebMcpTools() {
51921
+ const testingApi = getBuiltinModelContextTesting();
51922
+ if (!testingApi?.listTools) return [];
51923
+ try {
51924
+ const result = await testingApi.listTools();
51925
+ return Array.isArray(result) ? result : [];
51926
+ } catch {
51927
+ return [];
51928
+ }
51929
+ }
51930
+ async function executeBuiltinWebMcpTool(name16, input) {
51931
+ const testingApi = getBuiltinModelContextTesting();
51932
+ if (!testingApi?.executeTool) {
51933
+ throw new Error("当前浏览器不支持 navigator.modelContextTesting.executeTool。");
51934
+ }
51935
+ return await testingApi.executeTool(name16, JSON.stringify(input ?? {}));
51936
+ }
50905
51937
  let _navigator = null;
50906
51938
  function setNavigator(fn) {
50907
51939
  _navigator = fn;
50908
51940
  }
50909
- function waitForPageReady(path, timeoutMs = 1500) {
51941
+ function isCurrentPathMatched(path) {
51942
+ if (typeof window === "undefined") return false;
51943
+ const target = normalizeRoute(path);
51944
+ const current = normalizeRoute(window.location.pathname);
51945
+ return current === target || current.endsWith(target) && (current.length === target.length || current[current.lastIndexOf(target) - 1] === "/");
51946
+ }
51947
+ function waitForNavigationReady(path, timeoutMs = 1500) {
50910
51948
  if (typeof window === "undefined") {
50911
51949
  return Promise.resolve();
50912
51950
  }
@@ -50920,9 +51958,15 @@ ${observationText}
50920
51958
  resolve2();
50921
51959
  };
50922
51960
  const handleMessage = (event) => {
50923
- if (event.source !== window || event.data?.type !== MSG_PAGE_READY) return;
50924
- const route = normalizeRoute(String(event.data.route ?? ""));
50925
- if (route === target) {
51961
+ if (event.source !== window) return;
51962
+ if (event.data?.type === MSG_PAGE_READY) {
51963
+ const route = normalizeRoute(String(event.data.route ?? ""));
51964
+ if (route === target) {
51965
+ cleanup();
51966
+ }
51967
+ return;
51968
+ }
51969
+ if (event.data?.type === MSG_TOOL_CATALOG_CHANGED && isCurrentPathMatched(target)) {
50926
51970
  cleanup();
50927
51971
  }
50928
51972
  };
@@ -50930,63 +51974,144 @@ ${observationText}
50930
51974
  setTimeout(cleanup, timeoutMs);
50931
51975
  });
50932
51976
  }
51977
+ function definePageTool(definition) {
51978
+ return definition;
51979
+ }
51980
+ function registerPageTools(server, definitions2) {
51981
+ return definitions2.map(
51982
+ (definition) => server.registerTool(definition.name, definition.config, {
51983
+ route: definition.route,
51984
+ timeout: definition.timeout,
51985
+ invokeEffect: definition.invokeEffect
51986
+ })
51987
+ );
51988
+ }
51989
+ function mountPageTools(options) {
51990
+ return registerPageTool(options);
51991
+ }
51992
+ function registerRuntimePageTools(server, options) {
51993
+ const allTools = options.tools ?? [];
51994
+ if (!allTools.length) {
51995
+ throw new Error("registerRuntimePageTools: tools 不能为空。");
51996
+ }
51997
+ const explicitRoute = options.route ? normalizeRoute(options.route) : null;
51998
+ const routes = new Set(allTools.map((tool2) => normalizeRoute(tool2.route)));
51999
+ if (!explicitRoute && routes.size > 1) {
52000
+ throw new Error("registerRuntimePageTools: tools 包含多个 route,请显式传入 route。");
52001
+ }
52002
+ const mountRoute = explicitRoute ?? Array.from(routes)[0];
52003
+ const routeTools = allTools.filter((tool2) => normalizeRoute(tool2.route) === mountRoute);
52004
+ if (!routeTools.length) {
52005
+ throw new Error(`registerRuntimePageTools: route "${mountRoute}" 下未找到工具定义。`);
52006
+ }
52007
+ routeTools.forEach((definition) => {
52008
+ const route = normalizeRoute(definition.route);
52009
+ const existing = runtimeRegisteredTools.get(definition.name);
52010
+ if (existing) {
52011
+ if (existing.route !== route) {
52012
+ throw new Error(
52013
+ `registerRuntimePageTools: 工具 "${definition.name}" 已绑定路由 "${existing.route}",不能重复绑定到 "${route}"。`
52014
+ );
52015
+ }
52016
+ existing.refCount += 1;
52017
+ return;
52018
+ }
52019
+ const tool2 = server.registerTool(definition.name, definition.config, {
52020
+ route,
52021
+ timeout: definition.timeout,
52022
+ invokeEffect: definition.invokeEffect
52023
+ });
52024
+ runtimeRegisteredTools.set(definition.name, { tool: tool2, route, refCount: 1 });
52025
+ });
52026
+ const cleanupHandlers = registerPageTool({
52027
+ route: mountRoute,
52028
+ tools: routeTools,
52029
+ context: options.context
52030
+ });
52031
+ return () => {
52032
+ cleanupHandlers();
52033
+ if (options.removeOnUnmount === false) return;
52034
+ routeTools.forEach((definition) => {
52035
+ const existing = runtimeRegisteredTools.get(definition.name);
52036
+ if (!existing) return;
52037
+ existing.refCount -= 1;
52038
+ if (existing.refCount > 0) return;
52039
+ runtimeRegisteredTools.delete(definition.name);
52040
+ server.unregisterTool(definition.name);
52041
+ });
52042
+ };
52043
+ }
50933
52044
  function registerNavigateTool(server, options) {
50934
52045
  const name16 = options?.name ?? "navigate_to_page";
50935
52046
  const title2 = options?.title ?? "页面跳转";
50936
52047
  const description2 = options?.description ?? '当需要的工具在当前页面不可用时,使用此工具跳转到特定页面。例如:要查询订单时跳转到 "/orders",要创建价保时跳转到 "/price-protection"。';
50937
52048
  const timeoutMs = options?.timeoutMs ?? 1500;
50938
- return server.registerTool(
52049
+ const inputSchema = {
52050
+ path: stringType().describe('目标页面的路由地址,例如 "/orders"、"/inventory"、"/price-protection" 等。')
52051
+ };
52052
+ const handler = async ({
52053
+ path
52054
+ }) => {
52055
+ if (typeof window === "undefined") {
52056
+ return {
52057
+ content: [{ type: "text", text: "当前环境不支持页面跳转(window 不存在)。" }]
52058
+ };
52059
+ }
52060
+ if (!_navigator) {
52061
+ return {
52062
+ content: [
52063
+ {
52064
+ type: "text",
52065
+ text: "页面跳转失败:尚未在应用入口调用 setNavigator 注册导航函数,无法执行路由跳转。"
52066
+ }
52067
+ ]
52068
+ };
52069
+ }
52070
+ try {
52071
+ if (isCurrentPathMatched(path)) {
52072
+ return {
52073
+ content: [{ type: "text", text: `当前已在页面:${path}。请继续你的下一步操作。` }]
52074
+ };
52075
+ }
52076
+ const readyPromise = waitForNavigationReady(path, timeoutMs);
52077
+ await _navigator(path);
52078
+ await readyPromise;
52079
+ return {
52080
+ content: [{ type: "text", text: `已成功跳转至页面:${path}。请继续你的下一步操作。` }]
52081
+ };
52082
+ } catch (err) {
52083
+ return {
52084
+ content: [
52085
+ {
52086
+ type: "text",
52087
+ text: `页面跳转失败:${err instanceof Error ? err.message : String(err)}。`
52088
+ }
52089
+ ]
52090
+ };
52091
+ }
52092
+ };
52093
+ const registeredTool = server.registerTool(
50939
52094
  name16,
50940
52095
  {
50941
52096
  title: title2,
50942
52097
  description: description2,
50943
- inputSchema: {
50944
- path: stringType().describe('目标页面的路由地址,例如 "/orders"、"/inventory"、"/price-protection" 等。')
50945
- }
52098
+ inputSchema
50946
52099
  },
50947
- async ({ path }) => {
50948
- if (typeof window === "undefined") {
50949
- return {
50950
- content: [{ type: "text", text: "当前环境不支持页面跳转(window 不存在)。" }]
50951
- };
50952
- }
50953
- if (!_navigator) {
50954
- return {
50955
- content: [
50956
- {
50957
- type: "text",
50958
- text: "页面跳转失败:尚未在应用入口调用 setNavigator 注册导航函数,无法执行路由跳转。"
50959
- }
50960
- ]
50961
- };
50962
- }
50963
- try {
50964
- const target = normalizeRoute(path);
50965
- const current = normalizeRoute(window.location.pathname);
50966
- const isAlreadyOnTarget = current === target || current.endsWith(target) && (current.length === target.length || current[current.lastIndexOf(target) - 1] === "/");
50967
- if (isAlreadyOnTarget) {
50968
- return {
50969
- content: [{ type: "text", text: `当前已在页面:${path}。请继续你的下一步操作。` }]
50970
- };
50971
- }
50972
- const readyPromise = waitForPageReady(path, timeoutMs);
50973
- await _navigator(path);
50974
- await readyPromise;
50975
- return {
50976
- content: [{ type: "text", text: `已成功跳转至页面:${path}。请继续你的下一步操作。` }]
50977
- };
50978
- } catch (err) {
50979
- return {
50980
- content: [
50981
- {
50982
- type: "text",
50983
- text: `页面跳转失败:${err instanceof Error ? err.message : String(err)}。`
50984
- }
50985
- ]
50986
- };
50987
- }
50988
- }
52100
+ handler
50989
52101
  );
52102
+ const managedByPageTools = typeof server.unregisterTool === "function";
52103
+ if (!managedByPageTools) {
52104
+ void registerBuiltinWebMcpTool({
52105
+ name: name16,
52106
+ description: description2,
52107
+ inputSchema,
52108
+ execute: async (input) => {
52109
+ return await handler(input);
52110
+ }
52111
+ });
52112
+ return attachBuiltinUnregisterOnRemove(name16, registeredTool);
52113
+ }
52114
+ return registeredTool;
50990
52115
  }
50991
52116
  function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50992
52117
  return (input) => {
@@ -51029,21 +52154,24 @@ ${observationText}
51029
52154
  if (effectConfig) {
51030
52155
  showToolInvokeEffect(effectConfig);
51031
52156
  }
51032
- if (activePages.get(route)) {
52157
+ if (isToolReadyOnRoute(route, name16)) {
51033
52158
  sendCallOnce();
51034
52159
  return;
51035
52160
  }
51036
52161
  readyHandler = (event) => {
51037
- if (event.source === window && event.data?.type === MSG_PAGE_READY && event.data.route === route) {
51038
- window.removeEventListener("message", readyHandler);
51039
- sendCallOnce();
51040
- }
52162
+ if (event.source !== window || event.data?.type !== MSG_PAGE_READY) return;
52163
+ const readyRoute = normalizeRoute(String(event.data.route ?? ""));
52164
+ if (readyRoute !== route) return;
52165
+ const readyTools = Array.isArray(event.data.toolNames) ? new Set(event.data.toolNames.map((item) => String(item))) : null;
52166
+ if (readyTools && !readyTools.has(name16)) return;
52167
+ window.removeEventListener("message", readyHandler);
52168
+ sendCallOnce();
51041
52169
  };
51042
52170
  window.addEventListener("message", readyHandler);
51043
52171
  if (_navigator) {
51044
52172
  await _navigator(route);
51045
52173
  }
51046
- if (activePages.get(route)) {
52174
+ if (isToolReadyOnRoute(route, name16)) {
51047
52175
  window.removeEventListener("message", readyHandler);
51048
52176
  sendCallOnce();
51049
52177
  }
@@ -51056,31 +52184,125 @@ ${observationText}
51056
52184
  });
51057
52185
  };
51058
52186
  }
51059
- function withPageTools(server) {
52187
+ function withPageTools(server, options) {
52188
+ const nativeMode = options?.nativeWebMcp?.mode ?? "auto";
52189
+ const shouldRegisterBuiltin = nativeMode !== "disabled";
52190
+ const proxyRegisteredTools = /* @__PURE__ */ new Map();
52191
+ const unregisterByName = (target, name16, silent = false) => {
52192
+ const existing = proxyRegisteredTools.get(name16);
52193
+ const hadTrackedState = !!existing;
52194
+ debugWebMcpLog("proxy-unregister-start", { name: name16, hasExisting: !!existing, silent });
52195
+ tryDirectBuiltinUnregisterByName(name16);
52196
+ proxyRegisteredTools.delete(name16);
52197
+ runtimeRegisteredTools.delete(name16);
52198
+ if (existing) {
52199
+ try {
52200
+ existing.remove();
52201
+ } catch {
52202
+ }
52203
+ }
52204
+ void unregisterBuiltinWebMcpTool(name16);
52205
+ if (!silent && hadTrackedState) {
52206
+ notifyServerToolListChanged(target);
52207
+ broadcastToolCatalogChanged();
52208
+ }
52209
+ debugWebMcpLog("proxy-unregister-done", { name: name16, removed: !!existing, silent });
52210
+ return !!existing;
52211
+ };
51060
52212
  return new Proxy(server, {
51061
52213
  get(target, prop, receiver) {
52214
+ if (prop === "unregisterTool") {
52215
+ return (name16) => unregisterByName(target, name16, false);
52216
+ }
51062
52217
  if (prop === "registerTool") {
51063
52218
  return (name16, config2, handlerOrRoute) => {
52219
+ debugWebMcpLog("proxy-register-start", {
52220
+ name: name16,
52221
+ mode: typeof handlerOrRoute === "function" ? "callback" : "route",
52222
+ shouldRegisterBuiltin
52223
+ });
52224
+ unregisterByName(target, name16, true);
51064
52225
  const rawRegister = target.registerTool.bind(target);
51065
52226
  if (typeof handlerOrRoute === "function") {
51066
- return rawRegister(name16, config2, handlerOrRoute);
52227
+ const registeredTool2 = rawRegister(name16, config2, handlerOrRoute);
52228
+ const wrapped2 = shouldRegisterBuiltin ? attachBuiltinUnregisterOnRemove(name16, registeredTool2) : registeredTool2;
52229
+ proxyRegisteredTools.set(name16, wrapped2);
52230
+ notifyServerToolListChanged(target);
52231
+ broadcastToolCatalogChanged();
52232
+ if (shouldRegisterBuiltin) {
52233
+ void registerBuiltinWebMcpTool({
52234
+ name: name16,
52235
+ description: config2?.description,
52236
+ inputSchema: config2?.inputSchema,
52237
+ execute: async (input) => {
52238
+ return await handlerOrRoute(input);
52239
+ }
52240
+ });
52241
+ }
52242
+ debugWebMcpLog("proxy-register-done", { name: name16, mode: "callback" });
52243
+ return wrapped2;
51067
52244
  }
51068
52245
  const { route, timeout, invokeEffect } = handlerOrRoute;
51069
- toolRouteMap.set(name16, route);
52246
+ const normalizedRoute = normalizeRoute(route);
51070
52247
  const effectConfig = resolveRuntimeEffectConfig(name16, config2?.title, invokeEffect);
51071
- return rawRegister(name16, config2, buildPageHandler(name16, route, timeout, effectConfig));
52248
+ const pageHandler = buildPageHandler(name16, normalizedRoute, timeout, effectConfig);
52249
+ const registeredTool = rawRegister(name16, config2, pageHandler);
52250
+ const wrapped = shouldRegisterBuiltin ? attachBuiltinUnregisterOnRemove(name16, registeredTool) : registeredTool;
52251
+ proxyRegisteredTools.set(name16, wrapped);
52252
+ notifyServerToolListChanged(target);
52253
+ broadcastToolCatalogChanged();
52254
+ if (shouldRegisterBuiltin) {
52255
+ void registerBuiltinWebMcpTool({
52256
+ name: name16,
52257
+ description: config2?.description,
52258
+ inputSchema: config2?.inputSchema,
52259
+ execute: async (input) => {
52260
+ return await pageHandler(input);
52261
+ }
52262
+ });
52263
+ }
52264
+ debugWebMcpLog("proxy-register-done", { name: name16, mode: "route" });
52265
+ return wrapped;
51072
52266
  };
51073
52267
  }
51074
52268
  return Reflect.get(target, prop, receiver);
51075
52269
  }
51076
52270
  });
51077
52271
  }
52272
+ function resolveRouteAndHandlers(options) {
52273
+ if ("handlers" in options) {
52274
+ return {
52275
+ route: normalizeRoute(options.route ?? window.location.pathname),
52276
+ handlers: options.handlers
52277
+ };
52278
+ }
52279
+ const tools = options.tools ?? [];
52280
+ if (!tools.length) {
52281
+ throw new Error("registerPageTool: tools 不能为空。");
52282
+ }
52283
+ const targetRoute = options.route ? normalizeRoute(options.route) : null;
52284
+ const uniqueRoutes = new Set(tools.map((item) => normalizeRoute(item.route)));
52285
+ if (!targetRoute && uniqueRoutes.size > 1) {
52286
+ throw new Error("registerPageTool: tools 包含多个 route,请显式传入 route 参数。");
52287
+ }
52288
+ const route = targetRoute ?? Array.from(uniqueRoutes)[0];
52289
+ const handlers = {};
52290
+ tools.filter((item) => normalizeRoute(item.route) === route).forEach((item) => {
52291
+ if (handlers[item.name]) {
52292
+ throw new Error(`registerPageTool: 工具 "${item.name}" 在 route "${route}" 上重复定义。`);
52293
+ }
52294
+ handlers[item.name] = (input) => item.handler(input, options.context);
52295
+ });
52296
+ if (!Object.keys(handlers).length) {
52297
+ throw new Error(`registerPageTool: route "${route}" 下未找到可激活的工具定义。`);
52298
+ }
52299
+ return { route, handlers };
52300
+ }
51078
52301
  function registerPageTool(options) {
51079
- const { route: routeOption, handlers } = options;
51080
- const normalizeRoute2 = (value) => value.replace(/\/+$/, "") || "/";
51081
- const route = normalizeRoute2(routeOption ?? window.location.pathname);
52302
+ const { route, handlers } = resolveRouteAndHandlers(options);
52303
+ const toolNames = Object.keys(handlers);
51082
52304
  const handleMessage = async (event) => {
51083
- if (event.source !== window || event.data?.type !== MSG_TOOL_CALL || normalizeRoute2(String(event.data?.route ?? "")) !== route || !(event.data.toolName in handlers)) {
52305
+ if (event.source !== window || event.data?.type !== MSG_TOOL_CALL || normalizeRoute(String(event.data?.route ?? "")) !== route || !(event.data.toolName in handlers)) {
51084
52306
  return;
51085
52307
  }
51086
52308
  const { callId, toolName, input } = event.data;
@@ -51098,9 +52320,9 @@ ${observationText}
51098
52320
  );
51099
52321
  }
51100
52322
  };
51101
- activePages.set(route, true);
52323
+ activePages.set(route, new Set(toolNames));
51102
52324
  window.addEventListener("message", handleMessage);
51103
- broadcastRouteChange(MSG_PAGE_READY, route);
52325
+ broadcastRouteChange(MSG_PAGE_READY, route, { toolNames });
51104
52326
  return () => {
51105
52327
  activePages.delete(route);
51106
52328
  window.removeEventListener("message", handleMessage);
@@ -51271,6 +52493,7 @@ ${lines.join("\n")}
51271
52493
  exports2.MSG_PAGE_LEAVE = MSG_PAGE_LEAVE;
51272
52494
  exports2.MSG_REMOTER_READY = MSG_REMOTER_READY;
51273
52495
  exports2.MSG_ROUTE_STATE_INITIAL = MSG_ROUTE_STATE_INITIAL;
52496
+ exports2.MSG_TOOL_CATALOG_CHANGED = MSG_TOOL_CATALOG_CHANGED;
51274
52497
  exports2.QrCode = QrCode;
51275
52498
  exports2.ResourceTemplate = ResourceTemplate;
51276
52499
  exports2.UriTemplate = UriTemplate;
@@ -51284,8 +52507,12 @@ ${lines.join("\n")}
51284
52507
  exports2.createSSEClientTransport = createSSEClientTransport;
51285
52508
  exports2.createSkillTools = createSkillTools;
51286
52509
  exports2.createStreamableHTTPClientTransport = createStreamableHTTPClientTransport;
52510
+ exports2.definePageTool = definePageTool;
52511
+ exports2.executeBuiltinWebMcpTool = executeBuiltinWebMcpTool;
52512
+ exports2.forceResetBuiltinWebMcpTools = forceResetBuiltinWebMcpTools;
51287
52513
  exports2.formatSkillsForSystemPrompt = formatSkillsForSystemPrompt;
51288
52514
  exports2.getAISDKTools = getAISDKTools;
52515
+ exports2.getActivePageTools = getActivePageTools;
51289
52516
  exports2.getActiveRoutes = getActiveRoutes;
51290
52517
  exports2.getDisplayName = getDisplayName;
51291
52518
  exports2.getMainSkillPathByName = getMainSkillPathByName;
@@ -51294,16 +52521,24 @@ ${lines.join("\n")}
51294
52521
  exports2.getSkillMdPaths = getSkillMdPaths;
51295
52522
  exports2.getSkillOverviews = getSkillOverviews;
51296
52523
  exports2.getToolRouteMap = getToolRouteMap;
52524
+ exports2.hasBuiltinWebMcpTool = hasBuiltinWebMcpTool;
52525
+ exports2.isBuiltinWebMcpSupported = isBuiltinWebMcpSupported;
51297
52526
  exports2.isMcpClient = isMcpClient;
51298
52527
  exports2.isMcpServer = isMcpServer;
51299
52528
  exports2.isMessageChannelClientTransport = isMessageChannelClientTransport;
51300
52529
  exports2.isMessageChannelServerTransport = isMessageChannelServerTransport;
51301
52530
  exports2.isSSEClientTransport = isSSEClientTransport;
51302
52531
  exports2.isStreamableHTTPClientTransport = isStreamableHTTPClientTransport;
52532
+ exports2.listBuiltinWebMcpTools = listBuiltinWebMcpTools;
52533
+ exports2.mountPageTools = mountPageTools;
51303
52534
  exports2.parseSkillFrontMatter = parseSkillFrontMatter;
52535
+ exports2.registerBuiltinWebMcpTool = registerBuiltinWebMcpTool;
51304
52536
  exports2.registerNavigateTool = registerNavigateTool;
51305
52537
  exports2.registerPageTool = registerPageTool;
52538
+ exports2.registerPageTools = registerPageTools;
52539
+ exports2.registerRuntimePageTools = registerRuntimePageTools;
51306
52540
  exports2.setNavigator = setNavigator;
52541
+ exports2.unregisterBuiltinWebMcpTool = unregisterBuiltinWebMcpTool;
51307
52542
  exports2.withPageTools = withPageTools;
51308
52543
  exports2.z = z;
51309
52544
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });