MCPcopy Create free account
hub / github.com/MaxBittker/runebench / _parse_opencode_log

Function _parse_opencode_log

agents/opencode_adapter.py:339–499  ·  view source on GitHub ↗

Parse an OpenCode JSONL log file into an ATIF Trajectory.

(
    log_path: Path,
    model_name: str,
    agent_name: str,
    instruction: str | None = None,
)

Source from the content-addressed store, hash-verified

337 f"echo \"[{prefix}-loop] Run ${vp}_RUN starting (budget=${{{vp}_TIMEOUT}}s)\" | tee -a /logs/agent/{log_file}; "
338 f"{vp}_RUN_START=$(date +%s); "
339 f"timeout ${{{vp}_TIMEOUT}}s opencode --model {escaped_model} run --format=json {escaped_instruction} "
340 f"2>&1 </dev/null | tee -a /logs/agent/{log_file}; "
341 f"{vp}_RUN_DUR=$(( $(date +%s) - {vp}_RUN_START )); "
342 f"echo \"[{prefix}-loop] opencode exited after ${{{vp}_RUN_DUR}}s\" | tee -a /logs/agent/{log_file}; "
343 # Track fast failures (< 10s) to avoid spinning on broken setups
344 f"if [ ${vp}_RUN_DUR -lt 10 ]; then {vp}_FAST_FAILS=$(({vp}_FAST_FAILS + 1)); else {vp}_FAST_FAILS=0; fi; "
345 "while true; do "
346 # Consecutive fast failures usually mean a transient broken setup
347 # (locked db, API hiccup). Before giving up for good, cool down
348 # once for 60s and retry with a fresh session; abort only if the
349 # fast-fails come right back.
350 f" if [ ${vp}_FAST_FAILS -ge ${vp}_MAX_FAST_FAILS ]; then "
351 f" if [ ${vp}_COOLDOWN_USED -ge 1 ]; then "
352 f" echo \"[{prefix}-loop] ${{{vp}_FAST_FAILS}} consecutive fast failures (<10s) after cooldown, aborting\" | tee -a /logs/agent/{log_file}; "
353 " break; "
354 " fi; "
355 f" {vp}_COOLDOWN_USED=1; {vp}_FAST_FAILS=0; {vp}_RESUME=0; "
356 f" echo \"[{prefix}-loop] ${{{vp}_MAX_FAST_FAILS}} consecutive fast failures (<10s) — cooling down 60s, then retrying with a fresh session\" | tee -a /logs/agent/{log_file}; "
357 " sleep 60; "
358 " fi; "
359 f" {vp}_ELAPSED=$(( $(date +%s) - {vp}_START )); "
360 f" {vp}_REMAINING=$(( {vp}_TIMEOUT - {vp}_ELAPSED )); "
361 f" echo \"[{prefix}-loop] Elapsed: ${{{vp}_ELAPSED}}s, Remaining: ${{{vp}_REMAINING}}s\" | tee -a /logs/agent/{log_file}; "
362 f" if [ ${vp}_REMAINING -lt ${vp}_MIN_RESTART ]; then "
363 f" echo \"[{prefix}-loop] Less than ${{{vp}_MIN_RESTART}}s remaining, stopping restart loop\" | tee -a /logs/agent/{log_file}; "
364 " break; "
365 " fi; "
366 f" {vp}_RUN=$(({vp}_RUN + 1)); "
367 # Resume the previous session (context preserved) when possible:
368 # pull the newest sessionID out of this session's own JSON log.
369 f" {vp}_SID=''; "
370 f" if [ ${vp}_RESUME -eq 1 ]; then {vp}_SID=$(grep -o '\"sessionID\":\"[^\"]*\"' /logs/agent/{log_file} | tail -1 | cut -d'\"' -f4); fi; "
371 f" echo \"[{prefix}-loop] Run ${vp}_RUN starting (${{{vp}_REMAINING}}s remaining)\" | tee -a /logs/agent/{log_file}; "
372 f" {vp}_RUN_START=$(date +%s); "
373 f" if [ -n \"${vp}_SID\" ]; then "
374 f" echo \"[{prefix}-loop] Resuming session ${vp}_SID\" | tee -a /logs/agent/{log_file}; "
375 f" timeout ${{{vp}_REMAINING}}s opencode --model {escaped_model} run --format=json --session \"${vp}_SID\" {resume_message} "
376 f" 2>&1 </dev/null | tee -a /logs/agent/{log_file}; "
377 " else "
378 f" timeout ${{{vp}_REMAINING}}s opencode --model {escaped_model} run --format=json {continue_instruction} "
379 f" 2>&1 </dev/null | tee -a /logs/agent/{log_file}; "
380 " fi; "
381 f" {vp}_RUN_DUR=$(( $(date +%s) - {vp}_RUN_START )); "
382 f" echo \"[{prefix}-loop] opencode exited after ${{{vp}_RUN_DUR}}s\" | tee -a /logs/agent/{log_file}; "
383 # A fast-failing resume likely means the stored session is bad
384 # (locked db, corrupt state) — fall back to a fresh session.
385 f" if [ ${vp}_RUN_DUR -lt 10 ]; then "
386 f" {vp}_FAST_FAILS=$(({vp}_FAST_FAILS + 1)); "
387 f" if [ -n \"${vp}_SID\" ]; then {vp}_RESUME=0; echo \"[{prefix}-loop] Resume failed fast — next run starts a fresh session\" | tee -a /logs/agent/{log_file}; fi; "
388 f" else {vp}_FAST_FAILS=0; {vp}_RESUME=1; fi; "
389 "done; "
390 f"echo \"[{prefix}-loop] Finished after ${vp}_RUN runs\" | tee -a /logs/agent/{log_file}"
391 )
392
393 def _agent_env(self) -> dict[str, str]:
394 env = self._resolve_api_key_env()
395 env["OPENCODE_YOLO"] = "true"
396 env["OPENCODE_DANGEROUSLY_SKIP_PERMISSIONS"] = "true"

Callers 1

Calls 1

Tested by

no test coverage detected