Merge pull request 'The call record: every model call, for the operator's study (M6.6a)' (#179) from call-record into main
This commit was merged in pull request #179.
This commit is contained in:
commit
c1f3d9dafb
22 files changed
+1346
-48
No files matched your search
@@ -1,11 +1,13 @@
|
||||
"""Running one task once with one driver model, and recording it."""
|
||||
|
||||
import contextlib
|
||||
import io
|
||||
import shlex
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
from collections.abc import Iterator
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
@@ -21,6 +23,7 @@ from nisse_core.log.canonical import (
|
||||
UserMessage,
|
||||
)
|
||||
from nisse_core.loop.driver import Driver, RunOutcome
|
||||
from nisse_core.models import calls
|
||||
from nisse_core.models.catalog import ModelFacts
|
||||
from nisse_core.models.compact import Compactor
|
||||
from nisse_core.oplog import OpLog
|
||||
@@ -184,6 +187,37 @@ def _count(events: list[StoredEvent]) -> tuple[int, int]:
|
||||
return failed, invented
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _run_dir(keep: Path | None, workdir: Path | None, name: str) -> Iterator[Path]:
|
||||
"""Where a run's state store and call record go: kept under ``keep``
|
||||
for the status page (X6), or a temporary directory."""
|
||||
if keep is not None:
|
||||
root = keep / f"{name}-{uuid.uuid4().hex[:8]}"
|
||||
root.mkdir(parents=True)
|
||||
yield root
|
||||
return
|
||||
with tempfile.TemporaryDirectory(dir=workdir) as tmp:
|
||||
yield Path(tmp)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _recording(client: Any, root: Path) -> Iterator[None]:
|
||||
"""The run's calls recorded beside its own state store (L7), as the
|
||||
agent records its own, so the run measures what the agent would do."""
|
||||
recorder = calls.CallRecorder(calls.path_for(root / "state.db"))
|
||||
had = hasattr(client, "call_recorder")
|
||||
previous = getattr(client, "call_recorder", None)
|
||||
client.call_recorder = recorder
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if had:
|
||||
client.call_recorder = previous
|
||||
else:
|
||||
del client.call_recorder
|
||||
recorder.close()
|
||||
|
||||
|
||||
def run_task(
|
||||
task: Task,
|
||||
facts: ModelFacts,
|
||||
@@ -194,6 +228,7 @@ def run_task(
|
||||
note: str = "",
|
||||
commit: str = "",
|
||||
workdir: Path | None = None,
|
||||
keep: Path | None = None,
|
||||
) -> RunRecord:
|
||||
"""Run one task once: seed a workspace, hand the driver an agreed item
|
||||
whose restatement is the task's plan, then judge the result with the
|
||||
@@ -202,8 +237,7 @@ def run_task(
|
||||
It is the loop's own driver, system prompt and tools, so what is measured
|
||||
is what the agent would do, without the harness around it: the milestone
|
||||
is started but no branch is cut, and finishing it ends the run."""
|
||||
with tempfile.TemporaryDirectory(dir=workdir) as tmp:
|
||||
root = Path(tmp)
|
||||
with _run_dir(keep, workdir, task.name) as root, _recording(client, root):
|
||||
# The workspace is on the build VM, like the agent's own (L13).
|
||||
workspace = Workspace(
|
||||
host,
|
||||
|
||||
Reference in new issue
Block a user