Skip to content

Fix format_ids schema to use structured format ID objects - #123

Merged
bokelley merged 2 commits into
mainfrom
bokelley/fix-format-ids-schema
Oct 15, 2025
Merged

Fix format_ids schema to use structured format ID objects#123
bokelley merged 2 commits into
mainfrom
bokelley/fix-format-ids-schema

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Fixed critical schema bug where format_ids was incorrectly defined as arrays of strings instead of structured format ID objects with agent_url and id fields.

Changes

Schema Updates (4 files)

  • static/schemas/v1/media-buy/package-request.json
  • static/schemas/v1/media-buy/list-creative-formats-request.json
  • static/schemas/v1/creative/list-creative-formats-request.json
  • static/schemas/v1/media-buy/get-products-request.json

All now use $ref to /schemas/v1/core/format-id.json instead of type: "string".

Documentation Updates (16 examples across 4 files)

  • docs/media-buy/task-reference/create_media_buy.md (10 examples)
  • docs/media-buy/product-discovery/media-products.md (3 examples)
  • docs/media-buy/advanced-topics/pricing-models.md (2 examples)
  • docs/media-buy/task-reference/list_creative_formats.md (1 example)

All examples now use structured format IDs:

"format_ids": [
  {
    "agent_url": "https://creatives.adcontextprotocol.org",
    "id": "video_standard_30s"
  }
]

CLAUDE.md Cleanup

Removed outdated formats_to_provide reference in favor of the consistent format_ids field name.

Rationale

This aligns with the protocol's core requirement that format IDs are ALWAYS structured objects to:

  • Avoid parsing ambiguity
  • Handle namespace collisions between creative agents
  • Maintain consistency across the protocol

Test Plan

  • All schema validation tests pass
  • All example validation tests pass
  • TypeScript compilation succeeds
  • Documentation build succeeds

🤖 Generated with Claude Code

bokelley and others added 2 commits October 15, 2025 07:53
Changed format_ids from arrays of strings to arrays of format-id objects
(with agent_url and id fields) across all schemas and documentation.

**Schema changes:**
- static/schemas/v1/media-buy/package-request.json
- static/schemas/v1/media-buy/list-creative-formats-request.json
- static/schemas/v1/creative/list-creative-formats-request.json
- static/schemas/v1/media-buy/get-products-request.json

**Documentation updates (16 examples):**
- docs/media-buy/task-reference/create_media_buy.md (10 examples)
- docs/media-buy/product-discovery/media-products.md (3 examples)
- docs/media-buy/advanced-topics/pricing-models.md (2 examples)
- docs/media-buy/task-reference/list_creative_formats.md (1 example)

This aligns with the protocol's requirement that format IDs are ALWAYS
structured objects to avoid parsing ambiguity and handle namespace
collisions between creative agents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The schema correctly uses format_ids consistently throughout. Updated
the 'Better Field Naming' example to reflect the actual field name used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley
bokelley merged commit be6181a into main Oct 15, 2025
4 checks passed
bokelley added a commit to prebid/salesagent that referenced this pull request Oct 15, 2025
- Downloaded latest package-request.json schema (now uses FormatId objects)
- Regenerated all Pydantic schemas from latest AdCP spec
- Fixed schema generator bug: format_ids now correctly uses list[FormatId] not list[str]
- Updated server comment to reflect new spec (both request and response use FormatId)
- Maintains backward compatibility with string format IDs from older clients

Per adcontextprotocol/adcp#123:
- format_ids changed from array of strings to array of FormatId objects
- FormatId structure: {agent_url: string, id: string}
- Avoids parsing ambiguity and handles namespace collisions
bokelley added a commit to prebid/salesagent that referenced this pull request Oct 15, 2025
* Fix format_ids handling: separate request and response fields

**Problem:**
The Package model had a validator that automatically converted format_ids
(array of strings) to format_ids_to_provide (array of FormatId objects)
during model initialization. This caused validation errors when clients
sent v1.8.0 requests with format_ids as strings, because the validator
ran too early and converted the data before the server could process it.

**Root Cause:**
- AdCP v1.8.0 spec defines TWO different fields:
  - `format_ids` (request): array of strings in package-request.json
  - `format_ids_to_provide` (response): array of FormatId objects in core/package.json
- The Package model was trying to serve both purposes with automatic migration
- The @model_validator ran during request deserialization, breaking client compatibility

**Solution:**
1. **schemas.py**: Removed the automatic migration validator
   - Added explicit `format_ids: list[str]` field for requests
   - Kept `format_ids_to_provide: list[FormatId]` field for responses
   - Package model now accepts both formats without auto-conversion

2. **main.py**: Added explicit conversion in create_media_buy response building
   - Convert format_ids → format_ids_to_provide when building response
   - Happens after request validation, before response serialization
   - Removes format_ids from response (only format_ids_to_provide in output)

**Testing:**
- All existing package-related unit tests pass (20 tests)
- Manual testing confirms Package model accepts format_ids as strings
- No breaking changes to existing code paths

**Result:**
✅ Clients can now send format_ids: ["display_300x250"] (v1.8.0 format)
✅ Server accepts request without validation errors
✅ Server responds with format_ids_to_provide: [{"agent_url": "...", "id": "..."}]
✅ Full AdCP v1.8.0 compatibility maintained

* Update schemas to use FormatId objects per AdCP PR #123

- Downloaded latest package-request.json schema (now uses FormatId objects)
- Regenerated all Pydantic schemas from latest AdCP spec
- Fixed schema generator bug: format_ids now correctly uses list[FormatId] not list[str]
- Updated server comment to reflect new spec (both request and response use FormatId)
- Maintains backward compatibility with string format IDs from older clients

Per adcontextprotocol/adcp#123:
- format_ids changed from array of strings to array of FormatId objects
- FormatId structure: {agent_url: string, id: string}
- Avoids parsing ambiguity and handles namespace collisions

* Fix schema generator: regenerate with correct package-request schema

Root cause: Outdated cached schema file had format_ids as list[str] instead of
list[FormatId] with $ref to format-id.json.

Investigation findings:
1. Schema generator's resolve_refs_in_schema() function works correctly
2. Issue was outdated cached file: tests/e2e/schemas/v1/_schemas_v1_media-buy_package-request_json.json
3. Old cached schema had: items: {type: 'string'}
4. New cached schema has: items: {$ref: '/schemas/v1/core/format-id.json'}
5. After downloading latest schema, generator correctly resolved $ref to FormatId

Result:
✅ Generated schemas now correctly use list[FormatId] (lines 378-384, 712-718)
✅ FormatId structure properly inlined (lines 13-29) with agent_url and id fields
✅ Schema generator working as designed - just needed updated input files

Lesson: Always ensure cached schemas are up-to-date before regenerating.

* Enhance schema sync checker to validate format_ids structure

Adds automated validation to prevent outdated schemas from causing
schema generator issues in the future.

Changes:
1. Added package-request.json and format-id.json to critical schemas list
2. Added new validate_format_ids_structure() check that specifically validates:
   - format_ids field uses $ref to /schemas/v1/core/format-id.json
   - Detects if format_ids incorrectly uses {type: 'string'}
   - Provides clear error messages with fix instructions
3. Runs as first check in pre-commit hook for early detection

Prevention:
This prevents the root cause issue from PR investigation:
- Old cached schema had format_ids: {items: {type: 'string'}}
- New spec requires format_ids: {items: {$ref: '/schemas/v1/core/format-id.json'}}
- Schema generator was working correctly, but had wrong input

Testing:
✅ Runs successfully: uv run python scripts/check_schema_sync.py
✅ Validates format_ids structure correctly
✅ Provides actionable error messages

Result:
Future schema updates will be caught by pre-commit hook before
causing schema generator issues.

* Add comprehensive schema update documentation

Documents the complete schema update process to prevent future issues.

Contents:
- Overview of schema caching and validation
- Automated protection via pre-commit hooks
- Step-by-step update procedures (automatic and manual)
- Troubleshooting guide for common issues
- Schema validation checks explanation
- Best practices and workflow diagrams
- Reference to AdCP PR #123 format_ids changes

Key sections:
1. When to update schemas
2. How to update (automatic vs manual)
3. Schema validation checks (format_ids, critical schemas, full sync)
4. Troubleshooting common issues
5. Update workflow diagram
6. Best practices

This prevents the issue we encountered where outdated cached schemas
caused the generator to produce incorrect types.

* Sync all schemas and regenerate with latest AdCP spec

Systematic fix to ensure all cached schemas match live registry.

Changes:
1. Updated cached schemas (tests/e2e/schemas/v1/):
   - get-products-request.json
   - list-creative-formats-request.json

2. Regenerated all Pydantic models (src/core/schemas_generated/):
   - 77 schema files updated
   - All models now use latest schema definitions
   - format_ids correctly uses list[FormatId] throughout

