Skip to content

Add chat streaming for completions - #471

Closed
elimoss wants to merge 21 commits into
mainfrom
chat-streaming
Closed

Add chat streaming for completions#471
elimoss wants to merge 21 commits into
mainfrom
chat-streaming

Conversation

@elimoss

@elimoss elimoss commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

yield incremental completion tokens as they stream in from the provider followed by a LLMResult containing the completed Message or ToolRequestMessage. The former supports streaming UIs while the latter constitutes the canonical completion. existing calls in non-streaming contexts are unchanged.

also, since we are handling streams now, changed some types around iterators to require aclose so we can cleanly close provider streams when necessary. this is achieved with a ClosableAsyncIterator that narrowly requires aclose, and AsyncGenerator in cases where that is the actual return type

@elimoss
elimoss marked this pull request as ready for review July 17, 2026 23:35
Copilot AI review requested due to automatic review settings July 17, 2026 23:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new streaming API to LLMModel/LiteLLMModel that yields incremental text deltas from provider streaming, followed by a single canonical terminal LLMResult containing the completed Message/ToolRequestMessage (keeping existing non-streaming call paths intact).

Changes:

  • Introduces LLMModel.call_stream() and plumbing to request Chat Completions streaming with delta-yielding support.
  • Refactors Chat Completion parsing into _parse_chat_completion() and enhances custom tool parser type detection.
  • Improves stream lifecycle handling (aclose) and adds/updates tests + README docs for streaming behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/lmi/src/lmi/llms.py Adds call_stream, stream config validation, stream delta yielding in acompletion_iter, stream closure improvements, and parsing refactor.
packages/lmi/src/lmi/cost_tracker.py Adds TrackedStreamWrapper.aclose() to support contextlib.aclosing on tracked provider streams.
packages/lmi/tests/test_llms.py Adds realistic stream-chunk builders and comprehensive call_stream tests (text + tool call assembly + closure + validation/callback behavior).
packages/lmi/tests/test_dispatch.py Adds coverage ensuring _commit_stream closes the underlying source iterator when the committed stream is closed early.
packages/lmi/tests/test_cost_tracking.py Adds coverage ensuring TrackedStreamWrapper.aclose() forwards to the wrapped stream.
packages/lmi/README.md Fixes a typo and documents call_stream usage/semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/tests/test_llms.py
Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/src/lmi/llms.py Outdated

@sidnarayanan sidnarayanan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving to unblock, but can you do a pass on documentation?

Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/src/lmi/llms.py Outdated
Comment thread packages/lmi/src/lmi/llms.py Outdated
elimoss and others added 6 commits July 24, 2026 09:47
Require list[Message] on call_stream, matching call; the str convenience
stays on call_single. Stop setting seconds_to_first_token and
seconds_to_last_token in the call_stream path, since nothing reads them.
Explain why consumers must close the iterator early, and restore comments
and formatting that the streaming rewrite disturbed.
The streaming path skipped messages with no content, which drops a message
that holds only tool calls. The tool responses answering it are then left
without a request and providers reject the conversation. The non-streaming
path has always sent every message, so this makes the two match.
@elimoss

elimoss commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator Author

got through a prototype and it just wasn't really that much faster in practice.

@elimoss elimoss closed this Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants