Skip to content

Conversation

@PSthelyBlog
Copy link
Owner

Summary

  • Replace anthropic Python SDK with claude-code-sdk to enable automatic authentication inheritance from Claude Code CLI
  • Add new utils/agent_sdk.py module with wrapper functions for Agent SDK
  • Update all agents (Design, Build, Publish) to use the new SDK
  • Make API key optional (SDK handles auth automatically)
  • Update tests and documentation

Key Changes

New Authentication Options

  1. Subscription Auth (Pro/Max): Run claude once to login → SDK uses it automatically
  2. API Key Auth: Set ANTHROPIC_API_KEY → works as before

No explicit configuration needed - the SDK handles auth priority automatically.

Files Changed

  • pyproject.toml - Replace anthropic>=0.40.0 with claude-code-sdk>=0.0.10
  • src/game_workflow/utils/agent_sdk.py - NEW SDK wrapper utilities
  • src/game_workflow/agents/design.py - Use Agent SDK for generation
  • src/game_workflow/agents/publish.py - Use Agent SDK for generation
  • src/game_workflow/agents/build.py - Use native Agent SDK instead of subprocess
  • src/game_workflow/agents/base.py - Make API key optional with deprecation warning
  • All test files updated with new mocking patterns
  • README.md and docs/setup.md updated with new auth instructions

Test plan

  • Unit tests pass: pytest tests/unit -v (337 passed)
  • Linting passes: ruff check .
  • Formatting passes: ruff format --check .
  • CI pipeline passes

Closes #37

🤖 Generated with Claude Code

Replace the `anthropic` Python SDK with `claude-code-sdk` to enable
automatic authentication inheritance from Claude Code CLI.

Key changes:
- Add new utils/agent_sdk.py module with generate_structured_response()
  and invoke_claude_code() wrapper functions
- Update DesignAgent to use Agent SDK for concept/GDD/tech spec generation
- Update PublishAgent to use Agent SDK for store page content generation
- Update BuildAgent to use native Agent SDK instead of subprocess-based
  ClaudeCodeRunner
- Make API key optional in BaseAgent (SDK handles auth automatically)
- Update all tests to use new mocking patterns for Agent SDK
- Update documentation with new authentication options

Benefits:
- Subscription support (Pro/Max): Run `claude` once to login, SDK uses
  it automatically
- API Key support: Set ANTHROPIC_API_KEY, works as before
- No explicit configuration needed - SDK handles auth priority

Closes #37

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link

Summary of Changes

Hello @PSthelyBlog, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request undertakes a significant refactoring by migrating the project's AI agent interactions from the legacy anthropic Python SDK to the more integrated claude-code-sdk. This transition simplifies the authentication process by enabling automatic credential inheritance from the Claude Code CLI, making API key management more streamlined. The core agents have been updated to use a new set of utility functions, centralizing and modernizing how they interact with the Claude API for both text generation and agentic code execution.

Highlights

  • SDK Migration: Migrated the project's core agents from the anthropic Python SDK to the new claude-code-sdk to leverage enhanced features and authentication mechanisms.
  • Simplified Authentication: Authentication is now more flexible, supporting automatic inheritance from the Claude Code CLI (for subscription users) and making the ANTHROPIC_API_KEY optional. A deprecation warning is issued if the API key is still set.
  • New Agent SDK Utilities: Introduced a new module src/game_workflow/utils/agent_sdk.py containing wrapper functions (generate_structured_response and invoke_claude_code) to standardize interactions with the claude-code-sdk.
  • Agent Refactoring: The Design, Build, and Publish agents have been refactored to utilize the new claude-code-sdk utilities, removing direct anthropic client calls and ClaudeCodeRunner subprocess invocations.
  • Documentation Updates: Updated README.md and docs/setup.md to clearly explain the new authentication options and requirements.
  • Migration Plan Document: A new migration-plan.md file has been added, detailing the objective, benefits, affected files, and implementation steps for this SDK transition.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request successfully migrates the project from the Anthropic Python SDK to the Claude Agent SDK, enabling automatic authentication inheritance and simplifying API calls. The changes are well-implemented across agents (Design, Build, Publish) and documentation, with corresponding updates to unit tests. The new agent_sdk.py module provides clear wrapper functions for structured generation and agentic tasks. However, there are two high severity issues identified in the new src/game_workflow/utils/agent_sdk.py file regarding error handling for ResultMessage objects, which could lead to less specific error reporting or false positives for success. These should be addressed to ensure robust error handling as outlined in the migration plan.

Comment on lines +56 to +71
async for message in query(
prompt=full_prompt,
options=ClaudeCodeOptions(
model=model,
max_turns=1, # Single turn for generation tasks
),
):
# Handle different message types
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
text_parts.append(block.text)

result = "".join(text_parts)
if not result:
raise RuntimeError("Agent SDK returned empty response")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The generate_structured_response function should explicitly handle ResultMessage errors from the Agent SDK. The current implementation only checks if the final result is empty, which might mask specific errors reported by the SDK. Implementing a check for message.is_error will provide more precise error reporting, as outlined in the migration plan.

Suggested change
async for message in query(
prompt=full_prompt,
options=ClaudeCodeOptions(
model=model,
max_turns=1, # Single turn for generation tasks
),
):
# Handle different message types
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
text_parts.append(block.text)
result = "".join(text_parts)
if not result:
raise RuntimeError("Agent SDK returned empty response")
async for message in query(
prompt=full_prompt,
options=ClaudeCodeOptions(
model=model,
max_turns=1, # Single turn for generation tasks
),
):
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
text_parts.append(block.text)
# Check for errors if the SDK yields messages with an 'is_error' attribute
if hasattr(message, "is_error") and message.is_error:
raise RuntimeError(f"Agent SDK error: {message}")
result = "".join(text_parts)
if not result:
raise RuntimeError("Agent SDK returned empty response or an unhandled error occurred.")

Comment on lines +137 to +143
async for message in query(prompt=full_prompt, options=options):
# Collect text output from messages
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
output_parts.append(block.text)
logger.debug(f"claude-code: {block.text[:100]}...")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The invoke_claude_code function currently marks the operation as success=True unless an exception is caught during the query iteration. It should also explicitly check for ResultMessage errors within the async for loop, as suggested in the migration plan, to accurately reflect the outcome of the Claude Code execution. If a ResultMessage indicates an error, success should be set to False and the error_message captured.

Suggested change
async for message in query(prompt=full_prompt, options=options):
# Collect text output from messages
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
output_parts.append(block.text)
logger.debug(f"claude-code: {block.text[:100]}...")
async for message in query(prompt=full_prompt, options=options):
# Collect text output from messages
if hasattr(message, "content"):
for block in message.content:
if hasattr(block, "text"):
output_parts.append(block.text)
logger.debug(f"claude-code: {block.text[:100]}...")
# Check for errors if the SDK yields messages with an 'is_error' attribute
if hasattr(message, "is_error") and message.is_error:
error_message = f"Claude Code execution reported an error: {message}"
success = False
break # Exit loop on error

@PSthelyBlog PSthelyBlog merged commit 321ee8d into main Jan 22, 2026
4 checks passed
@PSthelyBlog PSthelyBlog deleted the feature/37-migrate-to-agent-sdk branch January 22, 2026 16:22
PSthelyBlog pushed a commit that referenced this pull request Jan 22, 2026
- Mark migration-plan.md as complete with PR #38 reference
- Add completion summary with implementation details
- Add Session 17 to notes.md documenting the migration work

Co-Authored-By: Claude Opus 4.5 <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.

Migrate from Anthropic Python SDK to Claude Agent SDK

2 participants