Process:
- Ran: uv run python scripts/check_schema_sync.py --update
- Verified: All schemas now in sync with adcontextprotocol.org
- Regenerated: uv run python scripts/generate_schemas.py

Validation:
✅ All schemas in sync
✅ format_ids structure validated
✅ Schema generator working correctly
✅ No errors in schema sync check

This ensures the codebase is fully synchronized with the official
AdCP spec and prevents future schema drift issues.

* Update documentation: clarify automated schema validation

Enhanced schema-updates.md to clearly explain automated protection.

Changes:
- Added 'Pre-commit Hook (Runs Automatically)' section
- Specified that validation runs on EVERY commit
- Listed exactly what gets validated (format IDs, 7 critical schemas, 30+ endpoints)
- Clarified that commits are BLOCKED if schemas out of sync
- Added clear error message example with fix instructions

This makes it crystal clear that the automation is:
1. Always running (every commit)
2. Comprehensive (all schemas checked)
3. Enforced (commits blocked on failure)
4. Actionable (clear fix instructions)

Result: Developers understand the protection is automatic and systematic.

* Fix schema adapter to handle format_ids conversion

- Handle both dict and Pydantic model cases for filters in GetProductsRequest.to_generated()
- Update test expectations to reflect AdCP PR #123 (format_ids as FormatId objects)
- Tests now pass: schema adapters properly convert string format_ids to FormatId objects during roundtrip

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Oct 15, 2025
* Fix format_ids schema to use structured format ID objects

Changed format_ids from arrays of strings to arrays of format-id objects
(with agent_url and id fields) across all schemas and documentation.

**Schema changes:**
- static/schemas/v1/media-buy/package-request.json
- static/schemas/v1/media-buy/list-creative-formats-request.json
- static/schemas/v1/creative/list-creative-formats-request.json
- static/schemas/v1/media-buy/get-products-request.json

**Documentation updates (16 examples):**
- docs/media-buy/task-reference/create_media_buy.md (10 examples)
- docs/media-buy/product-discovery/media-products.md (3 examples)
- docs/media-buy/advanced-topics/pricing-models.md (2 examples)
- docs/media-buy/task-reference/list_creative_formats.md (1 example)

This aligns with the protocol's requirement that format IDs are ALWAYS
structured objects to avoid parsing ambiguity and handle namespace
collisions between creative agents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Remove outdated formats_to_provide reference from CLAUDE.md

The schema correctly uses format_ids consistently throughout. Updated
the 'Better Field Naming' example to reflect the actual field name used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Oct 15, 2025
* Fix format_ids schema to use structured format ID objects

Changed format_ids from arrays of strings to arrays of format-id objects
(with agent_url and id fields) across all schemas and documentation.

**Schema changes:**
- static/schemas/v1/media-buy/package-request.json
- static/schemas/v1/media-buy/list-creative-formats-request.json
- static/schemas/v1/creative/list-creative-formats-request.json
- static/schemas/v1/media-buy/get-products-request.json

**Documentation updates (16 examples):**
- docs/media-buy/task-reference/create_media_buy.md (10 examples)
- docs/media-buy/product-discovery/media-products.md (3 examples)
- docs/media-buy/advanced-topics/pricing-models.md (2 examples)
- docs/media-buy/task-reference/list_creative_formats.md (1 example)

This aligns with the protocol's requirement that format IDs are ALWAYS
structured objects to avoid parsing ambiguity and handle namespace
collisions between creative agents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)



* Remove outdated formats_to_provide reference from CLAUDE.md

The schema correctly uses format_ids consistently throughout. Updated
the 'Better Field Naming' example to reflect the actual field name used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)



---------

Co-authored-by: Claude <noreply@anthropic.com>
danf-newton pushed a commit to Newton-Research-Inc/salesagent that referenced this pull request Nov 24, 2025
* Fix format_ids handling: separate request and response fields

**Problem:**
The Package model had a validator that automatically converted format_ids
(array of strings) to format_ids_to_provide (array of FormatId objects)
during model initialization. This caused validation errors when clients
sent v1.8.0 requests with format_ids as strings, because the validator
ran too early and converted the data before the server could process it.

**Root Cause:**
- AdCP v1.8.0 spec defines TWO different fields:
  - `format_ids` (request): array of strings in package-request.json
  - `format_ids_to_provide` (response): array of FormatId objects in core/package.json
- The Package model was trying to serve both purposes with automatic migration
- The @model_validator ran during request deserialization, breaking client compatibility

