fix(browser): preserve distinct WebMCP declaration metadata (#2854)
* fix(browser): preserve distinct WebMCP declaration metadata * test(browser): retain the first equivalent declaration location
This commit is contained in:
@@ -714,3 +714,54 @@ it("keeps RPC lexical identity and bundled factory recognition in captured scrip
|
||||
]);
|
||||
expect(result.completeness.status).toBe("complete");
|
||||
});
|
||||
|
||||
it("retains distinct WebMCP descriptions and names while deduplicating equivalent properties", () => {
|
||||
const result = analyzeCapturedWebBundle(
|
||||
inspection(`
|
||||
document.modelContext.registerTool({ name: "lookup", description: "first", inputSchema: { properties: { alpha: {} } } });
|
||||
document.modelContext.registerTool({ name: "lookup", description: "second", inputSchema: { properties: { alpha: {} } } });
|
||||
document.modelContext.registerTool({ name: "equivalent", inputSchema: { properties: { alpha: {}, beta: {} } } });
|
||||
document.modelContext.registerTool({ name: "equivalent", inputSchema: { properties: { beta: {}, alpha: {}, alpha: {} } } });
|
||||
document.modelContext.registerTool({ description: "unnamed" });
|
||||
document.modelContext.registerTool({ name: "", description: "unnamed" });
|
||||
`),
|
||||
);
|
||||
|
||||
expect(
|
||||
result.observations.webmcp_declarations.map(
|
||||
({ name, description, schema_property_names }) => ({
|
||||
name,
|
||||
description,
|
||||
schema_property_names,
|
||||
}),
|
||||
),
|
||||
).toEqual([
|
||||
{
|
||||
name: "lookup",
|
||||
description: "first",
|
||||
schema_property_names: ["alpha"],
|
||||
},
|
||||
{
|
||||
name: "lookup",
|
||||
description: "second",
|
||||
schema_property_names: ["alpha"],
|
||||
},
|
||||
{
|
||||
name: "equivalent",
|
||||
description: null,
|
||||
schema_property_names: ["alpha", "beta"],
|
||||
},
|
||||
{ name: null, description: "unnamed", schema_property_names: [] },
|
||||
{ name: "", description: "unnamed", schema_property_names: [] },
|
||||
]);
|
||||
expect(result.observations.webmcp_declarations[2]?.location).toEqual({
|
||||
script_key: `scr_${"1".repeat(64)}`,
|
||||
line: 4,
|
||||
column: 6,
|
||||
});
|
||||
expect(
|
||||
result.observations.webmcp_declarations.every(
|
||||
({ trust }) => trust === "page-declared-untrusted",
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
@@ -293,19 +293,18 @@ const addWebMcpDeclaration = (
|
||||
: [],
|
||||
)
|
||||
: [];
|
||||
const metadata = {
|
||||
name: name ?? null,
|
||||
description: description ?? null,
|
||||
schema_property_names: [...new Set(schemaPropertyNames)].sort(),
|
||||
};
|
||||
// Deduplicate the metadata we return, preserving omission and descriptions.
|
||||
// Property names are a variable-length source-derived list: NUL-joins
|
||||
// would collapse ["a\0b"] with ["a", "b"] and drop a declaration.
|
||||
const key = compositeKey([
|
||||
"webmcp",
|
||||
script.script_key,
|
||||
name ?? "",
|
||||
schemaPropertyNames,
|
||||
]);
|
||||
const key = compositeKey(["webmcp", script.script_key, metadata]);
|
||||
addUnique(accumulator, key, () =>
|
||||
accumulator.webMcp.push({
|
||||
name: name ?? null,
|
||||
description: description ?? null,
|
||||
schema_property_names: [...new Set(schemaPropertyNames)].sort(),
|
||||
...metadata,
|
||||
trust: "page-declared-untrusted",
|
||||
location: location(script.script_key, node),
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user