Skip to content

parseSseChunk does not unwrap the SSE envelope — tool_result AND done diverge from Python (TS↔Python drift) #53

Description

@AndreLFSMartins

Summary

parseSseChunk in packages/core/src/session.ts assigns the entire SSE data object directly for envelope-style events instead of unwrapping the inner payload the way the Python SDK does. This affects two event types (same root cause):

Event TS (parseSseChunk) Python (_parse_stream_event)
tool_result toolCall: data (whole object) raw.get("toolCall") → inner ToolCallRecord
done result: data as SendResult (whole object) raw.get("result") → inner SendResult

Python (packages/python/src/codespar/_async_session.py) and its tests (packages/python/tests/test_streaming.py) treat the canonical wire payload as { "type": "<evt>", "toolCall"|"result": { … } }. TS does not unwrap, so against that canonical payload:

  • tool_resultevent.toolCall.tool_name is undefined (record is one level deeper).
  • doneevent.result.message is undefined (SendResult is one level deeper).

A single backend payload cannot satisfy both SDKs for either event. Sibling of #51 (malformed SSE); same family of parseSseChunk wire drift.

Consequence

Any TS sendStream consumer doing event.toolCall.tool_name or event.result.message (the documented StreamEvent shape in @codespar/types) gets undefined on canonical backend payloads — a silent logic failure, not a network error. Forbidden by CLAUDE.md ("NEVER let TS + Python drift").

Decision needed

Confirm the backend's real tool_result and done data shapes (codespar-enterprise Fastify routes), then align parseSseChunk to unwrap data.toolCall / data.result (mirroring Python) — or, if the backend truly sends the bare objects, stop unwrapping in Python. Parser/contract change → escalated for a maintainer decision, not changed unilaterally.

Acceptance criteria

  • TS and Python yield an equivalent ToolCallRecord (tool_result) and SendResult (done) from the same canonical payloads, with regression tests on both sides using identical fixtures.

Test coverage status

PR #52 pins both as narrow drift tripwires (normal passing tests asserting the current TS-wrapped shape; they fail loudly when the parser is aligned, forcing this issue to be closed deliberately). No parser change in #52 (test-only).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions