Skip to content

Commit 8be1868

Browse files
committed
fix: use iter_content instead of iter_lines for SSE stream parsing
iter_lines() buffers entire response before yielding, causing 0 lines to be read from long-running agentic tool streams. Changed to: - iter_content(chunk_size=None) for raw streaming - Manual line splitting with buffer - Break immediately when result found (agentic tools return single result) This allows processing SSE events as they arrive instead of waiting for stream completion.
1 parent 54360e0 commit 8be1868

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

test_http_agentic_tools.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -189,34 +189,45 @@ def send_request(self, payload, timeout=60):
189189
print(f" ⚠️ No session ID in headers: {list(response.headers.keys())}")
190190

191191
# Parse SSE stream for JSON-RPC responses
192+
# Use iter_lines with chunk_size to properly read streaming data
192193
result_data = None
193194
line_count = 0
194195

195-
for line in response.iter_lines(decode_unicode=True):
196-
line_count += 1
197-
if not line:
198-
continue
199-
200-
# Skip SSE comments
201-
if line.startswith(':'):
202-
continue
203-
204-
# SSE data events
205-
if line.startswith('data: '):
206-
data = line[6:] # Remove 'data: ' prefix
207-
try:
208-
event = json.loads(data)
209-
# Look for the final result
210-
if "result" in event:
211-
result_data = event
212-
# Don't break - keep reading to consume full stream
213-
elif "error" in event:
214-
print(f"❌ MCP error: {event['error']}")
215-
return None, time.time() - start_time
216-
except json.JSONDecodeError as e:
217-
print(f"⚠️ Failed to parse SSE data (line {line_count}): {e}")
218-
print(f" Data preview: {data[:200]}")
219-
continue
196+
# iter_lines can buffer - use raw iteration instead
197+
buffer = ""
198+
for chunk in response.iter_content(chunk_size=None, decode_unicode=True):
199+
if chunk:
200+
buffer += chunk
201+
# Process complete lines
202+
while '\n' in buffer:
203+
line, buffer = buffer.split('\n', 1)
204+
line = line.strip()
205+
line_count += 1
206+
207+
if not line:
208+
continue
209+
210+
# Skip SSE comments
211+
if line.startswith(':'):
212+
continue
213+
214+
# SSE data events
215+
if line.startswith('data: '):
216+
data = line[6:] # Remove 'data: ' prefix
217+
try:
218+
event = json.loads(data)
219+
# Look for the final result
220+
if "result" in event:
221+
result_data = event
222+
# For agentic tools, there's only one result - can break
223+
break
224+
elif "error" in event:
225+
print(f"❌ MCP error: {event['error']}")
226+
return None, time.time() - start_time
227+
except json.JSONDecodeError as e:
228+
print(f"⚠️ Failed to parse SSE data (line {line_count}): {e}")
229+
print(f" Data preview: {data[:200]}")
230+
continue
220231

221232
duration = time.time() - start_time
222233
if result_data:

0 commit comments

Comments
 (0)