Lightning.Tesla.Adapter.Finch (Lightning v2.19.0-pre)
View SourceEnough of Tesla's Finch adapter for the Apollo client, with the failure reason preserved on a streamed response.
Not a faithful copy: it drops upstream's build/4 clauses for multipart,
stream and function request bodies, and hands the body to Finch.build/4 as
it stands. Anything but a plain body therefore fails further down, in Mint,
rather than here. Apollo sends JSON.
Upstream's streaming path returns nil from its Stream.unfold for a
mid-stream error, a mid-stream timeout, and a clean end alike, discarding the
reason. Every AI chat therefore ended up reporting "Stream ended without
complete response" whatever had actually happened - a hung Apollo, a severed
connection, and a genuinely short answer were indistinguishable.
A sentinel inside the stream is not an option: Tesla.Middleware.SSE
concatenates elements as binaries and would fail on anything else. But the
Stream.unfold body runs in the calling process, so the reason is left in
that process's dictionary and read back with take_stream_error/0 once the
stream has been consumed.
Also passes :request_timeout through to Finch, which the 1.18.3 we pin
drops.
Both are fixed upstream, in separate releases: the option pass-through in
1.19.0 (tesla#879), the
stream reason in 1.21.1
(tesla#912). This module
exists only because we pin ~> 1.18.2; bumping to 1.21.1 deletes it, and the
reason then arrives as a raised Tesla.Error rather than through
take_stream_error/0, so the caller in Lightning.AiAssistant changes with
it. Tracked in #5080.
Summary
Functions
Why the last streamed response stopped, if it stopped badly.
Functions
@spec take_stream_error() :: term() | nil
Why the last streamed response stopped, if it stopped badly.
Returns nil when the stream ended cleanly. Reading clears it, so a later
request cannot pick up an earlier one's failure.