mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(web): read WebMCP inputs from schema properties
Remove the fallback that interpreted schema metadata as parameter names. Preserve exact literal property keys, including empty names, without inventing names for missing or dynamic properties. Keep this an observed name projection. Refs #3331, #3765 Co-authored-by: abdooo2235 <abdalrhmantheiv15@gmail.com>
This commit is contained in:
@@ -1034,6 +1034,47 @@ describe("web metadata key semantics", () => {
|
||||
expect.objectContaining({ name: "valid" }),
|
||||
]);
|
||||
});
|
||||
|
||||
it("projects only exact input schema property names", () => {
|
||||
const result = analyzeCapturedWebBundle(
|
||||
inspection(`
|
||||
document.modelContext.registerTool({
|
||||
name: "literal",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: { type: {}, properties: {}, "": {}, [dynamicKey]: {}, ...dynamicProperties }
|
||||
}
|
||||
});
|
||||
document.modelContext.registerTool({ name: "missing properties", inputSchema: { type: "object" } });
|
||||
document.modelContext.registerTool({ name: "dynamic properties", inputSchema: { properties: dynamicProperties } });
|
||||
document.modelContext.registerTool({ name: "null properties", inputSchema: { properties: null } });
|
||||
document.modelContext.registerTool({ name: "missing schema" });
|
||||
document.modelContext.registerTool({ name: "dynamic schema", inputSchema: schema });
|
||||
document.modelContext.registerTool({ name: "null schema", inputSchema: null });
|
||||
document.modelContext.registerTool({ name: "spread schema", inputSchema: { ...schema } });
|
||||
document.modelContext.registerTool({
|
||||
name: "computed literal keys",
|
||||
["inputSchema"]: { ["properties"]: { [""]: {}, ["literal"]: {}, [dynamicKey]: {} } }
|
||||
});
|
||||
`),
|
||||
);
|
||||
|
||||
expect(
|
||||
result.observations.webmcp_declarations.map(
|
||||
({ name, schema_property_names }) => ({ name, schema_property_names }),
|
||||
),
|
||||
).toEqual([
|
||||
{ name: "literal", schema_property_names: ["", "properties", "type"] },
|
||||
{ name: "missing properties", schema_property_names: [] },
|
||||
{ name: "dynamic properties", schema_property_names: [] },
|
||||
{ name: "null properties", schema_property_names: [] },
|
||||
{ name: "missing schema", schema_property_names: [] },
|
||||
{ name: "dynamic schema", schema_property_names: [] },
|
||||
{ name: "null schema", schema_property_names: [] },
|
||||
{ name: "spread schema", schema_property_names: [] },
|
||||
{ name: "computed literal keys", schema_property_names: ["", "literal"] },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it("retains WebMCP declarations through optional member and call chaining", () => {
|
||||
|
||||
@@ -8,7 +8,10 @@ import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.
|
||||
import { indexJavaScriptBindingsWithReceiversSteps } from "./javascript/javascriptSemanticAnalysis.js";
|
||||
import { completeSemanticSteps } from "./javascript/javascriptSemanticTraversal.js";
|
||||
import type { JavaScriptOpenReceiverFact } from "./javascript/javascriptSemanticAnalysis.js";
|
||||
import { semanticStaticPropertyName } from "./javascript/javascriptAstValues.js";
|
||||
import {
|
||||
semanticStaticPropertyKey,
|
||||
semanticStaticPropertyName,
|
||||
} from "./javascript/javascriptAstValues.js";
|
||||
import {
|
||||
calleeName,
|
||||
endpointArgument,
|
||||
@@ -315,20 +318,15 @@ const addWebMcpDeclaration = (
|
||||
const schema =
|
||||
objectValue(declaration, "inputSchema") ??
|
||||
objectValue(declaration, "input_schema");
|
||||
const declaredProperties = t.isObjectExpression(schema)
|
||||
const properties = t.isObjectExpression(schema)
|
||||
? objectValue(schema, "properties")
|
||||
: undefined;
|
||||
const propertyObject = t.isObjectExpression(declaredProperties)
|
||||
? declaredProperties
|
||||
: schema;
|
||||
const schemaPropertyNames = t.isObjectExpression(propertyObject)
|
||||
? propertyObject.properties.flatMap((property) =>
|
||||
t.isObjectProperty(property)
|
||||
? [
|
||||
semanticStaticPropertyName(property.key, property.computed),
|
||||
].filter(Boolean)
|
||||
: [],
|
||||
)
|
||||
const schemaPropertyNames = t.isObjectExpression(properties)
|
||||
? properties.properties.flatMap((property) => {
|
||||
if (!t.isObjectProperty(property)) return [];
|
||||
const key = semanticStaticPropertyKey(property.key, property.computed);
|
||||
return key === null ? [] : [key];
|
||||
})
|
||||
: [];
|
||||
const metadata = {
|
||||
name: name ?? null,
|
||||
|
||||
Reference in New Issue
Block a user