From 1984201fa700b86b101df995d06e59530b569d89 Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Sat, 22 Nov 2025 14:46:40 -0500 Subject: [PATCH] Simplify format-id schema for better code generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace complex oneOf/not/anyOf validation pattern with simpler dependencies keyword. Produces single type instead of union types while maintaining identical validation semantics. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .changeset/simplify-format-id-schema.md | 31 +++++++++++++++++++++ static/schemas/source/core/format-id.json | 33 ++++++++++------------- 2 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 .changeset/simplify-format-id-schema.md diff --git a/.changeset/simplify-format-id-schema.md b/.changeset/simplify-format-id-schema.md new file mode 100644 index 0000000000..13189cfcd8 --- /dev/null +++ b/.changeset/simplify-format-id-schema.md @@ -0,0 +1,31 @@ +--- +"adcontextprotocol": patch +--- + +Simplify format-id schema structure for better code generation compatibility. + +**Problem**: The previous schema used a complex `oneOf`/`not`/`anyOf` pattern in `allOf` to express that width/height fields are optional but must appear together. This caused code generators to interpret the schema as two separate types (FormatId1, FormatId2) rather than a single type with optional fields, forcing union types everywhere format_id was used. + +**Solution**: Replaced the complex validation pattern with a simpler approach: +- Moved width/height fields directly into the format-id schema properties +- Used JSON Schema `dependencies` keyword to enforce that width and height must appear together +- Maintained identical validation semantics while producing cleaner generated types + +**Impact**: +- Code generators now produce a single FormatId type with optional width/height fields +- No breaking changes to the wire format or validation behavior +- Improved developer experience with better TypeScript/Python type hints +- Eliminates need for union types when referencing format_id + +**Example generated type (TypeScript)**: +```typescript +// Before: FormatId1 | FormatId2 +// After: +interface FormatId { + agent_url: string; + id: string; + width?: number; // optional, but must have height if present + height?: number; // optional, but must have width if present + duration_ms?: number; +} +``` diff --git a/static/schemas/source/core/format-id.json b/static/schemas/source/core/format-id.json index f79acb4db2..a90032ba43 100644 --- a/static/schemas/source/core/format-id.json +++ b/static/schemas/source/core/format-id.json @@ -15,6 +15,16 @@ "pattern": "^[a-zA-Z0-9_-]+$", "description": "Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant." }, + "width": { + "type": "integer", + "minimum": 1, + "description": "Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, + "height": { + "type": "integer", + "minimum": 1, + "description": "Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants." + }, "duration_ms": { "type": "number", "minimum": 1, @@ -23,23 +33,8 @@ }, "required": ["agent_url", "id"], "additionalProperties": false, - "allOf": [ - { - "oneOf": [ - { - "not": { - "anyOf": [ - {"required": ["width"]}, - {"required": ["height"]} - ] - } - }, - { - "allOf": [ - {"$ref": "/schemas/core/dimensions.json"} - ] - } - ] - } - ] + "dependencies": { + "width": ["height"], + "height": ["width"] + } }