fix: address Copilot review round 40 — a required name counts as a field

A schema may require a property it never declares: `{ type: "object",
required: ["token"] }` is legal and the tool plainly takes an argument.
declaresAnyFields counted only `properties`, so an App tool shaped that way —
including nested under a composition — was reported input-free and
auto-invoked with `{}`.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-26 15:49:54 -04:00
commit 8f935adaad

View file

@ -498,6 +498,11 @@ export function declaresAnyFields(
): boolean {
if (schema === undefined) return false;
if (Object.keys(propertiesOf(schema)).length > 0) return true;
// A schema may require a name it never declares — `{ required: ["token"] }`
// is a legal object schema, and the tool plainly takes an argument. Counting
// it here is what stops an App tool with that shape being auto-invoked with
// `{}` for want of a `properties` map.
if (requiredOf(schema).length > 0) return true;
// A `$ref`'s shape is unknown rather than empty, so it counts. Reporting "no
// fields" for `anyOf: [{ $ref: … }, { $ref: … }]` would auto-invoke an App
// tool with `{}` on the strength of something never read.