@senior: opencode logs #3

Merged
ffaerber merged 1 commits from ai/issue-2 into main 2026-07-02 15:21:48 +02:00
Showing only changes of commit 15285d228f - Show all commits
+48 -29
View File
@@ -174,29 +174,6 @@ jobs:
"### comment by \($who):\n\(.body)\n"' > /tmp/thread.md 2>/dev/null || true
echo "thread comments fetched: $(grep -c '^### comment by ' /tmp/thread.md 2>/dev/null || echo 0)"
# TEMPORARY: capture opencode's --format json event schema and POST it as an issue comment
# (easier to find than reusable-workflow step logs). Removed once captured.
- name: DEBUG capture --format json schema
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GT: ${{ secrets.GITEA_TOKEN }}
NUM: ${{ github.event.issue.number }}
run: |
cd /tmp && rm -f probe.txt
opencode run --model anthropic/claude-sonnet-5 --auto --format json \
"Create a file /tmp/probe.txt containing the word hi, then say one sentence about what you did." \
> /tmp/events.jsonl 2>/tmp/events.err || true
n=$(wc -l < /tmp/events.jsonl)
types=$(jq -rc '.type // (keys|join("+"))' /tmp/events.jsonl 2>/dev/null | sort | uniq -c)
examples=$(jq -s -c 'map(select(type=="object" and .type!=null)) | group_by(.type) | map(.[0])[]' /tmp/events.jsonl 2>/dev/null | cut -c1-700)
[ -z "$examples" ] && examples=$(head -c 3000 /tmp/events.jsonl)
body=$(printf 'DEBUG opencode --format json — %s events\n\n**types:**\n```\n%s\n```\n\n**one example per type:**\n```\n%s\n```\n\n**stderr tail:**\n```\n%s\n```' \
"$n" "$types" "$examples" "$(tail -8 /tmp/events.err)")
API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
curl -sS -X POST -H "Authorization: token $GT" -H "Content-Type: application/json" \
"$API/issues/$NUM/comments" -d "$(jq -nc --arg b "$body" '{body:$b}')" \
-w '\ndebug comment -> HTTP %{http_code}\n' || true
- name: Run agent
id: run
env:
@@ -288,22 +265,55 @@ jobs:
LATEST INSTRUCTION FROM MAINTAINER:
${CMT}"
echo "opencode version: $(opencode --version 2>&1)"
# Success is exit code 0 — the agent may make tool-only changes with no text summary,
# so DO NOT treat empty stdout as failure. Only retry a non-zero exit that looks transient.
# Capture the raw JSON event stream (--format json) so the activity log can be built
# from it afterwards. The plain --auto reply text == concatenation of all assistant
# "text" parts, so reconstruct /tmp/agent_out.md from those — the Publish step below
# keeps reading agent_out.md exactly as before. Success is exit code 0: the agent may
# make tool-only changes with no text summary, so DO NOT treat empty output as failure.
rc=1
for attempt in 1 2 3; do
echo "opencode attempt $attempt/3 for @$NAME ($MODEL)"
rc=0
opencode run --model "$MODEL" --auto "$PROMPT" ${{ steps.imgs.outputs.files }} \
>/tmp/agent_out.md 2>/tmp/agent_err.log || rc=$?
echo "rc=$rc"; echo "--- stdout (reply) ---"; cat /tmp/agent_out.md; echo "--- stderr (trace) ---"; cat /tmp/agent_err.log
opencode run --model "$MODEL" --auto --format json "$PROMPT" ${{ steps.imgs.outputs.files }} \
>/tmp/events.jsonl 2>/tmp/agent_err.log || rc=$?
echo "rc=$rc"; echo "--- events ($(wc -l < /tmp/events.jsonl 2>/dev/null || echo 0) lines) ---"
echo "--- stderr (trace) ---"; cat /tmp/agent_err.log
[ $rc -eq 0 ] && break
if grep -qiE 'overloaded|429|529|rate.?limit|timeout|ETIMEDOUT|ECONNRESET|EAI_AGAIN' /tmp/agent_out.md /tmp/agent_err.log; then
if grep -qiE 'overloaded|429|529|rate.?limit|timeout|ETIMEDOUT|ECONNRESET|EAI_AGAIN' /tmp/events.jsonl /tmp/agent_err.log; then
echo "transient error — backing off $((attempt*20))s"; sleep $((attempt * 20)); continue
fi
echo "non-transient failure (rc=$rc) — not retrying"; break
done
[ $rc -eq 0 ] || { echo "agent failed"; exit 1; }
# Reconstruct the plain-text reply from assistant text parts (== what plain --auto prints).
jq -r 'select(.type=="text") | .part.text // ""' /tmp/events.jsonl > /tmp/agent_out.md 2>/dev/null || true
echo "reconstructed reply ($(wc -l < /tmp/agent_out.md 2>/dev/null || echo 0) lines):"; cat /tmp/agent_out.md
- name: Build activity log (tool calls + reasoning) from the event stream
id: log
env:
MODE: ${{ steps.prep.outputs.mode }}
run: |
# Only dev agents (mode=pr) get an activity-log comment — comment-only roles (pm/qa)
# do no tool calls, so a trail would be empty/noise.
if [ "$MODE" != "pr" ]; then
echo "skipping activity log for comment-mode agent"; : > /tmp/activity_log.md; exit 0
fi
jq -r '
def trunc(n): if length > n then (.[0:n] + "…") else . end;
select(.type=="tool_use" or .type=="text") |
if .type=="text" then
"💬 " + ((.part.text // "") | trunc(4000))
else
(.part.tool // "?") as $t |
((.part.state.title // (.part.state.input | tojson | trunc(160)) // "")) as $title |
"🔧 **" + $t + "**: `" + ($title | trunc(240)) + "`"
end
' /tmp/events.jsonl > /tmp/activity_log.md 2>/dev/null || true
n=$(wc -l < /tmp/activity_log.md 2>/dev/null || echo 0)
echo "activity log: $n entries"
[ "$n" -eq 0 ] && : > /tmp/activity_log.md
head -3 /tmp/activity_log.md
- name: Publish — PR (dev agents) or comment (pm), always reply in the issue
env:
@@ -464,6 +474,15 @@ jobs:
post "$(printf '🤖 **@%s** — updated %s branch/PR:%b\n\n%s' "$NAME" "$count" "$links" "$prdesc")"
fi
# Post the agent's activity trail (tool calls + reasoning) as a separate comment so
# it is visible on the PR thread. Additive — kept here even when nothing changed, so a
# follow-up run (re-trigger) can see what this run did via the fetched issue thread.
if [ -s /tmp/activity_log.md ]; then
entries=$(wc -l < /tmp/activity_log.md 2>/dev/null || echo 0)
log=$(cat /tmp/activity_log.md)
post "$(printf '🤖 **@%s** — activity log (%s entries):\n<details>\n<summary>tool calls & reasoning</summary>\n\n%s\n\n</details>' "$NAME" "$entries" "$log")"
fi
- name: Mark done with 🚀 (remove 👀)
env:
GT: ${{ secrets.GITEA_TOKEN }}