agentic-dev-loop 0.12.2__py3-none-any.whl → 0.13.0__py3-none-any.whl
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.
- agentic_dev_loop/engine/cli.py +67 -0
- agentic_dev_loop/engine/graph.py +2 -1
- agentic_dev_loop/engine/provider_wire.py +7 -0
- agentic_dev_loop/reporting/__init__.py +43 -0
- agentic_dev_loop/reporting/metrics.py +593 -0
- agentic_dev_loop/reporting/render.py +175 -0
- agentic_dev_loop/reporting/sources.py +770 -0
- agentic_dev_loop/viz/page.py +1 -1
- agentic_dev_loop/viz/server.py +7 -3
- agentic_dev_loop-0.13.0.dist-info/METADATA +642 -0
- {agentic_dev_loop-0.12.2.dist-info → agentic_dev_loop-0.13.0.dist-info}/RECORD +15 -11
- agentic_dev_loop-0.12.2.dist-info/METADATA +0 -936
- {agentic_dev_loop-0.12.2.dist-info → agentic_dev_loop-0.13.0.dist-info}/WHEEL +0 -0
- {agentic_dev_loop-0.12.2.dist-info → agentic_dev_loop-0.13.0.dist-info}/entry_points.txt +0 -0
- {agentic_dev_loop-0.12.2.dist-info → agentic_dev_loop-0.13.0.dist-info}/licenses/LICENSE +0 -0
- {agentic_dev_loop-0.12.2.dist-info → agentic_dev_loop-0.13.0.dist-info}/top_level.txt +0 -0
agentic_dev_loop/engine/cli.py
CHANGED
|
@@ -206,6 +206,71 @@ def _run_copilot_models(argv: list[str]) -> int:
|
|
|
206
206
|
return 0
|
|
207
207
|
|
|
208
208
|
|
|
209
|
+
def _report_parser() -> argparse.ArgumentParser:
|
|
210
|
+
parser = argparse.ArgumentParser(
|
|
211
|
+
prog="agentic-dev-loop report",
|
|
212
|
+
description="Report accumulated agentic-dev-loop run history as "
|
|
213
|
+
"read-only markdown.")
|
|
214
|
+
parser.add_argument("run_id", nargs="?", default=None,
|
|
215
|
+
help="12-hex run dir name for a deep dive "
|
|
216
|
+
"(default: aggregate report)")
|
|
217
|
+
parser.add_argument("--since", default=None,
|
|
218
|
+
help="only threads starting at or after this ISO "
|
|
219
|
+
"datetime")
|
|
220
|
+
parser.add_argument("--until", default=None,
|
|
221
|
+
help="only threads starting before this ISO datetime")
|
|
222
|
+
parser.add_argument("--status", action="append", default=None,
|
|
223
|
+
help="filter by status (success/failed/interrupted/"
|
|
224
|
+
"running); repeatable or comma-separated")
|
|
225
|
+
parser.add_argument("--runs-root", default=None,
|
|
226
|
+
help="runs root (default: $AGENTIC_DEV_LOOP_RUNS_ROOT "
|
|
227
|
+
"or ~/.agentic-dev-loop/runs)")
|
|
228
|
+
parser.add_argument("--audit-dir", "--state-dir", dest="audit_dir",
|
|
229
|
+
default=None,
|
|
230
|
+
help="sandbox audit dir (default: "
|
|
231
|
+
"$AGENTIC_DEV_LOOP_STATE_DIR or "
|
|
232
|
+
"~/.agentic-dev-loop/state)")
|
|
233
|
+
return parser
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def _run_report(argv: list[str]) -> int:
|
|
237
|
+
from agentic_dev_loop.reporting import (
|
|
238
|
+
apply_filters, build_run_records, discover, find_run_dir,
|
|
239
|
+
pure_metrics, read_audit, read_dir, render_markdown, runs_root)
|
|
240
|
+
|
|
241
|
+
args = _report_parser().parse_args(argv)
|
|
242
|
+
root = runs_root(args.runs_root)
|
|
243
|
+
notice = None
|
|
244
|
+
if args.run_id is not None:
|
|
245
|
+
run_dir = find_run_dir(args.run_id, root)
|
|
246
|
+
if run_dir is None:
|
|
247
|
+
print(f"report: unknown run id: {args.run_id}", file=sys.stderr)
|
|
248
|
+
return 1
|
|
249
|
+
dirs = [run_dir]
|
|
250
|
+
else:
|
|
251
|
+
dirs = discover(root)
|
|
252
|
+
if not root.is_dir():
|
|
253
|
+
notice = f"runs root not found: {root}"
|
|
254
|
+
audit_pool = read_audit(args.audit_dir)
|
|
255
|
+
records = build_run_records([read_dir(path) for path in dirs], audit_pool)
|
|
256
|
+
filters = {key: getattr(args, key)
|
|
257
|
+
for key in ("since", "until", "status") if getattr(args, key)}
|
|
258
|
+
try:
|
|
259
|
+
records = apply_filters(
|
|
260
|
+
records, since=args.since, until=args.until,
|
|
261
|
+
statuses=args.status)
|
|
262
|
+
except ValueError as exc:
|
|
263
|
+
print(f"report: {exc}", file=sys.stderr)
|
|
264
|
+
return 1
|
|
265
|
+
if not records and notice is None:
|
|
266
|
+
notice = "no runs recorded" if not dirs else "no runs matched filters"
|
|
267
|
+
metrics = pure_metrics(records)
|
|
268
|
+
sys.stdout.write(render_markdown(
|
|
269
|
+
records, metrics, deep_dive=args.run_id is not None,
|
|
270
|
+
filters=filters, notice=notice))
|
|
271
|
+
return 0
|
|
272
|
+
|
|
273
|
+
|
|
209
274
|
def build_parser(cfg_path) -> argparse.ArgumentParser:
|
|
210
275
|
"""The full parser for one pipeline: core flags + loader-contributed."""
|
|
211
276
|
registry, _ = _registry_for(cfg_path)
|
|
@@ -226,6 +291,8 @@ def main(argv: list[str] | None = None, *, keep_alive: bool = True) -> int:
|
|
|
226
291
|
return _run_copilot_login(argv[1:])
|
|
227
292
|
if argv and argv[0] == "copilot-models":
|
|
228
293
|
return _run_copilot_models(argv[1:])
|
|
294
|
+
if argv and argv[0] == "report":
|
|
295
|
+
return _run_report(argv[1:])
|
|
229
296
|
if argv and argv[0] == "run-status":
|
|
230
297
|
from .run_status import _run_status
|
|
231
298
|
return _run_status(argv[1:])
|
agentic_dev_loop/engine/graph.py
CHANGED
|
@@ -27,6 +27,7 @@ from .hostboundary import (check_orchestrator_install,
|
|
|
27
27
|
from .isolation import startup_sandbox
|
|
28
28
|
from .llm import build_llm
|
|
29
29
|
from .loaders import resolve_docs
|
|
30
|
+
from .provider_wire import provider_name
|
|
30
31
|
from .secrets import resolve_secrets, scan_env_files
|
|
31
32
|
from .registry import (Registry, default_registry, load_extensions,
|
|
32
33
|
validate_action_mounts_egress, validate_action_network)
|
|
@@ -291,7 +292,7 @@ def _run_pipeline(cfg, base, registry, state_dir, max_attempts, args, viz_bus,
|
|
|
291
292
|
httpd, _thread = viz.serve_viz(
|
|
292
293
|
bus, topology["mermaid"], start_state["subject"],
|
|
293
294
|
args.viz_port, topology["nodes"], topology["flow"],
|
|
294
|
-
topology["edges"])
|
|
295
|
+
topology["edges"], provider_name(cfg.llm.base_url))
|
|
295
296
|
bound = httpd.server_address[1]
|
|
296
297
|
url = f"http://127.0.0.1:{bound}"
|
|
297
298
|
if args.viz_port and bound != args.viz_port:
|
|
@@ -40,6 +40,13 @@ def adapter_for(base_url: str | None) -> WireAdapter | None:
|
|
|
40
40
|
return WIRE_ADAPTERS.get(base_url.rstrip("/"))
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
def provider_name(base_url: str | None) -> str:
|
|
44
|
+
"""Display name of the LLM provider behind a base URL."""
|
|
45
|
+
if base_url is not None and base_url.rstrip("/") == COPILOT_BASE_URL:
|
|
46
|
+
return "Copilot"
|
|
47
|
+
return "OpenAI"
|
|
48
|
+
|
|
49
|
+
|
|
43
50
|
class WireShapeError(RuntimeError):
|
|
44
51
|
"""A surfaced or outgoing wire shape that cannot carry a tool call.
|
|
45
52
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Read-only run-history reporting (unit 12)."""
|
|
2
|
+
|
|
3
|
+
from .metrics import Metric, apply_filters, pure_metrics
|
|
4
|
+
from .render import render_markdown
|
|
5
|
+
from .sources import (
|
|
6
|
+
AuditRecord,
|
|
7
|
+
Attempt,
|
|
8
|
+
DirData,
|
|
9
|
+
ProseFacts,
|
|
10
|
+
RunRecord,
|
|
11
|
+
StepVerdict,
|
|
12
|
+
audit_dir,
|
|
13
|
+
build_run_records,
|
|
14
|
+
discover,
|
|
15
|
+
find_run_dir,
|
|
16
|
+
is_test_command,
|
|
17
|
+
parse_ts,
|
|
18
|
+
read_audit,
|
|
19
|
+
read_dir,
|
|
20
|
+
runs_root,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"AuditRecord",
|
|
25
|
+
"Attempt",
|
|
26
|
+
"DirData",
|
|
27
|
+
"Metric",
|
|
28
|
+
"ProseFacts",
|
|
29
|
+
"RunRecord",
|
|
30
|
+
"StepVerdict",
|
|
31
|
+
"apply_filters",
|
|
32
|
+
"audit_dir",
|
|
33
|
+
"build_run_records",
|
|
34
|
+
"discover",
|
|
35
|
+
"find_run_dir",
|
|
36
|
+
"is_test_command",
|
|
37
|
+
"parse_ts",
|
|
38
|
+
"pure_metrics",
|
|
39
|
+
"read_audit",
|
|
40
|
+
"read_dir",
|
|
41
|
+
"render_markdown",
|
|
42
|
+
"runs_root",
|
|
43
|
+
]
|