Metadata-Version: 2.4
Name: claude-code-agent
Version: 0.1.0
Summary: Configurable agent framework wrapping claude-agent-sdk
Project-URL: Homepage, https://github.com/sii-nyc/claude-code-agent
Project-URL: Repository, https://github.com/sii-nyc/claude-code-agent
Project-URL: Issues, https://github.com/sii-nyc/claude-code-agent/issues
Author-email: sii-nyc <253108120111@sii.edu.cn>
License-Expression: MIT
License-File: LICENSE
Keywords: agent,claude,claude-code,llm,mcp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: claude-agent-sdk>=0.1.58
Provides-Extra: all
Requires-Dist: python-dotenv>=1.0; extra == 'all'
Requires-Dist: pyyaml>=6.0; extra == 'all'
Provides-Extra: dotenv
Requires-Dist: python-dotenv>=1.0; extra == 'dotenv'
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
Description-Content-Type: text/markdown

# claude-code-agent

基于 `claude-agent-sdk` 的通用 Python 包，封装 Claude Code 的 agent 能力，提供可配置的 agent 框架。可在任意 Python 项目中安装使用。

## 特性

- **可配置的 Agent**：通过 `AgentConfig` dataclass 或 YAML 文件配置模型、工具、权限、系统提示词等
- **Skills 管理**：自动将 skills 从共享库复制到工作目录，Claude Code 自动发现和加载
- **自定义工具**：支持包内 Registry 模式（自动发现）和调用方直接传入两种方式注册 MCP 工具
- **并行执行**：`run_agents_parallel` 支持多 agent 并发运行，可控制最大并发数
- **CLI**：提供 `claude-code-agent run` 命令行入口，支持 YAML 配置 + 参数覆盖
- **配置校验**：启动前自动验证配置合法性，提前暴露错误

## 安装

```bash
# 基本安装
uv add claude-code-agent

# 安装全部可选依赖（pyyaml + python-dotenv）
uv add 'claude-code-agent[all]'

# 或使用 pip
pip install claude-code-agent
pip install 'claude-code-agent[all]'
```

## 快速开始

### Python API

```python
import asyncio
from claude_code_agent import AgentConfig, run_agent

async def main():
    config = AgentConfig(
        workdir="./workspace/task_1",
        model="claude-sonnet-4-6",
        permission_mode="bypassPermissions",
        builtin_tools=["Read", "Glob", "Grep", "Edit", "Bash"],
    )
    result = await run_agent("please review this code", config)
    print(result.result)
    print(f"Cost: ${result.total_cost_usd:.4f}, Turns: {result.num_turns}")

asyncio.run(main())
```

### YAML 配置 + CLI

创建 `agent_config.yaml`：

```yaml
workdir: ./workspace/task_1
model: claude-sonnet-4-6
max_turns: 30
permission_mode: bypassPermissions
builtin_tools:
  - Read
  - Glob
  - Grep
  - Edit
  - Bash
system_prompt: You are a helpful assistant.
```

运行：

```bash
claude-code-agent run --config agent_config.yaml "please review this code"
```

CLI 参数可覆盖 YAML 配置：

```bash
claude-code-agent run --config agent_config.yaml --model claude-opus-4-6 --max-turns 50 "prompt"
```

## AgentConfig 参数

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `workdir` | `str \| Path` | **必填** | 工作目录路径 |
| `model` | `str \| None` | `None` | 模型标识符 |
| `max_turns` | `int \| None` | `None` | 最大对话轮数 |
| `permission_mode` | `str` | `"bypassPermissions"` | 权限模式 |
| `builtin_tools` | `list[str]` | `["Read", "Glob", "Grep"]` | 内置工具列表 |
| `toolsets` | `dict[str, dict]` | `{}` | 包内注册的工具集 |
| `mcp_servers` | `dict[str, Any]` | `{}` | MCP 工具服务器配置 |
| `system_prompt` | `str \| None` | `None` | 系统提示词 |
| `skills_lib` | `str \| Path \| None` | `None` | Skills 库路径 |
| `skills` | `list[str]` | `[]` | skill 名称列表 |
| `cleanup_workdir` | `bool` | `False` | 任务结束后是否删除工作目录 |
| `env_file` | `str \| Path \| None` | `None` | .env 文件路径 |
| `max_retries` | `int` | `0` | 失败重试次数（0 = 不重试） |
| `retry_base_delay` | `float` | `1.0` | 重试退避基础延迟（秒） |

## Skills

将 skills 库中的 skill 自动复制到工作目录：

```python
config = AgentConfig(
    workdir="./workspace/task_1",
    skills_lib="./my-skills-lib",       # 共享 skills 库
    skills=["code_review", "summarize"], # 选择要用的 skill
)
```

Skills 库目录结构：

```
my-skills-lib/
├── code_review/
│   └── SKILL.md
├── summarize/
│   └── SKILL.md
└── refactor/
    └── SKILL.md
```

安全复制策略：目标已存在则跳过，不覆盖。

## 自定义工具

### Registry 模式（包内自动注册）

在 `claude_code_agent/tools/` 下创建模块，使用装饰器自动注册：

```python
# src/claude_code_agent/tools/paper_tools.py
from claude_code_agent.tools import register_toolset
from mcp.server import Server

@register_toolset("paper_tools")
def create_paper_tools(config: dict) -> dict:
    server = Server("paper-tools")

    @server.tool()
    async def fetch_paper(arxiv_id: str) -> str:
        ...

    return {"type": "sdk", "name": "paper-tools", "instance": server}
```

配置中引用：

```python
config = AgentConfig(workdir="./task_1", toolsets={"paper_tools": {"dataset_dir": "papers"}})
```

### 直接传入模式

```python
from mcp.server import Server

my_server = Server("my-tools")

@my_server.tool()
async def search_database(query: str) -> str:
    ...

config = AgentConfig(
    workdir="./task_1",
    mcp_servers={"my-tools": {"type": "sdk", "name": "my-tools", "instance": my_server}},
)
```

两种方式可同时使用，同名冲突时 `mcp_servers`（直接传入）优先。

## 并行执行

```python
import asyncio
from dataclasses import replace
from claude_code_agent import AgentConfig, run_agents_parallel

async def main():
    base = AgentConfig(workdir="./ws", model="claude-sonnet-4-6", cleanup_workdir=True)
    tasks = [
        {"prompt": "review module A", "config": replace(base, workdir="./ws/a")},
        {"prompt": "review module B", "config": replace(base, workdir="./ws/b")},
    ]
    results = await run_agents_parallel(tasks, max_concurrency=4)
    for i, r in enumerate(results):
        if isinstance(r, Exception):
            print(f"Task {i} failed: {r}")
        else:
            print(f"Task {i}: {r.result}")

asyncio.run(main())
```

## 项目结构

```
claude-code-agent/
├── pyproject.toml
├── README.md
├── src/
│   └── claude_code_agent/
│       ├── __init__.py      # 公开 API: AgentConfig, run_agent, run_agents_parallel
│       ├── config.py        # AgentConfig dataclass + YAML 加载 + 校验
│       ├── runner.py        # run_agent, run_agents_parallel
│       ├── skills.py        # skills 复制/清理
│       ├── cli.py           # CLI 入口
│       └── tools/
│           └── __init__.py  # TOOL_REGISTRY + @register_toolset
└── tests/
```

## 开发

```bash
# 安装开发依赖
uv sync

# 运行测试
uv run pytest -v

# 验证 CLI
uv run claude-code-agent run --help
```

