fix: improve opencode trial resume controls
This commit is contained in:
@@ -3,7 +3,9 @@ from __future__ import annotations
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Any, Literal
|
||||
|
||||
PromptMode = Literal["auto", "continue", "final-report"]
|
||||
|
||||
FINAL_REPORT_PROMPT = (
|
||||
"Your workflow attempt is over. Do not continue coding. Return only the "
|
||||
@@ -62,6 +64,15 @@ def resume_prompt_for_result(result: dict[str, object]) -> str:
|
||||
return CONTINUE_PROMPT
|
||||
|
||||
|
||||
def resume_prompt_for_mode(result: dict[str, object], mode: PromptMode) -> str:
|
||||
"""Return the operator-selected resume prompt, falling back to auto detection."""
|
||||
if mode == "continue":
|
||||
return CONTINUE_PROMPT
|
||||
if mode == "final-report":
|
||||
return FINAL_REPORT_PROMPT
|
||||
return resume_prompt_for_result(result)
|
||||
|
||||
|
||||
def build_resume_command(
|
||||
*,
|
||||
session_id: str,
|
||||
@@ -77,6 +88,81 @@ def build_resume_command(
|
||||
return command
|
||||
|
||||
|
||||
def resume_command_from_result(
|
||||
result: dict[str, Any],
|
||||
*,
|
||||
session_id: str | None = None,
|
||||
attach_url: str | None = None,
|
||||
model: str | None = None,
|
||||
variant: str | None = None,
|
||||
prompt_mode: PromptMode = "auto",
|
||||
) -> list[str]:
|
||||
"""Build a resume command from new metadata or recover it from old raw results."""
|
||||
opencode = result.get("opencode")
|
||||
if isinstance(opencode, dict):
|
||||
command = opencode.get("resume_command")
|
||||
has_override = (
|
||||
any(value is not None for value in (session_id, attach_url, model, variant))
|
||||
or prompt_mode != "auto"
|
||||
)
|
||||
if (
|
||||
not has_override
|
||||
and isinstance(command, list)
|
||||
and all(isinstance(part, str) for part in command)
|
||||
):
|
||||
return command
|
||||
|
||||
stdout = result.get("stdout")
|
||||
stdout_text = stdout if isinstance(stdout, str) else ""
|
||||
if isinstance(opencode, dict):
|
||||
metadata_session_id = opencode.get("session_id")
|
||||
metadata_model = opencode.get("model")
|
||||
metadata_variant = opencode.get("variant")
|
||||
metadata_attach_url = opencode.get("attach_url")
|
||||
else:
|
||||
metadata_session_id = None
|
||||
metadata_model = None
|
||||
metadata_variant = None
|
||||
metadata_attach_url = None
|
||||
|
||||
recovered_session_id = (
|
||||
session_id
|
||||
or (metadata_session_id if isinstance(metadata_session_id, str) else None)
|
||||
or extract_session_id(stdout_text)
|
||||
)
|
||||
if not recovered_session_id:
|
||||
raise ValueError("result has no opencode session id; pass --session")
|
||||
|
||||
result_model = result.get("model")
|
||||
result_variant = result.get("variant")
|
||||
resolved_model = (
|
||||
model
|
||||
or (metadata_model if isinstance(metadata_model, str) else None)
|
||||
or (result_model if isinstance(result_model, str) else None)
|
||||
)
|
||||
resolved_variant = (
|
||||
variant
|
||||
or (metadata_variant if isinstance(metadata_variant, str) else None)
|
||||
or (result_variant if isinstance(result_variant, str) else None)
|
||||
)
|
||||
resolved_attach_url = attach_url or (
|
||||
metadata_attach_url if isinstance(metadata_attach_url, str) else None
|
||||
)
|
||||
|
||||
if not resolved_model:
|
||||
raise ValueError("result has no opencode model; pass --model")
|
||||
if not resolved_variant:
|
||||
raise ValueError("result has no opencode variant; pass --variant")
|
||||
|
||||
return build_resume_command(
|
||||
session_id=recovered_session_id,
|
||||
attach_url=resolved_attach_url,
|
||||
model=resolved_model,
|
||||
variant=resolved_variant,
|
||||
prompt=resume_prompt_for_mode(result, prompt_mode),
|
||||
)
|
||||
|
||||
|
||||
def display_resume_command(command: list[str]) -> str:
|
||||
"""Render an argv list for copy-paste display without changing execution."""
|
||||
return subprocess.list2cmdline(command)
|
||||
|
||||
Reference in New Issue
Block a user