Files
roboco/docker/agent-grok.Dockerfile
T
Renn F b0857915a1 fix(grok): correct opencode provider (Responses API), stdin, reasoning cost
A live opencode run against api.x.ai/v1 surfaced three real bugs:

1. Provider package — grok-build-0.1 is driven via the OpenAI Responses API
   (opencode calls model.responses()). @ai-sdk/openai-compatible is
   chat/completions only and errors "responses is not a function". Switch the
   generated opencode.json provider + the grok image to @ai-sdk/openai.
2. Headless hang — `opencode run` blocks after init without a TTY; close stdin
   (`< /dev/null`) in the entrypoint so it proceeds to the model call.
3. Reasoning-token cost — grok-build-0.1 is a reasoning model; reasoning tokens
   bill as output but opencode stores them in a separate column. cost_for_session
   folds tokens_reasoning into output (else ~22x undercount).

Verified end-to-end against a real session row (input=6120, output=1,
reasoning=226, cache_read=1856): our pricing reproduces opencode's stored USD
cost ($0.0069452) exactly. Tests anchored to that real row.
2026-06-18 09:57:20 +02:00

38 lines
1.7 KiB
Docker

# Grok (xAI) Agent Image
# =============================================================================
# Runs grok-build-0.1 through the opencode CLI (OpenAI protocol) instead of
# Claude Code, while reusing the base image's roboco venv + uv + the RoboCo MCP
# gateway servers. The entrypoint renders opencode.json from the spawn env +
# mounted mcp-config.json (see roboco.llm.providers.opencode_config) and runs
# opencode. One runtime image serves every role — role behaviour comes from the
# mounted system prompt / manifest / mcp-config, exactly as on the Claude path.
# =============================================================================
FROM roboco-agent-base
USER root
# opencode — the OpenAI-protocol agent runtime. grok-build-0.1 is driven via the
# OpenAI Responses API, so the provider package is @ai-sdk/openai (NOT
# @ai-sdk/openai-compatible, which is chat/completions only and errors with
# "responses is not a function"). opencode resolves it at runtime, but
# pre-installing keeps first spawn off the network.
RUN npm install -g opencode-ai @ai-sdk/openai \
&& npm cache clean --force \
&& rm -rf /root/.npm /tmp/*
# Command guard / secret-scrub plugin (bash-guard parity for the opencode runtime).
# Referenced from the generated opencode.json `plugin:` array.
COPY docker/grok/secret-scrub.js /app/opencode-plugins/secret-scrub.js
# Entrypoint: render opencode.json, then run opencode (overrides base's `claude`).
COPY docker/scripts/grok-agent-entrypoint.sh /app/scripts/grok-agent-entrypoint.sh
RUN chmod 0755 /app/scripts/grok-agent-entrypoint.sh
USER agent
LABEL role="grok-runtime"
LABEL description="Grok (xAI) agent runtime — grok-build-0.1 via opencode (OpenAI protocol)"
ENTRYPOINT ["/app/scripts/grok-agent-entrypoint.sh"]