@opentiny/next-sdk 0.2.6 → 0.2.8

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.
@@ -3087,7 +3087,7 @@
3087
3087
  if (hasRequiredUtils$2) return utils$2;
3088
3088
  hasRequiredUtils$2 = 1;
3089
3089
  const isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3090
- const isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3090
+ const isIPv42 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3091
3091
  function stringArrayToHexStripped(input) {
3092
3092
  let acc = "";
3093
3093
  let code2 = 0;
@@ -3310,7 +3310,7 @@
3310
3310
  }
3311
3311
  if (component.host !== void 0) {
3312
3312
  let host = unescape(component.host);
3313
- if (!isIPv4(host)) {
3313
+ if (!isIPv42(host)) {
3314
3314
  const ipV6res = normalizeIPv6(host);
3315
3315
  if (ipV6res.isIPV6 === true) {
3316
3316
  host = `[${ipV6res.escapedHost}]`;
@@ -3331,7 +3331,7 @@
3331
3331
  recomposeAuthority,
3332
3332
  normalizeComponentEncoding,
3333
3333
  removeDotSegments,
3334
- isIPv4,
3334
+ isIPv4: isIPv42,
3335
3335
  isUUID,
3336
3336
  normalizeIPv6,
3337
3337
  stringArrayToHexStripped
@@ -3552,7 +3552,7 @@
3552
3552
  function requireFastUri() {
3553
3553
  if (hasRequiredFastUri) return fastUri.exports;
3554
3554
  hasRequiredFastUri = 1;
3555
- const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = requireUtils$2();
3555
+ const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4: isIPv42, nonSimpleDomain } = requireUtils$2();
3556
3556
  const { SCHEMES, getSchemeHandler } = requireSchemes();
3557
3557
  function normalize(uri2, options) {
3558
3558
  if (typeof uri2 === "string") {
@@ -3733,7 +3733,7 @@
3733
3733
  parsed.port = matches[5];
3734
3734
  }
3735
3735
  if (parsed.host) {
3736
- const ipv4result = isIPv4(parsed.host);
3736
+ const ipv4result = isIPv42(parsed.host);
3737
3737
  if (ipv4result === false) {
3738
3738
  const ipv6result = normalizeIPv6(parsed.host);
3739
3739
  parsed.host = ipv6result.host.toLowerCase();
@@ -26986,10 +26986,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
26986
26986
  const DEFAULT_QR_CODE_URL = "https://ai.opentiny.design/next-remoter";
26987
26987
  const DEFAULT_LOGO_URL = "https://ai.opentiny.design/next-remoter/svgs/logo-next-no-bg-left.svg";
26988
26988
  const getDefaultMenuItems = (options) => {
26989
- return [
26989
+ const hasSession = !!options.sessionId;
26990
+ const baseItems = [
26990
26991
  {
26991
26992
  action: "qr-code",
26992
- show: true,
26993
+ show: hasSession,
26993
26994
  text: "扫码登录",
26994
26995
  desc: "使用手机遥控页面",
26995
26996
  icon: qrCode
@@ -27003,7 +27004,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27003
27004
  },
27004
27005
  {
27005
27006
  action: "remote-url",
27006
- show: true,
27007
+ show: hasSession,
27007
27008
  text: `遥控器链接`,
27008
27009
  desc: `${options.remoteUrl}`,
27009
27010
  active: true,
@@ -27013,14 +27014,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27013
27014
  },
27014
27015
  {
27015
27016
  action: "remote-control",
27016
- show: true,
27017
+ show: hasSession,
27017
27018
  text: `识别码`,
27018
- desc: `${options.sessionId.slice(-6)}`,
27019
+ desc: hasSession ? `${options.sessionId.slice(-6)}` : "",
27019
27020
  know: true,
27020
27021
  showCopyIcon: true,
27021
27022
  icon: scan
27022
27023
  }
27023
27024
  ];
27025
+ return baseItems;
27024
27026
  };
27025
27027
  class FloatingBlock {
27026
27028
  constructor(options) {
@@ -27052,9 +27054,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27052
27054
  trigger: "hover"
27053
27055
  });
27054
27056
  };
27055
- if (!options.sessionId) {
27056
- throw new Error("sessionId is required");
27057
- }
27058
27057
  this.options = {
27059
27058
  ...options,
27060
27059
  qrCodeUrl: options.qrCodeUrl || DEFAULT_QR_CODE_URL,
@@ -27073,11 +27072,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27073
27072
  return this.options.qrCodeUrl?.includes("?") ? "&sessionId=" : "?sessionId=";
27074
27073
  }
27075
27074
  /**
27076
- * 合并菜单项配置
27077
- * @param userMenuItems 用户自定义菜单项配置
27078
- * @returns 合并后的菜单项配置
27075
+ * 合并菜单项配置。
27076
+ * - sessionId:使用默认菜单 + 用户配置(可定制每一项的 show/text/icon 等)
27077
+ * - 无 sessionId:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27079
27078
  */
27080
27079
  mergeMenuItems(userMenuItems) {
27080
+ if (!this.options.sessionId) {
27081
+ return [];
27082
+ }
27081
27083
  if (!userMenuItems) {
27082
27084
  return getDefaultMenuItems(this.options);
27083
27085
  }
@@ -27087,7 +27089,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27087
27089
  return {
27088
27090
  ...defaultItem,
27089
27091
  ...userItem,
27090
- // 确保show属性存在,默认为true
27091
27092
  show: userItem.show !== void 0 ? userItem.show : defaultItem.show
27092
27093
  };
27093
27094
  }
@@ -27231,9 +27232,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27231
27232
  this.closeDropdown();
27232
27233
  }
27233
27234
  copyRemoteControl() {
27235
+ if (!this.options.sessionId) return;
27234
27236
  this.copyToClipboard(this.options.sessionId.slice(-6));
27235
27237
  }
27236
27238
  copyRemoteURL() {
27239
+ if (!this.options.sessionId) return;
27237
27240
  this.copyToClipboard(this.options.remoteUrl + this.sessionPrefix + this.options.sessionId);
27238
27241
  }
27239
27242
  // 实现复制到剪贴板功能
@@ -27281,8 +27284,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27281
27284
  }, 300);
27282
27285
  }, 1500);
27283
27286
  }
27284
- // 创建二维码弹窗
27287
+ // 创建二维码弹窗(无 sessionId 时不展示)
27285
27288
  async showQRCode() {
27289
+ if (!this.options.sessionId) return;
27286
27290
  const qrCode2 = new QrCode((this.options.qrCodeUrl || "") + this.sessionPrefix + this.options.sessionId, {});
27287
27291
  const base642 = await qrCode2.toDataURL();
27288
27292
  const modal = this.createModal(
@@ -27758,6 +27762,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
27758
27762
  this.dropdownMenu.parentNode.removeChild(this.dropdownMenu);
27759
27763
  }
27760
27764
  }
27765
+ // 隐藏组件
27766
+ hide() {
27767
+ if (this.floatingBlock) {
27768
+ this.floatingBlock.style.display = "none";
27769
+ }
27770
+ this.closeDropdown();
27771
+ }
27772
+ // 显示组件
27773
+ show() {
27774
+ if (this.floatingBlock) {
27775
+ this.floatingBlock.style.display = "flex";
27776
+ }
27777
+ }
27761
27778
  }
27762
27779
  const createRemoter = (options = {}) => {
27763
27780
  return new FloatingBlock(options);
@@ -28053,25 +28070,30 @@ Error message: ${getErrorMessage$2(cause)}`,
28053
28070
  }
28054
28071
  function createToolNameMapping({
28055
28072
  tools = [],
28056
- providerToolNames
28073
+ providerToolNames,
28074
+ resolveProviderToolName
28057
28075
  }) {
28076
+ var _a22;
28058
28077
  const customToolNameToProviderToolName = {};
28059
28078
  const providerToolNameToCustomToolName = {};
28060
28079
  for (const tool2 of tools) {
28061
- if (tool2.type === "provider" && tool2.id in providerToolNames) {
28062
- const providerToolName = providerToolNames[tool2.id];
28080
+ if (tool2.type === "provider") {
28081
+ const providerToolName = (_a22 = resolveProviderToolName == null ? void 0 : resolveProviderToolName(tool2)) != null ? _a22 : tool2.id in providerToolNames ? providerToolNames[tool2.id] : void 0;
28082
+ if (providerToolName == null) {
28083
+ continue;
28084
+ }
28063
28085
  customToolNameToProviderToolName[tool2.name] = providerToolName;
28064
28086
  providerToolNameToCustomToolName[providerToolName] = tool2.name;
28065
28087
  }
28066
28088
  }
28067
28089
  return {
28068
28090
  toProviderToolName: (customToolName) => {
28069
- var _a22;
28070
- return (_a22 = customToolNameToProviderToolName[customToolName]) != null ? _a22 : customToolName;
28091
+ var _a32;
28092
+ return (_a32 = customToolNameToProviderToolName[customToolName]) != null ? _a32 : customToolName;
28071
28093
  },
28072
28094
  toCustomToolName: (providerToolName) => {
28073
- var _a22;
28074
- return (_a22 = providerToolNameToCustomToolName[providerToolName]) != null ? _a22 : providerToolName;
28095
+ var _a32;
28096
+ return (_a32 = providerToolNameToCustomToolName[providerToolName]) != null ? _a32 : providerToolName;
28075
28097
  }
28076
28098
  };
28077
28099
  }
@@ -28264,8 +28286,103 @@ Error message: ${getErrorMessage$2(cause)}`,
28264
28286
  }
28265
28287
  return result;
28266
28288
  }