**Solution:**
1. **schemas.py**: Removed the automatic migration validator
   - Added explicit `format_ids: list[str]` field for requests
   - Kept `format_ids_to_provide: list[FormatId]` field for responses
   - Package model now accepts both formats without auto-conversion

2. **main.py**: Added explicit conversion in create_media_buy response building
   - Convert format_ids → format_ids_to_provide when building response
   - Happens after request validation, before response serialization
   - Removes format_ids from response (only format_ids_to_provide in output)

**Testing:**
- All existing package-related unit tests pass (20 tests)
- Manual testing confirms Package model accepts format_ids as strings
- No breaking changes to existing code paths

**Result:**
✅ Clients can now send format_ids: ["display_300x250"] (v1.8.0 format)
✅ Server accepts request without validation errors
✅ Server responds with format_ids_to_provide: [{"agent_url": "...", "id": "..."}]
✅ Full AdCP v1.8.0 compatibility maintained

* Update schemas to use FormatId objects per AdCP PR prebid#123

- Downloaded latest package-request.json schema (now uses FormatId objects)
- Regenerated all Pydantic schemas from latest AdCP spec
- Fixed schema generator bug: format_ids now correctly uses list[FormatId] not list[str]
- Updated server comment to reflect new spec (both request and response use FormatId)
- Maintains backward compatibility with string format IDs from older clients

Per adcontextprotocol/adcp#123:
- format_ids changed from array of strings to array of FormatId objects
- FormatId structure: {agent_url: string, id: string}
- Avoids parsing ambiguity and handles namespace collisions

* Fix schema generator: regenerate with correct package-request schema

Root cause: Outdated cached schema file had format_ids as list[str] instead of
list[FormatId] with $ref to format-id.json.

Investigation findings:
1. Schema generator's resolve_refs_in_schema() function works correctly
2. Issue was outdated cached file: tests/e2e/schemas/v1/_schemas_v1_media-buy_package-request_json.json
3. Old cached schema had: items: {type: 'string'}
4. New cached schema has: items: {$ref: '/schemas/v1/core/format-id.json'}
5. After downloading latest schema, generator correctly resolved $ref to FormatId

Result:
✅ Generated schemas now correctly use list[FormatId] (lines 378-384, 712-718)
✅ FormatId structure properly inlined (lines 13-29) with agent_url and id fields
✅ Schema generator working as designed - just needed updated input files

Lesson: Always ensure cached schemas are up-to-date before regenerating.

* Enhance schema sync checker to validate format_ids structure

Adds automated validation to prevent outdated schemas from causing
schema generator issues in the future.

Changes:
1. Added package-request.json and format-id.json to critical schemas list
2. Added new validate_format_ids_structure() check that specifically validates:
   - format_ids field uses $ref to /schemas/v1/core/format-id.json
   - Detects if format_ids incorrectly uses {type: 'string'}
   - Provides clear error messages with fix instructions
3. Runs as first check in pre-commit hook for early detection

Prevention:
This prevents the root cause issue from PR investigation:
- Old cached schema had format_ids: {items: {type: 'string'}}
- New spec requires format_ids: {items: {$ref: '/schemas/v1/core/format-id.json'}}
- Schema generator was working correctly, but had wrong input

Testing:
✅ Runs successfully: uv run python scripts/check_schema_sync.py
✅ Validates format_ids structure correctly
✅ Provides actionable error messages

Result:
Future schema updates will be caught by pre-commit hook before
causing schema generator issues.

* Add comprehensive schema update documentation

Documents the complete schema update process to prevent future issues.

Contents:
- Overview of schema caching and validation
- Automated protection via pre-commit hooks
- Step-by-step update procedures (automatic and manual)
- Troubleshooting guide for common issues
- Schema validation checks explanation
- Best practices and workflow diagrams
- Reference to AdCP PR prebid#123 format_ids changes

Key sections:
1. When to update schemas
2. How to update (automatic vs manual)
3. Schema validation checks (format_ids, critical schemas, full sync)
4. Troubleshooting common issues
5. Update workflow diagram
6. Best practices

This prevents the issue we encountered where outdated cached schemas
caused the generator to produce incorrect types.

* Sync all schemas and regenerate with latest AdCP spec

Systematic fix to ensure all cached schemas match live registry.

Changes:
1. Updated cached schemas (tests/e2e/schemas/v1/):
   - get-products-request.json
   - list-creative-formats-request.json

