connector::output — responses and streams
The types returned by the Connector request methods.
ChatOutput — one-shot reply
pub struct ChatOutput { /* raw, message */ }
impl ChatOutput {
pub fn message(&self) -> &str // extracted text of the model's reply
pub fn raw(&self) -> &str // raw JSON response, unmodified
}
raw() is the escape hatch: usage, finish_reason, tool_calls, and anything
else the API returned is there to parse manually.
StreamChunk — one item in a stream
pub struct StreamChunk { /* raw, token, reasoning, finish_reason, thinking_blocks, tool_call */ }
impl StreamChunk {
pub fn token(&self) -> &str // text delta
pub fn reasoning(&self) -> &str // reasoning/thinking delta
pub fn thinking_blocks(&self) -> Option<&[ClaudeThinkingBlock]> // Claude only
pub fn finish_reason(&self) -> Option<&str> // "stop", "length", ...
pub fn tool_call(&self) -> Option<&NativeToolCall> // provider-delivered structured call
}
reasoning()is the streamed thinking text (many reasoning models emit it separately from the visible token). The TUI shows it in a collapsible “Thought” block and never echoes it back to the model.thinking_blocks()carries Claude extended-thinking blocks (text + signature) for verbatim replay — seeClaudeThinkingBlock.finish_reason()isSomeonly on the final chunk:"stop","length","content_filter","tool_calls", or provider-specific values.tool_call()carries a tool call the provider delivered NATIVELY (structuredtool_calls/tool_use/functionCallparts — id, name, the raw accumulatedargumentsJSON text, and the Geminithought_signaturewhen present). The harness routes it straight to the extractor’s native validation funnel (ExtractAction::register_native_call) — no inline-JSON round trip. It isNonefor text/reasoning chunks and for the legacy inline-JSON path (local providers, which arrive astokentext).
ChatStream — the streaming response
pub struct ChatStream { /* boxed async stream + last_raw */ }
impl Stream for ChatStream { type Item = Result<StreamChunk, ConnectorError>; }
impl ChatStream {
pub async fn raw(&mut self) -> Result<&str, ConnectorError> // last SSE frame
}
Yields Result<StreamChunk> items (use tokio_stream::StreamExt to drive
it). After the stream ends, raw() returns the last SSE data: frame —
typically the one carrying usage, finish_reason, and the concatenated
content. If the stream was not fully consumed, raw() drains it first.
Returns StreamTerminated if the stream ended without ever receiving a
frame (e.g. connection reset before any data).
LsOutput + ModelInfo — model listing
pub struct LsOutput { /* raw, models */ }
impl LsOutput {
pub fn models(&self) -> &[ModelInfo]
pub fn raw(&self) -> &str
}
pub struct ModelInfo { id: String }
impl ModelInfo { pub fn id(&self) -> &str }
Connector::list_models() returns the provider’s model list with the raw
JSON alongside.
Next: error — ConnectorError and classification.
Summary
ChatOutputwraps a one-shot reply withmessage()(extracted text) andraw()(unmodified JSON response).StreamChunkrepresents one streaming item withtoken()(text delta),reasoning()(thinking delta),thinking_blocks()(Claude extended thinking),finish_reason()(final chunk only), andtool_call()(a provider-delivered native tool call, validated directly by the harness without a text round trip).ChatStreamis the streaming response implementingStream<Item = Result<StreamChunk>>; after the stream ends,raw()returns the last SSE frame (usage, finish_reason, etc.).LsOutputandModelInfohandle model listing:list_models()returns available models with raw JSON alongside.thinking_blocks()carries Claude extended-thinking blocks for verbatim replay (cryptographic signature validation);skip_serializing_ifkeeps this off other providers’ wire formats.- Streaming uses
tokio_stream::StreamExtto drive; incomplete streams returnStreamTerminatedwhen no frame was ever received.