Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ async def process_response_body_buffer(buffer: bytearray):
# Handle both SSE format and plain JSON-RPC format
data = None

# Check if this is SSE format (starts with "event:" or "data:")
if text.strip().startswith(("event:", "data:")):
# Check if this is SSE format (starts with "id:", "event:", or "data:")
if text.strip().startswith(("event:", "data:", "id:")):
# Parse SSE format
lines = text.split("\n")
for line in lines:
Expand Down
25 changes: 25 additions & 0 deletions tests/test_tool_post_invoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,31 @@ async def test_process_response_body_buffer_with_sse_format(mock_envoy_modules,
assert response is not None


@pytest.mark.asyncio
async def test_process_response_body_buffer_with_sse_id_prefix(mock_envoy_modules, mock_manager):
"""SSE stream starting with 'id:' field is detected and parsed correctly."""
setup_response_mocks(mock_envoy_modules)
import src.server

setup_manager_with_result(mock_manager)
src.server.manager = mock_manager

tool_result = {
"jsonrpc": "2.0",
"id": 10,
"result": {"content": [{"type": "text", "text": "Echo: my password is secret"}]},
}
# SSE streams may begin with 'id:' before 'event:' or 'data:' lines
sse_body = f"id: sse-event-001\ndata: \n\nevent: message\nid: sse-event-002\ndata: {json.dumps(tool_result)}\n\n"
buffer = bytearray(sse_body.encode("utf-8"))
response = await src.server.process_response_body_buffer(buffer)

assert mock_manager.invoke_hook.called
payload = mock_manager.invoke_hook.call_args[0][1]
verify_payload_content(payload, tool_result["result"], "Echo: my password is secret")
assert response is not None


@pytest.mark.asyncio
async def test_process_response_body_buffer_multiple_chunks_scenario(mock_envoy_modules, mock_manager):
"""Multi-chunk buffer is assembled and processed as one unit."""
Expand Down
Loading