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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16200,7 +16200,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16200
16200
  }
16201
16201
  return String(error);
16202
16202
  }
16203
- function getSchemaDescription$1(schema) {
16203
+ function getSchemaDescription(schema) {
16204
16204
  return schema.description;
16205
16205
  }
16206
16206
  function isSchemaOptional(schema) {
@@ -23674,7 +23674,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
23674
23674
  if (!shape)
23675
23675
  return [];
23676
23676
  return Object.entries(shape).map(([name16, field]) => {
23677
- const description2 = getSchemaDescription$1(field);
23677
+ const description2 = getSchemaDescription(field);
23678
23678
  const isOptional = isSchemaOptional(field);
23679
23679
  return {
23680
23680
  name: name16,
@@ -45310,6 +45310,11 @@ ${user}:`]
45310
45310
  filename: (_a22 = item.filename) != null ? _a22 : "data",
45311
45311
  file_data: `data:${item.mediaType};base64,${item.data}`
45312
45312
  };
45313
+ case "file-url":
45314
+ return {
45315
+ type: "input_file",
45316
+ file_url: item.url
45317
+ };
45313
45318
  default:
45314
45319
  warnings.push({
45315
45320
  type: "other",
@@ -45368,6 +45373,12 @@ ${user}:`]
45368
45373
  file_data: `data:${item.mediaType};base64,${item.data}`
45369
45374
  };
45370
45375
  }
45376
+ case "file-url": {
45377
+ return {
45378
+ type: "input_file",
45379
+ file_url: item.url
45380
+ };
45381
+ }
45371
45382
  default: {
45372
45383
  warnings.push({
45373
45384
  type: "other",
@@ -48709,7 +48720,7 @@ ${user}:`]
48709
48720
  };
48710
48721
  }
48711
48722
  };
48712
- var VERSION$2 = "3.0.48";
48723
+ var VERSION$2 = "3.0.49";
48713
48724
  function createOpenAI(options = {}) {
48714
48725
  var _a10, _b9;
48715
48726
  const baseURL = (_a10 = withoutTrailingSlash$1(
@@ -50524,6 +50535,40 @@ Error message: ${getErrorMessage(cause)}`,
50524
50535
  throw error;
50525
50536
  }
50526
50537
  };
50538
+ const getBuiltinMcpTools = async (client) => {
50539
+ const tools = {};
50540
+ if (!client) {
50541
+ return tools;
50542
+ }
50543
+ const testing = client;
50544
+ const listFn = testing.listTools ?? testing.getTools;
50545
+ if (!listFn) {
50546
+ return tools;
50547
+ }
50548
+ const rawList = await listFn.call(testing);
50549
+ const list = Array.isArray(rawList) ? rawList : [];
50550
+ for (const descriptor of list) {
50551
+ const { name: name16, description: description2, inputSchema = {} } = descriptor;
50552
+ const normalizedSchema = {
50553
+ type: "object",
50554
+ properties: inputSchema.properties ?? {},
50555
+ ...inputSchema.required ? { required: inputSchema.required } : {},
50556
+ additionalProperties: false,
50557
+ ...inputSchema
50558
+ };
50559
+ tools[name16] = dynamicTool({
50560
+ description: description2 ?? "",
50561
+ inputSchema: jsonSchema(normalizedSchema),
50562
+ async execute(args) {
50563
+ if (!testing.executeTool) {
50564
+ throw new Error(`navigator.modelContextTesting.executeTool is not available`);
50565
+ }
50566
+ return testing.executeTool(name16, JSON.stringify(args ?? {}));
50567
+ }
50568
+ });
50569
+ }
50570
+ return tools;
50571
+ };
50527
50572
  function generateReActToolsPrompt(tools) {
50528
50573
  const toolEntries = Object.entries(tools);
50529
50574
  if (toolEntries.length === 0) {
@@ -50640,6 +50685,14 @@ Thought: 用户想要获取今天的日期,我需要调用日期相关的工
50640
50685
  async _createOneClient(serverConfig) {
50641
50686
  try {
50642
50687
  let transport;
50688
+ if ("type" in serverConfig && serverConfig.type === "builtin") {
50689
+ const builtinClient = serverConfig.client;
50690
+ return {
50691
+ tools: () => getBuiltinMcpTools(builtinClient),
50692
+ close: async () => {
50693
+ }
50694
+ };
50695
+ }
50643
50696
  if ("type" in serverConfig && serverConfig.type.toLocaleLowerCase() === "streamablehttp") {
50644
50697
  const configWithHeaders = serverConfig;
50645
50698
  const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
@@ -51541,7 +51594,6 @@ ${observationText}
51541
51594
  });
51542
51595
  }
51543
51596
  setupIframeRemoterBridge();
51544
- const runtimeRegisteredTools = /* @__PURE__ */ new Map();
51545
51597
  function broadcastToolCatalogChanged() {
51546
51598
  if (typeof window === "undefined") return;
51547
51599
  const payload = {
@@ -51578,362 +51630,6 @@ ${observationText}
51578
51630
  const toolNames = activePages.get(route);
51579
51631
  return !!toolNames && toolNames.has(toolName);
51580
51632
  }
51581
- const nativeRegisteredTools = /* @__PURE__ */ new Set();
51582
- const nativeToolDisposers = /* @__PURE__ */ new Map();
51583
- const nativeRegisteredToolDefs = /* @__PURE__ */ new Map();
51584
- const nativeRegisterTasks = /* @__PURE__ */ new Map();
51585
- const BUILTIN_REMOVE_PATCH_SYMBOL = Symbol("builtin-remove-patched");
51586
- function attachBuiltinUnregisterOnRemove(name16, tool2) {
51587
- const mutableTool = tool2;
51588
- if (mutableTool[BUILTIN_REMOVE_PATCH_SYMBOL]) return tool2;
51589
- if (typeof mutableTool.remove !== "function") return tool2;
51590
- const originalRemove = mutableTool.remove.bind(mutableTool);
51591
- mutableTool.remove = () => {
51592
- try {
51593
- originalRemove();
51594
- } finally {
51595
- void unregisterBuiltinWebMcpTool(name16);
51596
- }
51597
- };
51598
- mutableTool[BUILTIN_REMOVE_PATCH_SYMBOL] = true;
51599
- return mutableTool;
51600
- }
51601
- function getBuiltinModelContext() {
51602
- if (typeof navigator === "undefined") return null;
51603
- const nav = navigator;
51604
- if (!nav.modelContext?.registerTool) return null;
51605
- return nav.modelContext;
51606
- }
51607
- function getBuiltinModelContextTesting() {
51608
- if (typeof navigator === "undefined") return null;
51609
- const nav = navigator;
51610
- return nav.modelContextTesting ?? null;
51611
- }
51612
- function isWebMcpDebugEnabled() {
51613
- if (typeof window === "undefined") return false;
51614
- const w = window;
51615
- if (w.__NEXT_SDK_WEBMCP_DEBUG__ === true) return true;
51616
- try {
51617
- return window.localStorage?.getItem("next-sdk:webmcp-debug") === "1";
51618
- } catch {
51619
- return false;
51620
- }
51621
- }
51622
- function debugWebMcpLog(event, payload = {}) {
51623
- if (!isWebMcpDebugEnabled()) return;
51624
- try {
51625
- console.info("[next-sdk/webmcp]", event, payload);
51626
- } catch {
51627
- }
51628
- }
51629
- async function debugBuiltinToolSnapshot(event) {
51630
- if (!isWebMcpDebugEnabled()) return;
51631
- const testingApi = getBuiltinModelContextTesting();
51632
- if (!testingApi) {
51633
- debugWebMcpLog(`${event}:snapshot`, { available: false });
51634
- return;
51635
- }
51636
- try {
51637
- const list = testingApi.listTools ?? testingApi.getTools;
51638
- if (!list) {
51639
- debugWebMcpLog(`${event}:snapshot`, { available: false, reason: "no-list-method" });
51640
- return;
51641
- }
51642
- const result = await list();
51643
- const tools = Array.isArray(result) ? result : [];
51644
- const names2 = tools.map((item) => {
51645
- if (!item || typeof item !== "object") return "";
51646
- return String(item.name ?? "");
51647
- }).filter(Boolean);
51648
- debugWebMcpLog(`${event}:snapshot`, { count: names2.length, names: names2 });
51649
- } catch (error) {
51650
- debugWebMcpLog(`${event}:snapshot-error`, { error: error instanceof Error ? error.message : String(error) });
51651
- }
51652
- }
51653
- function tryDirectBuiltinUnregisterByName(name16) {
51654
- const modelContext = getBuiltinModelContext();
51655
- if (!modelContext?.unregisterTool) {
51656
- debugWebMcpLog("direct-unregister-skip", { name: name16, reason: "missing-unregister" });
51657
- return;
51658
- }
51659
- debugWebMcpLog("direct-unregister-start", { name: name16 });
51660
- try {
51661
- const result = modelContext.unregisterTool.call(modelContext, name16);
51662
- if (result && typeof result === "object" && "then" in result) {
51663
- void result.then(() => {
51664
- debugWebMcpLog("direct-unregister-done", { name: name16, async: true });
51665
- void debugBuiltinToolSnapshot(`direct-unregister-done:${name16}`);
51666
- }).catch((error) => {
51667
- debugWebMcpLog("direct-unregister-error", { name: name16, async: true, error: error instanceof Error ? error.message : String(error) });
51668
- });
51669
- return;
51670
- }
51671
- debugWebMcpLog("direct-unregister-done", { name: name16, async: false });
51672
- void debugBuiltinToolSnapshot(`direct-unregister-done:${name16}`);
51673
- } catch {
51674
- debugWebMcpLog("direct-unregister-error", { name: name16, async: false });
51675
- }
51676
- }
51677
- function resolveBuiltinToolDisposer(result) {
51678
- if (typeof result === "function") {
51679
- return result;
51680
- }
51681
- if (!result || typeof result !== "object") {
51682
- return null;
51683
- }
51684
- const value = result;
51685
- if (typeof value.unregister === "function") return value.unregister.bind(value);
51686
- if (typeof value.remove === "function") return value.remove.bind(value);
51687
- if (typeof value.dispose === "function") return value.dispose.bind(value);
51688
- if (typeof value.close === "function") return value.close.bind(value);
51689
- return null;
51690
- }
51691
- function isBuiltinWebMcpSupported() {
51692
- return !!getBuiltinModelContext();
51693
- }
51694
- function getSchemaTypeName(schema) {
51695
- return schema._def?.typeName;
51696
- }
51697
- function getSchemaDescription(schema) {
51698
- return schema.description;
51699
- }
51700
- function withSchemaDescription(schema, base) {
51701
- const description2 = getSchemaDescription(schema);
51702
- return description2 ? { ...base, description: description2 } : base;
51703
- }
51704
- function isOptionalSchema(schema) {
51705
- const typeName = getSchemaTypeName(schema);
51706
- if (typeName === ZodFirstPartyTypeKind.ZodOptional || typeName === ZodFirstPartyTypeKind.ZodDefault) {
51707
- return true;
51708
- }
51709
- if (typeName === ZodFirstPartyTypeKind.ZodEffects) {
51710
- const inner = schema._def.schema;
51711
- return isOptionalSchema(inner);
51712
- }
51713
- return false;
51714
- }
51715
- function toPrimitiveJsonType(value) {
51716
- if (typeof value === "string") return "string";
51717
- if (typeof value === "number") return "number";
51718
- if (typeof value === "boolean") return "boolean";
51719
- if (value === null) return "null";
51720
- return void 0;
51721
- }
51722
- function zodTypeToJsonSchema(schema) {
51723
- const typeName = getSchemaTypeName(schema);
51724
- switch (typeName) {
51725
- case ZodFirstPartyTypeKind.ZodString:
51726
- return withSchemaDescription(schema, { type: "string" });
51727
- case ZodFirstPartyTypeKind.ZodNumber:
51728
- return withSchemaDescription(schema, { type: "number" });
51729
- case ZodFirstPartyTypeKind.ZodBoolean:
51730
- return withSchemaDescription(schema, { type: "boolean" });
51731
- case ZodFirstPartyTypeKind.ZodArray: {
51732
- const itemSchema = schema._def.type;
51733
- return withSchemaDescription(schema, { type: "array", items: zodTypeToJsonSchema(itemSchema) });
51734
- }
51735
- case ZodFirstPartyTypeKind.ZodEnum: {
51736
- const values = schema.options ?? [];
51737
- return withSchemaDescription(schema, { type: "string", enum: values });
51738
- }
51739
- case ZodFirstPartyTypeKind.ZodNativeEnum: {
51740
- const rawValues = Object.values(schema._def.values);
51741
- const enumValues = rawValues.filter(
51742
- (value) => typeof value === "string" || typeof value === "number"
51743
- );
51744
- return withSchemaDescription(schema, { enum: enumValues });
51745
- }
51746
- case ZodFirstPartyTypeKind.ZodLiteral: {
51747
- const literalValue = schema._def.value;
51748
- const primitiveType = toPrimitiveJsonType(literalValue);
51749
- return withSchemaDescription(schema, {
51750
- ...primitiveType ? { type: primitiveType } : {},
51751
- const: literalValue ?? null
51752
- });
51753
- }
51754
- case ZodFirstPartyTypeKind.ZodUnion: {
51755
- const options = schema._def.options ?? [];
51756
- return withSchemaDescription(schema, { anyOf: options.map((item) => zodTypeToJsonSchema(item)) });
51757
- }
51758
- case ZodFirstPartyTypeKind.ZodNullable: {
51759
- const inner = schema._def.innerType;
51760
- return withSchemaDescription(schema, { anyOf: [zodTypeToJsonSchema(inner), { type: "null" }] });
51761
- }
51762
- case ZodFirstPartyTypeKind.ZodObject: {
51763
- const schemaDef = schema;
51764
- const shape = schemaDef.shape ?? (typeof schemaDef._def?.shape === "function" ? schemaDef._def.shape() : schemaDef._def?.shape) ?? {};
51765
- return withSchemaDescription(schema, zodShapeToJsonSchema(shape));
51766
- }
51767
- case ZodFirstPartyTypeKind.ZodEffects: {
51768
- const inner = schema._def.schema;
51769
- return withSchemaDescription(schema, zodTypeToJsonSchema(inner));
51770
- }
51771
- case ZodFirstPartyTypeKind.ZodOptional:
51772
- case ZodFirstPartyTypeKind.ZodDefault: {
51773
- const inner = schema._def.innerType;
51774
- return withSchemaDescription(schema, zodTypeToJsonSchema(inner));
51775
- }
51776
- default:
51777
- return withSchemaDescription(schema, {});
51778
- }
51779
- }
51780
- function zodShapeToJsonSchema(shape = {}) {
51781
- const properties2 = {};
51782
- const required2 = [];
51783
- Object.entries(shape).forEach(([key, schema]) => {
51784
- properties2[key] = zodTypeToJsonSchema(schema);
51785
- if (!isOptionalSchema(schema)) {
51786
- required2.push(key);
51787
- }
51788
- });
51789
- return {
51790
- type: "object",
51791
- properties: properties2,
51792
- ...required2.length ? { required: required2 } : {},
51793
- additionalProperties: false
51794
- };
51795
- }
51796
- async function registerBuiltinWebMcpTool(options) {
51797
- const modelContext = getBuiltinModelContext();
51798
- if (!modelContext) {
51799
- debugWebMcpLog("register-builtin-skip", { name: options.name, reason: "unsupported" });
51800
- return false;
51801
- }
51802
- if (nativeRegisteredTools.has(options.name)) {
51803
- debugWebMcpLog("register-builtin-skip", { name: options.name, reason: "already-registered" });
51804
- return true;
51805
- }
51806
- const cleanupLocalRegisterState = () => {
51807
- nativeToolDisposers.delete(options.name);
51808
- nativeRegisteredToolDefs.delete(options.name);
51809
- nativeRegisteredTools.delete(options.name);
51810
- };
51811
- debugWebMcpLog("register-builtin-start", { name: options.name });
51812
- const task = (async () => {
51813
- const toolDefinition = {
51814
- name: options.name,
51815
- description: options.description,
51816
- inputSchema: zodShapeToJsonSchema(options.inputSchema ?? {}),
51817
- execute: options.execute
51818
- };
51819
- const result = await modelContext.registerTool(toolDefinition);
51820
- const disposer = resolveBuiltinToolDisposer(result);
51821
- if (disposer) {
51822
- nativeToolDisposers.set(options.name, disposer);
51823
- }
51824
- nativeRegisteredToolDefs.set(options.name, toolDefinition);
51825
- nativeRegisteredTools.add(options.name);
51826
- debugWebMcpLog("register-builtin-success", { name: options.name, hasDisposer: !!disposer });
51827
- void debugBuiltinToolSnapshot(`register-success:${options.name}`);
51828
- })();
51829
- nativeRegisterTasks.set(options.name, task);
51830
- try {
51831
- await task;
51832
- return true;
51833
- } catch (error) {
51834
- cleanupLocalRegisterState();
51835
- debugWebMcpLog("register-builtin-error", {
51836
- name: options.name,
51837
- error: error instanceof Error ? error.message : String(error)
51838
- });
51839
- return false;
51840
- } finally {
51841
- nativeRegisterTasks.delete(options.name);
51842
- }
51843
- }
51844
- async function unregisterBuiltinWebMcpTool(name16) {
51845
- debugWebMcpLog("unregister-builtin-start", { name: name16 });
51846
- const cleanup = () => {
51847
- nativeToolDisposers.delete(name16);
51848
- nativeRegisteredToolDefs.delete(name16);
51849
- nativeRegisteredTools.delete(name16);
51850
- };
51851
- const pendingRegister = nativeRegisterTasks.get(name16);
51852
- if (pendingRegister) {
51853
- try {
51854
- await pendingRegister;
51855
- } catch {
51856
- }
51857
- }
51858
- const disposer = nativeToolDisposers.get(name16);
51859
- if (disposer) {
51860
- try {
51861
- await disposer();
51862
- cleanup();
51863
- debugWebMcpLog("unregister-builtin-success", { name: name16, method: "disposer" });
51864
- void debugBuiltinToolSnapshot(`unregister-success:${name16}`);
51865
- return true;
51866
- } catch (error) {
51867
- debugWebMcpLog("unregister-builtin-disposer-error", {
51868
- name: name16,
51869
- error: error instanceof Error ? error.message : String(error)
51870
- });
51871
- }
51872
- }
51873
- const modelContext = getBuiltinModelContext();
51874
- if (!modelContext) {
51875
- cleanup();
51876
- debugWebMcpLog("unregister-builtin-skip", { name: name16, reason: "unsupported" });
51877
- return false;
51878
- }
51879
- if (!modelContext.unregisterTool) {
51880
- cleanup();
51881
- debugWebMcpLog("unregister-builtin-skip", { name: name16, reason: "missing-unregister" });
51882
- return false;
51883
- }
51884
- const definition = nativeRegisteredToolDefs.get(name16);
51885
- const candidates = [name16, { name: name16 }, { toolName: name16 }, { tool: { name: name16 } }, definition].filter(Boolean);
51886
- for (const candidate of candidates) {
51887
- try {
51888
- debugWebMcpLog("unregister-builtin-try", { name: name16, candidate });
51889
- const result = await modelContext.unregisterTool.call(modelContext, candidate);
51890
- if (result === false) continue;
51891
- cleanup();
51892
- debugWebMcpLog("unregister-builtin-success", { name: name16, method: "unregisterTool", candidate });
51893
- void debugBuiltinToolSnapshot(`unregister-success:${name16}`);
51894
- return true;
51895
- } catch (error) {
51896
- debugWebMcpLog("unregister-builtin-try-error", {
51897
- name: name16,
51898
- candidate,
51899
- error: error instanceof Error ? error.message : String(error)
51900
- });
51901
- }
51902
- }
51903
- cleanup();
51904
- debugWebMcpLog("unregister-builtin-failed", { name: name16 });
51905
- void debugBuiltinToolSnapshot(`unregister-failed:${name16}`);
51906
- return false;
51907
- }
51908
- function hasBuiltinWebMcpTool(name16) {
51909
- return nativeRegisteredTools.has(name16);
51910
- }
51911
- async function forceResetBuiltinWebMcpTools() {
51912
- const names2 = Array.from(nativeRegisteredTools);
51913
- for (const name16 of names2) {
51914
- try {
51915
- await unregisterBuiltinWebMcpTool(name16);
51916
- } catch {
51917
- }
51918
- }
51919
- }
51920
- async function listBuiltinWebMcpTools() {
51921
- const testingApi = getBuiltinModelContextTesting();
51922
- if (!testingApi?.listTools) return [];
51923
- try {
51924
- const result = await testingApi.listTools();
51925
- return Array.isArray(result) ? result : [];
51926
- } catch {
51927
- return [];
51928
- }
51929
- }
51930
- async function executeBuiltinWebMcpTool(name16, input) {
51931
- const testingApi = getBuiltinModelContextTesting();
51932
- if (!testingApi?.executeTool) {
51933
- throw new Error("当前浏览器不支持 navigator.modelContextTesting.executeTool。");
51934
- }
51935
- return await testingApi.executeTool(name16, JSON.stringify(input ?? {}));
51936
- }
51937
51633
  let _navigator = null;
51938
51634
  function setNavigator(fn) {
51939
51635
  _navigator = fn;
@@ -51986,61 +51682,6 @@ ${observationText}
51986
51682
  })
51987
51683
  );
51988
51684
  }
51989
- function mountPageTools(options) {
51990
- return registerPageTool(options);
51991
- }
51992
- function registerRuntimePageTools(server, options) {
51993
- const allTools = options.tools ?? [];
51994
- if (!allTools.length) {
51995
- throw new Error("registerRuntimePageTools: tools 不能为空。");
51996
- }
51997
- const explicitRoute = options.route ? normalizeRoute(options.route) : null;
51998
- const routes = new Set(allTools.map((tool2) => normalizeRoute(tool2.route)));
51999
- if (!explicitRoute && routes.size > 1) {
52000
- throw new Error("registerRuntimePageTools: tools 包含多个 route,请显式传入 route。");
52001
- }
52002
- const mountRoute = explicitRoute ?? Array.from(routes)[0];
52003
- const routeTools = allTools.filter((tool2) => normalizeRoute(tool2.route) === mountRoute);
52004
- if (!routeTools.length) {
52005
- throw new Error(`registerRuntimePageTools: route "${mountRoute}" 下未找到工具定义。`);
52006
- }
52007
- routeTools.forEach((definition) => {
52008
- const route = normalizeRoute(definition.route);
52009
- const existing = runtimeRegisteredTools.get(definition.name);
52010
- if (existing) {
52011
- if (existing.route !== route) {
52012
- throw new Error(
52013
- `registerRuntimePageTools: 工具 "${definition.name}" 已绑定路由 "${existing.route}",不能重复绑定到 "${route}"。`
52014
- );
52015
- }
52016
- existing.refCount += 1;
52017
- return;
52018
- }
52019
- const tool2 = server.registerTool(definition.name, definition.config, {
52020
- route,
52021
- timeout: definition.timeout,
52022
- invokeEffect: definition.invokeEffect
52023
- });
52024
- runtimeRegisteredTools.set(definition.name, { tool: tool2, route, refCount: 1 });
52025
- });
52026
- const cleanupHandlers = registerPageTool({
52027
- route: mountRoute,
52028
- tools: routeTools,
52029
- context: options.context
52030
- });
52031
- return () => {
52032
- cleanupHandlers();
52033
- if (options.removeOnUnmount === false) return;
52034
- routeTools.forEach((definition) => {
52035
- const existing = runtimeRegisteredTools.get(definition.name);
52036
- if (!existing) return;
52037
- existing.refCount -= 1;
52038
- if (existing.refCount > 0) return;
52039
- runtimeRegisteredTools.delete(definition.name);
52040
- server.unregisterTool(definition.name);
52041
- });
52042
- };
52043
- }
52044
51685
  function registerNavigateTool(server, options) {
52045
51686
  const name16 = options?.name ?? "navigate_to_page";
52046
51687
  const title2 = options?.title ?? "页面跳转";
@@ -52090,7 +51731,7 @@ ${observationText}
52090
51731
  };
52091
51732
  }
52092
51733
  };
52093
- const registeredTool = server.registerTool(
51734
+ return server.registerTool(
52094
51735
  name16,
52095
51736
  {
52096
51737
  title: title2,
@@ -52099,19 +51740,6 @@ ${observationText}
52099
51740
  },
52100
51741
  handler
52101
51742
  );
52102
- const managedByPageTools = typeof server.unregisterTool === "function";
52103
- if (!managedByPageTools) {
52104
- void registerBuiltinWebMcpTool({
52105
- name: name16,
52106
- description: description2,
52107
- inputSchema,
52108
- execute: async (input) => {
52109
- return await handler(input);
52110
- }
52111
- });
52112
- return attachBuiltinUnregisterOnRemove(name16, registeredTool);
52113
- }
52114
- return registeredTool;
52115
51743
  }
52116
51744
  function buildPageHandler(name16, route, timeout = 3e4, effectConfig) {
52117
51745
  return (input) => {
@@ -52185,28 +51813,21 @@ ${observationText}
52185
51813
  };
52186
51814
  }
52187
51815
  function withPageTools(server, options) {
52188
- const nativeMode = options?.nativeWebMcp?.mode ?? "auto";
52189
- const shouldRegisterBuiltin = nativeMode !== "disabled";
52190
51816
  const proxyRegisteredTools = /* @__PURE__ */ new Map();
52191
51817
  const unregisterByName = (target, name16, silent = false) => {
52192
51818
  const existing = proxyRegisteredTools.get(name16);
52193
51819
  const hadTrackedState = !!existing;
52194
- debugWebMcpLog("proxy-unregister-start", { name: name16, hasExisting: !!existing, silent });
52195
- tryDirectBuiltinUnregisterByName(name16);
52196
51820
  proxyRegisteredTools.delete(name16);
52197
- runtimeRegisteredTools.delete(name16);
52198
51821
  if (existing) {
52199
51822
  try {
52200
51823
  existing.remove();
52201
51824
  } catch {
52202
51825
  }
52203
51826
  }
52204
- void unregisterBuiltinWebMcpTool(name16);
52205
51827
  if (!silent && hadTrackedState) {
52206
51828
  notifyServerToolListChanged(target);
52207
51829
  broadcastToolCatalogChanged();
52208
51830
  }
52209
- debugWebMcpLog("proxy-unregister-done", { name: name16, removed: !!existing, silent });
52210
51831
  return !!existing;
52211
51832
  };
52212
51833
  return new Proxy(server, {
@@ -52216,53 +51837,24 @@ ${observationText}
52216
51837
  }
52217
51838
  if (prop === "registerTool") {
52218
51839
  return (name16, config2, handlerOrRoute) => {
52219
- debugWebMcpLog("proxy-register-start", {
52220
- name: name16,
52221
- mode: typeof handlerOrRoute === "function" ? "callback" : "route",
52222
- shouldRegisterBuiltin
52223
- });
52224
51840
  unregisterByName(target, name16, true);
52225
51841
  const rawRegister = target.registerTool.bind(target);
52226
51842
  if (typeof handlerOrRoute === "function") {
52227
51843
  const registeredTool2 = rawRegister(name16, config2, handlerOrRoute);
52228
- const wrapped2 = shouldRegisterBuiltin ? attachBuiltinUnregisterOnRemove(name16, registeredTool2) : registeredTool2;
52229
- proxyRegisteredTools.set(name16, wrapped2);
51844
+ proxyRegisteredTools.set(name16, registeredTool2);
52230
51845
  notifyServerToolListChanged(target);
52231
51846
  broadcastToolCatalogChanged();
52232
- if (shouldRegisterBuiltin) {
52233
- void registerBuiltinWebMcpTool({
52234
- name: name16,
52235
- description: config2?.description,
52236
- inputSchema: config2?.inputSchema,
52237
- execute: async (input) => {
52238
- return await handlerOrRoute(input);
52239
- }
52240
- });
52241
- }
52242
- debugWebMcpLog("proxy-register-done", { name: name16, mode: "callback" });
52243
- return wrapped2;
51847
+ return registeredTool2;
52244
51848
  }
52245
51849
  const { route, timeout, invokeEffect } = handlerOrRoute;
52246
51850
  const normalizedRoute = normalizeRoute(route);
52247
51851
  const effectConfig = resolveRuntimeEffectConfig(name16, config2?.title, invokeEffect);
52248
51852
  const pageHandler = buildPageHandler(name16, normalizedRoute, timeout, effectConfig);
52249
51853
  const registeredTool = rawRegister(name16, config2, pageHandler);
52250
- const wrapped = shouldRegisterBuiltin ? attachBuiltinUnregisterOnRemove(name16, registeredTool) : registeredTool;
52251
- proxyRegisteredTools.set(name16, wrapped);
51854
+ proxyRegisteredTools.set(name16, registeredTool);
52252
51855
  notifyServerToolListChanged(target);
52253
51856
  broadcastToolCatalogChanged();
52254
- if (shouldRegisterBuiltin) {
52255
- void registerBuiltinWebMcpTool({
52256
- name: name16,
52257
- description: config2?.description,
52258
- inputSchema: config2?.inputSchema,
52259
- execute: async (input) => {
52260
- return await pageHandler(input);
52261
- }
52262
- });
52263
- }
52264
- debugWebMcpLog("proxy-register-done", { name: name16, mode: "route" });
52265
- return wrapped;
51857
+ return registeredTool;
52266
51858
  };
52267
51859
  }
52268
51860
  return Reflect.get(target, prop, receiver);
@@ -52329,6 +51921,57 @@ ${observationText}
52329
51921
  broadcastRouteChange(MSG_PAGE_LEAVE, route);
52330
51922
  };
52331
51923
  }
51924
+ function getNativeModelContext() {
51925
+ if (typeof navigator === "undefined") return null;
51926
+ const nav = navigator;
51927
+ return nav.modelContext || nav.modelContextTesting || null;
51928
+ }
51929
+ const _modelContextHandlers = /* @__PURE__ */ new Map();
51930
+ let _modelContextCleanup = null;
51931
+ function syncModelContextToPage() {
51932
+ if (typeof window === "undefined") return;
51933
+ if (_modelContextCleanup) {
51934
+ _modelContextCleanup();
51935
+ _modelContextCleanup = null;
51936
+ }
51937
+ if (_modelContextHandlers.size === 0) {
51938
+ return;
51939
+ }
51940
+ const route = normalizeRoute(window.location.pathname);
51941
+ _modelContextCleanup = registerPageTool({
51942
+ route,
51943
+ handlers: Object.fromEntries(_modelContextHandlers)
51944
+ });
51945
+ }
51946
+ const modelContext = {
51947
+ /**
51948
+ * 注册一个 WebMCP 工具
51949
+ */
51950
+ registerTool: (config2) => {
51951
+ const { name: name16, execute } = config2;
51952
+ _modelContextHandlers.set(name16, execute);
51953
+ const nativeCtx = getNativeModelContext();
51954
+ if (nativeCtx && typeof nativeCtx.registerTool === "function") {
51955
+ nativeCtx.registerTool(config2);
51956
+ }
51957
+ syncModelContextToPage();
51958
+ broadcastToolCatalogChanged();
51959
+ },
51960
+ /**
51961
+ * 注销一个 WebMCP 工具
51962
+ */
51963
+ unregisterTool: (name16) => {
51964
+ const nativeCtx = getNativeModelContext();
51965
+ if (nativeCtx && typeof nativeCtx.unregisterTool === "function") {
51966
+ nativeCtx.unregisterTool(name16);
51967
+ }
51968
+ if (_modelContextHandlers.has(name16)) {
51969
+ _modelContextHandlers.delete(name16);
51970
+ syncModelContextToPage();
51971
+ broadcastToolCatalogChanged();
51972
+ }
51973
+ }
51974
+ };
52332
51975
  const MAIN_SKILL_PATH_REG = /^\.\/[^/]+\/SKILL\.md$/;
52333
51976
  const FRONT_MATTER_BLOCK_REG = /^---\s*\n([\s\S]+?)\s*\n---/;
52334
51977
  function parseSkillFrontMatter(content) {
@@ -52508,8 +52151,6 @@ ${lines.join("\n")}
52508
52151
  exports2.createSkillTools = createSkillTools;
52509
52152
  exports2.createStreamableHTTPClientTransport = createStreamableHTTPClientTransport;
52510
52153
  exports2.definePageTool = definePageTool;
52511
- exports2.executeBuiltinWebMcpTool = executeBuiltinWebMcpTool;
52512
- exports2.forceResetBuiltinWebMcpTools = forceResetBuiltinWebMcpTools;
52513
52154
  exports2.formatSkillsForSystemPrompt = formatSkillsForSystemPrompt;
52514
52155
  exports2.getAISDKTools = getAISDKTools;
52515
52156
  exports2.getActivePageTools = getActivePageTools;
@@ -52521,24 +52162,18 @@ ${lines.join("\n")}
52521
52162
  exports2.getSkillMdPaths = getSkillMdPaths;
52522
52163
  exports2.getSkillOverviews = getSkillOverviews;
52523
52164
  exports2.getToolRouteMap = getToolRouteMap;
52524
- exports2.hasBuiltinWebMcpTool = hasBuiltinWebMcpTool;
52525
- exports2.isBuiltinWebMcpSupported = isBuiltinWebMcpSupported;
52526
52165
  exports2.isMcpClient = isMcpClient;
52527
52166
  exports2.isMcpServer = isMcpServer;
52528
52167
  exports2.isMessageChannelClientTransport = isMessageChannelClientTransport;
52529
52168
  exports2.isMessageChannelServerTransport = isMessageChannelServerTransport;
52530
52169
  exports2.isSSEClientTransport = isSSEClientTransport;
52531
52170
  exports2.isStreamableHTTPClientTransport = isStreamableHTTPClientTransport;
52532
- exports2.listBuiltinWebMcpTools = listBuiltinWebMcpTools;
52533
- exports2.mountPageTools = mountPageTools;
52171
+ exports2.modelContext = modelContext;
52534
52172
  exports2.parseSkillFrontMatter = parseSkillFrontMatter;
52535
- exports2.registerBuiltinWebMcpTool = registerBuiltinWebMcpTool;
52536
52173
  exports2.registerNavigateTool = registerNavigateTool;
52537
52174
  exports2.registerPageTool = registerPageTool;
52538
52175
  exports2.registerPageTools = registerPageTools;
52539
- exports2.registerRuntimePageTools = registerRuntimePageTools;
52540
52176
  exports2.setNavigator = setNavigator;
52541
- exports2.unregisterBuiltinWebMcpTool = unregisterBuiltinWebMcpTool;
52542
52177
  exports2.withPageTools = withPageTools;
52543
52178
  exports2.z = z;
52544
52179
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });