@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.
- package/agent/AgentModelProvider.ts +11 -1
- package/agent/type.ts +22 -1
- package/agent/utils/getBuiltinMcpTools.ts +74 -0
- package/dist/{AgentModelProvider-BIOOEdcN.js → AgentModelProvider-D13Uqnne.js} +213 -178
- package/dist/agent/AgentModelProvider.d.ts +5 -2
- package/dist/agent/type.d.ts +23 -0
- package/dist/agent/utils/getBuiltinMcpTools.d.ts +12 -0
- package/dist/core.js +1 -1
- package/dist/index.es.dev.js +113 -478
- package/dist/index.es.js +9589 -9858
- package/dist/index.js +539 -853
- package/dist/index.umd.dev.js +113 -478
- package/dist/index.umd.js +66 -66
- package/dist/page-tools/bridge.d.ts +19 -43
- package/dist/webagent.dev.js +54 -1
- package/dist/webagent.es.dev.js +54 -1
- package/dist/webagent.es.js +1217 -1172
- package/dist/webagent.js +32 -32
- package/package.json +1 -1
- package/page-tools/bridge.ts +96 -614
package/dist/index.umd.dev.js
CHANGED
|
@@ -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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
52229
|
-
proxyRegisteredTools.set(name16, wrapped2);
|
|
51844
|
+
proxyRegisteredTools.set(name16, registeredTool2);
|
|
52230
51845
|
notifyServerToolListChanged(target);
|
|
52231
51846
|
broadcastToolCatalogChanged();
|
|
52232
|
-
|
|
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
|
-
|
|
52251
|
-
proxyRegisteredTools.set(name16, wrapped);
|
|
51854
|
+
proxyRegisteredTools.set(name16, registeredTool);
|
|
52252
51855
|
notifyServerToolListChanged(target);
|
|
52253
51856
|
broadcastToolCatalogChanged();
|
|
52254
|
-
|
|
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.
|
|
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" });
|