@opentiny/next-sdk 0.2.6 → 0.2.7

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(
@@ -28053,25 +28057,30 @@ Error message: ${getErrorMessage$2(cause)}`,
28053
28057
  }
28054
28058
  function createToolNameMapping({
28055
28059
  tools = [],
28056
- providerToolNames
28060
+ providerToolNames,
28061
+ resolveProviderToolName
28057
28062
  }) {
28063
+ var _a22;
28058
28064
  const customToolNameToProviderToolName = {};
28059
28065
  const providerToolNameToCustomToolName = {};
28060
28066
  for (const tool2 of tools) {
28061
- if (tool2.type === "provider" && tool2.id in providerToolNames) {
28062
- const providerToolName = providerToolNames[tool2.id];
28067
+ if (tool2.type === "provider") {
28068
+ const providerToolName = (_a22 = resolveProviderToolName == null ? void 0 : resolveProviderToolName(tool2)) != null ? _a22 : tool2.id in providerToolNames ? providerToolNames[tool2.id] : void 0;
28069
+ if (providerToolName == null) {
28070
+ continue;
28071
+ }
28063
28072
  customToolNameToProviderToolName[tool2.name] = providerToolName;
28064
28073
  providerToolNameToCustomToolName[providerToolName] = tool2.name;
28065
28074
  }
28066
28075
  }
28067
28076
  return {
28068
28077
  toProviderToolName: (customToolName) => {
28069
- var _a22;
28070
- return (_a22 = customToolNameToProviderToolName[customToolName]) != null ? _a22 : customToolName;
28078
+ var _a32;
28079
+ return (_a32 = customToolNameToProviderToolName[customToolName]) != null ? _a32 : customToolName;
28071
28080
  },
28072
28081
  toCustomToolName: (providerToolName) => {
28073
- var _a22;
28074
- return (_a22 = providerToolNameToCustomToolName[providerToolName]) != null ? _a22 : providerToolName;
28082
+ var _a32;
28083
+ return (_a32 = providerToolNameToCustomToolName[providerToolName]) != null ? _a32 : providerToolName;
28075
28084
  }
28076
28085
  };
28077
28086
  }
@@ -28264,8 +28273,103 @@ Error message: ${getErrorMessage$2(cause)}`,
28264
28273
  }
28265
28274
  return result;
28266
28275
  }
28276
+ function validateDownloadUrl(url2) {
28277
+ let parsed;
28278
+ try {
28279
+ parsed = new URL(url2);
28280
+ } catch (e) {
28281
+ throw new DownloadError({
28282
+ url: url2,
28283
+ message: `Invalid URL: ${url2}`
28284
+ });
28285
+ }
28286
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
28287
+ throw new DownloadError({
28288
+ url: url2,
28289
+ message: `URL scheme must be http or https, got ${parsed.protocol}`
28290
+ });
28291
+ }
28292
+ const hostname2 = parsed.hostname;
28293
+ if (!hostname2) {
28294
+ throw new DownloadError({
28295
+ url: url2,
28296
+ message: `URL must have a hostname`
28297
+ });
28298
+ }
28299
+ if (hostname2 === "localhost" || hostname2.endsWith(".local") || hostname2.endsWith(".localhost")) {
28300
+ throw new DownloadError({
28301
+ url: url2,
28302
+ message: `URL with hostname ${hostname2} is not allowed`
28303
+ });
28304
+ }
28305
+ if (hostname2.startsWith("[") && hostname2.endsWith("]")) {
28306
+ const ipv62 = hostname2.slice(1, -1);
28307
+ if (isPrivateIPv6(ipv62)) {
28308
+ throw new DownloadError({
28309
+ url: url2,
28310
+ message: `URL with IPv6 address ${hostname2} is not allowed`
28311
+ });
28312
+ }
28313
+ return;
28314
+ }
28315
+ if (isIPv4(hostname2)) {
28316
+ if (isPrivateIPv4(hostname2)) {
28317
+ throw new DownloadError({
28318
+ url: url2,
28319
+ message: `URL with IP address ${hostname2} is not allowed`
28320
+ });
28321
+ }
28322
+ return;
28323
+ }
28324
+ }
28325
+ function isIPv4(hostname2) {
28326
+ const parts = hostname2.split(".");
28327
+ if (parts.length !== 4) return false;
28328
+ return parts.every((part) => {
28329
+ const num = Number(part);
28330
+ return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
28331
+ });
28332
+ }
28333
+ function isPrivateIPv4(ip) {
28334
+ const parts = ip.split(".").map(Number);
28335
+ const [a, b] = parts;
28336
+ if (a === 0) return true;
28337
+ if (a === 10) return true;
28338
+ if (a === 127) return true;
28339
+ if (a === 169 && b === 254) return true;
28340
+ if (a === 172 && b >= 16 && b <= 31) return true;
28341
+ if (a === 192 && b === 168) return true;
28342
+ return false;
28343
+ }
28344
+ function isPrivateIPv6(ip) {
28345
+ const normalized = ip.toLowerCase();
28346
+ if (normalized === "::1") return true;
28347
+ if (normalized === "::") return true;
28348
+ if (normalized.startsWith("::ffff:")) {
28349
+ const mappedPart = normalized.slice(7);
28350
+ if (isIPv4(mappedPart)) {
28351
+ return isPrivateIPv4(mappedPart);
28352
+ }
28353
+ const hexParts = mappedPart.split(":");
28354
+ if (hexParts.length === 2) {
28355
+ const high = parseInt(hexParts[0], 16);
28356
+ const low = parseInt(hexParts[1], 16);
28357
+ if (!isNaN(high) && !isNaN(low)) {
28358
+ const a = high >> 8 & 255;
28359
+ const b = high & 255;
28360
+ const c = low >> 8 & 255;
28361
+ const d = low & 255;
28362
+ return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
28363
+ }
28364
+ }
28365
+ }
28366
+ if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
28367
+ if (normalized.startsWith("fe80")) return true;
28368
+ return false;
28369
+ }
28267
28370
  async function downloadBlob(url2, options) {
28268
28371
  var _a22, _b22;
28372
+ validateDownloadUrl(url2);
28269
28373
  try {
28270
28374
  const response = await fetch(url2, {
28271
28375
  signal: options == null ? void 0 : options.abortSignal
@@ -28431,7 +28535,7 @@ Error message: ${getErrorMessage$2(cause)}`,
28431
28535
  );
28432
28536
  return Object.fromEntries(normalizedHeaders.entries());
28433
28537
  }
28434
- var VERSION$7 = "4.0.15";
28538
+ var VERSION$7 = "4.0.19";
28435
28539
  var getOriginalFetch = () => globalThis.fetch;
28436
28540
  var getFromApi = async ({
28437
28541
  url: url2,
@@ -28574,8 +28678,8 @@ Error message: ${getErrorMessage$2(cause)}`,
28574
28678
  "x-m4a": "m4a"
28575
28679
  }[subtype]) != null ? _a22 : subtype;
28576
28680
  }
28577
- var suspectProtoRx$1 = /"__proto__"\s*:/;
28578
- var suspectConstructorRx$1 = /"constructor"\s*:/;
28681
+ var suspectProtoRx$1 = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
28682
+ 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
28683
  function _parse$1(text2) {
28580
28684
  const obj = JSON.parse(text2);
28581
28685
  if (obj === null || typeof obj !== "object") {
@@ -28595,7 +28699,7 @@ Error message: ${getErrorMessage$2(cause)}`,
28595
28699
  if (Object.prototype.hasOwnProperty.call(node, "__proto__")) {
28596
28700
  throw new SyntaxError("Object contains forbidden prototype property");
28597
28701
  }
28598
- if (Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
28702
+ if (Object.prototype.hasOwnProperty.call(node, "constructor") && node.constructor !== null && typeof node.constructor === "object" && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
28599
28703
  throw new SyntaxError("Object contains forbidden prototype property");
28600
28704
  }
28601
28705
  for (const key in node) {
@@ -30082,6 +30186,33 @@ Error message: ${getErrorMessage$2(cause)}`,
30082
30186
  function dynamicTool(tool2) {
30083
30187
  return { ...tool2, type: "dynamic" };
30084
30188
  }
30189
+ function createProviderToolFactory({
30190
+ id: id2,
30191
+ inputSchema
30192
+ }) {
30193
+ return ({
30194
+ execute,
30195
+ outputSchema: outputSchema2,
30196
+ needsApproval,
30197
+ toModelOutput,
30198
+ onInputStart,
30199
+ onInputDelta,
30200
+ onInputAvailable,
30201
+ ...args
30202
+ }) => tool({
30203
+ type: "provider",
30204
+ id: id2,
30205
+ args,
30206
+ inputSchema,
30207
+ outputSchema: outputSchema2,
30208
+ execute,
30209
+ needsApproval,
30210
+ toModelOutput,
30211
+ onInputStart,
30212
+ onInputDelta,
30213
+ onInputAvailable
30214
+ });
30215
+ }
30085
30216
  function createProviderToolFactoryWithOutputSchema({
30086
30217
  id: id2,
30087
30218
  inputSchema,
@@ -31552,7 +31683,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
31552
31683
  var _a92;
31553
31684
  return (_a92 = indexBrowserExports.getContext().headers) == null ? void 0 : _a92["x-vercel-id"];
31554
31685
  }
31555
- var VERSION$6 = "3.0.58";
31686
+ var VERSION$6 = "3.0.66";
31556
31687
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
31557
31688
  function createGatewayProvider(options = {}) {
31558
31689
  var _a92, _b9;
@@ -33079,6 +33210,8 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33079
33210
  }
33080
33211
  async function notify(options) {
33081
33212
  for (const callback of asArray(options.callbacks)) {
33213
+ if (callback == null)
33214
+ continue;
33082
33215
  try {
33083
33216
  await callback(options.event);
33084
33217
  } catch (_ignored) {
@@ -33385,7 +33518,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33385
33518
  }
33386
33519
  return void 0;
33387
33520
  }
33388
- var VERSION$4 = "6.0.104";
33521
+ var VERSION$4 = "6.0.116";
33389
33522
  var download = async ({
33390
33523
  url: url2,
33391
33524
  maxBytes,
@@ -33393,6 +33526,7 @@ Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the toke
33393
33526
  }) => {
33394
33527
  var _a21;
33395
33528
  const urlText = url2.toString();
33529
+ validateDownloadUrl(urlText);
33396
33530
  try {
33397
33531
  const response = await fetch(urlText, {
33398
33532
  headers: withUserAgentSuffix$1(
@@ -34498,6 +34632,44 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
34498
34632
  }))
34499
34633
  );
34500
34634
  }
34635
+ function getGlobalTelemetryIntegrations() {
34636
+ var _a21;
34637
+ return (_a21 = globalThis.AI_SDK_TELEMETRY_INTEGRATIONS) != null ? _a21 : [];
34638
+ }
34639
+ function getGlobalTelemetryIntegration() {
34640
+ const globalIntegrations = getGlobalTelemetryIntegrations();
34641
+ return (integrations) => {
34642
+ const localIntegrations = asArray(integrations);
34643
+ const allIntegrations = [...globalIntegrations, ...localIntegrations];
34644
+ function createTelemetryComposite(getListenerFromIntegration) {
34645
+ const listeners = allIntegrations.map(getListenerFromIntegration).filter(Boolean);
34646
+ return async (event) => {
34647
+ for (const listener of listeners) {
34648
+ try {
34649
+ await listener(event);
34650
+ } catch (_ignored) {
34651
+ }
34652
+ }
34653
+ };
34654
+ }
34655
+ return {
34656
+ onStart: createTelemetryComposite((integration) => integration.onStart),
34657
+ onStepStart: createTelemetryComposite(
34658
+ (integration) => integration.onStepStart
34659
+ ),
34660
+ onToolCallStart: createTelemetryComposite(
34661
+ (integration) => integration.onToolCallStart
34662
+ ),
34663
+ onToolCallFinish: createTelemetryComposite(
34664
+ (integration) => integration.onToolCallFinish
34665
+ ),
34666
+ onStepFinish: createTelemetryComposite(
34667
+ (integration) => integration.onStepFinish
34668
+ ),
34669
+ onFinish: createTelemetryComposite((integration) => integration.onFinish)
34670
+ };
34671
+ };
34672
+ }
34501
34673
  function asLanguageModelUsage(usage) {
34502
34674
  return {
34503
34675
  inputTokens: usage.inputTokens.total,
@@ -36048,6 +36220,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36048
36220
  ...settings
36049
36221
  }) {
36050
36222
  const model = resolveLanguageModel(modelArg);
36223
+ const createGlobalTelemetry = getGlobalTelemetryIntegration();
36051
36224
  const stopConditions = asArray(stopWhen);
36052
36225
  const totalTimeoutMs = getTotalTimeoutMs(timeout);
36053
36226
  const stepTimeoutMs = getStepTimeoutMs(timeout);
@@ -36078,6 +36251,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36078
36251
  prompt,
36079
36252
  messages
36080
36253
  });
36254
+ const globalTelemetry = createGlobalTelemetry(telemetry == null ? void 0 : telemetry.integrations);
36081
36255
  await notify({
36082
36256
  event: {
36083
36257
  model: modelInfo,
@@ -36107,7 +36281,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36107
36281
  metadata: telemetry == null ? void 0 : telemetry.metadata,
36108
36282
  experimental_context
36109
36283
  },
36110
- callbacks: onStart
36284
+ callbacks: [
36285
+ onStart,
36286
+ globalTelemetry.onStart
36287
+ ]
36111
36288
  });
36112
36289
  const tracer = getTracer(telemetry);
36113
36290
  try {
@@ -36152,8 +36329,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36152
36329
  experimental_context,
36153
36330
  stepNumber: 0,
36154
36331
  model: modelInfo,
36155
- onToolCallStart,
36156
- onToolCallFinish
36332
+ onToolCallStart: [
36333
+ onToolCallStart,
36334
+ globalTelemetry.onToolCallStart
36335
+ ],
36336
+ onToolCallFinish: [
36337
+ onToolCallFinish,
36338
+ globalTelemetry.onToolCallFinish
36339
+ ]
36157
36340
  });
36158
36341
  const toolContent = [];
36159
36342
  for (const output2 of toolOutputs) {
@@ -36162,7 +36345,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36162
36345
  input: output2.input,
36163
36346
  tool: tools == null ? void 0 : tools[output2.toolName],
36164
36347
  output: output2.type === "tool-result" ? output2.output : output2.error,
36165
- errorMode: output2.type === "tool-error" ? "json" : "none"
36348
+ errorMode: output2.type === "tool-error" ? "text" : "none"
36166
36349
  });
36167
36350
  toolContent.push({
36168
36351
  type: "tool-result",
@@ -36279,7 +36462,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36279
36462
  metadata: telemetry == null ? void 0 : telemetry.metadata,
36280
36463
  experimental_context
36281
36464
  },
36282
- callbacks: onStepStart
36465
+ callbacks: [
36466
+ onStepStart,
36467
+ globalTelemetry.onStepStart
36468
+ ]
36283
36469
  });
36284
36470
  currentModelResponse = await retry(
36285
36471
  () => {
@@ -36457,8 +36643,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36457
36643
  experimental_context,
36458
36644
  stepNumber: steps.length,
36459
36645
  model: stepModelInfo,
36460
- onToolCallStart,
36461
- onToolCallFinish
36646
+ onToolCallStart: [
36647
+ onToolCallStart,
36648
+ globalTelemetry.onToolCallStart
36649
+ ],
36650
+ onToolCallFinish: [
36651
+ onToolCallFinish,
36652
+ globalTelemetry.onToolCallFinish
36653
+ ]
36462
36654
  })
36463
36655
  );
36464
36656
  }
@@ -36525,7 +36717,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36525
36717
  model: stepModelInfo.modelId
36526
36718
  });
36527
36719
  steps.push(currentStepResult);
36528
- await notify({ event: currentStepResult, callbacks: onStepFinish });
36720
+ await notify({
36721
+ event: currentStepResult,
36722
+ callbacks: [onStepFinish, globalTelemetry.onStepFinish]
36723
+ });
36529
36724
  } finally {
36530
36725
  if (stepTimeoutId != null) {
36531
36726
  clearTimeout(stepTimeoutId);
@@ -36606,7 +36801,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
36606
36801
  steps,
36607
36802
  totalUsage
36608
36803
  },
36609
- callbacks: onFinish
36804
+ callbacks: [
36805
+ onFinish,
36806
+ globalTelemetry.onFinish
36807
+ ]
36610
36808
  });
36611
36809
  let resolvedOutput;
36612
36810
  if (lastStep.finishReason === "stop") {
@@ -37225,7 +37423,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37225
37423
  state.message.parts.push({
37226
37424
  type: "file",
37227
37425
  mediaType: chunk.mediaType,
37228
- url: chunk.url
37426
+ url: chunk.url,
37427
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37229
37428
  });
37230
37429
  write();
37231
37430
  break;
@@ -37882,7 +38081,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
37882
38081
  file: new DefaultGeneratedFileWithType({
37883
38082
  data: chunk.data,
37884
38083
  mediaType: chunk.mediaType
37885
- })
38084
+ }),
38085
+ ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
37886
38086
  });
37887
38087
  break;
37888
38088
  }
@@ -38270,6 +38470,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38270
38470
  this.outputSpecification = output;
38271
38471
  this.includeRawChunks = includeRawChunks;
38272
38472
  this.tools = tools;
38473
+ const createGlobalTelemetry = getGlobalTelemetryIntegration();
38474
+ const globalTelemetry = createGlobalTelemetry(telemetry == null ? void 0 : telemetry.integrations);
38273
38475
  let stepFinish;
38274
38476
  let recordedContent = [];
38275
38477
  const recordedResponseMessages = [];
@@ -38371,7 +38573,11 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38371
38573
  delete activeReasoningContent[part.id];
38372
38574
  }
38373
38575
  if (part.type === "file") {
38374
- recordedContent.push({ type: "file", file: part.file });
38576
+ recordedContent.push({
38577
+ type: "file",
38578
+ file: part.file,
38579
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
38580
+ });
38375
38581
  }
38376
38582
  if (part.type === "source") {
38377
38583
  recordedContent.push(part);
@@ -38417,7 +38623,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38417
38623
  },
38418
38624
  providerMetadata: part.providerMetadata
38419
38625
  });
38420
- await notify({ event: currentStepResult, callbacks: onStepFinish });
38626
+ await notify({
38627
+ event: currentStepResult,
38628
+ callbacks: [onStepFinish, globalTelemetry.onStepFinish]
38629
+ });
38421
38630
  logWarnings({
38422
38631
  warnings: recordedWarnings,
38423
38632
  provider: modelInfo.provider,
@@ -38481,7 +38690,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38481
38690
  providerMetadata: finalStep.providerMetadata,
38482
38691
  steps: recordedSteps
38483
38692
  },
38484
- callbacks: onFinish
38693
+ callbacks: [
38694
+ onFinish,
38695
+ globalTelemetry.onFinish
38696
+ ]
38485
38697
  });
38486
38698
  rootSpan.setAttributes(
38487
38699
  await selectTelemetryAttributes({
@@ -38638,7 +38850,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38638
38850
  ...callbackTelemetryProps,
38639
38851
  experimental_context
38640
38852
  },
38641
- callbacks: onStart
38853
+ callbacks: [
38854
+ onStart,
38855
+ globalTelemetry.onStart
38856
+ ]
38642
38857
  });
38643
38858
  const initialMessages = initialPrompt.messages;
38644
38859
  const initialResponseMessages = [];
@@ -38688,8 +38903,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38688
38903
  experimental_context,
38689
38904
  stepNumber: recordedSteps.length,
38690
38905
  model: modelInfo,
38691
- onToolCallStart,
38692
- onToolCallFinish,
38906
+ onToolCallStart: [
38907
+ onToolCallStart,
38908
+ globalTelemetry.onToolCallStart
38909
+ ],
38910
+ onToolCallFinish: [
38911
+ onToolCallFinish,
38912
+ globalTelemetry.onToolCallFinish
38913
+ ],
38693
38914
  onPreliminaryToolResult: (result2) => {
38694
38915
  toolExecutionStepStreamController == null ? void 0 : toolExecutionStepStreamController.enqueue(result2);
38695
38916
  }
@@ -38726,7 +38947,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38726
38947
  input: output2.input,
38727
38948
  tool: tools == null ? void 0 : tools[output2.toolName],
38728
38949
  output: output2.type === "tool-result" ? output2.output : output2.error,
38729
- errorMode: output2.type === "tool-error" ? "json" : "none"
38950
+ errorMode: output2.type === "tool-error" ? "text" : "none"
38730
38951
  })
38731
38952
  });
38732
38953
  }
@@ -38840,7 +39061,10 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38840
39061
  ...callbackTelemetryProps,
38841
39062
  experimental_context
38842
39063
  },
38843
- callbacks: onStepStart
39064
+ callbacks: [
39065
+ onStepStart,
39066
+ globalTelemetry.onStepStart
39067
+ ]
38844
39068
  });
38845
39069
  const {
38846
39070
  result: { stream: stream2, response, request },
@@ -38916,8 +39140,14 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
38916
39140
  generateId: generateId2,
38917
39141
  stepNumber: recordedSteps.length,
38918
39142
  model: stepModelInfo,
38919
- onToolCallStart,
38920
- onToolCallFinish
39143
+ onToolCallStart: [
39144
+ onToolCallStart,
39145
+ globalTelemetry.onToolCallStart
39146
+ ],
39147
+ onToolCallFinish: [
39148
+ onToolCallFinish,
39149
+ globalTelemetry.onToolCallFinish
39150
+ ]
38921
39151
  });
38922
39152
  const stepRequest = ((_i = include == null ? void 0 : include.requestBody) != null ? _i : true) ? request != null ? request : {} : { ...request, body: void 0 };
38923
39153
  const stepToolCalls = [];
@@ -39499,7 +39729,8 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
39499
39729
  controller.enqueue({
39500
39730
  type: "file",
39501
39731
  mediaType: part.file.mediaType,
39502
- url: `data:${part.file.mediaType};base64,${part.file.base64}`
39732
+ url: `data:${part.file.mediaType};base64,${part.file.base64}`,
39733
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
39503
39734
  });
39504
39735
  break;
39505
39736
  }
@@ -41821,7 +42052,7 @@ Learn more: \x1B[34m${moreInfoURL}\x1B[0m
41821
42052
  function getOpenAILanguageModelCapabilities(modelId) {
41822
42053
  const supportsFlexProcessing = modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41823
42054
  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");
42055
+ const isReasoningModel = modelId.startsWith("o1") || modelId.startsWith("o3") || modelId.startsWith("o4-mini") || modelId.startsWith("gpt-5") && !modelId.startsWith("gpt-5-chat");
41825
42056
  const supportsNonReasoningParameters = modelId.startsWith("gpt-5.1") || modelId.startsWith("gpt-5.2");
41826
42057
  const systemMessageMode = isReasoningModel ? "developer" : "system";
41827
42058
  return {
@@ -43728,6 +43959,30 @@ ${user}:`]
43728
43959
  var codeInterpreter = (args = {}) => {
43729
43960
  return codeInterpreterToolFactory(args);
43730
43961
  };
43962
+ var customArgsSchema = lazySchema(
43963
+ () => zodSchema(
43964
+ object$2({
43965
+ name: string(),
43966
+ description: string().optional(),
43967
+ format: union([
43968
+ object$2({
43969
+ type: literal("grammar"),
43970
+ syntax: _enum(["regex", "lark"]),
43971
+ definition: string()
43972
+ }),
43973
+ object$2({
43974
+ type: literal("text")
43975
+ })
43976
+ ]).optional()
43977
+ })
43978
+ )
43979
+ );
43980
+ var customInputSchema = lazySchema(() => zodSchema(string()));
43981
+ var customToolFactory = createProviderToolFactory({
43982
+ id: "openai.custom",
43983
+ inputSchema: customInputSchema
43984
+ });
43985
+ var customTool = (args) => customToolFactory(args);
43731
43986
  var comparisonFilterSchema = object$2({
43732
43987
  key: string(),
43733
43988
  type: _enum(["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"]),
@@ -44080,6 +44335,16 @@ ${user}:`]
44080
44335
  *
44081
44336
  */
44082
44337
  applyPatch,
44338
+ /**
44339
+ * Custom tools let callers constrain model output to a grammar (regex or
44340
+ * Lark syntax). The model returns a `custom_tool_call` output item whose
44341
+ * `input` field is a string matching the specified grammar.
44342
+ *
44343
+ * @param name - The name of the custom tool.
44344
+ * @param description - An optional description of the tool.
44345
+ * @param format - The output format constraint (grammar type, syntax, and definition).
44346
+ */
44347
+ customTool,
44083
44348
  /**
44084
44349
  * The Code Interpreter tool allows models to write and run Python code in a
44085
44350
  * sandboxed environment to solve complex problems in domains like data analysis,
@@ -44120,7 +44385,7 @@ ${user}:`]
44120
44385
  * Local shell is a tool that allows agents to run shell commands locally
44121
44386
  * on a machine you or the user provides.
44122
44387
  *
44123
- * Supported models: `gpt-5-codex` and `codex-mini-latest`
44388
+ * Supported models: `gpt-5-codex`
44124
44389
  */
44125
44390
  localShell,
44126
44391
  /**
@@ -44218,9 +44483,10 @@ ${user}:`]
44218
44483
  hasConversation = false,
44219
44484
  hasLocalShellTool = false,
44220
44485
  hasShellTool = false,
44221
- hasApplyPatchTool = false
44486
+ hasApplyPatchTool = false,
44487
+ customProviderToolNames
44222
44488
  }) {
44223
- var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
44489
+ var _a10, _b9, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
44224
44490
  const input = [];
44225
44491
  const warnings = [];
44226
44492
  const processedApprovalIds = /* @__PURE__ */ new Set();
@@ -44389,6 +44655,16 @@ ${user}:`]
44389
44655
  });
44390
44656
  break;
44391
44657
  }
44658
+ if (customProviderToolNames == null ? void 0 : customProviderToolNames.has(resolvedToolName)) {
44659
+ input.push({
44660
+ type: "custom_tool_call",
44661
+ call_id: part.toolCallId,
44662
+ name: resolvedToolName,
44663
+ input: typeof part.input === "string" ? part.input : JSON.stringify(part.input),
44664
+ id: id2
44665
+ });
44666
+ break;
44667
+ }
44392
44668
  input.push({
44393
44669
  type: "function_call",
44394
44670
  call_id: part.toolCallId,
@@ -44593,6 +44869,61 @@ ${user}:`]
44593
44869
  });
44594
44870
  continue;
44595
44871
  }
44872
+ if (customProviderToolNames == null ? void 0 : customProviderToolNames.has(resolvedToolName)) {
44873
+ let outputValue;
44874
+ switch (output.type) {
44875
+ case "text":
44876
+ case "error-text":
44877
+ outputValue = output.value;
44878
+ break;
44879
+ case "execution-denied":
44880
+ outputValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
44881
+ break;
44882
+ case "json":
44883
+ case "error-json":
44884
+ outputValue = JSON.stringify(output.value);
44885
+ break;
44886
+ case "content":
44887
+ outputValue = output.value.map((item) => {
44888
+ var _a22;
44889
+ switch (item.type) {
44890
+ case "text":
44891
+ return { type: "input_text", text: item.text };
44892
+ case "image-data":
44893
+ return {
44894
+ type: "input_image",
44895
+ image_url: `data:${item.mediaType};base64,${item.data}`
44896
+ };
44897
+ case "image-url":
44898
+ return {
44899
+ type: "input_image",
44900
+ image_url: item.url
44901
+ };
44902
+ case "file-data":
44903
+ return {
44904
+ type: "input_file",
44905
+ filename: (_a22 = item.filename) != null ? _a22 : "data",
44906
+ file_data: `data:${item.mediaType};base64,${item.data}`
44907
+ };
44908
+ default:
44909
+ warnings.push({
44910
+ type: "other",
44911
+ message: `unsupported custom tool content part type: ${item.type}`
44912
+ });
44913
+ return void 0;
44914
+ }
44915
+ }).filter(isNonNullable);
44916
+ break;
44917
+ default:
44918
+ outputValue = "";
44919
+ }
44920
+ input.push({
44921
+ type: "custom_tool_call_output",
44922
+ call_id: part.toolCallId,
44923
+ output: outputValue
44924
+ });
44925
+ continue;
44926
+ }
44596
44927
  let contentValue;
44597
44928
  switch (output.type) {
44598
44929
  case "text":
@@ -44600,7 +44931,7 @@ ${user}:`]
44600
44931
  contentValue = output.value;
44601
44932
  break;
44602
44933
  case "execution-denied":
44603
- contentValue = (_l = output.reason) != null ? _l : "Tool execution denied.";
44934
+ contentValue = (_m = output.reason) != null ? _m : "Tool execution denied.";
44604
44935
  break;
44605
44936
  case "json":
44606
44937
  case "error-json":
@@ -44809,6 +45140,13 @@ ${user}:`]
44809
45140
  })
44810
45141
  ])
44811
45142
  }),
45143
+ object$2({
45144
+ type: literal("custom_tool_call"),
45145
+ id: string(),
45146
+ call_id: string(),
45147
+ name: string(),
45148
+ input: string()
45149
+ }),
44812
45150
  object$2({
44813
45151
  type: literal("shell_call"),
44814
45152
  id: string(),
@@ -44861,6 +45199,14 @@ ${user}:`]
44861
45199
  arguments: string(),
44862
45200
  status: literal("completed")
44863
45201
  }),
45202
+ object$2({
45203
+ type: literal("custom_tool_call"),
45204
+ id: string(),
45205
+ call_id: string(),
45206
+ name: string(),
45207
+ input: string(),
45208
+ status: literal("completed")
45209
+ }),
44864
45210
  object$2({
44865
45211
  type: literal("code_interpreter_call"),
44866
45212
  id: string(),
@@ -45044,6 +45390,12 @@ ${user}:`]
45044
45390
  output_index: number$1(),
45045
45391
  delta: string()
45046
45392
  }),
45393
+ object$2({
45394
+ type: literal("response.custom_tool_call_input.delta"),
45395
+ item_id: string(),
45396
+ output_index: number$1(),
45397
+ delta: string()
45398
+ }),
45047
45399
  object$2({
45048
45400
  type: literal("response.image_generation_call.partial_image"),
45049
45401
  item_id: string(),
@@ -45291,6 +45643,13 @@ ${user}:`]
45291
45643
  arguments: string(),
45292
45644
  id: string()
45293
45645
  }),
45646
+ object$2({
45647
+ type: literal("custom_tool_call"),
45648
+ call_id: string(),
45649
+ name: string(),
45650
+ input: string(),
45651
+ id: string()
45652
+ }),
45294
45653
  object$2({
45295
45654
  type: literal("computer_call"),
45296
45655
  id: string(),
@@ -45574,14 +45933,18 @@ ${user}:`]
45574
45933
  );
45575
45934
  async function prepareResponsesTools({
45576
45935
  tools,
45577
- toolChoice
45936
+ toolChoice,
45937
+ toolNameMapping,
45938
+ customProviderToolNames
45578
45939
  }) {
45940
+ var _a10;
45579
45941
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
45580
45942
  const toolWarnings = [];
45581
45943
  if (tools == null) {
45582
45944
  return { tools: void 0, toolChoice: void 0, toolWarnings };
45583
45945
  }
45584
45946
  const openaiTools2 = [];
45947
+ const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
45585
45948
  for (const tool2 of tools) {
45586
45949
  switch (tool2.type) {
45587
45950
  case "function":
@@ -45723,6 +46086,20 @@ ${user}:`]
45723
46086
  });
45724
46087
  break;
45725
46088
  }
46089
+ case "openai.custom": {
46090
+ const args = await validateTypes$1({
46091
+ value: tool2.args,
46092
+ schema: customArgsSchema
46093
+ });
46094
+ openaiTools2.push({
46095
+ type: "custom",
46096
+ name: args.name,
46097
+ description: args.description,
46098
+ format: args.format
46099
+ });
46100
+ resolvedCustomProviderToolNames.add(args.name);
46101
+ break;
46102
+ }
45726
46103
  }
45727
46104
  break;
45728
46105
  }
@@ -45743,12 +46120,14 @@ ${user}:`]
45743
46120
  case "none":
45744
46121
  case "required":
45745
46122
  return { tools: openaiTools2, toolChoice: type2, toolWarnings };
45746
- case "tool":
46123
+ case "tool": {
46124
+ const resolvedToolName = (_a10 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _a10 : toolChoice.toolName;
45747
46125
  return {
45748
46126
  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 },
46127
+ 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
46128
  toolWarnings
45751
46129
  };
46130
+ }
45752
46131
  default: {
45753
46132
  const _exhaustiveCheck = type2;
45754
46133
  throw new UnsupportedFunctionalityError$1({
@@ -45897,7 +46276,19 @@ ${user}:`]
45897
46276
  "openai.web_search_preview": "web_search_preview",
45898
46277
  "openai.mcp": "mcp",
45899
46278
  "openai.apply_patch": "apply_patch"
45900
- }
46279
+ },
46280
+ resolveProviderToolName: (tool2) => tool2.id === "openai.custom" ? tool2.args.name : void 0
46281
+ });
46282
+ const customProviderToolNames = /* @__PURE__ */ new Set();
46283
+ const {
46284
+ tools: openaiTools2,
46285
+ toolChoice: openaiToolChoice,
46286
+ toolWarnings
46287
+ } = await prepareResponsesTools({
46288
+ tools,
46289
+ toolChoice,
46290
+ toolNameMapping,
46291
+ customProviderToolNames
45901
46292
  });
45902
46293
  const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({
45903
46294
  prompt,
@@ -45909,7 +46300,8 @@ ${user}:`]
45909
46300
  hasConversation: (openaiOptions == null ? void 0 : openaiOptions.conversation) != null,
45910
46301
  hasLocalShellTool: hasOpenAITool("openai.local_shell"),
45911
46302
  hasShellTool: hasOpenAITool("openai.shell"),
45912
- hasApplyPatchTool: hasOpenAITool("openai.apply_patch")
46303
+ hasApplyPatchTool: hasOpenAITool("openai.apply_patch"),
46304
+ customProviderToolNames: customProviderToolNames.size > 0 ? customProviderToolNames : void 0
45913
46305
  });
45914
46306
  warnings.push(...inputWarnings);
45915
46307
  const strictJsonSchema = (_d = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _d : true;
@@ -46042,14 +46434,6 @@ ${user}:`]
46042
46434
  });
46043
46435
  delete baseArgs.service_tier;
46044
46436
  }
46045
- const {
46046
- tools: openaiTools2,
46047
- toolChoice: openaiToolChoice,
46048
- toolWarnings
46049
- } = await prepareResponsesTools({
46050
- tools,
46051
- toolChoice
46052
- });
46053
46437
  const shellToolEnvType = (_i = (_h = (_g = tools == null ? void 0 : tools.find(
46054
46438
  (tool2) => tool2.type === "provider" && tool2.id === "openai.shell"
46055
46439
  )) == null ? void 0 : _g.args) == null ? void 0 : _h.environment) == null ? void 0 : _i.type;
@@ -46299,6 +46683,22 @@ ${user}:`]
46299
46683
  });
46300
46684
  break;
46301
46685
  }
46686
+ case "custom_tool_call": {
46687
+ hasFunctionCall = true;
46688
+ const toolName = toolNameMapping.toCustomToolName(part.name);
46689
+ content.push({
46690
+ type: "tool-call",
46691
+ toolCallId: part.call_id,
46692
+ toolName,
46693
+ input: JSON.stringify(part.input),
46694
+ providerMetadata: {
46695
+ [providerOptionsName]: {
46696
+ itemId: part.id
46697
+ }
46698
+ }
46699
+ });
46700
+ break;
46701
+ }
46302
46702
  case "web_search_call": {
46303
46703
  content.push({
46304
46704
  type: "tool-call",
@@ -46557,6 +46957,19 @@ ${user}:`]
46557
46957
  id: value.item.call_id,
46558
46958
  toolName: value.item.name
46559
46959
  });
46960
+ } else if (value.item.type === "custom_tool_call") {
46961
+ const toolName = toolNameMapping.toCustomToolName(
46962
+ value.item.name
46963
+ );
46964
+ ongoingToolCalls[value.output_index] = {
46965
+ toolName,
46966
+ toolCallId: value.item.call_id
46967
+ };
46968
+ controller.enqueue({
46969
+ type: "tool-input-start",
46970
+ id: value.item.call_id,
46971
+ toolName
46972
+ });
46560
46973
  } else if (value.item.type === "web_search_call") {
46561
46974
  ongoingToolCalls[value.output_index] = {
46562
46975
  toolName: toolNameMapping.toCustomToolName(
@@ -46741,6 +47154,27 @@ ${user}:`]
46741
47154
  }
46742
47155
  }
46743
47156
  });