28289
+ function validateDownloadUrl(url2) {
28290
+ let parsed;
28291
+ try {
28292
+ parsed = new URL(url2);
28293
+ } catch (e) {
28294
+ throw new DownloadError({
28295
+ url: url2,
28296
+ message: `Invalid URL: ${url2}`
28297
+ });
28298
+ }
28299
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
28300
+ throw new DownloadError({
28301
+ url: url2,
28302
+ message: `URL scheme must be http or https, got ${parsed.protocol}`
28303
+ });
28304
+ }
28305
+ const hostname2 = parsed.hostname;
28306
+ if (!hostname2) {
28307
+ throw new DownloadError({
28308
+ url: url2,
28309
+ message: `URL must have a hostname`
28310
+ });
28311
+ }
28312
+ if (hostname2 === "localhost" || hostname2.endsWith(".local") || hostname2.endsWith(".localhost")) {
28313
+ throw new DownloadError({
28314
+ url: url2,
28315
+ message: `URL with hostname ${hostname2} is not allowed`
28316
+ });
28317
+ }
28318
+ if (hostname2.startsWith("[") && hostname2.endsWith("]")) {
28319
+ const ipv62 = hostname2.slice(1, -1);
28320
+ if (isPrivateIPv6(ipv62)) {
28321
+ throw new DownloadError({
28322
+ url: url2,
28323
+ message: `URL with IPv6 address ${hostname2} is not allowed`
28324
+ });
28325
+ }
28326
+ return;
28327
+ }
28328
+ if (isIPv4(hostname2)) {
28329
+ if (isPrivateIPv4(hostname2)) {
28330
+ throw new DownloadError({
28331
+ url: url2,
28332
+ message: `URL with IP address ${hostname2} is not allowed`
28333
+ });
28334
+ }
28335
+ return;
28336
+ }
28337
+ }
28338
+ function isIPv4(hostname2) {
28339
+ const parts = hostname2.split(".");
28340
+ if (parts.length !== 4) return false;
28341
+ return parts.every((part) => {
28342
+ const num = Number(part);
28343
+ return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
28344
+ });
28345
+ }
28346
+ function isPrivateIPv4(ip) {
28347
+ const parts = ip.split(".").map(Number);
28348
+ const [a, b] = parts;
28349
+ if (a === 0) return true;
28350
+ if (a === 10) return true;
28351
+ if (a === 127) return true;
28352
+ if (a === 169 && b === 254) return true;
28353
+ if (a === 172 && b >= 16 && b <= 31) return true;
28354
+ if (a === 192 && b === 168) return true;
28355
+ return false;
28356
+ }
28357
+ function isPrivateIPv6(ip) {
28358
+ const normalized = ip.toLowerCase();
28359
+ if (normalized === "::1") return true;
28360
+ if (normalized === "::") return true;
28361
+ if (normalized.startsWith("::ffff:")) {
28362
+ const mappedPart = normalized.slice(7);
28363
+ if (isIPv4(mappedPart)) {
28364
+ return isPrivateIPv4(mappedPart);
28365
+ }
28366
+ const hexParts = mappedPart.split(":");
28367
+ if (hexParts.length === 2) {
28368
+ const high = parseInt(hexParts[0], 16);
28369
+ const low = parseInt(hexParts[1], 16);
28370
+ if (!isNaN(high) && !isNaN(low)) {
28371
+ const a = high >> 8 & 255;
28372
+ const b = high & 255;
28373
+ const c = low >> 8 & 255;
28374
+ const d = low & 255;
28375
+ return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
28376
+ }
28377
+ }
28378
+ }
28379
+ if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
28380
+ if (normalized.startsWith("fe80")) return true;
28381
+ return false;
28382
+ }
28267
28383
  async function downloadBlob(url2, options) {
28268
28384
  var _a22, _b22;
28385
+ validateDownloadUrl(url2);
28269
28386
  try {
28270
28387
  const response = await fetch(url2, {
28271
28388
  signal: options == null ? void 0 : options.abortSignal
@@ -28431,7 +28548,7 @@ Error message: ${getErrorMessage$2(cause)}`,
28431
28548
  );
28432
28549
  return Object.fromEntries(normalizedHeaders.entries());
28433
28550
  }
28434
- var VERSION$7 = "4.0.15";
28551
+ var VERSION$7 = "4.0.19";
28435
28552
  var getOriginalFetch = () => globalThis.fetch;
28436
28553
  var getFromApi = async ({
28437
28554
  url: url2,
@@ -28574,8 +28691,8 @@ Error message: ${getErrorMessage$2(cause)}`,
28574
28691
  "x-m4a": "m4a"
28575
28692
  }[subtype]) != null ? _a22 : subtype;
28576
28693
  }
28577
- var suspectProtoRx$1 = /"__proto__"\s*:/;
28578
- var suspectConstructorRx$1 = /"constructor"\s*:/;
28694
+ var suspectProtoRx$1 = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
28695
+ var suspectConstructorRx$1 = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
28579
28696
  function _parse$1(text2) {
28580
28697
  const obj = JSON.parse(text2);
28581
28698
  if (obj === null || typeof obj !== "object") {
@@ -28595,7 +28712,7 @@ Error message: ${getErrorMessage$2(cause)}`,
28595
28712
  if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
28596
28713
  throw new SyntaxError("Object contains forbidden prototype property");
28597
28714
  }
28598
- if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
28715
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
28599
28716
  throw new SyntaxError("Object contains forbidden prototype property");
28600
28717
  }
28601
28718
  for (const key in node) {
@@ -30082,6 +30199,33 @@ Error message: ${getErrorMessage$2(cause)}`,
30082
30199
  function dynamicTool(tool2) {
30083
30200
  return { ...tool2, type: "dynamic" };
30084
30201
  }
30202
+ function createProviderToolFactory({
30203
+ id: id2,
30204
+ inputSchema
30205
+ }) {
30206
+ return ({
30207
+ execute,
30208
+ outputSchema: outputSchema2,
30209
+ needsApproval,
30210
+ toModelOutput,
30211
+ onInputStart,
30212
+ onInputDelta,
30213
+ onInputAvailable,
30214
+ ...args
30215
+ }) => tool({
30216
+ type: "provider",
30217
+ id: id2,
30218
+ args,
30219
+ inputSchema,
30220
+ outputSchema: outputSchema2,
30221
+ execute,
30222
+ needsApproval,
30223
+ toModelOutput,
30224
+ onInputStart,
30225
+ onInputDelta,
30226
+ onInputAvailable
30227
+ });
30228
+ }
30085
30229
  function createProviderToolFactoryWithOutputSchema({
30086
30230
  id: id2,
30087
30231
  inputSchema,
@@ -31552,7 +31696,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
31552
31696
  var _a92;
31553
31697
  return (_a92 = indexBrowserExports.getContext().headers) == null ? void 0 : _a92["x-vercel-id"];
31554
31698
  }
31555
- var VERSION$6 = "3.0.58";
31699
+ var VERSION$6 = "3.0.66";
31556
31700
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
31557
31701
  function createGatewayProvider(options = {}) {
31558
31702
  var _a92, _b9;
@@ -33079,6 +33223,8 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33079
33223
  }
33080
33224
  async function notify(options) {
33081
33225
  for (const callback of asArray(options.callbacks)) {
33226
+ if (callback == null)
33227
+ continue;
33082
33228
  try {
33083
33229
  await callback(options.event);
33084
33230
  } catch (_ignored) {
@@ -33385,7 +33531,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33385
33531
  }
33386
33532
  return void 0;
33387
33533
  }
33388
- var VERSION$4 = "6.0.104";
33534
+ var VERSION$4 = "6.0.116";
33389
33535
  var download = async ({
33390
33536
  url: url2,
33391
33537
  maxBytes,
@@ -33393,6 +33539,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33393
33539
  }) => {
33394
33540
  var _a21;
33395
33541
  const urlText = url2.toString();
33542
+ validateDownloadUrl(urlText);
33396
33543
  try {
33397
33544
  const response = await fetch(urlText, {
33398
33545
  headers: withUserAgentSuffix$1(
@@ -34498,6 +34645,44 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
34498
34645
  }))
34499
34646
  );
34500
34647
  }
34648
+ function getGlobalTelemetryIntegrations() {
34649
+ var _a21;
34650
+ return (_a21 = globalThis.AI_SDK_TELEMETRY_INTEGRATIONS) != null ? _a21 : [];
34651
+ }
34652
+ function getGlobalTelemetryIntegration() {
34653
+ const globalIntegrations = getGlobalTelemetryIntegrations();
34654
+ return (integrations) => {
34655
+ const localIntegrations = asArray(integrations);
34656
+ const allIntegrations = [...globalIntegrations, ...localIntegrations];
34657
+ function createTelemetryComposite(getListenerFromIntegration) {
34658
+ const listeners = allIntegrations.map(getListenerFromIntegration).filter(Boolean);
34659
+ return async (event) => {
34660
+ for (const listener of listeners) {
34661
+ try {
34662
+ await listener(event);
34663
+ } catch (_ignored) {
34664
+ }
34665
+ }
34666
+ };
34667
+ }
34668
+ return {
34669
+ onStart: createTelemetryComposite((integration) => integration.onStart),
34670
+ onStepStart: createTelemetryComposite(
34671
+ (integration) => integration.onStepStart
34672
+ ),
34673
+ onToolCallStart: createTelemetryComposite(
34674
+ (integration) => integration.onToolCallStart
34675
+ ),
34676
+ onToolCallFinish: createTelemetryComposite(
34677
+ (integration) => integration.onToolCallFinish
34678
+ ),
34679
+ onStepFinish: createTelemetryComposite(
34680
+ (integration) => integration.onStepFinish
34681
+ ),
34682
+ onFinish: createTelemetryComposite((integration) => integration.onFinish)
34683
+ };
34684
+ };
34685
+ }
34501
34686
  function asLanguageModelUsage(usage) {
34502
34687
  return {
34503
34688
  inputTokens: usage.inputTokens.total,
@@ -36048,6 +36233,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36048
36233
  ...settings
36049
36234
  }) {
36050
36235
  const model = resolveLanguageModel(modelArg);
36236
+ const createGlobalTelemetry = getGlobalTelemetryIntegration();
36051
36237
  const stopConditions = asArray(stopWhen);
36052
36238
  const totalTimeoutMs = getTotalTimeoutMs(timeout);
36053
36239
  const stepTimeoutMs = getStepTimeoutMs(timeout);
@@ -36078,6 +36264,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36078
36264
  prompt,
36079
36265
  messages
36080
36266
  });
36267
+ const globalTelemetry = createGlobalTelemetry(telemetry == null ? void 0 : telemetry.integrations);
36081
36268
  await notify({
36082
36269
  event: {
36083
36270
  model: modelInfo,
@@ -36107,7 +36294,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36107
36294
  metadata: telemetry == null ? void 0 : telemetry.metadata,
36108
36295
  experimental_context
36109
36296
  },
36110
- callbacks: onStart
36297
+ callbacks: [
36298
+ onStart,
36299
+ globalTelemetry.onStart
36300
+ ]
36111
36301
  });
36112
36302
  const tracer = getTracer(telemetry);
36113
36303
  try {
@@ -36152,8 +36342,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36152
36342
  experimental_context,
36153
36343
  stepNumber: 0,
36154
36344
  model: modelInfo,
36155
- onToolCallStart,
36156
- onToolCallFinish
36345
+ onToolCallStart: [
36346
+ onToolCallStart,
36347
+ globalTelemetry.onToolCallStart
36348
+ ],
36349
+ onToolCallFinish: [
36350
+ onToolCallFinish,
36351
+ globalTelemetry.onToolCallFinish
36352
+ ]
36157
36353
  });
36158
36354
  const toolContent = [];
36159
36355
  for (const output2 of toolOutputs) {
@@ -36162,7 +36358,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36162
36358
  input: output2.input,
36163
36359
  tool: tools == null ? void 0 : tools[output2.toolName],
36164
36360
  output: output2.type === "tool-result" ? output2.output : output2.error,
36165
- errorMode: output2.type === "tool-error" ? "json" : "none"
36361
+ errorMode: output2.type === "tool-error" ? "text" : "none"
36166
36362
  });
36167
36363
  toolContent.push({
36168
36364
  type: "tool-result",
@@ -36279,7 +36475,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36279
36475
  metadata: telemetry == null ? void 0 : telemetry.metadata,
36280
36476
  experimental_context
36281
36477
  },
36282
- callbacks: onStepStart
36478
+ callbacks: [
36479
+ onStepStart,
36480
+ globalTelemetry.onStepStart
36481
+ ]
36283
36482
  });
36284
36483
  currentModelResponse = await retry(
36285
36484
  () => {
@@ -36457,8 +36656,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36457
36656
  experimental_context,
36458
36657
  stepNumber: steps.length,
36459
36658
  model: stepModelInfo,
36460
- onToolCallStart,
36461
- onToolCallFinish
36659
+ onToolCallStart: [
36660
+ onToolCallStart,
36661
+ globalTelemetry.onToolCallStart
36662
+ ],
36663
+ onToolCallFinish: [
36664
+ onToolCallFinish,
36665
+ globalTelemetry.onToolCallFinish
36666
+ ]
36462
36667
  })
36463
36668
  );
36464
36669
  }
@@ -36525,7 +36730,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36525
36730
  model: stepModelInfo.modelId
36526
36731
  });
36527
36732
  steps.push(currentStepResult);
36528
- await notify({ event: currentStepResult, callbacks: onStepFinish });
36733
+ await notify({
36734
+ event: currentStepResult,
36735
+ callbacks: [onStepFinish, globalTelemetry.onStepFinish]
36736
+ });
36529
36737
  } finally {
36530
36738
  if (stepTimeoutId != null) {
36531
36739
  clearTimeout(stepTimeoutId);
@@ -36606,7 +36814,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36606
36814
  steps,
36607
36815
  totalUsage
36608
36816
  },
36609
- callbacks: onFinish
36817
+ callbacks: [
36818
+ onFinish,
36819
+ globalTelemetry.onFinish
36820
+ ]
36610
36821
  });
36611
36822
  let resolvedOutput;
36612
36823
  if (lastStep.finishReason === "stop") {
@@ -37225,7 +37436,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37225
37436
  state.message.parts.push({
37226
37437
  type: "file",
37227
37438
  mediaType: chunk.mediaType,
37228
- url: chunk.url
37439
+ url: chunk.url,
37440
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37229
37441
  });
37230
37442
  write();
37231
37443
  break;
@@ -37882,7 +38094,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37882
38094
  file: new DefaultGeneratedFileWithType({
37883
38095
  data: chunk.data,
37884
38096
  mediaType: chunk.mediaType
37885
- })
38097
+ }),
38098
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37886
38099
  });
37887
38100
  break;
37888
38101
  }
@@ -38270,6 +38483,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38270
38483
  this.outputSpecification = output;
38271
38484
  this.includeRawChunks = includeRawChunks;
38272
38485
  this.tools = tools;
38486
+ const createGlobalTelemetry = getGlobalTelemetryIntegration();
38487
+ const globalTelemetry = createGlobalTelemetry(telemetry == null ? void 0 : telemetry.integrations);
38273
38488
  let stepFinish;
38274
38489
  let recordedContent = [];
38275
38490
  const recordedResponseMessages = [];
@@ -38371,7 +38586,11 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38371
38586
  delete activeReasoningContent[part.id];
38372
38587
  }
38373
38588
  if (part.type === "file") {
38374
- recordedContent.push({ type: "file", file: part.file });
38589
+ recordedContent.push({
38590
+ type: "file",
38591
+ file: part.file,
38592
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
38593
+ });
38375
38594
  }
38376
38595
  if (part.type === "source") {
38377
38596
  recordedContent.push(part);
@@ -38417,7 +38636,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38417
38636
  },
38418
38637
  providerMetadata: part.providerMetadata
38419
38638
  });
38420
- await notify({ event: currentStepResult, callbacks: onStepFinish });
38639
+ await notify({
38640
+ event: currentStepResult,
38641
+ callbacks: [onStepFinish, globalTelemetry.onStepFinish]
38642
+ });
38421
38643
  logWarnings({
38422
38644
  warnings: recordedWarnings,
38423
38645
  provider: modelInfo.provider,
@@ -38481,7 +38703,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38481
38703
  providerMetadata: finalStep.providerMetadata,
38482
38704
  steps: recordedSteps
38483
38705
  },
38484
- callbacks: onFinish
38706
+ callbacks: [
38707
+ onFinish,
38708
+ globalTelemetry.onFinish
38709
+ ]
38485
38710
  });
38486
38711
  rootSpan.setAttributes(
38487
38712
  await selectTelemetryAttributes({
@@ -38638,7 +38863,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38638
38863
  ...callbackTelemetryProps,
38639
38864
  experimental_context
38640
38865
  },
38641
- callbacks: onStart
38866
+ callbacks: [
38867
+ onStart,
38868
+ globalTelemetry.onStart
38869
+ ]
38642
38870
  });
38643
38871
  const initialMessages = initialPrompt.messages;
38644
38872
  const initialResponseMessages = [];
@@ -38688,8 +38916,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38688
38916
  experimental_context,
38689
38917
  stepNumber: recordedSteps.length,
38690
38918
  model: modelInfo,
38691
- onToolCallStart,
38692
- onToolCallFinish,
38919
+ onToolCallStart: [
38920
+ onToolCallStart,
38921
+ globalTelemetry.onToolCallStart
38922
+ ],
38923
+ onToolCallFinish: [
38924
+ onToolCallFinish,
38925
+ globalTelemetry.onToolCallFinish
38926
+ ],
38693
38927
  onPreliminaryToolResult: (result2) => {
38694
38928
  toolExecutionStepStreamController == null ? void 0 : toolExecutionStepStreamController.enqueue(result2);
38695
38929
  }
@@ -38726,7 +38960,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38726
38960
  input: output2.input,
38727
38961
  tool: tools == null ? void 0 : tools[output2.toolName],
38728
38962
  output: output2.type === "tool-result" ? output2.output : output2.error,
38729
- errorMode: output2.type === "tool-error" ? "json" : "none"
38963
+ errorMode: output2.type === "tool-error" ? "text" : "none"
38730
38964
  })
38731
38965
  });
38732
38966
  }
@@ -38840,7 +39074,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38840
39074
  ...callbackTelemetryProps,
38841
39075
  experimental_context
38842
39076
  },
38843
- callbacks: onStepStart
39077
+ callbacks: [
39078
+ onStepStart,
39079
+ globalTelemetry.onStepStart
39080
+ ]
38844
39081
  });
38845
39082
  const {
38846
39083
  result: { stream: stream2, response, request },
@@ -38916,8 +39153,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38916
39153
  generateId: generateId2,
38917
39154
  stepNumber: recordedSteps.length,
38918
39155
  model: stepModelInfo,
38919
- onToolCallStart,
38920
- onToolCallFinish
39156
+ onToolCallStart: [
39157
+ onToolCallStart,
39158
+ globalTelemetry.onToolCallStart
39159
+ ],
39160
+ onToolCallFinish: [
39161
+ onToolCallFinish,
39162
+ globalTelemetry.onToolCallFinish
39163
+ ]
38921
39164
  });
38922
39165
  const stepRequest = ((_i = include == null ? void 0 : include.requestBody) != null ? _i : true) ? request != null ? request : {} : { ...request, body: void 0 };
38923
39166
  const stepToolCalls = [];
@@ -39499,7 +39742,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39499
39742
  controller.enqueue({
39500
39743
  type: "file",
39501
39744
  mediaType: part.file.mediaType,
39502
- url: `data:${part.file.mediaType};base64,${part.file.base64}`
39745
+ url: `data:${part.file.mediaType};base64,${part.file.base64}`,
39746
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
39503
39747
  });
39504
39748
  break;
39505
39749
  }
@@ -41821,7 +42065,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41821
42065
  function getOpenAILanguageModelCapabilities(modelId) {
41822
42066
  const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41823
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");
41824
- const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("codex-mini") || modelId.startsWith("computer-use-preview") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
42068
+ const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41825
42069
  const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2");
41826
42070
  const systemMessageMode = isReasoningModel ? "developer" : "system";
41827
42071
  return {
@@ -43728,6 +43972,30 @@ ${user}:`]
43728
43972
  var codeInterpreter = (args = {}) => {
43729
43973
  return codeInterpreterToolFactory(args);
43730
43974
  };
43975
+ var customArgsSchema = lazySchema(
43976
+ () => zodSchema(
43977
+ object$2({
43978
+ name: string(),
43979
+ description: string().optional(),
43980
+ format: union([
43981
+ object$2({
43982
+ type: literal("grammar"),
43983
+ syntax: _enum(["regex", "lark"]),
43984
+ definition: string()
43985
+ }),
43986
+ object$2({
43987
+ type: literal("text")
43988
+ })
43989
+ ]).optional()
43990
+ })
43991
+ )
43992
+ );
43993
+ var customInputSchema = lazySchema(() => zodSchema(string()));
43994
+ var customToolFactory = createProviderToolFactory({
43995
+ id: "openai.custom",
43996
+ inputSchema: customInputSchema
43997
+ });
43998
+ var customTool = (args) => customToolFactory(args);
43731
43999
  var comparisonFilterSchema = object$2({
43732
44000
  key: string(),
43733
44001
  type: _enum(["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"]),
@@ -44080,6 +44348,16 @@ ${user}:`]
44080
44348
  *
44081
44349
  */
44082
44350
  applyPatch,
44351
+ /**
44352
+ * Custom tools let callers constrain model output to a grammar (regex or
44353
+ * Lark syntax). The model returns a `custom_tool_call` output item whose
44354
+ * `input` field is a string matching the specified grammar.
44355
+ *
44356
+ * @param name - The name of the custom tool.
44357
+ * @param description - An optional description of the tool.
44358
+ * @param format - The output format constraint (grammar type, syntax, and definition).
44359
+ */
44360
+ customTool,
44083
44361
  /**
44084
44362
  * The Code Interpreter tool allows models to write and run Python code in a
44085
44363
  * sandboxed environment to solve complex problems in domains like data analysis,
@@ -44120,7 +44398,7 @@ ${user}:`]
44120
44398
  * Local shell is a tool that allows agents to run shell commands locally
44121
44399
  * on a machine you or the user provides.
44122
44400
  *
44123
- * Supported models: `gpt-5-codex` and `codex-mini-latest`
44401
+ * Supported models: `gpt-5-codex`
44124
44402
  */
44125
44403
  localShell,
44126
44404
  /**
@@ -44218,9 +44496,10 @@ ${user}:`]
44218
44496
  hasConversation = false,
44219
44497
  hasLocalShellTool = false,
44220
44498
  hasShellTool = false,
44221
- hasApplyPatchTool = false
44499
+ hasApplyPatchTool = false,
44500
+ customProviderToolNames
44222
44501
  }) {
44223
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
44502
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
44224
44503
  const input = [];
44225
44504
  const warnings = [];
44226
44505
  const processedApprovalIds = /* @__PURE__ */ new Set();
@@ -44389,6 +44668,16 @@ ${user}:`]
44389
44668
  });
44390
44669
  break;
44391
44670
  }
44671
+ if (customProviderToolNames == null ? void 0 : customProviderToolNames.has(resolvedToolName)) {
44672
+ input.push({
44673
+ type: "custom_tool_call",
44674
+ call_id: part.toolCallId,
44675
+ name: resolvedToolName,
44676
+ input: typeof part.input === "string" ? part.input : JSON.stringify(part.input),
44677
+ id: id2
44678
+ });
44679
+ break;
44680
+ }
44392
44681
  input.push({
44393
44682
  type: "function_call",
44394
44683
  call_id: part.toolCallId,
@@ -44593,6 +44882,61 @@ ${user}:`]
44593
44882
  });
44594
44883
  continue;
44595
44884
  }
44885
+ if (customProviderToolNames == null ? void 0 : customProviderToolNames.has(resolvedToolName)) {
44886
+ let outputValue;
44887
+ switch (output.type) {
44888
+ case "text":
44889
+ case "error-text":
44890
+ outputValue = output.value;
44891
+ break;
44892
+ case "execution-denied":
44893
+ outputValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
44894
+ break;
44895
+ case "json":
44896
+ case "error-json":
44897
+ outputValue = JSON.stringify(output.value);
44898
+ break;
44899
+ case "content":
44900
+ outputValue = output.value.map((item) => {
44901
+ var _a22;
44902
+ switch (item.type) {
44903
+ case "text":
44904
+ return { type: "input_text", text: item.text };
44905
+ case "image-data":
44906
+ return {
44907
+ type: "input_image",
44908
+ image_url: `data:${item.mediaType};base64,${item.data}`
44909
+ };
44910
+ case "image-url":
44911
+ return {
44912
+ type: "input_image",
44913
+ image_url: item.url
44914
+ };
44915
+ case "file-data":
44916
+ return {
44917
+ type: "input_file",
44918
+ filename: (_a22 = item.filename) != null ? _a22 : "data",
44919
+ file_data: `data:${item.mediaType};base64,${item.data}`
44920
+ };
44921
+ default:
44922
+ warnings.push({
44923
+ type: "other",
44924
+ message: `unsupported custom tool content part type: ${item.type}`
44925
+ });
44926
+ return void 0;
44927
+ }
44928
+ }).filter(isNonNullable);
44929
+ break;
44930
+ default:
44931
+ outputValue = "";
44932
+ }
44933
+ input.push({
44934
+ type: "custom_tool_call_output",
44935
+ call_id: part.toolCallId,
44936
+ output: outputValue
44937
+ });
44938
+ continue;
44939
+ }
44596
44940
  let contentValue;
44597
44941
  switch (output.type) {
44598
44942
  case "text":
@@ -44600,7 +44944,7 @@ ${user}:`]
44600
44944
  contentValue = output.value;
44601
44945
  break;
44602
44946
  case "execution-denied":
44603
- contentValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
44947
+ contentValue = (_m = output.reason) != null ? _m : "Tool execution denied.";
44604
44948
  break;
44605
44949
  case "json":
44606
44950
  case "error-json":
@@ -44809,6 +45153,13 @@ ${user}:`]
44809
45153
  })
44810
45154
  ])
44811
45155
  }),
45156
+ object$2({
45157
+ type: literal("custom_tool_call"),
45158
+ id: string(),
45159
+ call_id: string(),
45160
+ name: string(),
45161
+ input: string()
45162
+ }),
44812
45163
  object$2({
44813
45164
  type: literal("shell_call"),
44814
45165
  id: string(),
@@ -44861,6 +45212,14 @@ ${user}:`]
44861
45212
  arguments: string(),
44862
45213
  status: literal("completed")
44863
45214
  }),
45215
+ object$2({
45216
+ type: literal("custom_tool_call"),
45217
+ id: string(),
45218
+ call_id: string(),
45219
+ name: string(),
45220
+ input: string(),
45221
+ status: literal("completed")
45222
+ }),
44864
45223
  object$2({
44865
45224
  type: literal("code_interpreter_call"),
44866
45225
  id: string(),
@@ -45044,6 +45403,12 @@ ${user}:`]
45044
45403
  output_index: number$1(),
45045
45404
  delta: string()
45046
45405
  }),
45406
+ object$2({
45407
+ type: literal("response.custom_tool_call_input.delta"),
45408
+ item_id: string(),
45409
+ output_index: number$1(),
45410
+ delta: string()
45411
+ }),
45047
45412
  object$2({
45048
45413
  type: literal("response.image_generation_call.partial_image"),
45049
45414
  item_id: string(),
@@ -45291,6 +45656,13 @@ ${user}:`]
45291
45656
  arguments: string(),
45292
45657
  id: string()
45293
45658
  }),
45659
+ object$2({
45660
+ type: literal("custom_tool_call"),
45661
+ call_id: string(),
45662
+ name: string(),
45663
+ input: string(),
45664
+ id: string()
45665
+ }),
45294
45666
  object$2({
45295
45667
  type: literal("computer_call"),
45296
45668
  id: string(),
@@ -45574,14 +45946,18 @@ ${user}:`]
45574
45946
  );
45575
45947
  async function prepareResponsesTools({
45576
45948
  tools,
45577
- toolChoice
45949
+ toolChoice,
45950
+ toolNameMapping,
45951
+ customProviderToolNames
45578
45952
  }) {
45953
+ var _a10;
45579
45954
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
45580
45955
  const toolWarnings = [];
45581
45956
  if (tools == null) {
45582
45957
  return { tools: void 0, toolChoice: void 0, toolWarnings };
45583
45958
  }
45584
45959
  const openaiTools2 = [];
45960
+ const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
45585
45961
  for (const tool2 of tools) {
45586
45962
  switch (tool2.type) {
45587
45963
  case "function":
@@ -45723,6 +46099,20 @@ ${user}:`]
45723
46099
  });
45724
46100
  break;
45725
46101
  }
46102
+ case "openai.custom": {
46103
+ const args = await validateTypes$1({
46104
+ value: tool2.args,
46105
+ schema: customArgsSchema
46106
+ });
46107
+ openaiTools2.push({
46108
+ type: "custom",
46109
+ name: args.name,
46110
+ description: args.description,
46111
+ format: args.format
46112
+ });
46113
+ resolvedCustomProviderToolNames.add(args.name);
46114
+ break;
46115
+ }
45726
46116
  }
45727
46117
  break;
45728
46118
  }
@@ -45743,12 +46133,14 @@ ${user}:`]
45743
46133
  case "none":
45744
46134
  case "required":
45745
46135
  return { tools: openaiTools2, toolChoice: type2, toolWarnings };
45746
- case "tool":
46136
+ case "tool": {
46137
+ const resolvedToolName = (_a10 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _a10 : toolChoice.toolName;
45747
46138
  return {
45748
46139
  tools: openaiTools2,
45749
- toolChoice: toolChoice.toolName === "code_interpreter" || toolChoice.toolName === "file_search" || toolChoice.toolName === "image_generation" || toolChoice.toolName === "web_search_preview" || toolChoice.toolName === "web_search" || toolChoice.toolName === "mcp" || toolChoice.toolName === "apply_patch" ? { type: toolChoice.toolName } : { type: "function", name: toolChoice.toolName },
46140
+ 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 },
45750
46141
  toolWarnings
45751
46142
  };
46143
+ }
45752
46144
  default: {
45753
46145
  const _exhaustiveCheck = type2;
45754
46146
  throw new UnsupportedFunctionalityError$1({
@@ -45897,7 +46289,19 @@ ${user}:`]
45897
46289
  "openai.web_search_preview": "web_search_preview",
45898
46290
  "openai.mcp": "mcp",
45899
46291
  "openai.apply_patch": "apply_patch"
45900
- }
46292
+ },
46293
+ resolveProviderToolName: (tool2) => tool2.id === "openai.custom" ? tool2.args.name : void 0
46294
+ });
46295
+ const customProviderToolNames = /* @__PURE__ */ new Set();
46296
+ const {
46297
+ tools: openaiTools2,
46298
+ toolChoice: openaiToolChoice,
46299
+ toolWarnings
46300
+ } = await prepareResponsesTools({
46301
+ tools,
46302
+ toolChoice,
46303
+ toolNameMapping,
46304
+ customProviderToolNames
45901
46305
  });
45902
46306
  const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({
45903
46307
  prompt,
@@ -45909,7 +46313,8 @@ ${user}:`]
45909
46313
  hasConversation: (openaiOptions == null ? void 0 : openaiOptions.conversation) != null,
45910
46314
  hasLocalShellTool: hasOpenAITool("openai.local_shell"),
45911
46315
  hasShellTool: hasOpenAITool("openai.shell"),
45912
- hasApplyPatchTool: hasOpenAITool("openai.apply_patch")
46316
+ hasApplyPatchTool: hasOpenAITool("openai.apply_patch"),
46317
+ customProviderToolNames: customProviderToolNames.size > 0 ? customProviderToolNames : void 0
45913
46318
  });
45914
46319
  warnings.push(...inputWarnings);
45915
46320
  const strictJsonSchema = (_d = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _d : true;
@@ -46042,14 +46447,6 @@ ${user}:`]
46042
46447
  });
46043
46448
  delete baseArgs.service_tier;
46044
46449
  }
46045
- const {
46046
- tools: openaiTools2,
46047
- toolChoice: openaiToolChoice,
46048
- toolWarnings
46049
- } = await prepareResponsesTools({
46050
- tools,
46051
- toolChoice
46052
- });
46053
46450
  const shellToolEnvType = (_i = (_h = (_g = tools == null ? void 0 : tools.find(
46054
46451
  (tool2) => tool2.type === "provider" && tool2.id === "openai.shell"
46055
46452
  )) == null ? void 0 : _g.args) == null ? void 0 : _h.environment) == null ? void 0 : _i.type;
@@ -46299,6 +46696,22 @@ ${user}:`]
46299
46696
  });
