mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-11 12:47:44 +01:00
Merge branch 'worktree-agent-a179fa4cf3532a65f'
This commit is contained in:
commit
99f4e171e3
@ -102,9 +102,14 @@ def step2_attempts(events: list[dict[str, Any]]) -> int:
|
|||||||
|
|
||||||
A ``fail`` (the list read as code, or named an operation) never reaches
|
A ``fail`` (the list read as code, or named an operation) never reaches
|
||||||
the checker, so it has no ``req_check``; a ``partial`` does, and is
|
the checker, so it has no ``req_check``; a ``partial`` does, and is
|
||||||
already counted there. CLI and app count one file alike.
|
already counted there. CLI and app count one file alike. A force
|
||||||
|
repeats the last try's grade but is not a try, so it is not counted.
|
||||||
"""
|
"""
|
||||||
fails = sum(1 for e in _step2_grades(events) if e.get("grade") == "fail")
|
fails = sum(
|
||||||
|
1
|
||||||
|
for e in _step2_grades(events)
|
||||||
|
if e.get("grade") == "fail" and e.get("forced") is not True
|
||||||
|
)
|
||||||
return req_state(events).tries + fails
|
return req_state(events).tries + fails
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,9 +5,9 @@ Reads ``$FAKE_CLAUDE_DIR/script.json``: ``{"haiku": [...], "coach": [...]}``.
|
|||||||
A call made with ``--model haiku`` is the checker; any other is the coach.
|
A call made with ``--model haiku`` is the checker; any other is the coach.
|
||||||
Each call takes the next answer of its kind -- ``{"result": "..."}`` is printed
|
Each call takes the next answer of its kind -- ``{"result": "..."}`` is printed
|
||||||
the way ``--output-format json`` prints it, ``{"exit": n, "stderr": "..."}``
|
the way ``--output-format json`` prints it, ``{"exit": n, "stderr": "..."}``
|
||||||
fails -- and appends ``{"kind", "args", "prompt"}`` to ``calls.jsonl`` so a
|
fails, ``"sleep": s`` delays either (a slow turn) -- and appends
|
||||||
test can prove what did and did not reach the model, and with which
|
``{"kind", "args", "prompt"}`` to ``calls.jsonl`` so a test can prove what did
|
||||||
``LEETCODE_COACH_LOG`` in its env.
|
and did not reach the model, and with which ``LEETCODE_COACH_LOG`` in its env.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@ -16,6 +16,7 @@ import json
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
@ -33,6 +34,7 @@ def main() -> int:
|
|||||||
counter.write_text(str(used + 1), encoding="utf-8")
|
counter.write_text(str(used + 1), encoding="utf-8")
|
||||||
script = json.loads((root / "script.json").read_text(encoding="utf-8"))
|
script = json.loads((root / "script.json").read_text(encoding="utf-8"))
|
||||||
answer = script[kind][used]
|
answer = script[kind][used]
|
||||||
|
time.sleep(float(answer.get("sleep", 0)))
|
||||||
if "exit" in answer:
|
if "exit" in answer:
|
||||||
sys.stderr.write(answer.get("stderr", ""))
|
sys.stderr.write(answer.get("stderr", ""))
|
||||||
return int(answer["exit"])
|
return int(answer["exit"])
|
||||||
|
|||||||
68
leetcode_coach/leetcode_coach/tests/_live_relay.py
Normal file
68
leetcode_coach/leetcode_coach/tests/_live_relay.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
"""Dev harness: the real relay on loopback, every outside dependency faked.
|
||||||
|
|
||||||
|
``python3 -m leetcode_coach.tests._live_relay PORT DIR [PACE_S]`` serves the
|
||||||
|
real `Relay` (lane, backend, HTTP API, phone mirror) on ``127.0.0.1:PORT``
|
||||||
|
so the app's own transport can be driven against it
|
||||||
|
(``app/tool/coach_live_check.sh``). Faked, so nothing real is read or
|
||||||
|
written: claude (``LEETCODE_CLAUDE_BIN``, set by the caller), the statement
|
||||||
|
fetch, the LeetCode Accepted probe, Anki (dry run), Ollama (the discard
|
||||||
|
port) and Firebase (an in-process `FakeRtdb`). Session logs and the relay's
|
||||||
|
own files go under ``DIR``. Writes ``DIR/ready`` once listening and runs
|
||||||
|
until SIGTERM / SIGINT.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from leetcode_coach import local_backend, progress
|
||||||
|
from leetcode_coach.relay.app import Relay
|
||||||
|
from leetcode_coach.relay.coach import Deps
|
||||||
|
from leetcode_coach.relay.probe import AcceptedProbe
|
||||||
|
from leetcode_coach.relay.rtdb import Rtdb
|
||||||
|
from leetcode_coach.tests._fake_rtdb import FakeRtdb
|
||||||
|
from leetcode_coach.tests._relay_statements import MISSING_NUMBER
|
||||||
|
from leetcode_coach.tests._relay_support import FakeProbe
|
||||||
|
|
||||||
|
DEAD_OLLAMA = "http://127.0.0.1:9"
|
||||||
|
REAL_PORT = 8777
|
||||||
|
WITH_PACE = 3
|
||||||
|
USAGE = "usage: _live_relay PORT DIR [PACE_S]"
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv: list[str]) -> int:
|
||||||
|
"""Serve until a signal; 2 on bad arguments."""
|
||||||
|
if len(argv) not in {WITH_PACE - 1, WITH_PACE} or not argv[0].isdigit():
|
||||||
|
sys.stderr.write(USAGE + "\n")
|
||||||
|
return 2
|
||||||
|
port, root = int(argv[0]), Path(argv[1])
|
||||||
|
if port == REAL_PORT:
|
||||||
|
sys.stderr.write("refusing the real relay's port\n")
|
||||||
|
return 2
|
||||||
|
pace = float(argv[2]) if len(argv) == WITH_PACE else 3.0
|
||||||
|
os.environ[progress.SESSIONS_ENV] = str(root / "sessions")
|
||||||
|
local_backend.OLLAMA_URL = DEAD_OLLAMA
|
||||||
|
deps = Deps(
|
||||||
|
state_dir=root / "relay",
|
||||||
|
fetch=lambda _slug: ("Missing Number", MISSING_NUMBER),
|
||||||
|
probe=AcceptedProbe(FakeProbe()),
|
||||||
|
cards_dry_run=True,
|
||||||
|
)
|
||||||
|
relay = Relay(deps, port=port, pace_s=pace)
|
||||||
|
fake = FakeRtdb.start()
|
||||||
|
signal.signal(signal.SIGTERM, lambda *_: relay.stop_event.set())
|
||||||
|
signal.signal(signal.SIGINT, lambda *_: relay.stop_event.set())
|
||||||
|
relay.start()
|
||||||
|
relay.link_phone(Rtdb(fake.url, lambda: "live-check"))
|
||||||
|
(root / "ready").write_text(str(relay.port), encoding="utf-8")
|
||||||
|
relay.stop_event.wait()
|
||||||
|
relay.stop()
|
||||||
|
fake.stop()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main(sys.argv[1:]))
|
||||||
@ -84,6 +84,16 @@ def test_step_two_attempts_count_incomplete_lists_and_fail_grades() -> None:
|
|||||||
assert phase.step2_attempts(events) == 3
|
assert phase.step2_attempts(events) == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_force_is_not_a_step_two_try() -> None:
|
||||||
|
"""A force repeats the last try's grade (`fail`); it is no try itself.
|
||||||
|
|
||||||
|
Measured against the live relay 2026-10-23: three named-a-tool fails and
|
||||||
|
a force showed ``attempts: 4`` in the state.
|
||||||
|
"""
|
||||||
|
fails = [_grade(2, "fail"), _grade(2, "fail"), _grade(2, "fail")]
|
||||||
|
assert phase.step2_attempts([*fails, _grade(2, "fail", forced=True)]) == 3
|
||||||
|
|
||||||
|
|
||||||
def _gate(log: Path, answers: list[bool] | None = None) -> phase.PhaseGate:
|
def _gate(log: Path, answers: list[bool] | None = None) -> phase.PhaseGate:
|
||||||
asked: list[str] = []
|
asked: list[str] = []
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user