Skip to content

feat: add top level async streaming - #655

Merged
jakelorocco merged 7 commits into
mainfrom
jal/finalize-async
Apr 2, 2026
Merged

feat: add top level async streaming#655
jakelorocco merged 7 commits into
mainfrom
jal/finalize-async

Conversation

@jakelorocco

@jakelorocco jakelorocco commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Misc PR

Type of PR

  • Bug Fix
  • New Feature
  • Documentation
  • Other

Description

Top level async functions (aquery, ainstruct, aact) can now return uncomputed ModelOutputThunks. These will be uncomputed by default if strategy=None.

Other top level functions (sync and atransform/achat, etc...) can only return ComputedModelOutputThunks (since their actions rely on the computed result).

ComputedModelOutputThunks are a new type that are just mots + is_computed == True. This allows for better type hinting of results. Sampling results are typed with these computed mots for the same reason as the sync functions.

Added infrastructure for supporting type-hinting tests to ensure future changes don't result in regressions. (Note: only added for the new type hinting, will need to retroactively add for older type hints.)

I've additionally added an m fix async command that can analyze python files with mellea code and ensure changes caused by the top level async change are fixed if necessary. I'd advise looking at the command description to see all the options; but it will correctly fix all changes in the current version of the code. In the future, if someone relies on passing an uncomputed mot around from those top-level async functions, there may be false positives that get fixed. The command --help message adds this context.

Adds an example for top level async streaming / lazy computation.

Testing

  • Tests added to the respective file if code was changed
  • New code has 100% coverage if code as added
  • Ensure existing tests and github automation passes (a maintainer will kick off the github automation when the rest of the PR is populated)

@github-actions

Copy link
Copy Markdown
Contributor

The PR description has been updated. Please fill out the template for your PR to be reviewed.

@mergify

mergify Bot commented Mar 16, 2026

Copy link
Copy Markdown

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert|release)(?:\(.+\))?:

@jakelorocco
jakelorocco marked this pull request as ready for review March 16, 2026 15:04
@jakelorocco
jakelorocco requested review from a team and nrfulton as code owners March 16, 2026 15:04
Comment thread mellea/core/base.py Outdated
Comment thread mellea/core/base.py Outdated
@planetf1 planetf1 added documentation Improvements or additions to documentation and removed documentation Improvements or additions to documentation labels Mar 17, 2026
@jakelorocco
jakelorocco force-pushed the jal/finalize-async branch 2 times, most recently from 0bb530f to 7cfb1ce Compare March 17, 2026 19:15

@psschwei psschwei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

minor nits but otherwise looks good to me

Comment thread test/core/test_streaming_sync_functions.py Outdated
Comment thread mellea/core/base.py Outdated
Comment thread mellea/core/base.py Outdated

@nrfulton nrfulton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The main thing we're still missing is an articulation of the motivation for this change (even in the PR description). Otherwise looks good. I did not review the CLI tool.

Comment thread cli/fix/__init__.py
Comment thread cli/fix/commands.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not reviewed.

Comment thread cli/fix/fixer.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not reviewed.

Comment thread cli/m.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not reviewed.

Comment thread test/cli/test_fix.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

not reviewed.

Comment thread docs/examples/async/async-with-lazy-compute.py
strategy=extracted.strategy,
format=self._response_model,
model_options=extracted.model_options,
await_result=True,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

might want to document in the docstring that setting this to false is probably a bad idea unless you really understand what you're doing...

@jakelorocco jakelorocco Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This specific invocation site will always be True (since generative slots rely on parsing the output).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When we chatted about the implementation of this, we agreed that the default should actually be lazy. So it's False by default. Most people won't be impacted though since strategies / sync will auto-compute this anyways.

Comment thread mellea/stdlib/functional.py
@jakelorocco

jakelorocco commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

The main thing we're still missing is an articulation of the motivation for this change (even in the PR description). Otherwise looks good. I did not review the CLI tool.

This needs to be added if we want to enable lazily computed model output thunks and streaming when utilizing mfuncs and sessions. Otherwise, streaming and lazy compute is limited to backend.generate calls.

I will find somewhere in the docs / examples to add this explanation. Done

@github-actions github-actions Bot added the enhancement New feature or request label Mar 26, 2026
@jakelorocco
jakelorocco force-pushed the jal/finalize-async branch 4 times, most recently from 812124b to d23fb9e Compare March 26, 2026 18:28
@nrfulton
nrfulton self-requested a review April 2, 2026 17:34

@nrfulton nrfulton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm

@jakelorocco
jakelorocco added this pull request to the merge queue Apr 2, 2026
Merged via the queue into main with commit deb9d24 Apr 2, 2026
8 checks passed
@jakelorocco
jakelorocco deleted the jal/finalize-async branch April 2, 2026 18:14
akihikokuroda added a commit to akihikokuroda/mellea that referenced this pull request May 27, 2026
* feat: add top level async streaming

Co-authored-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>

* feat: add examples for top level streaming

* fix: pr comments

* fix: pr comments and add simpler example

* fix: issues with docs gen / quality

* feat: add test files for mypy to catch overload typing issues

---------

Co-authored-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: make asynchronous functions / session functions return uncomputed model output thunks

4 participants