feat: validated streaming refactor POC + Phase 2 epic breakdown#1409
feat: validated streaming refactor POC + Phase 2 epic breakdown#1409ajbozarth wants to merge 4 commits into
Conversation
Prototype of the Phase 1 streaming refactor: replaces the two-task stream_with_chunking + StreamChunkingResult with a single stream() consumed by a plain `async for`, driven on the caller's task. - core: add ModelOutputThunk.__aiter__/__anext__ wrapping astream() in the async-iterator protocol (generic, usable for plain streaming too) - stdlib: new streaming_poc.py with stream()/Streamer — chunking and per-chunk validation layered over the shared iteration protocol, with full-output validation on natural completion and STREAMING_START/END hooks firing on the single task Behavioral parity with stream_with_chunking (streaming_failures, failure_reason, exception handling) except early-exit full_text is delta-granular pending MOT-owned chunking. Ships without tests/docs and does not remove the existing stream_with_chunking path. Assisted-by: Claude Code Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
Wire the STREAMING_EVENT hook into the single-task stream() flow, reusing the Phase 1 event dataclasses. Events fire at the same lifecycle points as stream_with_chunking (QuickCheck/Chunk per chunk, StreamingDone, FullValidation, Error, Completed), now uniformly through one _emit_event path on the caller's task — no event queue, no task hand-off. CompletedEvent fires the hook like every other event (the old queue-only carve-out was a task-boundary workaround, unneeded here). No caller-facing events() API yet; that surface is the remaining open design question. Assisted-by: Claude Code Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
Add the epic-breakdown planning doc and the origin simplification proposal to docs/dev/ for team review alongside the POC on this branch. These are transient planning artifacts — intended to become GitHub issues and be removed from the branch before any merge to main. - streaming-phase2-plan.md: decomposes the remaining validated-streaming work into five items (refactor, stream_parsed_repr, multi-modal, sampling integration, agent-authoring) with dependencies, a POC status, and open decisions for the planning call. - streaming-simplification.md: the origin proposal (from an offline discussion between @psschwei and @ajbozarth), included verbatim as the seed for the refactor direction. Assisted-by: Claude Code Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
Exercises the validated-streaming prototype (mellea.stdlib.streaming_poc) end to end without Ollama, using a deterministic mock stream. Prints one block per case: plain streaming, per-chunk pass/fail, judge-style stream-end validation pass/fail, and mid-stream exception propagation — plus the real STREAMING_* hooks to show the single-task event lifecycle. Marked `# pytest: skip` (excluded from CI): it drives an unplugged prototype and pokes ModelOutputThunk internals, so it is verification scaffolding, not a usage example. Delete once the refactor lands and a real test suite replaces it. Assisted-by: Claude Code Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
|
cc @psschwei @jakelorocco @planetf1 @nrfulton @HendrikStrobelt this is the POC and design doc that will drive the streaming validation call next Tuesday for early review |
|
This is a good simplification of the original design — the two-task split isn't needed, since nothing ended up using the independent A few things worth deciding explicitly ahead of Tuesday rather than leaving open: 1. Item 1/2 gating. Doing item 1 without item 2 leaves a rough edge — on early exit, 2. Shim vs. hard break. A shim keeps the old orchestrator running alongside the new one — back to the complexity item 1 removes. Given how new the API is, a hard break seems better. 3. A vs. C fork (item 2). Multi-modal matters, so C over A. But item 1 should still just yield plain strings — mix the two changes now and we'll end up breaking things twice. 4. Making it genuinely support parallel consumers is a bigger job — buffering, per-consumer cursors, deciding what a late joiner sees. Worth checking if anyone actually needs that before building it; otherwise the guard's enough. |
|
Some notes from todays call that will drive the work moving forward:
Next steps: I will expand this POC to complete the refactor and that will drive further discussion on chunk ownership and state. I will also rewrite the EPIC plan pitch to address the above and that will drive a future sync. If I missed anything or got any details wrong post here and I'll make sure to factor them in. |
|
@psschwei @jakelorocco @planetf1 @nrfulton @HendrikStrobelt heads up I have update the phase 2 epic #1013 and split out subissues based on Tuesdays call. the first sub issue will replace this POC and the reaming sub issues has on-going discussion points spun out of open items from our call if you want to take a look and give input before I get to them |
Pull Request
Issue
Related to #1013
Description
Draft — POC + planning artifacts for review, not a merge candidate.
This PR exists to share a proof-of-concept and a proposed epic breakdown ahead of Phase 2 planning. It is intentionally not a finished feature: the code is a parallel prototype, not wired into the framework, with no test suite or telemetry integration yet. The goal is to give reviewers something concrete to react to before the work is decomposed into issues.
What's here, and why:
mellea/stdlib/streaming_poc.py+ModelOutputThunk.__aiter__). It demonstrates that validated streaming can be a single-taskasync forprimitive rather than the current background-task orchestration — validating the core architectural claim behind the proposed refactor. It lives alongside the existingstream_with_chunkingrather than replacing it.docs/dev/streaming-phase2-plan.md) decomposing the remaining validated-streaming work into separately-shippable items with dependencies and open decisions, plus the origin proposal (docs/dev/streaming-simplification.md) it grew from.docs/examples/streaming/validated_streaming_poc.py,# pytest: skip) that exercises the POC end-to-end without Ollama, since nothing else drives the unplugged prototype.What this PR is not: it does not refactor the existing code, is not API-stable, and may be substantially reworked or discarded as the plan is finalized. Treat the docs as the primary artifact and the code as evidence.
Testing
Attribution
Adding a new component, requirement, sampling strategy, or tool?