drydock-cli 3.0.127__tar.gz → 3.0.128__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drydock_cli-3.0.127/drydock_cli.egg-info → drydock_cli-3.0.128}/PKG-INFO +1 -1
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/events.py +51 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tui/app.py +23 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tui/widgets.py +1 -1
- {drydock_cli-3.0.127 → drydock_cli-3.0.128/drydock_cli.egg-info}/PKG-INFO +1 -1
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/pyproject.toml +1 -1
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_events.py +33 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/LICENSE +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/NOTICE +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/README.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/__init__.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/__main__.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/advisor.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/agent.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/bash_safety.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/__init__.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/ml-data.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/ml-debug.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/ml-finetune.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/ml-metrics.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/ml-rl.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/ml-train.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/rmf-categorize.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/rmf-control.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/rmf-poam.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/rmf-review.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/stig-assess.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/builtin_skills/stig-remediate.md +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/cci.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/cli.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/compaction.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/config.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/detect.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/extract.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/gittools.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/graphrag.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/guards.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/loop_detect.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/mcp.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/poam.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/providers.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/recipes.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/rmf.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/rmf_graph.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/skills.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/stig.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/suggest.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/task_state.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tool_registry.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tools/__init__.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tui/__init__.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tui/approval.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tui/messages.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/tuning.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/verification.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock/web.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock_cli.egg-info/SOURCES.txt +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock_cli.egg-info/dependency_links.txt +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock_cli.egg-info/entry_points.txt +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock_cli.egg-info/requires.txt +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/drydock_cli.egg-info/top_level.txt +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/setup.cfg +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_advisor.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_approval.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_back_command.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_background.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_binary_output.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_crossplatform.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_output_bounding.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_process_group.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_safety.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_sanitize.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_shell.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_stdin.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_stop_partial.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_timeout_network.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_bash_timeout_param.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_cci.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_cli_agents.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_compact_command.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_compaction.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_config.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_config_migration.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_context_limit_config.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_detect.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_dispatch.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_e2e_connected.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_edit_replace_all.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_empty_response.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_extract.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_failure_loop.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_first_run_setup.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_gittools.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_glob_edit_edges.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_graphify_example.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_graphrag.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_graphrag_quoted_path.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_grep_and_read_robust.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_guards_and_tools.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_hallucinated_tools.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_leaked_tool_call.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_loop_detect.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_mcp.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_oneshot_unreachable.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_overthink_interrupt.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_plan_autocontinue.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_poam.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_providers_unreachable.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_read_index.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_recipes.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_repetition_interrupt.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_rmf.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_rmf_graph.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_rmf_stig_graph.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_runaway_repetition.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_screenshot.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_server_probe.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_skills.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_stall_retry.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_stig.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_stop.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_streaming_newlines.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_subagent.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_suggest.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_system_prompt_help.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_task_state.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_todo.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_tool_arg_coercion.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_tool_arg_coercion_more.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_tool_arg_parsing.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_tools_undo.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_tui.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_tuning.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_verification_gate.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_viewimage.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_vision_input.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_web_tools.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_windows_shell.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_write_content_coerce.py +0 -0
- {drydock_cli-3.0.127 → drydock_cli-3.0.128}/tests/test_xccdf.py +0 -0
|
@@ -66,3 +66,54 @@ def default_event_log_path():
|
|
|
66
66
|
import time
|
|
67
67
|
from pathlib import Path
|
|
68
68
|
return Path.home() / ".drydock" / "events" / f"session-{int(time.time())}.jsonl"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _events(events_or_path):
|
|
72
|
+
return events_or_path if isinstance(events_or_path, list) else EventLog.read(events_or_path)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def reconstruct_task_state(events_or_path):
|
|
76
|
+
"""Rebuild a TaskState (objective, acceptance criteria, phase) from an event
|
|
77
|
+
trace — the PRD "a task can be reconstructed from serialized state" / resume.
|
|
78
|
+
Returns a fresh TaskState (empty if the trace has no task_start)."""
|
|
79
|
+
from drydock.task_state import TaskState
|
|
80
|
+
ts = TaskState()
|
|
81
|
+
for e in _events(events_or_path):
|
|
82
|
+
t = e.get("type")
|
|
83
|
+
if t == "task_start":
|
|
84
|
+
ts.objective = e.get("objective", "") or ts.objective
|
|
85
|
+
ts.acceptance_criteria = list(e.get("acceptance_criteria", []) or ts.acceptance_criteria)
|
|
86
|
+
elif t in ("verify_gate", "verification", "done") and e.get("phase"):
|
|
87
|
+
ts.phase = e.get("phase", ts.phase)
|
|
88
|
+
elif t == "verify_gate":
|
|
89
|
+
ts.phase = "repair" if e.get("kind") == "failed" else "verify"
|
|
90
|
+
elif t == "done":
|
|
91
|
+
ts.phase = e.get("phase", ts.phase)
|
|
92
|
+
return ts
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def summarize(events_or_path) -> dict:
|
|
96
|
+
"""A compact digest of a task's execution trace for inspection/diagnosis."""
|
|
97
|
+
evs = _events(events_or_path)
|
|
98
|
+
tools: dict[str, int] = {}
|
|
99
|
+
turns = in_tok = out_tok = verify_pass = verify_fail = 0
|
|
100
|
+
phase = "understand"
|
|
101
|
+
for e in evs:
|
|
102
|
+
t = e.get("type")
|
|
103
|
+
if t == "turn":
|
|
104
|
+
turns += 1; in_tok += e.get("in_tok", 0) or 0; out_tok += e.get("out_tok", 0) or 0
|
|
105
|
+
elif t == "tool":
|
|
106
|
+
tools[e.get("name", "?")] = tools.get(e.get("name", "?"), 0) + 1
|
|
107
|
+
elif t == "verification":
|
|
108
|
+
if e.get("status") == "pass": verify_pass += 1
|
|
109
|
+
elif e.get("status") == "fail": verify_fail += 1
|
|
110
|
+
elif t == "done":
|
|
111
|
+
phase = e.get("phase", phase)
|
|
112
|
+
ts = reconstruct_task_state(evs)
|
|
113
|
+
return {
|
|
114
|
+
"objective": ts.objective, "acceptance_criteria": ts.acceptance_criteria,
|
|
115
|
+
"final_phase": phase, "turns": turns, "tools": tools,
|
|
116
|
+
"in_tok": in_tok, "out_tok": out_tok,
|
|
117
|
+
"verifications": {"pass": verify_pass, "fail": verify_fail},
|
|
118
|
+
"event_count": len(evs),
|
|
119
|
+
}
|
|
@@ -531,6 +531,8 @@ class DrydockApp(App):
|
|
|
531
531
|
self._cmd_context(arg)
|
|
532
532
|
elif cmd == "/shell":
|
|
533
533
|
self._cmd_shell()
|
|
534
|
+
elif cmd == "/events":
|
|
535
|
+
self._cmd_events()
|
|
534
536
|
elif cmd == "/advisor":
|
|
535
537
|
self._cmd_advisor(arg)
|
|
536
538
|
elif cmd == "/ask":
|
|
@@ -837,6 +839,27 @@ class DrydockApp(App):
|
|
|
837
839
|
else:
|
|
838
840
|
self._begin(prompt)
|
|
839
841
|
|
|
842
|
+
def _cmd_events(self) -> None:
|
|
843
|
+
"""Show a digest of this session's durable execution trace (event log)."""
|
|
844
|
+
log = self.state.events
|
|
845
|
+
if log is None:
|
|
846
|
+
self._info("Event log is off (config event_log = false).")
|
|
847
|
+
return
|
|
848
|
+
from drydock.events import summarize
|
|
849
|
+
s = summarize(str(log.path))
|
|
850
|
+
tools = ", ".join(f"{k}×{v}" for k, v in sorted(s["tools"].items())) or "none"
|
|
851
|
+
v = s["verifications"]
|
|
852
|
+
lines = [
|
|
853
|
+
f"Task trace — {log.path}",
|
|
854
|
+
f" objective : {(s['objective'] or '(none yet)')[:80]}",
|
|
855
|
+
f" criteria : {len(s['acceptance_criteria'])}",
|
|
856
|
+
f" phase : {s['final_phase']}",
|
|
857
|
+
f" turns : {s['turns']} tools: {tools}",
|
|
858
|
+
f" verifications: {v['pass']} passed, {v['fail']} failed",
|
|
859
|
+
f" tokens : {s['in_tok']:,} in / {s['out_tok']:,} out ({s['event_count']} events)",
|
|
860
|
+
]
|
|
861
|
+
self._info("\n".join(lines))
|
|
862
|
+
|
|
840
863
|
def _cmd_shell(self) -> None:
|
|
841
864
|
"""Show exactly which shell the Bash tool runs commands through, plus the
|
|
842
865
|
platform signals — so a 'still using bash on Windows' report is instantly
|
|
@@ -153,7 +153,7 @@ class PromptHistory:
|
|
|
153
153
|
# completes the prefix.
|
|
154
154
|
SLASH_COMMANDS = [
|
|
155
155
|
"/help", "/model", "/cwd", "/undo", "/back", "/stop", "/status",
|
|
156
|
-
"/compact", "/context", "/shell", "/advisor", "/ask", "/ask!", "/graphrag", "/skills",
|
|
156
|
+
"/compact", "/context", "/shell", "/events", "/advisor", "/ask", "/ask!", "/graphrag", "/skills",
|
|
157
157
|
"/loop", "/mcp", "/rmf", "/stig",
|
|
158
158
|
"/clear", "/quit",
|
|
159
159
|
]
|
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
|
7
7
|
# PyPI distribution name is drydock-cli (the established install name, continued
|
|
8
8
|
# from the retired v2 fork); the import package + CLI command stay `drydock`.
|
|
9
9
|
name = "drydock-cli"
|
|
10
|
-
version = "3.0.
|
|
10
|
+
version = "3.0.128"
|
|
11
11
|
description = "Drydock — a local, provider-agnostic terminal coding agent for local LLMs"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.11"
|
|
@@ -56,3 +56,36 @@ def test_run_writes_full_trace():
|
|
|
56
56
|
def test_disabled_no_events_attr():
|
|
57
57
|
st = agent.AgentState()
|
|
58
58
|
assert st.events is None # off by default on a bare AgentState
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_reconstruct_task_state_from_trace():
|
|
62
|
+
from drydock.events import EventLog, reconstruct_task_state
|
|
63
|
+
p = os.path.join(tempfile.mkdtemp(), "r.jsonl")
|
|
64
|
+
log = EventLog(p)
|
|
65
|
+
log.emit("task_start", objective="Recover the password", acceptance_criteria=["23 chars", "write out.txt"])
|
|
66
|
+
log.emit("tool", name="Write")
|
|
67
|
+
log.emit("done", phase="complete")
|
|
68
|
+
ts = reconstruct_task_state(p)
|
|
69
|
+
assert ts.objective == "Recover the password"
|
|
70
|
+
assert ts.acceptance_criteria == ["23 chars", "write out.txt"]
|
|
71
|
+
assert ts.phase == "complete"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_summarize_digest():
|
|
75
|
+
from drydock.events import EventLog, summarize
|
|
76
|
+
p = os.path.join(tempfile.mkdtemp(), "s.jsonl")
|
|
77
|
+
log = EventLog(p)
|
|
78
|
+
log.emit("task_start", objective="do X", acceptance_criteria=["a"])
|
|
79
|
+
log.emit("turn", in_tok=100, out_tok=50)
|
|
80
|
+
log.emit("tool", name="Bash"); log.emit("tool", name="Bash")
|
|
81
|
+
log.emit("verification", status="fail"); log.emit("verification", status="pass")
|
|
82
|
+
log.emit("done", phase="complete")
|
|
83
|
+
s = summarize(p)
|
|
84
|
+
assert s["turns"] == 1 and s["tools"] == {"Bash": 2}
|
|
85
|
+
assert s["verifications"] == {"pass": 1, "fail": 1} and s["final_phase"] == "complete"
|
|
86
|
+
assert s["in_tok"] == 100 and s["out_tok"] == 50
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_reconstruct_empty_trace():
|
|
90
|
+
from drydock.events import reconstruct_task_state
|
|
91
|
+
assert reconstruct_task_state([]).objective == ""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|