packages/client/src/client-handle.ts:60-75 collects buffered result_chunk events for a job and concatenates them. The encoding is sampled from sorted[0]?.encoding ?? "utf8", and the entire batch is then either base64-decoded or string-joined based on that single value. The wire schema in packages/core/src/messages/events.ts allows encoding per chunk, so a runtime that interleaves a utf8 text chunk with a base64 binary chunk produces valid wire frames; the client mis-decodes the second chunk by treating its base64 text as raw output (or, in the reverse, tries to base64-decode utf8 chunks and produces garbage). The TSDoc on collectChunks in packages/client/src/types.ts makes no mention of "single encoding only" — the contract reads as if mixed encodings are supported.
There is a related contradiction in the TSDoc: collectChunks is documented to "throw if the job did not stream a chunked result", but the implementation returns "" for the case chunks === undefined || chunks.length === 0 and only throws when result_id is missing on the terminal job.result. Either tighten the implementation or fix the comment.
Fix prompt: change collectChunks to decode each chunk by its own encoding field. Concretely, build the result as Buffer.concat(sorted.map((c) => c.encoding === "base64" ? Buffer.from(c.data, "base64") : Buffer.from(c.data, "utf8"))) for the binary case, and return a string only when every chunk's encoding is utf8. Make the return type string | Buffer already covers both shapes. Update the TSDoc to describe the per-chunk decoding rule and clarify the empty/missing-stream behavior to match the implementation (or change the implementation to throw, whichever matches the spec). Add tests in packages/client/test/ covering all-utf8, all-base64, mixed, single-chunk, empty-stream, and unknown-encoding inputs.
packages/client/src/client-handle.ts:60-75collects bufferedresult_chunkevents for a job and concatenates them. The encoding is sampled fromsorted[0]?.encoding ?? "utf8", and the entire batch is then either base64-decoded or string-joined based on that single value. The wire schema inpackages/core/src/messages/events.tsallowsencodingper chunk, so a runtime that interleaves autf8text chunk with abase64binary chunk produces valid wire frames; the client mis-decodes the second chunk by treating its base64 text as raw output (or, in the reverse, tries to base64-decode utf8 chunks and produces garbage). The TSDoc oncollectChunksinpackages/client/src/types.tsmakes no mention of "single encoding only" — the contract reads as if mixed encodings are supported.There is a related contradiction in the TSDoc:
collectChunksis documented to "throw if the job did not stream a chunked result", but the implementation returns""for the casechunks === undefined || chunks.length === 0and only throws whenresult_idis missing on the terminaljob.result. Either tighten the implementation or fix the comment.Fix prompt: change
collectChunksto decode each chunk by its ownencodingfield. Concretely, build the result asBuffer.concat(sorted.map((c) => c.encoding === "base64" ? Buffer.from(c.data, "base64") : Buffer.from(c.data, "utf8")))for the binary case, and return astringonly when every chunk's encoding isutf8. Make the return typestring | Bufferalready covers both shapes. Update the TSDoc to describe the per-chunk decoding rule and clarify the empty/missing-stream behavior to match the implementation (or change the implementation to throw, whichever matches the spec). Add tests inpackages/client/test/covering all-utf8, all-base64, mixed, single-chunk, empty-stream, and unknown-encoding inputs.