46300
46697
  break;
46301
46698
  }
46699
+ case "custom_tool_call": {
46700
+ hasFunctionCall = true;
46701
+ const toolName = toolNameMapping.toCustomToolName(part.name);
46702
+ content.push({
46703
+ type: "tool-call",
46704
+ toolCallId: part.call_id,
46705
+ toolName,
46706
+ input: JSON.stringify(part.input),
46707
+ providerMetadata: {
46708
+ [providerOptionsName]: {
46709
+ itemId: part.id
46710
+ }
46711
+ }
46712
+ });
46713
+ break;
46714
+ }
46302
46715
  case "web_search_call": {
46303
46716
  content.push({
46304
46717
  type: "tool-call",
@@ -46557,6 +46970,19 @@ ${user}:`]
46557
46970
  id: value.item.call_id,
46558
46971
  toolName: value.item.name
46559
46972
  });
46973
+ } else if (value.item.type === "custom_tool_call") {
46974
+ const toolName = toolNameMapping.toCustomToolName(
46975
+ value.item.name
46976
+ );
46977
+ ongoingToolCalls[value.output_index] = {
46978
+ toolName,
46979
+ toolCallId: value.item.call_id
46980
+ };
46981
+ controller.enqueue({
46982
+ type: "tool-input-start",
46983
+ id: value.item.call_id,
46984
+ toolName
46985
+ });
46560
46986
  } else if (value.item.type === "web_search_call") {
46561
46987
  ongoingToolCalls[value.output_index] = {
46562
46988
  toolName: toolNameMapping.toCustomToolName(
@@ -46741,6 +47167,27 @@ ${user}:`]
46741
47167
  }
46742
47168
  }
46743
47169
  });
47170
+ } else if (value.item.type === "custom_tool_call") {
47171
+ ongoingToolCalls[value.output_index] = void 0;
47172
+ hasFunctionCall = true;
47173
+ const toolName = toolNameMapping.toCustomToolName(
47174
+ value.item.name
47175
+ );
47176
+ controller.enqueue({
47177
+ type: "tool-input-end",
47178
+ id: value.item.call_id
47179
+ });
47180
+ controller.enqueue({
47181
+ type: "tool-call",
47182
+ toolCallId: value.item.call_id,
47183
+ toolName,
47184
+ input: JSON.stringify(value.item.input),
47185
+ providerMetadata: {
47186
+ [providerOptionsName]: {
47187
+ itemId: value.item.id
47188
+ }
47189
+ }
47190
+ });
46744
47191
  } else if (value.item.type === "web_search_call") {
46745
47192
  ongoingToolCalls[value.output_index] = void 0;
46746
47193
  controller.enqueue({
@@ -46990,6 +47437,15 @@ ${user}:`]
46990
47437
  delta: value.delta
46991
47438
  });
46992
47439
  }
47440
+ } else if (isResponseCustomToolCallInputDeltaChunk(value)) {
47441
+ const toolCall = ongoingToolCalls[value.output_index];
47442
+ if (toolCall != null) {
47443
+ controller.enqueue({
47444
+ type: "tool-input-delta",
47445
+ id: toolCall.toolCallId,
47446
+ delta: value.delta
47447
+ });
47448
+ }
46993
47449
  } else if (isResponseApplyPatchCallOperationDiffDeltaChunk(value)) {
46994
47450
  const toolCall = ongoingToolCalls[value.output_index];
46995
47451
  if (toolCall == null ? void 0 : toolCall.applyPatch) {
@@ -47250,6 +47706,9 @@ ${user}:`]
47250
47706
  function isResponseFunctionCallArgumentsDeltaChunk(chunk) {
47251
47707
  return chunk.type === "response.function_call_arguments.delta";
47252
47708
  }
47709
+ function isResponseCustomToolCallInputDeltaChunk(chunk) {
47710
+ return chunk.type === "response.custom_tool_call_input.delta";
47711
+ }
47253
47712
  function isResponseImageGenerationCallPartialImageChunk(chunk) {
47254
47713
  return chunk.type === "response.image_generation_call.partial_image";
47255
47714
  }
@@ -47631,7 +48090,7 @@ ${user}:`]
47631
48090
  };
47632
48091
  }
47633
48092
  };
47634
- var VERSION$2 = "3.0.36";
48093
+ var VERSION$2 = "3.0.41";
47635
48094
  function createOpenAI(options = {}) {
47636
48095
  var _a10, _b9;
47637
48096
  const baseURL = (_a10 = withoutTrailingSlash$1(
@@ -49451,9 +49910,13 @@ Error message: ${getErrorMessage(cause)}`,
49451
49910
  if (toolEntries.length === 0) {
49452
49911
  return "";
49453
49912
  }
49454
- let prompt = "\n\n# 工具调用\n\n";
49455
- prompt += "你可以根据需要调用以下工具:\n\n";
49456
- prompt += "<tools>\n";
49913
+ let prompt = `
49914
+ # 工具调用
49915
+
49916
+ 你可以根据需要调用以下工具:
49917
+
49918
+ <tools>
49919
+ `;
49457
49920
  toolEntries.forEach(([toolName, tool2]) => {
49458
49921
  const toolInfo = tool2;
49459
49922
  const description2 = toolInfo.description || "无描述";
@@ -49466,23 +49929,36 @@ Error message: ${getErrorMessage(cause)}`,
49466
49929
  prompt += `${JSON.stringify(toolJson, null, 2)}
49467
49930
  `;
49468
49931
  });
49469
- prompt += "</tools>\n\n";
49470
- prompt += "## 工具调用格式\n\n";
49471
- prompt += "要调用工具,请使用以下 XML 格式:\n";
49472
- prompt += "Thought: [你的思考过程]\n";
49473
- prompt += '<tool_call>{"name": "toolName", "arguments": {"arg1": "value1"}}</tool_call>\n\n';
49474
- prompt += "工具执行后,你将收到 <tool_response> 格式的结果。你可以继续思考或调用其他工具。\n\n";
49475
- prompt += "## 使用示例\n\n";
49476
- prompt += '如果用户要求"获取今天的日期",你可以这样调用工具:\n';
49477
- prompt += "Thought: 用户想要获取今天的日期,我需要调用日期相关的工具。\n";
49478
- prompt += '<tool_call>{"name": "get-today", "arguments": {}}</tool_call>\n\n';
49479
- prompt += "然后等待工具返回结果(Observation),再根据结果给出最终答案。\n\n";
49480
- prompt += "## 任务完成\n\n";
49481
- prompt += "当任务完成或无法继续时,直接给出最终答案即可。\n\n";
49482
- prompt += "**重要提示**:\n";
49483
- prompt += "- 必须严格按照 XML 格式调用工具\n";
49484
- prompt += "- arguments 必须是有效的 JSON 格式\n";
49485
- prompt += "- 如果不需要调用工具,直接给出最终答案即可\n";
49932
+ prompt += `
49933
+ </tools>
49934
+
49935
+ ## 工具调用格式
49936
+
49937
+ 要调用工具,请使用以下 XML 格式:
49938
+ Thought: [你的思考过程]
49939
+ <tool_call>
49940
+ {"name": "toolName", "arguments": {"arg1": "value1"}}
49941
+ </tool_call>
49942
+
49943
+ 工具执行后,你将收到 <tool_response> 格式的结果。你可以继续思考或调用其他工具。
49944
+
49945
+ ## 使用示例
49946
+
49947
+ 如果用户要求"获取今天的日期",你可以这样调用工具:
49948
+ Thought: 用户想要获取今天的日期,我需要调用日期相关的工具。
49949
+ <tool_call>{"name": "get-today", "arguments": {}}</tool_call>
49950
+
49951
+ 然后等待工具返回结果(Observation),再根据结果给出最终答案。
49952
+
49953
+ ## 任务完成
49954
+
49955
+ 当任务完成或无法继续时,直接给出最终答案即可。
49956
+
49957
+ **重要提示**:
49958
+ - 必须严格按照 XML 格式调用工具
49959
+ - arguments 必须是有效的 JSON 格式
49960
+ - 如果不需要调用工具,直接给出最终答案即可
49961
+ `;
49486
49962
  return prompt;
49487
49963
  }
49488
49964
  function parseReActAction(text2, availableTools) {
@@ -49702,15 +50178,24 @@ Error message: ${getErrorMessage(cause)}`,
49702
50178
  }
49703
50179
  this.onUpdatedTools?.();
49704
50180
  }
49705
- /** 创建临时允许调用的tools集合 */
49706
- _tempMergeTools(extraTool = {}) {
49707
- const toolsResult = Object.values(this.mcpTools).reduce((acc, curr) => ({ ...acc, ...curr }), {});
50181
+ /** 创建临时允许调用的 tools 集合,合并 mcpTools 与 extraTool */
50182
+ _tempMergeTools(extraTool = {}, deleteIgnored = true) {
50183
+ const toolsResult = Object.values(this.mcpTools).reduce(
50184
+ (acc, curr) => ({ ...acc, ...curr }),
50185
+ {}
50186
+ );
49708
50187
  Object.assign(toolsResult, extraTool);
49709
- this.ignoreToolnames.forEach((name16) => {
49710
- delete toolsResult[name16];
49711
- });
50188
+ if (deleteIgnored) {
50189
+ this.ignoreToolnames.forEach((name16) => {
50190
+ delete toolsResult[name16];
50191
+ });
50192
+ }
49712
50193
  return toolsResult;
49713
50194
  }
50195
+ /** 获取当前激活的 tools 名称列表(过滤 ignoreToolnames) */
50196
+ _getActiveToolNames(tools) {
50197
+ return Object.keys(tools).filter((name16) => !this.ignoreToolnames.includes(name16));
50198
+ }
49714
50199
  /** 生成 ReAct 模式的系统提示词(包含工具描述) */
49715
50200
  _generateReActSystemPrompt(tools, modelName, baseSystemPrompt) {
49716
50201
  const toolsPrompt = generateReActToolsPrompt(tools);
@@ -50054,12 +50539,14 @@ ${observationText}
50054
50539
  throw new Error("LLM is not initialized");
50055
50540
  }
50056
50541
  await this.initClientsAndTools();
50542
+ const allTools = this._tempMergeTools(options.tools, false);
50057
50543
  const chatOptions = {
50058
50544
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
50059
50545
  model: this.llm(model),
50060
50546
  stopWhen: stepCountIs(maxSteps),
50061
50547
  ...options,
50062
- tools: this._tempMergeTools(options.tools)
50548
+ tools: allTools,
50549
+ activeTools: this._getActiveToolNames(allTools)
50063
50550
  };
50064
50551
  let lastUserMessage = null;
50065
50552
  if (options.message && !options.messages) {
@@ -50089,6 +50576,454 @@ ${observationText}
50089
50576
  return this._chat(streamText, options);
50090
50577
  }
50091
50578
  }
50579
+ let overlayElement = null;
50580
+ let labelElement = null;
50581
+ let styleElement = null;
50582
+ let activeCount = 0;
50583
+ const BODY_GLOW_CLASS = "next-sdk-tool-body-glow";
50584
+ function ensureDomReady() {
50585
+ return typeof window !== "undefined" && typeof document !== "undefined";
50586
+ }
50587
+ function ensureStyleElement() {
50588
+ if (!ensureDomReady()) return;
50589
+ if (styleElement) return;
50590
+ const style = document.createElement("style");
50591
+ style.textContent = `
50592
+ .${BODY_GLOW_CLASS} {
50593
+ position: relative;
50594
+ }
50595
+
50596
+ .next-sdk-tool-overlay {
50597
+ position: fixed;
50598
+ inset: 0;
50599
+ z-index: 999999;
50600
+ pointer-events: none;
50601
+ display: flex;
50602
+ align-items: flex-end;
50603
+ justify-content: flex-start;
50604
+ padding: 0 0 18px 18px;
50605
+ background: transparent;
50606
+ animation: next-sdk-overlay-fade-in 260ms ease-out;
50607
+ }
50608
+
50609
+ .next-sdk-tool-overlay--exit {
50610
+ animation: next-sdk-overlay-fade-out 220ms ease-in forwards;
50611
+ }
50612
+
50613
+ .next-sdk-tool-overlay__glow-ring {
50614
+ display: none;
50615
+ }
50616
+
50617
+ .next-sdk-tool-overlay__panel {
50618
+ position: relative;
50619
+ min-width: min(320px, 78vw);
50620
+ max-width: min(420px, 82vw);
50621
+ padding: 10px 14px;
50622
+ border-radius: 999px;
50623
+ background:
50624
+ linear-gradient(135deg, rgba(15, 23, 42, 0.9), rgba(17, 24, 39, 0.9)),
50625
+ radial-gradient(circle at top left, rgba(96, 165, 250, 0.25), transparent 55%),
50626
+ radial-gradient(circle at bottom right, rgba(45, 212, 191, 0.22), transparent 60%);
50627
+ box-shadow:
50628
+ 0 12px 28px rgba(15, 23, 42, 0.78),
50629
+ 0 0 0 1px rgba(148, 163, 184, 0.26);
50630
+ display: flex;
50631
+ align-items: center;
50632
+ gap: 10px;
50633
+ pointer-events: none;
50634
+ transform-origin: center;
50635
+ animation: next-sdk-panel-pop-in 260ms cubic-bezier(0.18, 0.89, 0.32, 1.28);
50636
+ color: #e5e7eb;
50637
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif;
50638
+ }
50639
+
50640
+ .next-sdk-tool-overlay__indicator {
50641
+ width: 26px;
50642
+ height: 26px;
50643
+ border-radius: 999px;
50644
+ background: radial-gradient(circle at 30% 10%, #f9fafb, #93c5fd);
50645
+ box-shadow:
50646
+ 0 0 0 1px rgba(191, 219, 254, 0.6),
50647
+ 0 8px 18px rgba(37, 99, 235, 0.8),
50648
+ 0 0 28px rgba(56, 189, 248, 0.9);
50649
+ position: relative;
50650
+ flex-shrink: 0;
50651
+ display: flex;
50652
+ align-items: center;
50653
+ justify-content: center;
50654
+ overflow: hidden;
50655
+ }
50656
+
50657
+ .next-sdk-tool-overlay__indicator-orbit {
50658
+ position: absolute;
50659
+ inset: 2px;
50660
+ border-radius: inherit;
50661
+ border: 1px solid rgba(248, 250, 252, 0.6);
50662
+ box-sizing: border-box;
50663
+ opacity: 0.9;
50664
+ }
50665
+
50666
+ .next-sdk-tool-overlay__indicator-orbit::before {
50667
+ content: '';
50668
+ position: absolute;
50669
+ width: 6px;
50670
+ height: 6px;
50671
+ border-radius: 999px;
50672
+ background: #f9fafb;
50673
+ box-shadow:
50674
+ 0 0 12px rgba(248, 250, 252, 0.9),
50675
+ 0 0 24px rgba(250, 249, 246, 0.9);
50676
+ top: 0;
50677
+ left: 50%;
50678
+ transform: translate(-50%, -50%);
50679
+ transform-origin: 50% 18px;
50680
+ animation: next-sdk-indicator-orbit 1.4s linear infinite;
50681
+ }
50682
+
50683
+ .next-sdk-tool-overlay__indicator-core {
50684
+ width: 14px;
50685
+ height: 14px;
50686
+ border-radius: inherit;
50687
+ background: radial-gradient(circle at 30% 20%, #f9fafb, #bfdbfe);
50688
+ box-shadow:
50689
+ 0 0 12px rgba(248, 250, 252, 0.9),
50690
+ 0 0 32px rgba(191, 219, 254, 0.8);
50691
+ opacity: 0.96;
50692
+ }
50693
+
50694
+ .next-sdk-tool-overlay__content {
50695
+ display: flex;
50696
+ flex-direction: column;
50697
+ gap: 1px;
50698
+ min-width: 0;
50699
+ }
50700
+
50701
+ .next-sdk-tool-overlay__title {
50702
+ font-size: 11px;
50703
+ letter-spacing: 0.08em;
50704
+ text-transform: uppercase;
50705
+ color: rgba(156, 163, 175, 0.96);
50706
+ display: flex;
50707
+ align-items: center;
50708
+ gap: 6px;
50709
+ }
50710
+
50711
+ .next-sdk-tool-overlay__title-dot {
50712
+ width: 6px;
50713
+ height: 6px;
50714
+ border-radius: 999px;
50715
+ background: #22c55e;
50716
+ box-shadow:
50717
+ 0 0 8px rgba(34, 197, 94, 0.9),
50718
+ 0 0 14px rgba(22, 163, 74, 0.9);
50719
+ }
50720
+
50721
+ .next-sdk-tool-overlay__label {
50722
+ font-size: 12px;
50723
+ font-weight: 500;
50724
+ color: #e5e7eb;
50725
+ white-space: nowrap;
50726
+ text-overflow: ellipsis;
50727
+ overflow: hidden;
50728
+ }
50729
+
50730
+ @keyframes next-sdk-overlay-fade-in {
50731
+ from { opacity: 0; }
50732
+ to { opacity: 1; }
50733
+ }
50734
+
50735
+ @keyframes next-sdk-overlay-fade-out {
50736
+ from { opacity: 1; }
50737
+ to { opacity: 0; }
50738
+ }
50739
+
50740
+ @keyframes next-sdk-indicator-orbit {
50741
+ from {
50742
+ transform: translate(-50%, -50%) rotate(0deg) translateY(0);
50743
+ }
50744
+ to {
50745
+ transform: translate(-50%, -50%) rotate(360deg) translateY(0);
50746
+ }
50747
+ }
50748
+
50749
+ @keyframes next-sdk-panel-pop-in {
50750
+ 0% {
50751
+ opacity: 0;
50752
+ transform: scale(0.92) translateY(10px);
50753
+ }
50754
+ 100% {
50755
+ opacity: 1;
50756
+ transform: scale(1) translateY(0);
50757
+ }
50758
+ }
50759
+ `;
50760
+ document.head.appendChild(style);
50761
+ styleElement = style;
50762
+ }
50763
+ function ensureOverlayElement() {
50764
+ if (!ensureDomReady()) return;
50765
+ if (overlayElement) return;
50766
+ ensureStyleElement();
50767
+ const overlay = document.createElement("div");
50768
+ overlay.className = "next-sdk-tool-overlay";
50769
+ const glowRing = document.createElement("div");
50770
+ glowRing.className = "next-sdk-tool-overlay__glow-ring";
50771
+ const panel = document.createElement("div");
50772
+ panel.className = "next-sdk-tool-overlay__panel";
50773
+ const indicator = document.createElement("div");
50774
+ indicator.className = "next-sdk-tool-overlay__indicator";
50775
+ const indicatorOrbit = document.createElement("div");
50776
+ indicatorOrbit.className = "next-sdk-tool-overlay__indicator-orbit";
50777
+ const indicatorCore = document.createElement("div");
50778
+ indicatorCore.className = "next-sdk-tool-overlay__indicator-core";
50779
+ const content = document.createElement("div");
50780
+ content.className = "next-sdk-tool-overlay__content";
50781
+ const titleRow = document.createElement("div");
50782
+ titleRow.className = "next-sdk-tool-overlay__title";
50783
+ titleRow.textContent = "AI 正在调用页面工具";
50784
+ const titleDot = document.createElement("span");
50785
+ titleDot.className = "next-sdk-tool-overlay__title-dot";
50786
+ const label = document.createElement("div");
50787
+ label.className = "next-sdk-tool-overlay__label";
50788
+ titleRow.prepend(titleDot);
50789
+ content.appendChild(titleRow);
50790
+ content.appendChild(label);
50791
+ indicator.appendChild(indicatorOrbit);
50792
+ indicator.appendChild(indicatorCore);
50793
+ panel.appendChild(indicator);
50794
+ panel.appendChild(content);
50795
+ overlay.appendChild(glowRing);
50796
+ overlay.appendChild(panel);
50797
+ document.body.appendChild(overlay);
50798
+ overlayElement = overlay;
50799
+ labelElement = label;
50800
+ }
50801
+ function updateOverlay(config2) {
50802
+ if (!ensureDomReady()) return;
50803
+ ensureOverlayElement();
50804
+ if (!overlayElement || !labelElement) return;
50805
+ overlayElement.classList.remove("next-sdk-tool-overlay--exit");
50806
+ labelElement.textContent = config2.label;
50807
+ }
50808
+ function removeOverlayWithAnimation() {
50809
+ if (!overlayElement) return;
50810
+ overlayElement.classList.add("next-sdk-tool-overlay--exit");
50811
+ const localOverlay = overlayElement;
50812
+ let handled = false;
50813
+ let timerId;
50814
+ const handle = () => {
50815
+ if (handled) return;
50816
+ handled = true;
50817
+ if (timerId !== void 0) {
50818
+ clearTimeout(timerId);
50819
+ timerId = void 0;
50820
+ }
50821
+ if (localOverlay.parentNode) {
50822
+ localOverlay.parentNode.removeChild(localOverlay);
50823
+ }
50824
+ if (overlayElement === localOverlay) {
50825
+ overlayElement = null;
50826
+ labelElement = null;
50827
+ }
50828
+ localOverlay.removeEventListener("animationend", handle);
50829
+ };
50830
+ localOverlay.addEventListener("animationend", handle);
50831
+ timerId = setTimeout(handle, 500);
50832
+ }
50833
+ function showToolInvokeEffect(config2) {
50834
+ if (!ensureDomReady()) return;
50835
+ activeCount += 1;
50836
+ updateOverlay(config2);
50837
+ }
50838
+ function hideToolInvokeEffect() {
50839
+ if (!ensureDomReady() || activeCount <= 0) return;
50840
+ activeCount -= 1;
50841
+ if (activeCount === 0) {
50842
+ removeOverlayWithAnimation();
50843
+ }
50844
+ }
50845
+ function resolveRuntimeEffectConfig(toolName, toolTitle, value) {
50846
+ if (!value) return void 0;
50847
+ const baseLabel = toolTitle || toolName;
50848
+ if (typeof value === "boolean") {
50849
+ return value ? { label: baseLabel } : void 0;
50850
+ }
50851
+ return {
50852
+ label: value.label || baseLabel
50853
+ };
50854
+ }
50855
+ const MSG_TOOL_CALL = "next-sdk:tool-call";
50856
+ const MSG_TOOL_RESPONSE = "next-sdk:tool-response";
50857
+ const MSG_PAGE_READY = "next-sdk:page-ready";
50858
+ const MSG_PAGE_LEAVE = "next-sdk:page-leave";
50859
+ const MSG_REMOTER_READY = "next-sdk:remoter-ready";
50860
+ const MSG_ROUTE_STATE_INITIAL = "next-sdk:route-state-initial";
50861
+ const activePages = /* @__PURE__ */ new Map();
50862
+ const broadcastTargets = /* @__PURE__ */ new Set();
50863
+ function initBroadcastTargets() {
50864
+ if (typeof window !== "undefined") {
50865
+ broadcastTargets.add({ win: window, origin: window.location.origin || "*" });
50866
+ }
50867
+ }
50868
+ initBroadcastTargets();
50869
+ function broadcastRouteChange(type2, route) {
50870
+ const msg = { type: type2, route };
50871
+ broadcastTargets.forEach(({ win, origin }) => {
50872
+ try {
50873
+ win.postMessage(msg, origin);
50874
+ } catch {
50875
+ }
50876
+ });
50877
+ }
50878
+ function setupIframeRemoterBridge() {
50879
+ if (typeof window === "undefined") return;
50880
+ window.addEventListener("message", (event) => {
50881
+ if (event.data?.type !== MSG_REMOTER_READY || !event.source) return;
50882
+ if (event.origin !== window.location.origin) return;
50883
+ const target = event.source;
50884
+ broadcastTargets.add({ win: target, origin: event.origin || "*" });
50885
+ const payload = {
50886
+ type: MSG_ROUTE_STATE_INITIAL,
50887
+ toolRouteMap: Array.from(toolRouteMap.entries()),
50888
+ activeRoutes: Array.from(activePages.keys())
50889
+ };
50890
+ try {
50891
+ target.postMessage(payload, event.origin || "*");
50892
+ } catch {
50893
+ }
50894
+ });
50895
+ }
50896
+ setupIframeRemoterBridge();
50897
+ const toolRouteMap = /* @__PURE__ */ new Map();
50898
+ function getToolRouteMap() {
50899
+ return new Map(toolRouteMap);
50900
+ }
50901
+ function getActiveRoutes() {
50902
+ return new Set(activePages.keys());
50903
+ }
50904
+ let _navigator = null;
50905
+ function setNavigator(fn) {
50906
+ _navigator = fn;
50907
+ }
50908
+ function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
50909
+ return (input) => {
50910
+ const callId = randomUUID();
50911
+ return new Promise((resolve2, reject) => {
50912
+ let timer;
50913
+ let readyHandler;
50914
+ const cleanup = () => {
50915
+ clearTimeout(timer);
50916
+ window.removeEventListener("message", responseHandler);
50917
+ if (readyHandler) {
50918
+ window.removeEventListener("message", readyHandler);
50919
+ }
50920
+ if (effectConfig) {
50921
+ hideToolInvokeEffect();
50922
+ }
50923
+ };
50924
+ timer = setTimeout(() => {
50925
+ cleanup();
50926
+ reject(new Error(`工具 [${name16}] 调用超时 (${timeout}ms),请检查目标页面是否正确调用了 registerPageTool`));
50927
+ }, timeout);
50928
+ const responseHandler = (event) => {
50929
+ if (event.source === window && event.data?.type === MSG_TOOL_RESPONSE && event.data.callId === callId) {
50930
+ cleanup();
50931
+ event.data.error ? reject(new Error(event.data.error)) : resolve2(event.data.result);
50932
+ }
50933
+ };
50934
+ window.addEventListener("message", responseHandler);
50935
+ const sendCall = () => {
50936
+ window.postMessage({ type: MSG_TOOL_CALL, callId, toolName: name16, route, input }, window.location.origin || "*");
50937
+ };
50938
+ let callSent = false;
50939
+ const sendCallOnce = () => {
50940
+ if (callSent) return;
50941
+ callSent = true;
50942
+ sendCall();
50943
+ };
50944
+ const run = async () => {
50945
+ try {
50946
+ if (effectConfig) {
50947
+ showToolInvokeEffect(effectConfig);
50948
+ }
50949
+ if (activePages.get(route)) {
50950
+ sendCallOnce();
50951
+ return;
50952
+ }
50953
+ readyHandler = (event) => {
50954
+ if (event.source === window && event.data?.type === MSG_PAGE_READY && event.data.route === route) {
50955
+ window.removeEventListener("message", readyHandler);
50956
+ sendCallOnce();
50957
+ }
50958
+ };
50959
+ window.addEventListener("message", readyHandler);
50960
+ if (_navigator) {
50961
+ await _navigator(route);
50962
+ }
50963
+ if (activePages.get(route)) {
50964
+ window.removeEventListener("message", readyHandler);
50965
+ sendCallOnce();
50966
+ }
50967
+ } catch (err) {
50968
+ cleanup();
50969
+ reject(err instanceof Error ? err : new Error(String(err)));
50970
+ }
50971
+ };
50972
+ void run();
50973
+ });
50974
+ };
50975
+ }
50976
+ function withPageTools(server) {
50977
+ return new Proxy(server, {
50978
+ get(target, prop, receiver) {
50979
+ if (prop === "registerTool") {
50980
+ return (name16, config2, handlerOrRoute) => {
50981
+ const rawRegister = target.registerTool.bind(target);
50982
+ if (typeof handlerOrRoute === "function") {
50983
+ return rawRegister(name16, config2, handlerOrRoute);
50984
+ }
50985
+ const { route, timeout, invokeEffect } = handlerOrRoute;
50986
+ toolRouteMap.set(name16, route);
50987
+ const effectConfig = resolveRuntimeEffectConfig(name16, config2?.title, invokeEffect);
50988
+ return rawRegister(name16, config2, buildPageHandler(name16, route, timeout, effectConfig));
50989
+ };
50990
+ }
50991
+ return Reflect.get(target, prop, receiver);
50992
+ }
50993
+ });
50994
+ }
50995
+ function registerPageTool(options) {
50996
+ const { route: routeOption, handlers } = options;
50997
+ const normalizeRoute = (value) => value.replace(/\/+$/, "") || "/";
50998
+ const route = normalizeRoute(routeOption ?? window.location.pathname);
50999
+ const handleMessage = async (event) => {
51000
+ if (event.source !== window || event.data?.type !== MSG_TOOL_CALL || normalizeRoute(String(event.data?.route ?? "")) !== route || !(event.data.toolName in handlers)) {
51001
+ return;
51002
+ }
51003
+ const { callId, toolName, input } = event.data;
51004
+ try {
51005
+ const result = await handlers[toolName](input);
51006
+ window.postMessage({ type: MSG_TOOL_RESPONSE, callId, result }, window.location.origin || "*");
51007
+ } catch (err) {
51008
+ window.postMessage(
51009
+ {
51010
+ type: MSG_TOOL_RESPONSE,
51011
+ callId,
51012
+ error: err instanceof Error ? err.message : String(err)
51013
+ },
51014
+ window.location.origin || "*"
51015
+ );
51016
+ }
51017
+ };
51018
+ activePages.set(route, true);
51019
+ window.addEventListener("message", handleMessage);
51020
+ broadcastRouteChange(MSG_PAGE_READY, route);
51021
+ return () => {
51022
+ activePages.delete(route);
51023
+ window.removeEventListener("message", handleMessage);
51024
+ broadcastRouteChange(MSG_PAGE_LEAVE, route);
51025
+ };
51026
+ }
50092
51027
  const MAIN_SKILL_PATH_REG = /^\.\/[^/]+\/SKILL\.md$/;
50093
51028
  const FRONT_MATTER_BLOCK_REG = /^---\s*\n([\s\S]+?)\s*\n---/;
50094
51029
  function parseSkillFrontMatter(content) {
@@ -50101,14 +51036,27 @@ ${observationText}
50101
51036
  const description2 = descMatch?.[1]?.trim();
50102
51037
  return name16 && description2 ? { name: name16, description: description2 } : null;
50103
51038
  }
51039
+ function normalizeSkillModuleKeys(modules) {
51040
+ const result = {};
51041
+ for (const [key, content] of Object.entries(modules)) {
51042
+ const normalizedKey = key.replace(/\\/g, "/");
51043
+ const skillsIndex = normalizedKey.lastIndexOf("skills/");
51044
+ const relativePath = skillsIndex >= 0 ? normalizedKey.slice(skillsIndex + 7) : normalizedKey;
51045
+ const standardPath = relativePath.startsWith("./") ? relativePath : `./${relativePath}`;
51046
+ result[standardPath] = content;
51047
+ }
51048
+ return result;
51049
+ }
50104
51050
  function getMainSkillPaths(modules) {
50105
- return Object.keys(modules).filter((path) => MAIN_SKILL_PATH_REG.test(path));
51051
+ const normalized = normalizeSkillModuleKeys(modules);
51052
+ return Object.keys(normalized).filter((path) => MAIN_SKILL_PATH_REG.test(path));
50106
51053
  }
50107
51054
  function getSkillOverviews(modules) {
50108
- const mainPaths = getMainSkillPaths(modules);
51055
+ const normalized = normalizeSkillModuleKeys(modules);
51056
+ const mainPaths = Object.keys(normalized).filter((path) => MAIN_SKILL_PATH_REG.test(path));
50109
51057
  const list = [];
50110
51058
  for (const path of mainPaths) {
50111
- const content = modules[path];
51059
+ const content = normalized[path];
50112
51060
  if (!content) continue;
50113
51061
  const parsed = parseSkillFrontMatter(content);
50114
51062
  if (!parsed) continue;
@@ -50130,34 +51078,100 @@ ${lines.join("\n")}
50130
51078
  当需要用到某技能时,请使用 get_skill_content 工具获取该技能的完整文档内容。`;
50131
51079
  }
50132
51080
  function getSkillMdPaths(modules) {
50133
- return Object.keys(modules);
51081
+ const normalized = normalizeSkillModuleKeys(modules);
51082
+ return Object.keys(normalized);
50134
51083
  }
50135
51084
  function getSkillMdContent(modules, path) {
50136
- return modules[path];
51085
+ const normalized = normalizeSkillModuleKeys(modules);
51086
+ const exactMatch = normalized[path];
51087
+ if (exactMatch) return exactMatch;
51088
+ const suffix = path.replace(/^\.?\//, "/");
51089
+ const matchingKey = Object.keys(normalized).find((key) => key.endsWith(suffix));
51090
+ return matchingKey ? normalized[matchingKey] : void 0;
50137
51091
  }
50138
51092
  function getMainSkillPathByName(modules, name16) {
50139
- return getMainSkillPaths(modules).find((p) => p.startsWith(`./${name16}/SKILL.md`));
51093
+ const normalizedModules = normalizeSkillModuleKeys(modules);
51094
+ const paths = getMainSkillPaths(normalizedModules);
51095
+ const dirMatch = paths.find((p) => p.startsWith(`./${name16}/SKILL.md`));
51096
+ if (dirMatch) return dirMatch;
51097
+ for (const p of paths) {
51098
+ const content = normalizedModules[p];
51099
+ if (content) {
51100
+ const parsed = parseSkillFrontMatter(content);
51101
+ if (parsed && parsed.name === name16) {
51102
+ return p;
51103
+ }
51104
+ }
51105
+ }
51106
+ return void 0;
50140
51107
  }
51108
+ const SKILL_INPUT_SCHEMA = objectType({
51109
+ skillName: stringType().optional().describe(
51110
+ '进入某个技能的主入口名称。优先匹配技能的目录名(如 ecommerce),或者技能的中文名称(如"客户价保单创建及审核")。'
51111
+ ),
51112
+ path: stringType().optional().describe("你想查阅的文档的路径。如 ./calculator/SKILL.md 或从其他文档里看到的相对路径 ./reference/inventory.md。"),
51113
+ currentPath: stringType().optional().describe(
51114
+ "你当前正在阅读的文档路径(如果有)。比如你刚刚读取了 ./ecommerce/SKILL.md,请把这个路径原样传回来,这样系统才能根据你的相对路径准确找到下一份文件。"
51115
+ )
51116
+ });
50141
51117
  function createSkillTools(modules) {
51118
+ const normalizedModules = normalizeSkillModuleKeys(modules);
50142
51119
  const getSkillContent = tool({
50143
- description: "根据技能名称或文档路径获取该技能的完整文档内容。传入 skillName(如 calculator)或 path(如 ./calculator/SKILL.md)。支持 .md、.json、.xml 等各类文本格式文件。",
50144
- inputSchema: objectType({
50145
- skillName: stringType().optional().describe("技能名称,与目录名一致,如 calculator"),
50146
- path: stringType().optional().describe("文档相对路径,如 ./calculator/SKILL.md 或 ./product-guide/reference/xxx.json")
50147
- }),
51120
+ description: "根据技能名称或文档路径获取该技能的完整文档内容。如果你想根据相对路径查阅文件,请务必同时提供你当前所在的文件路径 currentPath。",
51121
+ inputSchema: SKILL_INPUT_SCHEMA,
50148
51122
  execute: (args) => {
50149
- const { skillName, path: pathArg } = args;
51123
+ const { skillName, path: pathArg, currentPath: currentPathArg } = args;
50150
51124
  let content;
51125
+ let resolvedPath = "";
50151
51126
  if (pathArg) {
50152
- content = getSkillMdContent(modules, pathArg);
51127
+ let basePathContext = ".";
51128
+ if (currentPathArg) {
51129
+ const lastSlashIndex = currentPathArg.lastIndexOf("/");
51130
+ if (lastSlashIndex >= 0) {
51131
+ basePathContext = currentPathArg.slice(0, lastSlashIndex);
51132
+ }
51133
+ }
51134
+ const dummyBase = `http://localhost/${basePathContext}/`;
51135
+ const url2 = new URL(pathArg, dummyBase);
51136
+ resolvedPath = "." + url2.pathname;
51137
+ content = getSkillMdContent(normalizedModules, resolvedPath);
51138
+ if (content === void 0 && (pathArg.startsWith("./") || pathArg.startsWith("../")) && currentPathArg) {
51139
+ const baseParts = currentPathArg.split("/");
51140
+ if (baseParts.length >= 2) {
51141
+ const skillRoot = baseParts[1];
51142
+ const fallbackDummyBase = `http://localhost/${skillRoot}/`;
51143
+ const fallbackUrl = new URL(pathArg, fallbackDummyBase);
51144
+ const fallbackPath = "." + fallbackUrl.pathname;
51145
+ content = getSkillMdContent(normalizedModules, fallbackPath);
51146
+ if (content) {
51147
+ resolvedPath = fallbackPath;
51148
+ }
51149
+ }
51150
+ }
51151
+ if (content && !normalizedModules[resolvedPath]) {
51152
+ const suffix = resolvedPath.replace(/^\.?\//, "/");
51153
+ const matchingKey = Object.keys(normalizedModules).find((key) => key.endsWith(suffix));
51154
+ if (matchingKey) {
51155
+ resolvedPath = matchingKey;
51156
+ }
51157
+ }
50153
51158
  } else if (skillName) {
50154
- const mainPath = getMainSkillPathByName(modules, skillName);
50155
- content = mainPath ? getSkillMdContent(modules, mainPath) : void 0;
51159
+ const mainPath = getMainSkillPathByName(normalizedModules, skillName);
51160
+ if (mainPath) {
51161
+ resolvedPath = mainPath;
51162
+ content = getSkillMdContent(normalizedModules, mainPath);
51163
+ }
50156
51164
  }
50157
51165
  if (content === void 0) {
50158
- return { error: "未找到对应技能文档", skillName: skillName ?? pathArg };
51166
+ return {
51167
+ error: "未找到对应技能文档",
51168
+ skillName,
51169
+ path: pathArg,
51170
+ providedCurrentPath: currentPathArg,
51171
+ attemptedPath: resolvedPath
51172
+ };
50159
51173
  }
50160
- return { content, path: pathArg ?? getMainSkillPathByName(modules, skillName) };
51174
+ return { content, path: resolvedPath };
50161
51175
  }
50162
51176
  });
50163
51177
  return {
@@ -50171,6 +51185,9 @@ ${lines.join("\n")}
50171
51185
  exports2.ExtensionClientTransport = ExtensionClientTransport;
50172
51186
  exports2.ExtensionPageServerTransport = ExtensionPageServerTransport;
50173
51187
  exports2.InMemoryTransport = InMemoryTransport;
51188
+ exports2.MSG_PAGE_LEAVE = MSG_PAGE_LEAVE;
51189
+ exports2.MSG_REMOTER_READY = MSG_REMOTER_READY;
51190
+ exports2.MSG_ROUTE_STATE_INITIAL = MSG_ROUTE_STATE_INITIAL;
50174
51191
  exports2.QrCode = QrCode;
50175
51192
  exports2.ResourceTemplate = ResourceTemplate;
50176
51193
  exports2.UriTemplate = UriTemplate;
@@ -50186,12 +51203,14 @@ ${lines.join("\n")}
50186
51203
  exports2.createStreamableHTTPClientTransport = createStreamableHTTPClientTransport;
50187
51204
  exports2.formatSkillsForSystemPrompt = formatSkillsForSystemPrompt;
50188
51205
  exports2.getAISDKTools = getAISDKTools;
51206
+ exports2.getActiveRoutes = getActiveRoutes;
50189
51207
  exports2.getDisplayName = getDisplayName;
50190
51208
  exports2.getMainSkillPathByName = getMainSkillPathByName;
50191
51209
  exports2.getMainSkillPaths = getMainSkillPaths;
50192
51210
  exports2.getSkillMdContent = getSkillMdContent;
50193
51211
  exports2.getSkillMdPaths = getSkillMdPaths;
50194
51212
  exports2.getSkillOverviews = getSkillOverviews;
51213
+ exports2.getToolRouteMap = getToolRouteMap;
50195
51214
  exports2.isMcpClient = isMcpClient;
50196
51215
  exports2.isMcpServer = isMcpServer;
50197
51216
  exports2.isMessageChannelClientTransport = isMessageChannelClientTransport;
@@ -50199,6 +51218,9 @@ ${lines.join("\n")}
50199
51218
  exports2.isSSEClientTransport = isSSEClientTransport;
50200
51219
  exports2.isStreamableHTTPClientTransport = isStreamableHTTPClientTransport;
50201
51220
  exports2.parseSkillFrontMatter = parseSkillFrontMatter;
51221
+ exports2.registerPageTool = registerPageTool;
51222
+ exports2.setNavigator = setNavigator;
51223
+ exports2.withPageTools = withPageTools;
50202
51224
  exports2.z = z;
50203
51225
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
50204
51226
  }));