feat(cli): add claude-code init templates (sync / async / temporal)#435
Conversation
cd6bb70 to
ab23d6d
Compare
a92d37b to
ff359de
Compare
|
@greptile review |
ab23d6d to
d3f1fb6
Compare
ff359de to
e031d5d
Compare
|
@greptile review |
| 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 |
There was a problem hiding this comment.
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.
Artifacts
Repro: script that renders the uv project and checks the Docker COPY sources
- Contains supporting evidence from the run (text/x-python; charset=utf-8).
Repro: command transcript showing no uv.lock and emulated Docker COPY failure
- Keeps the command output available without making the summary code-heavy.
Repro: template availability check used during setup
- Keeps the command output available without making the summary code-heavy.
Ran code and verified through T-Rex
Prompt To Fix With AI
This 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.e031d5d to
8f7854a
Compare
|
@greptile review |
4310435 to
1638b8b
Compare
8f7854a to
6e3f0cf
Compare
|
@greptile review |
|
@greptile review |
1 similar comment
|
@greptile review |
1638b8b to
3a13b08
Compare
47ea82c to
2003757
Compare
3a13b08 to
e4db8d5
Compare
2003757 to
755d18e
Compare
| @acp.on_task_event_send | ||
| async def handle_task_event_send(params: SendEventParams): |
There was a problem hiding this comment.
SendEventParams.event.content is a TaskMessageContent union, not always text. Valid ACP payloads such as data or tool messages do not have a .content field, so sending one of those events to a generated Claude template raises AttributeError before the user message is recorded or any task error is streamed. Convert or reject non-text content before reading .content; the same assumption is present in the sync and temporal Claude handlers.
Artifacts
Repro: focused generated-template handler invocation script
- Contains supporting evidence from the run (text/x-python; charset=utf-8).
Stack trace captured during the T-Rex run
- Keeps the raw stack trace available without making the summary code-heavy.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/cli/templates/default-claude-code/project/acp.py.j2
Line: 133-134
Comment:
**Non-text events crash**
`SendEventParams.event.content` is a `TaskMessageContent` union, not always text. Valid ACP payloads such as data or tool messages do not have a `.content` field, so sending one of those events to a generated Claude template raises `AttributeError` before the user message is recorded or any task error is streamed. Convert or reject non-text content before reading `.content`; the same assumption is present in the sync and temporal Claude handlers.
How can I resolve this? If you propose a fix, please make it concise.e4db8d5 to
9fc5e23
Compare
755d18e to
63904c2
Compare
63904c2 to
f819115
Compare
9fc5e23 to
f55806c
Compare
|
|
||
| # Description of what your agent does | ||
| # Helps with documentation and discovery | ||
| description: {{ description }} |
There was a problem hiding this comment.
description is user-supplied text from the init prompt, but this template renders it as an unquoted YAML scalar. A description containing YAML-significant text such as Answers questions: with Claude or Claude # helper can make the generated manifest.yaml invalid or truncate the value, so the initialized agent may not load. The same unquoted-description issue exists in sync-claude-code/manifest.yaml.j2; quote the rendered description in both templates.
Artifacts
Repro: focused manifest render and YAML parse script
- Contains supporting evidence from the run (text/x-python; charset=utf-8).
Repro: failing render and YAML parse output
- Keeps the command output available without making the summary code-heavy.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/cli/templates/default-claude-code/manifest.yaml.j2
Line: 68
Comment:
**Manifest can break**
`description` is user-supplied text from the init prompt, but this template renders it as an unquoted YAML scalar. A description containing YAML-significant text such as `Answers questions: with Claude` or `Claude # helper` can make the generated `manifest.yaml` invalid or truncate the value, so the initialized agent may not load. The same unquoted-description issue exists in `sync-claude-code/manifest.yaml.j2`; quote the rendered description in both templates.
How can I resolve this? If you propose a fix, please make it concise.f55806c to
9861b8b
Compare
Add default-claude-code, sync-claude-code and temporal-claude-code templates across all three tiers, wiring the new TemplateType entries into the init flow. Scaffolded code imports ClaudeCodeTurn from the agentex.lib.adk facade. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Install the Claude Code CLI (@anthropic-ai/claude-code) in all three Dockerfiles so deployed images can actually run `claude`. - Wire ANTHROPIC_API_KEY (credential + env) in the default, sync and temporal manifests; the `claude` subprocess does not read LITELLM_API_KEY. - Surface CLI failures: capture a bounded stderr tail and raise on a non-zero exit instead of silently completing the turn. - Serialize temporal turns with an asyncio.Lock so overlapping signals don't race on _session_id, and raise the activity timeout to 30m for agentic runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the manifest fix: the claude-code templates spawn the `claude` CLI, which reads ANTHROPIC_API_KEY rather than LITELLM_API_KEY. Update the default, sync and temporal .env.example scaffolds accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Round-3 Greptile parity: the uv-path Dockerfile-uv.j2 variants (default, sync, temporal) installed node/npm but not the `claude` CLI, leaving use_uv=True containers non-functional. Mirror the npm install -g @anthropic-ai/claude-code step already added to the pip Dockerfiles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Round-4 Greptile review: - await proc.stdin.drain() before close() in all three claude-code subprocess helpers (matches the codex helpers; flushes large prompts before EOF). - Stop the manifest env block from setting ANTHROPIC_API_KEY to an empty string, which would shadow the credential mapping / .env value at runtime. The key now comes solely from the credential mapping (deploy) or .env (local). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f819115 to
4f2002c
Compare
Summary
Ninth slice of #425. Adds the claude-code
agentex inittemplates across all three tiers.default-claude-code,sync-claude-code,temporal-claude-codetemplate dirs.DEFAULT_CLAUDE_CODE,SYNC_CLAUDE_CODE,TEMPORAL_CLAUDE_CODEintoinit.py(enum, project-files map, prompts).ClaudeCodeTurnfrom theagentex.lib.adkfacade.Test plan
pytest tests/lib/cli/ -k "init or template"— 23 passed (all render to valid Python)Notes
Stacked on #434. Retarget to
nextafter the chain merges.🤖 Generated with Claude Code
Greptile Summary
agentex inittemplates for default, sync, and Temporal project tiers.Confidence Score: 4/5
Merge should wait for fixes to the OpenAI sync stream event lifecycle and the generated Claude Code Dockerfile.
The changed areas are covered by focused checks, and the remaining concerns are localized to stream event ordering and template rendering.
src/agentex/lib/adk/_modules/_openai_sync.py and src/agentex/lib/cli/templates/default-claude-code/Dockerfile.j2
What T-Rex did
Comments Outside Diff (3)
General comment
project/), so temporal run_worker.py is placed under project/run_worker.py. The root template map also renders manifest.yaml but does not render an agentex.json root file for these templates.src/agentex/lib/adk/_modules/_openai_sync.py, line 178-184 (link)Reasoning items are opened with
StreamTaskMessageStart, but this completion branch skips the matchingStreamTaskMessageDone. A reasoning stream that emits deltas and then completes leaves sync ACP clients with an unterminated reasoning message, and tracing has to mark the reasoning span incomplete during final cleanup instead of closing it normally.Artifacts
Repro: focused pytest harness for mocked sync OpenAI reasoning stream
Repro: verbose pytest output showing missing reasoning done event
Prompt To Fix With AI
src/agentex/lib/adk/_modules/_openai_sync.py, line 295-306 (link)After a reasoning item, the next text item can reuse the reasoning message index. The reasoning handlers increment
message_index, but this branch only increments text indices after tool output, so a normal reasoning-then-answer stream can emit the final textStartwith the same index as the reasoning message. Downstream consumers key open contexts byindex, so the answer can overwrite or alias the reasoning context and mix text output into the reasoning message.Artifacts
Repro: focused pytest harness for reasoning then text index reuse
Repro: verbose pytest output showing duplicate reasoning and text start indices
Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (16): Last reviewed commit: "fix(cli): drain claude stdin and stop en..." | Re-trigger Greptile