MCPcopy Create free account
hub / github.com/agentforce314/clawcodex / _serve_stdio

Function _serve_stdio

src/entrypoints/agent_server_cli.py:120–186  ·  view source on GitHub ↗

Single-session stdio transport — the hermes route's local link. Pumps newline-delimited JSON between this process's stdin/stdout and the in-process agent, reusing ``make_spawn_agent``/``AgentHandle`` exactly as the WS pump does. There is no socket, so nothing can idle-time-out. ``stdout

(workspace: str, agent_config: AgentServerConfig)

Source from the content-addressed store, hash-verified

118
119
120async def _serve_stdio(workspace: str, agent_config: AgentServerConfig) -> int:
121 """Single-session stdio transport — the hermes route's local link.
122
123 Pumps newline-delimited JSON between this process's stdin/stdout and the
124 in-process agent, reusing ``make_spawn_agent``/``AgentHandle`` exactly as the
125 WS pump does. There is no socket, so nothing can idle-time-out. ``stdout`` is
126 RESERVED for JSON frames (diagnostics go to ``stderr``); ``stdin`` EOF — the
127 parent TUI going away — ends the session.
128 """
129 index_path = Path.home() / ".clawcodex" / "server-sessions.json"
130 index_path.parent.mkdir(parents=True, exist_ok=True)
131 manager = SessionManager(workspace=workspace, index_path=index_path)
132 info = manager.create_session(cwd=workspace)
133 spawn = make_spawn_agent(agent_config)
134 agent = await spawn(info.id, workspace, None) # emits system/init as its first frame
135 manager.mark_running(info.id)
136
137 loop = asyncio.get_running_loop()
138 out = sys.stdout
139
140 async def outbound() -> None:
141 """Agent → stdout: one JSON object per line, flushed."""
142 async for msg in agent.messages_from_agent():
143 try:
144 out.write(json.dumps(msg) + "\n")
145 out.flush()
146 except (BrokenPipeError, OSError):
147 return
148
149 # Inbound: a daemon thread reads stdin lines and dispatches them onto the
150 # loop (mirrors the existing threaded pattern). stdin EOF resolves `closed`.
151 closed: asyncio.Future[None] = loop.create_future()
152
153 def _resolve_closed() -> None:
154 if not closed.done():
155 closed.set_result(None)
156
157 def _read_stdin() -> None:
158 try:
159 for raw in sys.stdin:
160 line = raw.strip()
161 if not line:
162 continue
163 try:
164 parsed = json.loads(line)
165 except json.JSONDecodeError:
166 continue
167 if isinstance(parsed, dict):
168 asyncio.run_coroutine_threadsafe(agent.send_to_agent(parsed), loop)
169 except Exception: # noqa: BLE001 - any stdin error ends the session cleanly
170 pass
171 finally:
172 loop.call_soon_threadsafe(_resolve_closed)
173
174 threading.Thread(target=_read_stdin, name="agent-server-stdin", daemon=True).start()
175
176 out_task = loop.create_task(outbound())
177 try:

Callers 1

Calls 10

create_sessionMethod · 0.95
mark_runningMethod · 0.95
SessionManagerClass · 0.90
make_spawn_agentFunction · 0.90
outboundFunction · 0.85
spawnFunction · 0.50
startMethod · 0.45
waitMethod · 0.45
cancelMethod · 0.45
shutdownMethod · 0.45

Tested by

no test coverage detected