MCPcopy Create free account
hub / github.com/RawdogReverend/TermNet / StreamCapture

Class StreamCapture

backend/termnet/main.py:18–77  ·  view source on GitHub ↗

Captures stdout from agent and streams it to websocket without dropping numeric content

Source from the content-addressed store, hash-verified

16logging.getLogger('websockets.protocol').setLevel(logging.CRITICAL)
17
18class StreamCapture:
19 """Captures stdout from agent and streams it to websocket without dropping numeric content"""
20
21 def __init__(self, websocket):
22 self.websocket = websocket
23 self.buffer = ""
24 self.original_stdout = sys.stdout
25 self.in_tool_execution = False
26 self.response_started = False
27
28 def write(self, text):
29 self.buffer += text
30 asyncio.create_task(self.process_buffer())
31
32 def flush(self):
33 self.original_stdout.flush()
34
35 async def process_buffer(self):
36 if not self.buffer:
37 return
38
39 text = self.buffer
40 self.buffer = ""
41
42 # Tool execution detection
43 if "🛠️ Executing tool:" in text or "Executing tool:" in text:
44 self.in_tool_execution = True
45 try:
46 await self.websocket.send(json.dumps({
47 "type": "tool_execution",
48 "message": "Processing with tools...",
49 "timestamp": time.time()
50 }))
51 except:
52 pass
53 return
54
55 if self.in_tool_execution:
56 # End tool execution once normal text comes in
57 if not ("Args:" in text or "command" in text or "action" in text):
58 self.in_tool_execution = False
59
60 # ✅ Do NOT strip here – just send raw text
61 if text:
62 try:
63 if not self.response_started:
64 await self.websocket.send(json.dumps({
65 "type": "response_start",
66 "timestamp": time.time()
67 }))
68 self.response_started = True
69
70 await self.websocket.send(json.dumps({
71 "type": "response_chunk",
72 "chunk": text, # ← raw text, spaces preserved
73 "timestamp": time.time()
74 }))
75 except:

Callers 1

stream_agent_responseMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected