Differences in Secret Names and Response Extraction Paths for Claude Code, Codex, OpenCode, and CodeLayer Agent Runners
Claude Code and CodeLayer require ANTHROPIC_API_KEY, Codex requires OPENAI_API_KEY, and OpenCode supports either provider, while response extraction ranges from native file output in Codex to complex JSON parsing in Claude Code and ANSI color stripping in CodeLayer.
The humanlayer/skills repository defines standardized GitHub Actions workflows for orchestrating LLM agents, with each runner template in plugins/design-control-loop/skills/design-control-loop/references/agent-runner-templates.md specifying distinct secret names and output processing logic. Understanding these differences ensures your CI pipelines correctly authenticate with providers and reliably extract the final assistant response for pull request bodies.
Secret Name Variations by Agent Provider
Each agent runner expects a specific environment variable for API authentication based on its underlying LLM provider.
Anthropic-Based Runners (Claude Code and CodeLayer)
Both Claude Code and CodeLayer integrate with Anthropic's API, requiring the ANTHROPIC_API_KEY secret. In the workflow definitions, this appears as:
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
According to the agent runner templates, Claude Code references this at line 28, while CodeLayer specifies it at line 17 for the environment block and line 23 for the secret injection.
OpenAI-Based Runners (Codex)
The Codex CLI runner exclusively uses OpenAI's API, expecting the OPENAI_API_KEY secret. The workflow references this at line 64:
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Provider-Agnostic Runners (OpenCode)
OpenCode supports multiple providers, typically defaulting to Anthropic or OpenAI depending on configuration. The example implementation in the repository uses ANTHROPIC_API_KEY at line 90, though the runner can accept OPENAI_API_KEY when configured for OpenAI models.
Response Extraction Path Implementations
The method for isolating the final assistant message varies significantly across runners due to differences in output formats.
Claude Code: Stream-JSON Parsing
Claude Code outputs stream-JSON format when using --output-format stream-json, requiring multi-stage extraction to isolate text content. As implemented in agent-runner-templates.md at lines 44-48, the extraction pipeline filters for the last assistant message containing text content:
cat /tmp/agent-output.txt | grep '^{' | jq -s '[.[] | select(.type == "assistant" and .message.content)] | last | .message.content[] | select(.type == "text") | .text' -r > /tmp/pr-body.md
This command first filters JSON lines, then selects the final assistant message and extracts nested text objects.
Codex: Native Output Flag
Codex eliminates post-processing complexity by providing the --output-last-message flag, which writes the final response directly to a specified file. At line 73 of the templates, the implementation simply passes:
codex exec "$PROMPT" --output-last-message /tmp/pr-body.md
No additional extraction commands are required, as the CLI handles file output internally.
OpenCode: Structured JSON Extraction
When invoked with --format json, OpenCode produces structured output requiring extraction from a .messages array. Lines 7-10 of the templates demonstrate filtering for the last assistant role entry:
cat /tmp/agent-output.txt | jq -r '.messages | map(select(.role == "assistant")) | last | .content' > /tmp/pr-body.md
This approach assumes the JSON output contains a top-level messages array with role-based entries.
CodeLayer: ANSI Color Stripping
CodeLayer emits ANSI-colored plain text rather than structured JSON, necessitating either color code removal or custom parsing. The basic extraction at lines 42-46 uses sed to strip escape sequences:
cat /tmp/agent-output.txt | sed 's/\x1b\[[0-9;]*m//g' > /tmp/pr-body.md
Alternatively, the repository provides a custom parser script located at ci-scripts/codelayer-output.ts, invoked via Bun for more sophisticated processing:
bun ci-scripts/codelayer-output.ts < /tmp/agent-output.txt > /tmp/pr-body.md
Complete Workflow Examples
Below are production-ready GitHub Actions snippets demonstrating secret injection and response extraction for each agent.
Claude Code Configuration
- uses: actions/setup-node@v4
with:
node-version: 24
- run: npm install -g @anthropic-ai/claude-code
- name: Run Claude Code
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "$PROMPT" \
--permission-mode bypassPermissions \
--output-format stream-json \
--verbose \
2>&1 | tee /tmp/agent-output.txt
- name: Extract PR body
run: |
cat /tmp/agent-output.txt \
| grep '^{' \
| jq -s '[.[] | select(.type == "assistant" and .message.content)] | last | .message.content[] | select(.type == "text") | .text' -r \
> /tmp/pr-body.md
Codex CLI Configuration
- uses: actions/setup-node@v4
with:
node-version: 24
- run: npm install -g @openai/codex
- name: Login Codex
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: printenv OPENAI_API_KEY | codex login --with-api-key
- name: Run Codex
run: |
codex exec "$PROMPT" \
--cd "$GITHUB_WORKSPACE" \
--ask-for-approval never \
--sandbox danger-full-access \
--json \
--output-last-message /tmp/pr-body.md \
2>&1 | tee /tmp/agent-output.txt
OpenCode Configuration
- uses: oven-sh/setup-bun@v2
- run: bun install -g opencode-ai
- name: Run OpenCode
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
opencode run "$PROMPT" \
--dir "$GITHUB_WORKSPACE" \
--model anthropic/claude-sonnet-4-5 \
--format json \
--dangerously-skip-permissions \
2>&1 | tee /tmp/agent-output.txt
- name: Extract PR body
run: |
cat /tmp/agent-output.txt \
| jq -r '.messages | map(select(.role == "assistant")) | last | .content' \
> /tmp/pr-body.md
CodeLayer Configuration
- uses: oven-sh/setup-bun@v2
- name: Run CodeLayer
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FORCE_COLOR: "3"
run: |
bunx @humanlayer/cli@latest codelayer \
--provider anthropic \
--model claude-opus-4-8 \
--thinking high \
--prompt "$PROMPT" \
2>&1 | tee /tmp/agent-output.txt
- name: Extract PR body
run: |
cat /tmp/agent-output.txt | sed 's/\x1b\[[0-9;]*m//g' > /tmp/pr-body.md
Summary
- Claude Code and CodeLayer both require the
ANTHROPIC_API_KEYsecret, while Codex exclusively usesOPENAI_API_KEYand OpenCode supports either provider. - Response extraction complexity varies significantly: Codex requires no post-processing due to its
--output-last-messageflag, while Claude Code needs complexjqfilters for stream-JSON, OpenCode uses simple JSON path extraction, and CodeLayer requires ANSI color code stripping. - The agent runner templates located at
plugins/design-control-loop/skills/design-control-loop/references/agent-runner-templates.mdserve as the authoritative reference for implementing these workflows in thehumanlayer/skillsrepository. - CodeLayer uniquely offers a dual extraction approach: basic
sedcolor stripping or a custom TypeScript parser atci-scripts/codelayer-output.ts.
Frequently Asked Questions
Why do Claude Code and CodeLayer use the same secret name but different extraction methods?
Both agents integrate with Anthropic's API, hence the shared ANTHROPIC_API_KEY requirement. However, Claude Code outputs structured stream-JSON requiring nested jq queries to isolate the final text content, while CodeLayer emits ANSI-colored plain text that requires color code stripping or custom parsing to produce clean markdown.
Can I use OpenAI models with the OpenCode runner instead of Anthropic?
Yes. While the example implementation in agent-runner-templates.md demonstrates ANTHROPIC_API_KEY usage, OpenCode supports provider configuration through its CLI flags. You would substitute OPENAI_API_KEY in the environment block and adjust the --model parameter to reference an OpenAI model identifier rather than the Anthropic claude-sonnet-4-5 example.
What happens if I don't strip ANSI codes from CodeLayer output?
The extracted PR body will contain raw terminal escape sequences (color codes, formatting characters) that render as gibberish or invisible characters in GitHub's markdown viewer. The sed command s/\x1b\[[0-9;]*m//g removes these sequences, or alternatively, the custom Bun parser at ci-scripts/codelayer-output.ts handles both color stripping and potential structural formatting.
Is the --output-last-message flag available in Claude Code or OpenCode?
No. The --output-last-message flag is specific to the Codex CLI. Claude Code requires stream-JSON parsing with jq, and OpenCode requires JSON message array extraction. Attempting to use this flag with the other agents will result in an unrecognized argument error or unexpected behavior.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →