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:
2026-06-12 03:37:12 +00:00
parent 7fc9b0f715
commit 31841fece4
80 changed files with 2095 additions and 323 deletions
+57 -3
View File
@@ -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",
]