-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add codex claude sdk #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
6858fb0
a30d304
3ad0d0f
5305846
8ecfa54
09d985c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,277 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from __future__ import annotations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any, Dict, List, Optional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pydantic import Field, model_validator, PrivateAttr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from base.agent.base_agent import BaseAgent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from claude_agent_sdk import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| query, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ClaudeAgentOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ClaudeSDKError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLINotFoundError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ProcessError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLIJSONDecodeError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLAUDE_AGENT_AVAILABLE = True | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except ImportError: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLAUDE_AGENT_AVAILABLE = False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fallback types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AssistantMessage = UserMessage = ResultMessage = Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TextBlock = ToolUseBlock = ToolResultBlock = Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ClaudeSDKError = CLINotFoundError = ProcessError = CLIJSONDecodeError = Exception | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class ClaudeCodeAgent(BaseAgent): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Claude Code Agent for code generation using Claude Agent SDK.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Claude Code Agent for code generation using Claude Agent SDK.""" | |
| """Claude Code Agent for code generation using Claude Agent SDK. | |
| This agent integrates with the external `claude_agent_sdk` package to provide | |
| code-centric automation such as writing, editing, and executing code in a | |
| local project directory. It is designed to be used as a `BaseAgent` | |
| subclass within the autoenv framework. | |
| Installation | |
| ------------ | |
| The `claude_agent_sdk` package must be installed for this agent to be fully | |
| functional. If it is missing, `CLAUDE_AGENT_AVAILABLE` will be set to | |
| ``False`` and calls into the SDK will fail. | |
| Install the SDK via pip: | |
| pip install claude-agent-sdk | |
| or add it to your project's dependencies. | |
| Requirements | |
| ----------- | |
| - Python environment with access to the Claude Code CLI used by | |
| `claude_agent_sdk`. | |
| - Valid configuration/credentials for the underlying Claude tooling, as | |
| required by the SDK and CLI. | |
| - (Optional) A working directory ``cwd`` that points to the root of the | |
| project the agent should operate on. | |
| Basic usage example | |
| ------------------- | |
| Instantiate the agent and run it on a coding task: | |
| .. code-block:: python | |
| from pathlib import Path | |
| from autoenv.claude_code_agent import ClaudeCodeAgent | |
| agent = ClaudeCodeAgent( | |
| cwd=Path("/path/to/your/project"), | |
| allowed_tools=["Read", "Write", "Bash"], | |
| max_turns=8, | |
| ) | |
| # Example high-level call (actual API depends on BaseAgent interface): | |
| result = agent.run("Add unit tests for the user authentication module.") | |
| print(result) | |
| Within larger systems, `ClaudeCodeAgent` can be composed with other agents | |
| or orchestrators that expect a `BaseAgent`-compatible interface. | |
| """ |
Outdated
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as CodexAgent - the permission_mode field lists four modes but doesn't explain what each mode does. This is especially important given the security implications of "bypassPermissions". Add detailed documentation for each permission mode.
| description="Permission mode: default|acceptEdits|bypassPermissions|plan" | |
| description=( | |
| "Controls how the agent handles permission prompts for edits, tool use, and commands. " | |
| "Supported values:\n" | |
| "- 'default': Use the Claude Code CLI / SDK's default interactive behavior for requesting\n" | |
| " permission before making changes or running tools.\n" | |
| "- 'acceptEdits': Automatically accept and apply code edits suggested by the agent while\n" | |
| " still requiring confirmation for other sensitive actions (e.g., shell commands).\n" | |
| "- 'bypassPermissions': Run tools, apply edits, and execute commands without asking for\n" | |
| " interactive confirmation. This effectively disables permission prompts and should only\n" | |
| " be used in fully trusted, sandboxed environments due to its security implications.\n" | |
| "- 'plan': Focus on generating and updating a plan of actions without automatically\n" | |
| " executing potentially destructive steps; execution typically requires separate approval." | |
| ) |
chenmancm169 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
chenmancm169 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
chenmancm169 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
chenmancm169 marked this conversation as resolved.
Show resolved
Hide resolved
chenmancm169 marked this conversation as resolved.
Show resolved
Hide resolved
chenmancm169 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
chenmancm169 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as CodexAgent - the call method accepts three different parameter names (request, task, prompt) which can lead to ambiguity. If multiple are provided, the precedence is undocumented. Consider standardizing on a single parameter name or clearly documenting the precedence order.
| """Execute the agent with given parameters.""" | |
| request = kwargs.pop('request', None) or kwargs.pop('task', None) or kwargs.pop('prompt', None) | |
| """Execute the agent with given parameters. | |
| Accepts a single text argument under one of the aliases: 'request', 'task', or 'prompt'. | |
| If more than one of these is provided, a ValueError is raised to avoid ambiguity. | |
| """ | |
| request = kwargs.pop("request", None) | |
| task = kwargs.pop("task", None) | |
| prompt = kwargs.pop("prompt", None) | |
| # Ensure we don't silently ignore conflicting inputs | |
| provided_count = sum(v is not None for v in (request, task, prompt)) | |
| if provided_count > 1: | |
| raise ValueError( | |
| "ClaudeCodeAgent.__call__ accepts only one of 'request', 'task', or 'prompt'. " | |
| f"Received: request={request!r}, task={task!r}, prompt={prompt!r}" | |
| ) | |
| # Preserve existing precedence: request > task > prompt | |
| if request is None: | |
| request = task if task is not None else prompt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback type assignments on lines 24-26 create type aliases that map to Any or Exception, which defeats the purpose of type hints. When CLAUDE_AGENT_AVAILABLE is False, these fallback types will allow any value without type checking, potentially hiding bugs. Consider using proper type stubs or Protocol definitions for better type safety when the SDK is not installed.