Files
aiturk-hermes-ide/tui_gateway/mobile_subagents.py
T

56 lines
2.4 KiB
Python

"""Read-only mobile subagent views, scoped to the invoking live session."""
import time
from pathlib import Path
def owned_records(session_id, transport, session, *, include_lineage=False):
from tools.delegate_tool import _active_subagents, _active_subagents_lock, _owns_subagent_record
if transport is None or session is None:
return []
with _active_subagents_lock:
records = [dict(row) for row in _active_subagents.values()]
return [row for row in records
if (row.get("owner_session_id") == session_id
and row.get("owner_transport") is transport
and row.get("owner_session_record") is session)
or (include_lineage and _owns_subagent_record(row, session.get("agent")))]
def roster(records):
fields = ("subagent_id", "parent_id", "depth", "goal", "delegation_id", "model",
"started_at", "status", "tool_count", "last_tool", "accepting_steer")
rows = []
for record in records:
row = {key: record[key] for key in fields if key in record}
started = record.get("started_at")
if isinstance(started, (int, float)):
row["elapsed_seconds"] = max(0, time.time() - started)
rows.append(row)
return {"subagents": rows, "delegations": []}
def transcript_tail(records, subagent_id):
result = {"subagent_id": subagent_id, "available": False, "text": "", "bytes_read": 0, "truncated": False}
record = next((r for r in records if r.get("subagent_id") == subagent_id), None)
if record is None:
return result
path = getattr(record.get("agent"), "_live_transcript_path", None)
if not isinstance(path, (str, Path)):
return result
try:
# Only the registry's own file is read; no client-supplied path is accepted.
from tools.delegation_live_log import live_transcript_root
path = Path(path)
root = live_transcript_root().resolve()
if path.is_symlink() or not path.resolve().is_relative_to(root):
return result
with path.open("rb") as stream:
size = stream.seek(0, 2)
stream.seek(max(0, size - 16384))
raw = stream.read(16384)
result.update(available=True, text=raw.decode("utf-8", errors="replace"),
bytes_read=len(raw), truncated=size > len(raw))
except OSError:
pass # A just-completed child's temporary transcript may already be gone.
return result