2. Regenerated all Pydantic models (src/core/schemas_generated/):
   - 77 schema files updated
   - All models now use latest schema definitions
   - format_ids correctly uses list[FormatId] throughout

Process:
- Ran: uv run python scripts/check_schema_sync.py --update
- Verified: All schemas now in sync with adcontextprotocol.org
- Regenerated: uv run python scripts/generate_schemas.py

Validation:
✅ All schemas in sync
✅ format_ids structure validated
✅ Schema generator working correctly
✅ No errors in schema sync check

This ensures the codebase is fully synchronized with the official
AdCP spec and prevents future schema drift issues.

* Update documentation: clarify automated schema validation

Enhanced schema-updates.md to clearly explain automated protection.

Changes:
- Added 'Pre-commit Hook (Runs Automatically)' section
- Specified that validation runs on EVERY commit
- Listed exactly what gets validated (format IDs, 7 critical schemas, 30+ endpoints)
- Clarified that commits are BLOCKED if schemas out of sync
- Added clear error message example with fix instructions

This makes it crystal clear that the automation is:
1. Always running (every commit)
2. Comprehensive (all schemas checked)
3. Enforced (commits blocked on failure)
4. Actionable (clear fix instructions)

Result: Developers understand the protection is automatic and systematic.

* Fix schema adapter to handle format_ids conversion

- Handle both dict and Pydantic model cases for filters in GetProductsRequest.to_generated()
- Update test expectations to reflect AdCP PR prebid#123 (format_ids as FormatId objects)
- Tests now pass: schema adapters properly convert string format_ids to FormatId objects during roundtrip

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Mar 18, 2026
When a working group leader adds a committee document, post a
notification to the WG's Slack channel so members can track updates.
This was missing — only published posts triggered channel notifications.

Includes isSlackConfigured() guard, APP_URL support, and mrkdwn
sanitization for title in link syntax.

Resolves Addie escalation #123 (Pia/Creative WG).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Mar 18, 2026
When a working group leader adds a committee document, post a
notification to the WG's Slack channel so members can track updates.
This was missing — only published posts triggered channel notifications.

Includes isSlackConfigured() guard, APP_URL support, and mrkdwn
sanitization for title in link syntax.

Resolves Addie escalation #123 (Pia/Creative WG).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
bokelley added a commit to bokelley/salesagent that referenced this pull request May 5, 2026
* Fix format_ids handling: separate request and response fields

**Problem:**
The Package model had a validator that automatically converted format_ids
(array of strings) to format_ids_to_provide (array of FormatId objects)
during model initialization. This caused validation errors when clients
sent v1.8.0 requests with format_ids as strings, because the validator
ran too early and converted the data before the server could process it.

**Root Cause:**
- AdCP v1.8.0 spec defines TWO different fields:
  - `format_ids` (request): array of strings in package-request.json
  - `format_ids_to_provide` (response): array of FormatId objects in core/package.json
- The Package model was trying to serve both purposes with automatic migration
- The @model_validator ran during request deserialization, breaking client compatibility

**Solution:**
1. **schemas.py**: Removed the automatic migration validator
   - Added explicit `format_ids: list[str]` field for requests
   - Kept `format_ids_to_provide: list[FormatId]` field for responses
   - Package model now accepts both formats without auto-conversion

2. **main.py**: Added explicit conversion in create_media_buy response building
   - Convert format_ids → format_ids_to_provide when building response
   - Happens after request validation, before response serialization
   - Removes format_ids from response (only format_ids_to_provide in output)

**Testing:**
- All existing package-related unit tests pass (20 tests)
- Manual testing confirms Package model accepts format_ids as strings
- No breaking changes to existing code paths

**Result:**
✅ Clients can now send format_ids: ["display_300x250"] (v1.8.0 format)
✅ Server accepts request without validation errors
✅ Server responds with format_ids_to_provide: [{"agent_url": "...", "id": "..."}]
✅ Full AdCP v1.8.0 compatibility maintained

* Update schemas to use FormatId objects per AdCP PR #123

- Downloaded latest package-request.json schema (now uses FormatId objects)
- Regenerated all Pydantic schemas from latest AdCP spec
- Fixed schema generator bug: format_ids now correctly uses list[FormatId] not list[str]
- Updated server comment to reflect new spec (both request and response use FormatId)
- Maintains backward compatibility with string format IDs from older clients

Per adcontextprotocol/adcp#123:
- format_ids changed from array of strings to array of FormatId objects
- FormatId structure: {agent_url: string, id: string}
- Avoids parsing ambiguity and handles namespace collisions

* Fix schema generator: regenerate with correct package-request schema

Root cause: Outdated cached schema file had format_ids as list[str] instead of
list[FormatId] with $ref to format-id.json.

Investigation findings:
1. Schema generator's resolve_refs_in_schema() function works correctly
2. Issue was outdated cached file: tests/e2e/schemas/v1/_schemas_v1_media-buy_package-request_json.json
3. Old cached schema had: items: {type: 'string'}
4. New cached schema has: items: {$ref: '/schemas/v1/core/format-id.json'}
5. After downloading latest schema, generator correctly resolved $ref to FormatId

Result:
✅ Generated schemas now correctly use list[FormatId] (lines 378-384, 712-718)
✅ FormatId structure properly inlined (lines 13-29) with agent_url and id fields
✅ Schema generator working as designed - just needed updated input files

Lesson: Always ensure cached schemas are up-to-date before regenerating.

* Enhance schema sync checker to validate format_ids structure

Adds automated validation to prevent outdated schemas from causing
schema generator issues in the future.

Changes:
1. Added package-request.json and format-id.json to critical schemas list
2. Added new validate_format_ids_structure() check that specifically validates:
   - format_ids field uses $ref to /schemas/v1/core/format-id.json
   - Detects if format_ids incorrectly uses {type: 'string'}
   - Provides clear error messages with fix instructions
3. Runs as first check in pre-commit hook for early detection

Prevention:
This prevents the root cause issue from PR investigation:
- Old cached schema had format_ids: {items: {type: 'string'}}
- New spec requires format_ids: {items: {$ref: '/schemas/v1/core/format-id.json'}}
- Schema generator was working correctly, but had wrong input

Testing:
✅ Runs successfully: uv run python scripts/check_schema_sync.py
✅ Validates format_ids structure correctly
✅ Provides actionable error messages

Result:
Future schema updates will be caught by pre-commit hook before
causing schema generator issues.

* Add comprehensive schema update documentation

Documents the complete schema update process to prevent future issues.

Contents:
- Overview of schema caching and validation
- Automated protection via pre-commit hooks
- Step-by-step update procedures (automatic and manual)
- Troubleshooting guide for common issues
- Schema validation checks explanation
- Best practices and workflow diagrams
- Reference to AdCP PR #123 format_ids changes

Key sections:
1. When to update schemas
2. How to update (automatic vs manual)
3. Schema validation checks (format_ids, critical schemas, full sync)
4. Troubleshooting common issues
5. Update workflow diagram
6. Best practices

This prevents the issue we encountered where outdated cached schemas
caused the generator to produce incorrect types.

* Sync all schemas and regenerate with latest AdCP spec

Systematic fix to ensure all cached schemas match live registry.

Changes:
1. Updated cached schemas (tests/e2e/schemas/v1/):
   - get-products-request.json
   - list-creative-formats-request.json

2. Regenerated all Pydantic models (src/core/schemas_generated/):
   - 77 schema files updated
   - All models now use latest schema definitions
   - format_ids correctly uses list[FormatId] throughout

Process:
- Ran: uv run python scripts/check_schema_sync.py --update
- Verified: All schemas now in sync with adcontextprotocol.org
- Regenerated: uv run python scripts/generate_schemas.py

Validation:
✅ All schemas in sync
✅ format_ids structure validated
✅ Schema generator working correctly
✅ No errors in schema sync check

This ensures the codebase is fully synchronized with the official
AdCP spec and prevents future schema drift issues.

* Update documentation: clarify automated schema validation

Enhanced schema-updates.md to clearly explain automated protection.

Changes:
- Added 'Pre-commit Hook (Runs Automatically)' section
- Specified that validation runs on EVERY commit
- Listed exactly what gets validated (format IDs, 7 critical schemas, 30+ endpoints)
- Clarified that commits are BLOCKED if schemas out of sync
- Added clear error message example with fix instructions

This makes it crystal clear that the automation is:
1. Always running (every commit)
2. Comprehensive (all schemas checked)
3. Enforced (commits blocked on failure)
4. Actionable (clear fix instructions)

Result: Developers understand the protection is automatic and systematic.

* Fix schema adapter to handle format_ids conversion

- Handle both dict and Pydantic model cases for filters in GetProductsRequest.to_generated()
- Update test expectations to reflect AdCP PR #123 (format_ids as FormatId objects)
- Tests now pass: schema adapters properly convert string format_ids to FormatId objects during roundtrip

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant