Skip to content

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Nov 5, 2025

🤖 I have created a release beep boop

0.1.1 (2025-11-05)

Bug Fixes

  • remove deprecated package-name parameter from release-please config (28d8154)

This PR was generated with Release Please. See documentation.

@bokelley bokelley merged commit 76ca691 into main Nov 5, 2025
1 check passed
@github-actions
Copy link
Contributor Author

github-actions bot commented Nov 5, 2025

🤖 Created releases:

🌻

bokelley added a commit that referenced this pull request Nov 7, 2025
Critical fix addressing code review feedback:

1. Add extend-exclude pattern to [tool.black] in pyproject.toml
   - Prevents black from reformatting generated.py
   - Uses regex pattern: /(generated|tasks)\.py$

2. Update Makefile format target documentation
   - Clarifies that generated files are excluded

3. Format __main__.py (black auto-fix)

This prevents the schema drift CI failures that occur when:
- Developer runs `make format` (includes black)
- Black reformats generated.py Field definitions (multiline)
- CI runs `make check-schema-drift` (regenerates without formatting)
- Generator outputs inline format
- CI detects drift and fails

With this fix, black will skip generated.py entirely, keeping it
in the inline format that the generator produces.

Resolves: Code Review Critical Issue #2

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

Co-Authored-By: Claude <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 7, 2025
Addresses protocol expert feedback for production readiness:

1. **Webhook Response Typing** (High Priority #1)
   - handle_webhook() now returns TaskResult[Any] instead of None
   - Added _parse_webhook_result() helper method
   - Maps webhook task_type to response types for type-safe parsing
   - Validates WebhookPayload schema with Pydantic
   - Example usage:
     ```python
     result = await client.handle_webhook(payload, signature)
     if result.success and isinstance(result.data, GetProductsResponse):
         print(f"Found {len(result.data.products)} products")
     ```

2. **ProtocolEnvelope Type** (High Priority #2)
   - Already auto-generated from schema (protocol-envelope.json)
   - Includes: context_id, task_id, status, message, timestamp, payload
   - Used for async operation responses
   - No code changes needed - type already exists

3. **Format Caching Documentation** (High Priority #3)
   - Added comprehensive caching guidance to CLAUDE.md
   - Documented TTL-based and LRU cache strategies
   - Explained cache invalidation options
   - Provided code examples for production implementations

Benefits:
- Type-safe webhook handling enables better error detection
- Structured webhook responses integrate with existing TaskResult pattern
- Production developers have clear caching guidance
- All async workflows now properly typed

All tests pass (92/92), linting and type checking clean.

Resolves: Protocol Expert High Priority Issues #1, #2, #3

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

Co-Authored-By: Claude <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 7, 2025
* fix: parse list_creative_formats response into structured type

Problem: Creative agent returns text content instead of structured data
- Current: TextContent(text='Found 42 creative formats')
- Expected: ListCreativeFormatsResponse(formats=[Format(...), ...])
- Cause: Adapters return raw content without type parsing

Solution:
- Add response_parser.py with parse_mcp_content() and parse_json_or_text()
- Update list_creative_formats() to parse adapter responses
- Handle both MCP (content array) and A2A (dict) response formats
- Return properly typed ListCreativeFormatsResponse objects
- Gracefully handle invalid responses with clear error messages

Testing:
- Added 12 unit tests for response parser functions
- Added 3 integration tests for list_creative_formats parsing
- All 83 tests pass

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

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

* fix: define FormatId as proper object type per ADCP spec

Problem: FormatId was incorrectly defined as a string type alias,
but the ADCP spec requires it to be a structured object with
agent_url and id fields.

Root Cause: The format-id.json schema was missing from the downloaded
schemas, causing the type generator to create a placeholder string type.

Solution:
- Downloaded format-id.json schema from adcontextprotocol.org
- Defined FormatId as proper Pydantic model with agent_url and id fields
- Updated tests to use correct FormatId structure: {agent_url, id}

This ensures all format references use the structured format ID objects
as required by the ADCP specification, enabling proper format resolution
across different creative agents.

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

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

* refactor: move response parsing to adapter layer

Problem: Response parsing was only implemented for list_creative_formats,
leaving all other methods returning unparsed raw data.

Solution: Move parsing logic to adapter base class so ALL methods benefit:

1. Added _parse_response() helper in ProtocolAdapter base class
   - Handles MCP content arrays and A2A dict responses
   - Validates against expected Pydantic types
   - Returns properly typed TaskResult

2. Added specific ADCP method declarations in base adapter
   - get_products, list_creative_formats, sync_creatives, etc.
   - Default implementations delegate to call_tool()
   - Keeps adapters simple while enabling type-safe interface

3. Updated client to use specific adapter methods
   - Calls adapter.list_creative_formats() instead of adapter.call_tool()
   - Delegates parsing to adapter._parse_response()
   - Removes duplicate parsing logic from client layer

Benefits:
- ALL ADCP methods now return properly typed responses
- Single parsing implementation shared across all methods
- Adapters handle protocol differences (MCP vs A2A)
- Client layer stays focused on business logic
- Type-safe interface prevents tool name typos

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

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

* remove: delete call_tool generic fallback method

Remove the generic call_tool() method from adapters and client.
No fallbacks - every ADCP method must be explicitly implemented.

Changes:
- Removed call_tool() from ProtocolAdapter base class
- Renamed internal helpers: call_tool → _call_a2a_tool / _call_mcp_tool
- Removed call_tool() from ADCPClient
- Updated all tests to mock specific methods instead of call_tool

Benefits:
- Forces explicit implementation of every ADCP protocol method
- No magic "it might work" fallbacks that hide bugs
- Clear contract: adapters MUST implement all 9 ADCP methods
- Type-safe: impossible to typo a tool name
- Better tooling: IDE autocomplete knows all methods

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

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

* fix: address critical code review issues

Fixed 3 critical issues identified in code review:

1. FormatId Validation (CRITICAL)
   - Added field_validator to enforce regex pattern ^[a-zA-Z0-9_-]+$
   - Pattern parameter alone doesn't enforce validation in Pydantic v2
   - Added 9 comprehensive validation tests
   - Prevents invalid format IDs with spaces, special chars, unicode

2. Inconsistent Response Parsing (MAJOR BUG)
   - Applied _parse_response() to ALL 9 client methods, not just one
   - Methods now return properly typed TaskResult[SpecificResponse]
   - Ensures MCP content arrays are parsed into structured objects
   - Consistent behavior across all ADCP protocol methods

3. Test Data Validation
   - Updated test_get_products to mock parsing separately
   - Verifies parsing is called with correct response types
   - All 92 tests pass (83 original + 9 new validation tests)

Impact:
- Type safety actually enforced, not just declared
- All responses properly parsed regardless of protocol (MCP/A2A)
- Invalid data caught at validation layer
- Consistent client behavior across all methods

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

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

* fix: auto-generate FormatId with validation in schema generation

Problem: CI failed because generated.py was manually edited but marked
as auto-generated. Schema validation check detected drift.

Root Cause:
- format-id.json schema was downloaded but not included in generation
- Generator hardcoded FormatId = str as fallback
- Manual edits violated "DO NOT EDIT" contract

Solution:
1. Add format-id.json to core_types list in generator
2. Remove hardcoded FormatId = str fallback
3. Add add_format_id_validation() post-processor
4. Auto-inject field_validator for pattern enforcement
5. Import re and field_validator in generated code

Result:
- generated.py now properly auto-generated with validation
- CI schema validation will pass
- FormatId validation maintained
- No manual edits required

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

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

* fix: normalize format-id.json formatting for CI

CI schema validation expects specific JSON formatting:
- Multiline "required" array
- Trailing newline at end of file

Ran scripts/fix_schema_refs.py to normalize formatting.

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

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

* fix: remove unused imports to pass linter

CI linter detected unused imports:
- TaskStatus in src/adcp/client.py (leftover from refactoring)
- parse_mcp_content in src/adcp/protocols/mcp.py (unused after moving parsing to base)

Removed both unused imports. All tests still pass (92/92).

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

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

* fix: apply linting and type checking fixes after local validation

- Auto-fix import ordering and remove unused imports
- Fix unused type:ignore comment in base.py
- Replace removed call_tool method in CLI with explicit dispatch
- Add _dispatch_tool helper with if/elif chain for mypy compatibility
- Fix line length issues (E501) in __main__.py

This commit demonstrates the lesson learned from the debugger analysis:
always run full validation (format + lint + typecheck + test) before
pushing to avoid sequential fix commits.

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

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

* fix: restore inline Field formatting in generated.py for CI

The CI check-schema-drift target regenerates models without running
black formatter, so generated.py should remain in the inline format
that the generator outputs. Running `make format` reformats Field
definitions to multiline, causing CI drift detection to fail.

This commit reverts the black formatting of generated.py to match
what `make regenerate-schemas` produces.

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

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

* fix: exclude generated.py from black formatting to prevent CI drift

Critical fix addressing code review feedback:

1. Add extend-exclude pattern to [tool.black] in pyproject.toml
   - Prevents black from reformatting generated.py
   - Uses regex pattern: /(generated|tasks)\.py$

2. Update Makefile format target documentation
   - Clarifies that generated files are excluded

3. Format __main__.py (black auto-fix)

This prevents the schema drift CI failures that occur when:
- Developer runs `make format` (includes black)
- Black reformats generated.py Field definitions (multiline)
- CI runs `make check-schema-drift` (regenerates without formatting)
- Generator outputs inline format
- CI detects drift and fails

With this fix, black will skip generated.py entirely, keeping it
in the inline format that the generator produces.

Resolves: Code Review Critical Issue #2

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

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

* refactor: implement code review suggestions for maintainability

Addresses remaining code review feedback from the reviewer agent:

1. CLI Dispatch Refactor (Suggestion #3)
   - Replace if/elif chain with dict-based TOOL_DISPATCH mapping
   - Single source of truth for available tools
   - Lazy initialization of request types to avoid circular imports
   - Easier to maintain and extend

2. Pydantic Validation Error Handling (Edge Case #6)
   - Catch ValidationError in _dispatch_tool()
   - Return user-friendly error messages showing field-level issues
   - Format: "Invalid request payload for {tool}:\n  - field: message"

3. Response Parser Error Context (Suggestion #4)
   - Add content preview to parse_mcp_content() error messages
   - Include first 2 items, max 500 chars for debugging
   - Helps diagnose real-world parsing failures

4. Adapter Response Parsing Edge Case (Edge Case #7)
   - Fix _parse_response() to explicitly construct TaskResult[T]
   - Handle success=False or data=None without type: ignore
   - Provide clear error message when data is missing

Benefits:
- Maintainability: CLI tool list in one place, easier to add new ADCP methods
- User Experience: Clear validation errors instead of Python tracebacks
- Debuggability: Content preview helps diagnose parsing issues
- Type Safety: Proper typed TaskResult construction without suppressions

All tests pass (92/92), linting and type checking clean.

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

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

* feat: implement high-priority protocol expert recommendations

Addresses protocol expert feedback for production readiness:

1. **Webhook Response Typing** (High Priority #1)
   - handle_webhook() now returns TaskResult[Any] instead of None
   - Added _parse_webhook_result() helper method
   - Maps webhook task_type to response types for type-safe parsing
   - Validates WebhookPayload schema with Pydantic
   - Example usage:
     ```python
     result = await client.handle_webhook(payload, signature)
     if result.success and isinstance(result.data, GetProductsResponse):
         print(f"Found {len(result.data.products)} products")
     ```

2. **ProtocolEnvelope Type** (High Priority #2)
   - Already auto-generated from schema (protocol-envelope.json)
   - Includes: context_id, task_id, status, message, timestamp, payload
   - Used for async operation responses
   - No code changes needed - type already exists

3. **Format Caching Documentation** (High Priority #3)
   - Added comprehensive caching guidance to CLAUDE.md
   - Documented TTL-based and LRU cache strategies
   - Explained cache invalidation options
   - Provided code examples for production implementations

Benefits:
- Type-safe webhook handling enables better error detection
- Structured webhook responses integrate with existing TaskResult pattern
- Production developers have clear caching guidance
- All async workflows now properly typed

All tests pass (92/92), linting and type checking clean.

Resolves: Protocol Expert High Priority Issues #1, #2, #3

🤖 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants