Stream agent output through kelos-capture instead of writing to /tmp
What type of PR is this?
/kind bug
What this PR does / why we need it:
Every agent entrypoint used to tee the agent's JSON-lines stdout into
/tmp/agent-output.jsonl so that /kelos/kelos-capture could re-read it
after the agent exited and emit token usage between the
---KELOS_OUTPUTS_*--- markers. /tmp counts against the pod's
ephemeral-storage limit and the file was never rotated, so a verbose
run could fill the ephemeral budget and trigger node-pressure eviction
that silently failed user tasks.
This PR inlines the parser into the pipe. Each entrypoint now does:
<agent> "${ARGS[@]}" | /kelos/kelos-capture
AGENT_EXIT_CODE=${PIPESTATUS[0]}
exit $AGENT_EXIT_CODE
kelos-capture reads stdin line by line, forwards each line unchanged
to its own stdout (pod logs are byte-identical to today), and
accumulates per-agent counters in memory:
claude-code/gemini/cursor— keep only the most recent
{"type":"result", ...}line.codex/opencode— sum tokens across everyturn.completed/
step_finishevent.
Memory cost is O(1) in the size of the stream, /tmp/agent-output.jsonl
is no longer created, and the controller's marker contract is
unchanged.
Which issue(s) this PR is related to:
Fixes #1187
Special notes for your reviewer:
ParseUsage(agentType, filePath)is replaced by
StreamUsage(agentType, io.Reader, io.Writer).- The agent's exit code is still propagated via
PIPESTATUS[0]— same
pattern as before, just withkelos-captureon the right of the pipe
instead oftee. - Unit tests in
internal/capturenow exercise the streaming path for
all five agent types and verify every input line is forwarded
unchanged. docs/agent-image-interface.mdupdated to describe the pipe form.
Does this PR introduce a user-facing change?
Fix Task pod eviction from unbounded /tmp/agent-output.jsonl growth: agent stdout is now streamed through kelos-capture instead of being teed to disk, removing the ephemeral-storage pressure point.
Summary by cubic
Stream agent stdout through /kelos/kelos-capture instead of teeing to /tmp, removing the ephemeral-storage hotspot that caused task pod evictions. Pod logs remain identical to previous behavior and the ---KELOS_OUTPUTS_*--- contract is unchanged.
-
Bug Fixes
- Removed
/tmp/agent-output.jsonlwrites to stop ephemeral-storage bloat and node-pressure evictions (fixes #1187). - Forwarding preserves bytes in order with no line-length cap, appends a final newline if missing, surfaces flush errors, and still emits usage at EOF.
- Removed
-
Refactors
- Replaced
ParseUsage(...)withStreamUsage(agentType, io.Reader, io.Writer);/kelos-capturenow streams stdin to stdout and accumulates usage in O(1) memory. - Updated entrypoints to
<agent> "${ARGS[@]}" | /kelos/kelos-capture; agent exit code preserved viaPIPESTATUS[0]. Tests cover large lines, newline-append, and flush-error paths; docs now prescribe the pipe pattern.
- Replaced