-
Notifications
You must be signed in to change notification settings - Fork 9
feat(cli): add claude-code init templates (sync / async / temporal) #435
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
Changes from all commits
eed55a2
6445182
ac4845e
378de92
4f2002c
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,43 @@ | ||
| # Python | ||
| __pycache__/ | ||
| *.py[cod] | ||
| *$py.class | ||
| *.so | ||
| .Python | ||
| build/ | ||
| develop-eggs/ | ||
| dist/ | ||
| downloads/ | ||
| eggs/ | ||
| .eggs/ | ||
| lib/ | ||
| lib64/ | ||
| parts/ | ||
| sdist/ | ||
| var/ | ||
| wheels/ | ||
| *.egg-info/ | ||
| .installed.cfg | ||
| *.egg | ||
|
|
||
| # Environments | ||
| .env** | ||
| .venv | ||
| env/ | ||
| venv/ | ||
| ENV/ | ||
| env.bak/ | ||
| venv.bak/ | ||
|
|
||
| # IDE | ||
| .idea/ | ||
| .vscode/ | ||
| *.swp | ||
| *.swo | ||
|
|
||
| # Git | ||
| .git | ||
| .gitignore | ||
|
|
||
| # Misc | ||
| .DS_Store |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # {{ agent_name }} - Environment Variables | ||
| # Copy this file to .env and fill in the values | ||
|
|
||
| # API key for the Claude Code CLI (the `claude` subprocess this agent spawns) | ||
| ANTHROPIC_API_KEY= | ||
|
|
||
| # LLM base URL (optional - override to use a different provider) | ||
| # OPENAI_BASE_URL= | ||
|
|
||
| # SGP Configuration (optional - for tracing) | ||
| # SGP_API_KEY= | ||
| # SGP_ACCOUNT_ID= | ||
| # SGP_CLIENT_BASE_URL= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # syntax=docker/dockerfile:1.3 | ||
| FROM python:3.12-slim | ||
| COPY --from=ghcr.io/astral-sh/uv:0.6.4 /uv /uvx /bin/ | ||
|
|
||
| # Install system dependencies | ||
| RUN apt-get update && apt-get install -y \ | ||
| htop \ | ||
| vim \ | ||
| curl \ | ||
| tar \ | ||
| python3-dev \ | ||
| postgresql-client \ | ||
| build-essential \ | ||
| libpq-dev \ | ||
| gcc \ | ||
| cmake \ | ||
| netcat-openbsd \ | ||
| nodejs \ | ||
| npm \ | ||
| && apt-get clean \ | ||
| && rm -rf /var/lib/apt/lists/** | ||
|
|
||
| # Install the Claude Code CLI: the agent shells out to `claude` on every turn, | ||
| # so the binary must be present in the runtime image. | ||
| RUN npm install -g @anthropic-ai/claude-code | ||
|
|
||
| ENV UV_COMPILE_BYTECODE=1 | ||
| ENV UV_LINK_MODE=copy | ||
| ENV UV_HTTP_TIMEOUT=1000 | ||
|
|
||
| WORKDIR /app/{{ project_path_from_build_root }} | ||
|
|
||
| # Copy dependency files for layer caching | ||
| COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./ | ||
|
|
||
| # Install dependencies (without project itself, for layer caching) | ||
| RUN --mount=type=cache,target=/root/.cache/uv \ | ||
| uv sync --locked --no-install-project --no-dev | ||
|
Comment on lines
+34
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ArtifactsRepro: script that renders the uv project and checks the Docker COPY sources
Repro: command transcript showing no uv.lock and emulated Docker COPY failure
Repro: template availability check used during setup
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agentex/lib/cli/templates/default-claude-code/Dockerfile-uv.j2
Line: 30-34
Comment:
**Missing uv lockfile**
`agentex init` renders `pyproject.toml` for `use_uv=True`, but it does not create a `uv.lock`. A new Claude template project built immediately after init therefore fails during Docker build at this `COPY ... uv.lock` step before `uv sync` can run. Please either generate the lockfile during init, remove `uv.lock` from the `COPY`, or make the Dockerfile support a fresh project without a lockfile.
How can I resolve this? If you propose a fix, please make it concise. |
||
|
|
||
| # Copy the project code | ||
| COPY {{ project_path_from_build_root }}/project ./project | ||
|
|
||
| # Install the project | ||
| RUN --mount=type=cache,target=/root/.cache/uv \ | ||
| uv sync --locked --no-dev | ||
|
|
||
| ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" | ||
| ENV PYTHONPATH=/app | ||
|
|
||
| # Run the agent using uvicorn | ||
| CMD ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # syntax=docker/dockerfile:1.3 | ||
| FROM python:3.12-slim | ||
| COPY --from=ghcr.io/astral-sh/uv:0.6.4 /uv /uvx /bin/ | ||
|
|
||
| # Install system dependencies | ||
| RUN apt-get update && apt-get install -y \ | ||
| htop \ | ||
| vim \ | ||
| curl \ | ||
| tar \ | ||
| python3-dev \ | ||
| postgresql-client \ | ||
| build-essential \ | ||
| libpq-dev \ | ||
| gcc \ | ||
| cmake \ | ||
| netcat-openbsd \ | ||
| nodejs \ | ||
| npm \ | ||
|
greptile-apps[bot] marked this conversation as resolved.
|
||
| && apt-get clean \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Install the Claude Code CLI: the agent shells out to `claude` on every turn, | ||
| # so the binary must be present in the runtime image. | ||
| RUN npm install -g @anthropic-ai/claude-code | ||
|
|
||
| RUN uv pip install --system --upgrade pip setuptools wheel | ||
|
|
||
| ENV UV_HTTP_TIMEOUT=1000 | ||
|
|
||
| # Copy just the requirements file to optimize caching | ||
| COPY {{ project_path_from_build_root }}/requirements.txt /app/{{ project_path_from_build_root }}/requirements.txt | ||
|
|
||
| WORKDIR /app/{{ project_path_from_build_root }} | ||
|
|
||
| # Install the required Python packages | ||
| RUN uv pip install --system -r requirements.txt | ||
|
|
||
| # Copy the project code | ||
| COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project | ||
|
|
||
| # Set environment variables | ||
| ENV PYTHONPATH=/app | ||
|
|
||
| # Run the agent using uvicorn | ||
| CMD ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # {{ agent_name }} - AgentEx Async Claude Code Agent | ||
|
|
||
| This template builds an **asynchronous** (non-Temporal) agent that drives the | ||
| **Claude Code CLI** through the unified harness surface on AgentEx: | ||
| - Spawns `claude -p --output-format stream-json --verbose` as a local subprocess | ||
| - Wraps the CLI's stdout stream in a `ClaudeCodeTurn` | ||
| - Delivers canonical `StreamTaskMessage*` events via `UnifiedEmitter.auto_send_turn` | ||
| (the async Redis push path), so the UI receives output in real time | ||
| - Tracing integration to SGP / AgentEx | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - The `claude` CLI installed and on your `PATH` | ||
| - An `ANTHROPIC_API_KEY` (or equivalent credential) in your environment | ||
|
|
||
| ## Running the Agent | ||
|
|
||
| ```bash | ||
| agentex agents run --manifest manifest.yaml | ||
| ``` | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| {{ project_name }}/ | ||
| βββ project/ | ||
| β βββ __init__.py | ||
| β βββ acp.py # ACP server, subprocess spawn, and event handlers | ||
| βββ Dockerfile | ||
| βββ manifest.yaml | ||
| βββ dev.ipynb | ||
| {% if use_uv %} | ||
| βββ pyproject.toml | ||
| {% else %} | ||
| βββ requirements.txt | ||
| {% endif %} | ||
| ``` | ||
|
|
||
| ## Key Concepts | ||
|
|
||
| ### Async ACP with the harness | ||
| The async ACP model streams events over Redis instead of an HTTP response. The | ||
| `@acp.on_task_event_send` handler spawns the Claude Code CLI and pushes the | ||
| harness events to the task stream. | ||
|
|
||
| ### The unified harness surface | ||
| `ClaudeCodeTurn` + `UnifiedEmitter` are the unified harness surface. The turn | ||
| normalizes CLI output into canonical AgentEx events; the emitter traces and | ||
| delivers them. | ||
|
|
||
| ## Development | ||
|
|
||
| ### 1. Customize the subprocess | ||
| Edit `_spawn_claude` in `project/acp.py` to change the CLI flags, working | ||
| directory, or how the prompt is delivered. | ||
|
|
||
| ### 2. Configure Credentials | ||
| Set your credentials via `manifest.yaml`, an exported environment variable, or a | ||
| `.env` file in the project directory. | ||
|
|
||
| ### 3. Run Locally | ||
| ```bash | ||
| export ENVIRONMENT=development && agentex agents run --manifest manifest.yaml | ||
| ``` |
Uh oh!
There was an error while loading. Please reload this page.