Repository navigation
fix(streams): release consumed completion payloads - #91
Merged
Merged
Conversation
Collaborator
Author
|
lgtm, releases consumed payloads while preserving manual history. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Streamfold 0.1.14 retains every completed SDK payload while a managed
readStructurediterator stays alive, even when the consumer discards each result andmaxActiveStreamsis 1. Long agent sessions consequently retain the text, parsed value, and snapshot of all previous calls.Reproduce with the added
managed-memory.test.js: consume 200 Vercel start/delta/end calls throughreadStructured, keep only weak references to their final values, pause before EOF, and force GC in a separate Node process. All 200 values stay alive before this change, versus only the current value for a custom adapter.Root cause
Built-in integrations keep a completion history for the manual
finish()API. Managed readers consumed the lifecycle updates but kept that same history until the integration was released.Change
Register each built-in integration's history in an internal weak map. Managed readers clear it after obtaining a batch, after EOF finalization, and during cleanup. Returned batches and consumer-owned results remain intact. Manual integrations keep their full history. Completed call IDs remain recorded for duplicate suppression; this does not claim constant memory for arbitrarily many IDs.
Custom integration objects are unchanged, and no public option or method is added.
Verification
SDK reader retained 200 payloadsand passes after it. It uses actual adapters, public values, weak references, and explicit GC, not internal history inspection. It also verifies all 200 manual completions remain available across repeatedfinish()calls.maxActiveStreams: 1. These are retained-object counts, not heap-byte or latency claims.pnpm release:check: 179 JavaScript tests and 11 Rust tests passed, plus types, syntax, Rust formatting, clippy, and package dry-run.pnpm bench, andpnpm bench:sdkpassed. No CPU speedup is claimed.Public surface
No public API, exports, dependencies, or types change. API guidance and changelog describe managed retention and the unchanged manual history contract.