chore: add agents/reports to gitignore and update agent infrastructure with timestamp streaming, write budget, and codename generation
- Add `agents/reports/` to `.gitignore` to prevent generated agent report files from being tracked - Implement `_TimestampStream` class and `install_timestamps()` function in `agents/agent.py` for prefixing stdout/stderr with timestamps and elapsed time - Export `install_timestamps`, `set_write_budget`, `clear_write_budget`, and `set_shell_restricted` from `agents/base.py`; add `_RUN_LOCK`, `AGENT_ICONS` dictionary, and `WRITE_BUDGET = 20` constant - Add `report_codename()` function and `CODENAME_ADJECTIVES`/`CODENAME_ANIMALS` tuples to `agents/core/__init__.py` for generating random agent report codenames - Expand `WRITE_TOOLS` tuple in `agents/core/__init__.py` to include `replace_lines`, `insert_lines`, and `delete_lines`; remove `SWARM_TOOLS` from `payloads_for` exclusion list - Update `CLAUDE.md` and `AGENTS.md` documentation with dataset column initialization rules and new agent infrastructure details - Reorder route table in `README.md` to list `/uploads` before `/messages` and document Swagger/ReDoc/OpenAPI schema endpoints
This commit is contained in:
+57
-3
@@ -3,10 +3,27 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import random
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
|
||||
CODENAME_ADJECTIVES = (
|
||||
"brave", "calm", "clever", "swift", "gentle", "bright", "bold", "cosmic", "lucky", "mighty",
|
||||
"noble", "quiet", "rapid", "sunny", "witty", "eager", "jolly", "keen", "merry", "proud",
|
||||
"sleek", "spry", "vivid", "zesty", "amber", "azure", "coral", "fuzzy", "golden", "happy",
|
||||
"snappy", "cozy", "breezy", "plucky", "dapper", "nimble", "quirky", "steady", "tidy", "wise",
|
||||
)
|
||||
CODENAME_ANIMALS = (
|
||||
"otter", "badger", "panda", "koala", "heron", "tiger", "gecko", "raven", "moose", "bison",
|
||||
"crane", "dingo", "ferret", "marmot", "walrus", "puffin", "ibis", "lemur", "tapir", "quokka",
|
||||
"narwhal", "ocelot", "wombat", "gibbon", "meerkat", "mongoose", "capybara", "axolotl", "pangolin", "armadillo",
|
||||
)
|
||||
|
||||
|
||||
def report_codename() -> str:
|
||||
return f"{random.choice(CODENAME_ADJECTIVES)}-{random.choice(CODENAME_ANIMALS)}"
|
||||
|
||||
from ..agent import (
|
||||
tool,
|
||||
react_loop,
|
||||
@@ -20,7 +37,15 @@ from ..agent import (
|
||||
|
||||
REPORTS_DIR = Path(__file__).resolve().parent.parent / "reports"
|
||||
|
||||
WRITE_TOOLS = ("create_file", "write_file", "edit_file", "patch_file")
|
||||
WRITE_TOOLS = (
|
||||
"create_file",
|
||||
"write_file",
|
||||
"edit_file",
|
||||
"patch_file",
|
||||
"replace_lines",
|
||||
"insert_lines",
|
||||
"delete_lines",
|
||||
)
|
||||
WEB_TOOLS = (
|
||||
"web_search",
|
||||
"deep_search",
|
||||
@@ -89,7 +114,7 @@ async def report_finding(
|
||||
|
||||
|
||||
def payloads_for(mode: str) -> list[dict[str, Any]]:
|
||||
exclude = WEB_TOOLS + SWARM_TOOLS
|
||||
exclude = WEB_TOOLS + SWARM_TOOLS + ("run_command",)
|
||||
if mode == "check":
|
||||
exclude = exclude + WRITE_TOOLS + ("verify",)
|
||||
return get_tool_payloads(exclude=exclude)
|
||||
@@ -149,6 +174,28 @@ def _md_report(name: str, mode: str, summary: dict[str, int], items: list[dict[s
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
REPORTS_KEEP = 25
|
||||
|
||||
|
||||
def report_path(name: str, codename: str, started: datetime) -> Path:
|
||||
stamp = started.strftime("%Y%m%d-%H%M%S")
|
||||
return REPORTS_DIR / f"{name}-{codename}-{stamp}"
|
||||
|
||||
|
||||
def prune_reports(prefix: str, keep: int = REPORTS_KEEP) -> None:
|
||||
existing = sorted(
|
||||
REPORTS_DIR.glob(f"{prefix}-*.json"),
|
||||
key=lambda path: path.stat().st_mtime,
|
||||
reverse=True,
|
||||
)
|
||||
for stale in existing[keep:]:
|
||||
for companion in (stale, stale.with_suffix(".md")):
|
||||
try:
|
||||
companion.unlink()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def write_reports(
|
||||
name: str,
|
||||
mode: str,
|
||||
@@ -156,14 +203,17 @@ def write_reports(
|
||||
finished: datetime,
|
||||
cost: Optional[dict[str, Any]] = None,
|
||||
incomplete: bool = False,
|
||||
codename: Optional[str] = None,
|
||||
) -> dict[str, Any]:
|
||||
REPORTS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
items = findings()
|
||||
summary = summarize(items)
|
||||
codename = codename or report_codename()
|
||||
stamp = started.strftime("%Y%m%d-%H%M%S")
|
||||
base = REPORTS_DIR / f"{name}-{stamp}"
|
||||
base = REPORTS_DIR / f"{name}-{codename}-{stamp}"
|
||||
payload = {
|
||||
"agent": name,
|
||||
"codename": codename,
|
||||
"mode": mode,
|
||||
"started_at": started.isoformat(),
|
||||
"finished_at": finished.isoformat(),
|
||||
@@ -174,6 +224,7 @@ def write_reports(
|
||||
}
|
||||
base.with_suffix(".json").write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
||||
base.with_suffix(".md").write_text(_md_report(name, mode, summary, items), encoding="utf-8")
|
||||
prune_reports(name)
|
||||
return {"summary": summary, "json": str(base.with_suffix(".json")), "items": items}
|
||||
|
||||
|
||||
@@ -191,5 +242,8 @@ __all__ = [
|
||||
"payloads_named",
|
||||
"summarize",
|
||||
"write_reports",
|
||||
"report_codename",
|
||||
"report_path",
|
||||
"prune_reports",
|
||||
"REPORTS_DIR",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user