feat: add hash routing for pushy agents
Some checks failed
tamq-ci / test (push) Failing after 6s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
tegwick 2026-08-25 00:08:57 +02:00
parent 00f04da5f6
commit e284c9f63c
16 changed files with 233 additions and 49 deletions

View file

@ -242,10 +242,10 @@ def test_real_tmux_pushy_mode_submits_one_shell_safe_input(tmp_path, monkeypatch
service = Service(store=store)
service._deliver_once()
expected = f"#flex-auth: What's next?\\x0asecond [{message_id}]"
expected = f"# from flex-auth: What's next?\\x0asecond [{message_id}]"
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
capture = manager._run("capture-pane", "-p", "-t", target)
capture = manager._run("capture-pane", "-p", "-J", "-t", target)
if expected in capture:
break
time.sleep(0.05)
@ -254,8 +254,128 @@ def test_real_tmux_pushy_mode_submits_one_shell_safe_input(tmp_path, monkeypatch
assert store.db.execute("SELECT COUNT(*) FROM leases").fetchone()[0] == 0
service._deliver_once()
repeated_capture = manager._run("capture-pane", "-p", "-t", target)
repeated_capture = manager._run("capture-pane", "-p", "-J", "-t", target)
assert repeated_capture.count(expected) == 1
finally:
store.close()
manager._run("kill-server", check=False)
@pytest.mark.skipif(shutil.which("tmux") is None, reason="tmux is not installed")
def test_real_tmux_hash_route_pushes_once_without_feedback(tmp_path, monkeypatch):
repo_a = tmp_path / "railiance-platform"
repo_b = tmp_path / "activity-core"
bin_dir = tmp_path / "bin"
for path in (repo_a, repo_b, bin_dir):
path.mkdir()
gita = bin_dir / "gita"
gita.write_text(
"#!/bin/sh\n"
"if [ \"$1\" = ls ]; then printf 'railiance-platform activity-core\\n'; exit 0; fi\n"
"exit 2\n",
encoding="utf-8",
)
gita.chmod(0o755)
fixture = tmp_path / "agent_fixture.py"
fixture.write_text(
"import sys\n"
"print('AGENT-READY', flush=True)\n"
"for line in sys.stdin:\n"
" print('AGENT:' + line.rstrip('\\r\\n'), flush=True)\n",
encoding="utf-8",
)
project_src = str(Path(__file__).resolve().parents[1] / "src")
existing_pythonpath = os.environ.get("PYTHONPATH")
monkeypatch.setenv(
"PYTHONPATH",
project_src if not existing_pythonpath else f"{project_src}:{existing_pythonpath}",
)
monkeypatch.setenv("PATH", f"{bin_dir}:{os.environ['PATH']}")
monkeypatch.setenv("TAMQ_STATE_DIR", str(tmp_path / "state"))
socket_name = f"tamq-hash-{os.getpid()}-{uuid4().hex[:8]}"
session = f"tamq-hash-{uuid4().hex[:8]}"
monkeypatch.setenv("TAMQ_TMUX_SOCKET", socket_name)
manager = TmuxManager(
session,
tmux_command=("tmux", "-L", socket_name),
tamq_command=(sys.executable, "-m", "tamq.cli"),
command_dir=tmp_path / "commands",
)
plan = LaunchPlan(
("railiance-platform", "activity-core"),
{
"railiance-platform": str(repo_a),
"activity-core": str(repo_b),
},
(sys.executable, str(fixture)),
)
store = None
try:
endpoint = manager.ensure_plan(plan, tap=True)
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
captures = {
repo: manager._run("capture-pane", "-p", "-t", f"{session}:{repo}")
for repo in plan.repos
}
if all("AGENT-READY" in output for output in captures.values()):
break
time.sleep(0.05)
assert all("AGENT-READY" in output for output in captures.values())
store = Store(tmp_path / "state" / "tamq.sqlite3")
store.register_endpoint(
endpoint.instance_key,
endpoint.pid,
endpoint.session,
endpoint.repos,
"pushy",
)
manager._run(
"send-keys",
"-t",
f"{session}:railiance-platform",
"-l",
"--",
"#activity-core: Hello!",
)
manager._run("send-keys", "-t", f"{session}:railiance-platform", "Enter")
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
rows = store.list()
if rows:
break
time.sleep(0.05)
assert len(rows) == 1
row = rows[0]
assert row["sender_repo"] == "railiance-platform"
assert row["target_repo"] == "activity-core"
assert row["body"] == "Hello!"
assert row["endpoint_id"] == endpoint.instance_key
service = Service(store=store)
service._deliver_once()
expected = f"# from railiance-platform: Hello! [{row['message_id']}]"
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
target_capture = manager._run(
"capture-pane", "-p", "-J", "-t", f"{session}:activity-core"
)
if f"AGENT:{expected}" in target_capture:
break
time.sleep(0.05)
assert f"AGENT:{expected}" in target_capture
assert store.list()[0]["state"] == "injected"
service._deliver_once()
time.sleep(0.1)
assert len(store.list()) == 1
assert manager._run(
"capture-pane", "-p", "-J", "-t", f"{session}:activity-core"
).count(f"AGENT:{expected}") == 1
finally:
if store is not None:
store.close()
manager._run("kill-server", check=False)