fix(examples): robust streaming example + streaming integration tests#6
Merged
Conversation
…on tests The streaming example could panic (`index out of range [0]`) when the stream produced no output — e.g. a transient empty/error response on a cold gRPC connection. Two robustness bugs: - the Iterator loop checked `!ok` before the error, silently swallowing a real gRPC status instead of surfacing it; - `acc.Response().GetOutputs()[0]` had no length guard. Rewrite the example to drain via `stream.Recv()` (io.EOF to end, any other error is fatal and surfaced) and guard the final output access, so it fails with a clear message rather than a panic. Apply the same guard to the README snippet. Add reproducible integration tests under `integration/` (build tag `integration`, skipped without XAI_API_KEY): repeated fresh-client streaming and the exact example pattern, asserting every run yields non-empty content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shanev
added a commit
that referenced
this pull request
Jul 2, 2026
Follow-up to #6 (which was merged without a codex pass). Codex found the fix was not faithfully proven or documented: - integration/streaming_acceptance_test.go: the test used the swallow-prone Iterator loop (!ok checked before the error) — the very bug it guards against — and did not mirror the shipped example (which uses stream.Recv). Rewrite it to drain via Recv exactly like the example, surface non-EOF errors, and bound each run with a 60s timeout so a stuck stream fails instead of hangs. - README.md: match the example's zero-output handling (log.Fatal, diagnosable) instead of silently doing nothing; use errors.Is(err, io.EOF); correct the "iterator helper" description to stream.Recv. - docs/tutorials/streaming.md: the Iterator section still showed the unsafe pattern (error swallowed via !ok, unguarded GetOutputs()[0]). Fix the ordering (surface real errors before breaking on !ok) and guard the final access. make ci green; the acceptance test passes 20/20 fresh streams against the API. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shanev
added a commit
that referenced
this pull request
Jul 2, 2026
* fix: address pre-release codex review of v0.1.3 A pre-tag codex review found release blockers and leftover instances of the streaming bugs #6/#7 fixed elsewhere: - Version was still 0.1.1 in two places (client.go, transport's default User-Agent) and would have shipped in a v0.1.3 tag. Move it to a single internal/version package referenced by both so they cannot drift; bump to 0.1.3. - integration/stream_test.go and examples/tool_call still swallowed non-EOF iterator errors (!ok checked before err); tool_call also had an unguarded GetOutputs()[0] panic. Fix ordering and guard, matching examples/streaming. - docs/tutorials/streaming.md silently ignored a zero-output stream while the README and example fail explicitly; make it consistent. - README ForEachChunk snippet reused an already-drained stream; show creating a fresh stream and use errors.Is for EOF. - examples/streaming: prompt now asks for an eight-line poem so the demo visibly streams token-by-token instead of finishing in a blink. make ci green; full integration suite passes live (20-run acceptance + TTFT test); example verified streaming with the new prompt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: sweep remaining unsafe snippet patterns flagged by codex Second codex pass on the v0.1.3 release found the same classes of issue in more release-facing snippets. Sweep all of them: - Guard every GetOutputs()[0] in README + docs (unary, deferred, accumulator finals in responses.md and tool-doc-search.md). - Stop swallowing errors in snippets: CreateStream / Create / Retrieve / Delete / StartDeferred / Documents.Search / ToolResponseMessage now check errors instead of `, _ :=`. - Tool Call Events snippet: check CreateStream error and non-EOF Recv errors (was looping over nil chunks on a mid-stream error). - ForEachChunk snippets (README + tutorial) create a fresh stream (a stream can only be consumed once) and tolerate io.EOF via errors.Is. - README callback snippet no longer references an undefined `req`. Repo-wide sweep confirms no remaining `, _ := client.` or unguarded GetOutputs()[0] in README, docs/, or examples/. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs+example: final codex sweep; stream reasoning deltas in the demo Third codex pass findings, all addressed: - performance.md, README tool/search snippets, tool-doc-search.md: stop swallowing errors from NewClient / FunctionTool / WebSource / Parameters / registry.Handle. - quickstarts.md: guard embeddings/images result indexing. - Make snippets compile as complete blocks: use or explicitly discard declared values (stored, full, msg). examples/streaming: TTFT investigation showed grok-4.3 streams typed reasoning deltas ~0.6s after the request, ~3-7s before the first answer token. Print the reasoning trace dimmed, then the answer — output starts immediately, and it demonstrates the typed-chunk advantage (reasoning vs content are separate fields, no parsing). Replace the duplicate final-answer print with an accumulator stats line (tokens + model). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: handle RequireStoredRequests error; complete replay-harness snippets Round-4 codex findings: RequireStoredRequests is fallible (error was dropped), and both replay snippets left client/err dangling. Check the errors and close the client. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * examples: shorten the done line so it doesn't wrap in a standard terminal Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
The streaming example (
examples/streaming) could panic (index out of range [0] with length 0) when a stream produced no output — reproduced intermittently on a freshgo run(cold gRPC connection returning a transient empty/error response). That's the headline example crashing at launch.Two robustness bugs:
Iteratorloop checked!okbefore the error, so a real gRPC status was silently swallowed instead of surfaced.acc.Response().GetOutputs()[0]had no length guard.Changes
examples/streaming/main.go— drain viastream.Recv()(io.EOF ends the loop; any other error is fatal and surfaced), and guard the final output access → fails with a clear message instead of a panic. Verified 8/8 clean fresh runs.README.md— same guard on the streaming snippet (+ fixed indentation).integration/— new reproducible integration tests (build tagintegration, skipped withoutXAI_API_KEY): repeated fresh-client streaming and the exact example pattern, asserting every run yields non-empty content. Gives the headline feature real coverage.make cigreen (build, test, vet, govulncheck 0, buf lint).🤖 Generated with Claude Code