refactor: unify agent history and harden runtime diagnostics
Preserve user guidance through history compression, stabilize Flash index targets, and retire withdrawn checks without applying stale verdicts. Improve runtime diagnostics, tool responses, and history rendering. Simplify documentation and comments. Validation: 2076 tests passed in the full suite; 381 affected tests and 26 frontend tests passed after cleanup. Ruff and the quality ratchet passed.
This commit is contained in:
1 parent
e983180b5b
commit
5d92939d91
127 files changed
+13738
-1988
No files matched your search
@@ -319,21 +319,54 @@ def build_checker_tools(
|
||||
# --- History formatting --------------------------------------------------------------
|
||||
|
||||
|
||||
def _format_history(ctx: ArtemisContext, limit: int = 60) -> str:
|
||||
def _load_steps(ctx: ArtemisContext) -> list[dict] | str:
|
||||
"""The agent-friendly step records, or the reason they are unavailable."""
|
||||
if not ctx.data_engine:
|
||||
return "No execution history available."
|
||||
try:
|
||||
steps = ctx.data_engine.get_agent_friendly_steps() or []
|
||||
return list(ctx.data_engine.get_agent_friendly_steps() or [])
|
||||
except Exception as e:
|
||||
return f"Failed to load execution history: {e}"
|
||||
|
||||
|
||||
def _step_offset_label(step: dict, session_start: float | None) -> str:
|
||||
"""Session-relative ``T+mm:ss`` label of a step: the clock every agent shares.
|
||||
|
||||
The recorded timestamp against the session start is authoritative; a
|
||||
record that only carries the engine's ``"97.7s"`` label is converted.
|
||||
"""
|
||||
from artemis.memory.transcript import format_session_offset
|
||||
|
||||
ts = step.get("timestamp")
|
||||
if isinstance(session_start, (int, float)) and isinstance(ts, (int, float)):
|
||||
return format_session_offset(float(ts) - float(session_start))
|
||||
rel = str(step.get("relative_time") or "").strip()
|
||||
if rel.startswith("T+"):
|
||||
return rel
|
||||
if rel.endswith("s"):
|
||||
try:
|
||||
return format_session_offset(float(rel[:-1]))
|
||||
except ValueError:
|
||||
pass
|
||||
return "T+??:??"
|
||||
|
||||
|
||||
def _format_history(ctx: ArtemisContext, limit: int = 60, steps: list[dict] | None = None) -> str:
|
||||
if steps is None:
|
||||
steps = _load_steps(ctx)
|
||||
if isinstance(steps, str):
|
||||
return steps
|
||||
if not steps:
|
||||
return "No execution history available."
|
||||
session_start = getattr(ctx.data_engine, "session_start_time", None)
|
||||
lines = []
|
||||
for s in steps[-limit:]:
|
||||
num = s.get("step_number")
|
||||
rel = s.get("relative_time", "")
|
||||
summary = s.get("summary") or ""
|
||||
summary = (s.get("summary") or "").strip()
|
||||
action = s.get("action_taken")
|
||||
if not summary and not action:
|
||||
# Nothing to audit on this step: an empty row is only noise.
|
||||
continue
|
||||
action_str = ""
|
||||
if action and not summary:
|
||||
# The shared renderer keeps the target's provenance visible: a
|
||||
@@ -343,8 +376,25 @@ def _format_history(ctx: ArtemisContext, limit: int = 60) -> str:
|
||||
action_str = format_actions_clean(action)[:160]
|
||||
except Exception:
|
||||
action_str = str(action)[:160]
|
||||
lines.append(f"- Step {num} ({rel}): {summary or action_str}".rstrip())
|
||||
return "\n".join(lines)
|
||||
label = _step_offset_label(s, session_start)
|
||||
lines.append(f"- Step {num} ({label}): {summary or action_str}".rstrip())
|
||||
return "\n".join(lines) or "No execution history available."
|
||||
|
||||
|
||||
def _format_user_guidance(ctx: ArtemisContext, steps: list[dict] | None = None) -> str:
|
||||
"""Every mid-run user instruction, read from the step it was stamped on."""
|
||||
if steps is None:
|
||||
steps = _load_steps(ctx)
|
||||
if isinstance(steps, str) or not steps:
|
||||
return "(none)"
|
||||
session_start = getattr(ctx.data_engine, "session_start_time", None)
|
||||
lines = []
|
||||
for s in steps:
|
||||
instruction = (s.get("extra_metadata") or {}).get("injected_instruction")
|
||||
if isinstance(instruction, str) and instruction.strip():
|
||||
label = _step_offset_label(s, session_start)
|
||||
lines.append(f'- Step {s.get("step_number")} ({label}): "{instruction.strip()}"')
|
||||
return "\n".join(lines) or "(none)"
|
||||
|
||||
|
||||
def _format_check_items(check_items: list) -> str:
|
||||
@@ -773,14 +823,16 @@ async def run_final_check(
|
||||
)
|
||||
|
||||
screenshot_b64, minimal_list = await _capture_final_screen(ctx)
|
||||
steps = _load_steps(ctx)
|
||||
|
||||
human_text = (
|
||||
f"# User's Original Goal\n{goal}\n\n"
|
||||
f"# User guidance received during the run\n{_format_user_guidance(ctx, steps)}\n\n"
|
||||
f"# Final Task Plan\n{plan_text or '(no plan)'}\n\n"
|
||||
f"# Declared Check Items\n{_format_check_items(items)}\n\n"
|
||||
f"# Verdict Ledger (checkpoint results, authoritative for on_complete"
|
||||
f" items)\n{_format_ledger(ledger)}\n\n"
|
||||
f"# Execution History (summaries)\n{_format_history(ctx)}\n\n"
|
||||
f"# Execution History (summaries)\n{_format_history(ctx, steps=steps)}\n\n"
|
||||
f"# Final Screen Elements\n{minimal_list}"
|
||||
)
|
||||
|
||||
|
||||
Reference in new issue
Block a user