47157
+ } else if (value.item.type === "custom_tool_call") {
47158
+ ongoingToolCalls[value.output_index] = void 0;
47159
+ hasFunctionCall = true;
47160
+ const toolName = toolNameMapping.toCustomToolName(
47161
+ value.item.name
47162
+ );
47163
+ controller.enqueue({
47164
+ type: "tool-input-end",
47165
+ id: value.item.call_id
47166
+ });
47167
+ controller.enqueue({
47168
+ type: "tool-call",
47169
+ toolCallId: value.item.call_id,
47170
+ toolName,
47171
+ input: JSON.stringify(value.item.input),
47172
+ providerMetadata: {
47173
+ [providerOptionsName]: {
47174
+ itemId: value.item.id
47175
+ }
47176
+ }
47177
+ });
46744
47178
  } else if (value.item.type === "web_search_call") {
46745
47179
  ongoingToolCalls[value.output_index] = void 0;
46746
47180
  controller.enqueue({
@@ -46990,6 +47424,15 @@ ${user}:`]
46990
47424
  delta: value.delta
46991
47425
  });
46992
47426
  }
47427
+ } else if (isResponseCustomToolCallInputDeltaChunk(value)) {
47428
+ const toolCall = ongoingToolCalls[value.output_index];
47429
+ if (toolCall != null) {
47430
+ controller.enqueue({
47431
+ type: "tool-input-delta",
47432
+ id: toolCall.toolCallId,
47433
+ delta: value.delta
47434
+ });
47435
+ }
46993
47436
  } else if (isResponseApplyPatchCallOperationDiffDeltaChunk(value)) {
46994
47437
  const toolCall = ongoingToolCalls[value.output_index];
46995
47438
  if (toolCall == null ? void 0 : toolCall.applyPatch) {
@@ -47250,6 +47693,9 @@ ${user}:`]
47250
47693
  function isResponseFunctionCallArgumentsDeltaChunk(chunk) {
47251
47694
  return chunk.type === "response.function_call_arguments.delta";
47252
47695
  }
47696
+ function isResponseCustomToolCallInputDeltaChunk(chunk) {
47697
+ return chunk.type === "response.custom_tool_call_input.delta";
47698
+ }
47253
47699
  function isResponseImageGenerationCallPartialImageChunk(chunk) {
47254
47700
  return chunk.type === "response.image_generation_call.partial_image";
47255
47701
  }
@@ -47631,7 +48077,7 @@ ${user}:`]
47631
48077
  };
47632
48078
  }
47633
48079
  };
47634
- var VERSION$2 = "3.0.36";
48080
+ var VERSION$2 = "3.0.41";
47635
48081
  function createOpenAI(options = {}) {
47636
48082
  var _a10, _b9;
47637
48083
  const baseURL = (_a10 = withoutTrailingSlash$1(
@@ -49451,9 +49897,13 @@ Error message: ${getErrorMessage(cause)}`,
49451
49897
  if (toolEntries.length === 0) {
49452
49898
  return "";
49453
49899
  }
49454
- let prompt = "\n\n# 工具调用\n\n";
49455
- prompt += "你可以根据需要调用以下工具:\n\n";
49456
- prompt += "<tools>\n";
49900
+ let prompt = `
49901
+ # 工具调用
49902
+
49903
+ 你可以根据需要调用以下工具:
49904
+
49905
+ <tools>
49906
+ `;
49457
49907
  toolEntries.forEach(([toolName, tool2]) => {
49458
49908
  const toolInfo = tool2;
49459
49909
  const description2 = toolInfo.description || "无描述";
@@ -49466,23 +49916,36 @@ Error message: ${getErrorMessage(cause)}`,
49466
49916
  prompt += `${JSON.stringify(toolJson, null, 2)}
49467
49917
  `;
49468
49918
  });
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";
49919
+ prompt += `
49920
+ </tools>
49921
+
49922
+ ## 工具调用格式
49923
+
49924
+ 要调用工具,请使用以下 XML 格式:
49925
+ Thought: [你的思考过程]
49926
+ <tool_call>
49927
+ {"name": "toolName", "arguments": {"arg1": "value1"}}
49928
+ </tool_call>
49929
+
49930
+ 工具执行后,你将收到 <tool_response> 格式的结果。你可以继续思考或调用其他工具。
49931
+
49932
+ ## 使用示例
49933
+
49934
+ 如果用户要求"获取今天的日期",你可以这样调用工具:
49935
+ Thought: 用户想要获取今天的日期,我需要调用日期相关的工具。
49936
+ <tool_call>{"name": "get-today", "arguments": {}}</tool_call>
49937
+
49938
+ 然后等待工具返回结果(Observation),再根据结果给出最终答案。
49939
+
49940
+ ## 任务完成
49941
+
49942
+ 当任务完成或无法继续时,直接给出最终答案即可。
49943
+
49944
+ **重要提示**:
49945
+ - 必须严格按照 XML 格式调用工具
49946
+ - arguments 必须是有效的 JSON 格式
49947
+ - 如果不需要调用工具,直接给出最终答案即可
49948
+ `;
49486
49949
  return prompt;
49487
49950
  }
49488
49951
  function parseReActAction(text2, availableTools) {
@@ -50089,6 +50552,171 @@ ${observationText}
50089
50552
  return this._chat(streamText, options);
50090
50553
  }
50091
50554
  }
50555
+ const MSG_TOOL_CALL = "next-sdk:tool-call";
50556
+ const MSG_TOOL_RESPONSE = "next-sdk:tool-response";
50557
+ const MSG_PAGE_READY = "next-sdk:page-ready";
50558
+ const MSG_PAGE_LEAVE = "next-sdk:page-leave";
50559
+ const MSG_REMOTER_READY = "next-sdk:remoter-ready";
50560
+ const MSG_ROUTE_STATE_INITIAL = "next-sdk:route-state-initial";
50561
+ const activePages = /* @__PURE__ */ new Map();
50562
+ const broadcastTargets = /* @__PURE__ */ new Set();
50563
+ function initBroadcastTargets() {
50564
+ if (typeof window !== "undefined") {
50565
+ broadcastTargets.add({ win: window, origin: window.location.origin || "*" });
50566
+ }
50567
+ }
50568
+ initBroadcastTargets();
50569
+ function broadcastRouteChange(type2, route) {
50570
+ const msg = { type: type2, route };
50571
+ broadcastTargets.forEach(({ win, origin }) => {
50572
+ try {
50573
+ win.postMessage(msg, origin);
50574
+ } catch {
50575
+ }
50576
+ });
50577
+ }
50578
+ function setupIframeRemoterBridge() {
50579
+ if (typeof window === "undefined") return;
50580
+ window.addEventListener("message", (event) => {
50581
+ if (event.data?.type !== MSG_REMOTER_READY || !event.source) return;
50582
+ if (event.origin !== window.location.origin) return;
50583
+ const target = event.source;
50584
+ broadcastTargets.add({ win: target, origin: event.origin || "*" });
50585
+ const payload = {
50586
+ type: MSG_ROUTE_STATE_INITIAL,
50587
+ toolRouteMap: Array.from(toolRouteMap.entries()),
50588
+ activeRoutes: Array.from(activePages.keys())
50589
+ };
50590
+ try {
50591
+ target.postMessage(payload, event.origin || "*");
50592
+ } catch {
50593
+ }
50594
+ });
50595
+ }
50596
+ setupIframeRemoterBridge();
50597
+ const toolRouteMap = /* @__PURE__ */ new Map();
50598
+ function getToolRouteMap() {
50599
+ return new Map(toolRouteMap);
50600
+ }
50601
+ function getActiveRoutes() {
50602
+ return new Set(activePages.keys());
50603
+ }
50604
+ let _navigator = null;
50605
+ function setNavigator(fn) {
50606
+ _navigator = fn;
50607
+ }
50608
+ function buildPageHandler(name16, route, timeout = 3e4) {
50609
+ return (input) => {
50610
+ const callId = randomUUID();
50611
+ return new Promise((resolve2, reject) => {
50612
+ let timer;
50613
+ let readyHandler;
50614
+ const cleanup = () => {
50615
+ clearTimeout(timer);
50616
+ window.removeEventListener("message", responseHandler);
50617
+ if (readyHandler) {
50618
+ window.removeEventListener("message", readyHandler);
50619
+ }
50620
+ };
50621
+ timer = setTimeout(() => {
50622
+ cleanup();
50623
+ reject(new Error(`工具 [${name16}] 调用超时 (${timeout}ms),请检查目标页面是否正确调用了 registerPageTool`));
50624
+ }, timeout);
50625
+ const responseHandler = (event) => {
50626
+ if (event.source === window && event.data?.type === MSG_TOOL_RESPONSE && event.data.callId === callId) {
50627
+ cleanup();
50628
+ event.data.error ? reject(new Error(event.data.error)) : resolve2(event.data.result);
50629
+ }
50630
+ };
50631
+ window.addEventListener("message", responseHandler);
50632
+ const sendCall = () => {
50633
+ window.postMessage({ type: MSG_TOOL_CALL, callId, toolName: name16, route, input }, window.location.origin || "*");
50634
+ };
50635
+ let callSent = false;
50636
+ const sendCallOnce = () => {
50637
+ if (callSent) return;
50638
+ callSent = true;
50639
+ sendCall();
50640
+ };
50641
+ const run = async () => {
50642
+ try {
50643
+ if (activePages.get(route)) {
50644
+ sendCallOnce();
50645
+ return;
50646
+ }
50647
+ readyHandler = (event) => {
50648
+ if (event.source === window && event.data?.type === MSG_PAGE_READY && event.data.route === route) {
50649
+ window.removeEventListener("message", readyHandler);
50650
+ sendCallOnce();
50651
+ }
50652
+ };
50653
+ window.addEventListener("message", readyHandler);
50654
+ if (_navigator) {
50655
+ await _navigator(route);
50656
+ }
50657
+ if (activePages.get(route)) {
50658
+ window.removeEventListener("message", readyHandler);
50659
+ sendCallOnce();
50660
+ }
50661
+ } catch (err) {
50662
+ cleanup();
50663
+ reject(err instanceof Error ? err : new Error(String(err)));
50664
+ }
50665
+ };
50666
+ void run();
50667
+ });
50668
+ };
50669
+ }
50670
+ function withPageTools(server) {
50671
+ return new Proxy(server, {
50672
+ get(target, prop, receiver) {
50673
+ if (prop === "registerTool") {
50674
+ return (name16, config2, handlerOrRoute) => {
50675
+ const rawRegister = target.registerTool.bind(target);
50676
+ if (typeof handlerOrRoute === "function") {
50677
+ return rawRegister(name16, config2, handlerOrRoute);
50678
+ }
50679
+ const { route, timeout } = handlerOrRoute;
50680
+ toolRouteMap.set(name16, route);
50681
+ return rawRegister(name16, config2, buildPageHandler(name16, route, timeout));
50682
+ };
50683
+ }
50684
+ return Reflect.get(target, prop, receiver);
50685
+ }
50686
+ });
50687
+ }
50688
+ function registerPageTool(options) {
50689
+ const { route: routeOption, handlers } = options;
50690
+ const normalizeRoute = (value) => value.replace(/\/+$/, "") || "/";
50691
+ const route = normalizeRoute(routeOption ?? window.location.pathname);
50692
+ const handleMessage = async (event) => {
50693
+ if (event.source !== window || event.data?.type !== MSG_TOOL_CALL || normalizeRoute(String(event.data?.route ?? "")) !== route || !(event.data.toolName in handlers)) {
50694
+ return;
50695
+ }
50696
+ const { callId, toolName, input } = event.data;
50697
+ try {
50698
+ const result = await handlers[toolName](input);
50699
+ window.postMessage({ type: MSG_TOOL_RESPONSE, callId, result }, window.location.origin || "*");
50700
+ } catch (err) {
50701
+ window.postMessage(
50702
+ {
50703
+ type: MSG_TOOL_RESPONSE,
50704
+ callId,
50705
+ error: err instanceof Error ? err.message : String(err)
50706
+ },
50707
+ window.location.origin || "*"
50708
+ );
50709
+ }
50710
+ };
50711
+ activePages.set(route, true);
50712
+ window.addEventListener("message", handleMessage);
50713
+ broadcastRouteChange(MSG_PAGE_READY, route);
50714
+ return () => {
50715
+ activePages.delete(route);
50716
+ window.removeEventListener("message", handleMessage);
50717
+ broadcastRouteChange(MSG_PAGE_LEAVE, route);
50718
+ };
50719
+ }
50092
50720
  const MAIN_SKILL_PATH_REG = /^\.\/[^/]+\/SKILL\.md$/;
50093
50721
  const FRONT_MATTER_BLOCK_REG = /^---\s*\n([\s\S]+?)\s*\n---/;
50094
50722
  function parseSkillFrontMatter(content) {
@@ -50101,14 +50729,27 @@ ${observationText}
50101
50729
  const description2 = descMatch?.[1]?.trim();
50102
50730
  return name16 && description2 ? { name: name16, description: description2 } : null;
50103
50731
  }
50732
+ function normalizeSkillModuleKeys(modules) {
50733
+ const result = {};
50734
+ for (const [key, content] of Object.entries(modules)) {
50735
+ const normalizedKey = key.replace(/\\/g, "/");
50736
+ const skillsIndex = normalizedKey.lastIndexOf("skills/");
50737
+ const relativePath = skillsIndex >= 0 ? normalizedKey.slice(skillsIndex + 7) : normalizedKey;
50738
+ const standardPath = relativePath.startsWith("./") ? relativePath : `./${relativePath}`;
50739
+ result[standardPath] = content;
50740
+ }
50741
+ return result;
50742
+ }
50104
50743
  function getMainSkillPaths(modules) {
50105
- return Object.keys(modules).filter((path) => MAIN_SKILL_PATH_REG.test(path));
50744
+ const normalized = normalizeSkillModuleKeys(modules);
50745
+ return Object.keys(normalized).filter((path) => MAIN_SKILL_PATH_REG.test(path));
50106
50746
  }
50107
50747
  function getSkillOverviews(modules) {
50108
- const mainPaths = getMainSkillPaths(modules);
50748
+ const normalized = normalizeSkillModuleKeys(modules);
50749
+ const mainPaths = Object.keys(normalized).filter((path) => MAIN_SKILL_PATH_REG.test(path));
50109
50750
  const list = [];
50110
50751
  for (const path of mainPaths) {
50111
- const content = modules[path];
50752
+ const content = normalized[path];
50112
50753
  if (!content) continue;
50113
50754
  const parsed = parseSkillFrontMatter(content);
50114
50755
  if (!parsed) continue;
@@ -50130,34 +50771,38 @@ ${lines.join("\n")}
50130
50771
  当需要用到某技能时,请使用 get_skill_content 工具获取该技能的完整文档内容。`;
50131
50772
  }
50132
50773
  function getSkillMdPaths(modules) {
50133
- return Object.keys(modules);
50774
+ const normalized = normalizeSkillModuleKeys(modules);
50775
+ return Object.keys(normalized);
50134
50776
  }
50135
50777
  function getSkillMdContent(modules, path) {
50136
- return modules[path];
50778
+ const normalized = normalizeSkillModuleKeys(modules);
50779
+ return normalized[path];
50137
50780
  }
50138
50781
  function getMainSkillPathByName(modules, name16) {
50139
50782
  return getMainSkillPaths(modules).find((p) => p.startsWith(`./${name16}/SKILL.md`));
50140
50783
  }
50784
+ const SKILL_INPUT_SCHEMA = objectType({
50785
+ skillName: stringType().optional().describe("技能名称,与目录名一致,如 calculator"),
50786
+ path: stringType().optional().describe("文档相对路径,如 ./calculator/SKILL.md 或 ./product-guide/reference/xxx.json")
50787
+ });
50141
50788
  function createSkillTools(modules) {
50789
+ const normalizedModules = normalizeSkillModuleKeys(modules);
50142
50790
  const getSkillContent = tool({
50143
50791
  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
- }),
50792
+ inputSchema: SKILL_INPUT_SCHEMA,
50148
50793
  execute: (args) => {
50149
50794
  const { skillName, path: pathArg } = args;
50150
50795
  let content;
50151
50796
  if (pathArg) {
50152
- content = getSkillMdContent(modules, pathArg);
50797
+ content = getSkillMdContent(normalizedModules, pathArg);
50153
50798
  } else if (skillName) {
50154
- const mainPath = getMainSkillPathByName(modules, skillName);
50155
- content = mainPath ? getSkillMdContent(modules, mainPath) : void 0;
50799
+ const mainPath = getMainSkillPathByName(normalizedModules, skillName);
50800
+ content = mainPath ? getSkillMdContent(normalizedModules, mainPath) : void 0;
50156
50801
  }
50157
50802
  if (content === void 0) {
50158
50803
  return { error: "未找到对应技能文档", skillName: skillName ?? pathArg };
50159
50804
  }
50160
- return { content, path: pathArg ?? getMainSkillPathByName(modules, skillName) };
50805
+ return { content, path: pathArg ?? getMainSkillPathByName(normalizedModules, skillName) };
50161
50806
  }
50162
50807
  });
50163
50808
  return {
@@ -50171,6 +50816,9 @@ ${lines.join("\n")}
50171
50816
  exports2.ExtensionClientTransport = ExtensionClientTransport;
50172
50817
  exports2.ExtensionPageServerTransport = ExtensionPageServerTransport;
50173
50818
  exports2.InMemoryTransport = InMemoryTransport;
50819
+ exports2.MSG_PAGE_LEAVE = MSG_PAGE_LEAVE;
50820
+ exports2.MSG_REMOTER_READY = MSG_REMOTER_READY;
50821
+ exports2.MSG_ROUTE_STATE_INITIAL = MSG_ROUTE_STATE_INITIAL;
50174
50822
  exports2.QrCode = QrCode;
50175
50823
  exports2.ResourceTemplate = ResourceTemplate;
50176
50824
  exports2.UriTemplate = UriTemplate;
@@ -50186,12 +50834,14 @@ ${lines.join("\n")}
50186
50834
  exports2.createStreamableHTTPClientTransport = createStreamableHTTPClientTransport;
50187
50835
  exports2.formatSkillsForSystemPrompt = formatSkillsForSystemPrompt;
50188
50836
  exports2.getAISDKTools = getAISDKTools;
50837
+ exports2.getActiveRoutes = getActiveRoutes;
50189
50838
  exports2.getDisplayName = getDisplayName;
50190
50839
  exports2.getMainSkillPathByName = getMainSkillPathByName;
50191
50840
  exports2.getMainSkillPaths = getMainSkillPaths;
50192
50841
  exports2.getSkillMdContent = getSkillMdContent;
50193
50842
  exports2.getSkillMdPaths = getSkillMdPaths;
50194
50843
  exports2.getSkillOverviews = getSkillOverviews;
50844
+ exports2.getToolRouteMap = getToolRouteMap;
50195
50845
  exports2.isMcpClient = isMcpClient;
50196
50846
  exports2.isMcpServer = isMcpServer;
50197
50847
  exports2.isMessageChannelClientTransport = isMessageChannelClientTransport;
@@ -50199,6 +50849,9 @@ ${lines.join("\n")}
50199
50849
  exports2.isSSEClientTransport = isSSEClientTransport;
50200
50850
  exports2.isStreamableHTTPClientTransport = isStreamableHTTPClientTransport;
50201
50851
  exports2.parseSkillFrontMatter = parseSkillFrontMatter;
50852
+ exports2.registerPageTool = registerPageTool;
50853
+ exports2.setNavigator = setNavigator;
50854
+ exports2.withPageTools = withPageTools;
50202
50855
  exports2.z = z;
50203
50856
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
50204
50857
  }));