docs: rewrite all hand-written docs for action-first clarity - #1056
docs: rewrite all hand-written docs for action-first clarity#1056tombeckenham wants to merge 3 commits into
Conversation
Cut ~12k lines of preamble and marketing across 141 pages. Lead with "if you need X, do Y", numbered steps, and code-first guidance. Leave auto-generated reference docs alone.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughChangesDocumentation consolidation
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit 6613175
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-byteplus
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-codex
@tanstack/ai-devtools-core
@tanstack/ai-durable-stream
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-grok-build
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-mcp
@tanstack/ai-memory
@tanstack/ai-mistral
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@tanstack/ai-persistence
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-sandbox
@tanstack/ai-sandbox-cloudflare
@tanstack/ai-sandbox-daytona
@tanstack/ai-sandbox-docker
@tanstack/ai-sandbox-local-process
@tanstack/ai-sandbox-sprites
@tanstack/ai-sandbox-vercel
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-utils
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
The ADHD rewrite left fragment fences without imports/groups. Complete snippets, re-add group/ignore tags, and fix enums so kiira check passes.
There was a problem hiding this comment.
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (19)
docs/adapters/gemini.md (1)
321-334: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse supported SDK enum values in the Imagen safety example.
personGeneration: "DONT_ALLOW"is valid, butsafetyFilterLevel: "BLOCK_SOME"is not a supportedSafetyFilterLevelvalue. Replace it with a supported string such asBLOCK_LOW_AND_ABOVE,BLOCK_MEDIUM_AND_ABOVE,BLOCK_NONE, orBLOCK_ONLY_HIGHso the// SafetyFilterLevel enumnote matches the API.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/gemini.md` around lines 321 - 334, Update the safetyFilterLevel value in the geminiImage Imagen example to a supported SafetyFilterLevel string, such as BLOCK_LOW_AND_ABOVE, while preserving the existing personGeneration example and enum note.docs/advanced/multimodal-content.md (2)
241-250: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRequire
mimeTypefor data sources inContentPartSchema.
ContentPartSchemaaccepts image sources with onlytypeandvalue, so invalid data-source messages can pass validation beforechat()rejects them. Use separatedataandurlsource schemas somimeTypeis required only for thedatabranch.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/multimodal-content.md` around lines 241 - 250, Update ContentPartSchema’s image source validation to use separate discriminated branches for data and URL sources. Require a string mimeType on the data branch while keeping URL sources valid with only their existing type and value fields.
417-424: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winHandle upload failures at the input boundary.
handleFileUploadrejects onFileReaderfailure, butvoid handleFileUpload(file)has no rejection handler. Catch the promise and show an upload error so read failures do not become unhandled promise rejections without user feedback.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/multimodal-content.md` around lines 417 - 424, Update the file input’s onChange handler to attach rejection handling when invoking handleFileUpload, displaying an upload error to the user if the promise rejects. Preserve the existing file selection and successful upload flow while ensuring FileReader failures are not left as unhandled rejections.docs/chat/connection-adapters.md (2)
411-424: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winParse the final NDJSON record.
The loop only parses lines that end with
\n. It never flushesTextDecoderor parses the residualbufferafterdone. A finalRUN_FINISHEDor data chunk without a trailing newline is dropped.Proposed fix
- if (done) break + if (done) { + buffer += decoder.decode() + if (buffer.trim()) { + yield JSON.parse(buffer) + } + break + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/chat/connection-adapters.md` around lines 411 - 424, The stream parser must flush the TextDecoder and parse any non-empty residual buffer after reader.read() reports done. Update the async generator around reader.read(), decoder.decode(), and the line-processing loop so a final NDJSON record without a trailing newline, including RUN_FINISHED or data chunks, is yielded before completion.
328-338: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winHonor
send’s abort signal.
sendreceivesabortSignalbut awaits the socketopenpromise unconditionally, sostop()can still complete the send after cancellation. Make the readiness wait interruptible and checkabortSignal.abortedbeforews.send.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/chat/connection-adapters.md` around lines 328 - 338, Update send to use its _abortSignal when awaiting ready, allowing cancellation to interrupt the readiness wait, and check _abortSignal.aborted immediately before ws.send. Preserve the existing payload and send behavior when the signal is not aborted.docs/api/ai-angular.md (1)
460-481: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMove
inject(Injector)inside a valid injection context.Line 463 calls
inject(Injector)at module scope, where Angular has no injection context. Use the injector from a field initializer or constructor, then pass that instance intorunInInjectionContext.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/api/ai-angular.md` around lines 460 - 481, Move the module-scope injector lookup into a valid Angular injection context, such as a field initializer or constructor on MyComponent/MyComponentAlt, then pass that injector instance to runInInjectionContext. Remove the top-level inject(Injector) call while preserving the existing injectChat example.docs/sandbox/durability.md (1)
35-35: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winMark the in-memory example as local-only.
The page requires durable stores and distributed locks for multi-replica deployments, but the primary example instantiates
InMemorySandboxInstanceStoreandInMemoryLockStorewithout a local-development warning. Two replicas can then create separate sandboxes for the same key. Label this example as local-only and show the production store replacements.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/sandbox/durability.md` at line 35, Update the durability documentation example around InMemorySandboxInstanceStore and InMemoryLockStore to clearly label the in-memory configuration as local-development-only. Add the corresponding production store replacements so multi-replica deployments use durable instance storage and distributed locking.docs/adapters/elevenlabs.md (1)
143-173: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCall
useRealtimeChatfrom a component or custom hook.The client-tools example invokes
useRealtimeChat(...)at module scope. React hooks cannot run outside components or custom hooks. Move this setup inside a component/custom hook, or separate the client tool definition from the hooked chat instance.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/elevenlabs.md` around lines 143 - 173, Move the useRealtimeChat invocation into a React component or custom hook, while keeping the getWeatherDef and getWeather client-tool definitions reusable at module scope. Ensure the chat setup still passes the elevenlabsRealtime adapter and getWeather tool without invoking the hook during module initialization.docs/advanced/locks.md (2)
137-145: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winKeep the per-thread work under the lock.
withLockreleases ownership when the callback resolves. The callback here only doesvoid signal, so the lock is released before the actual per-thread operation runs. Two requests for the same thread can enter concurrently. Move the protected operation inside the callback, or use a lifecycle hook that spans the run.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/locks.md` around lines 137 - 145, The serializePerThread middleware currently releases the lock immediately because its withLock callback only evaluates signal. Move the actual per-thread operation into the callback, or replace this with a lifecycle hook that keeps the lock held for the full run, ensuring requests sharing ctx.threadId remain serialized.
45-52: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse the current OpenAI model in the OpenAI examples.
docs/tools/provider-skills.md#L105anddocs/tools/provider-skills.md#L136usegpt-5.2, but the OpenAI model metadata contains newergpt-5.5,gpt-5.5-pro, and related IDs. Use the newest compatible OpenAI model ID there.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/locks.md` around lines 45 - 52, Update the OpenAI model identifiers in the examples to the newest compatible ID from the current OpenAI model metadata, replacing outdated gpt-5.2 references while preserving each example’s existing provider setup: docs/advanced/locks.md:45-52; docs/tools/provider-skills.md:49-56, 105-113; docs/advanced/typed-options.md:30-34, 85-91, 133-138; docs/adapters/elevenlabs.md:232-237, 248-256; docs/sandbox/durable-runs.md:41-43; docs/sandbox/durability.md:64-66; docs/tools/mcp-manual.md:49-56, 85-87, 140-142, 185-190, 232-234; docs/sandbox/cloudflare.md:35-38, 121-123. Leave sites that do not contain an OpenAI model reference unchanged.Source: Coding guidelines
docs/tools/mcp-manual.md (1)
72-96: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winClose MCP clients on the resource, prompt-body, and cancellation examples.
The resource example and final cancellation example create a manual MCP client and never call
mcp.close(). Thefinallyprompt-body example also containsmcp.close()inside only one of itstry/finallybranches. Either addmiddleware: [{ ..., onFinish: () => mcp.close(), onAbort: () => mcp.close(), onError: () => mcp.close() }]or close on every terminal path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/tools/mcp-manual.md` around lines 72 - 96, Ensure every manual MCP client is closed on all terminal paths: in docs/tools/mcp-manual.md lines 72-96, add cleanup for the resource example’s mcp client; in docs/tools/mcp-manual.md lines 169-193, add cleanup for the cancellation example. Also update the finally prompt-body example so mcp.close() executes regardless of which try/finally branch completes, using middleware terminal callbacks or equivalent comprehensive cleanup.docs/code-mode/code-mode-isolates.md (1)
90-103: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy liftSecurity Misconfiguration (CWE-306): Missing Authentication for Critical Function
Reachability: External
Require deployment-time protection for Cloudflare isolate Workers.
The driver sends
Authorizationonly when configured, with no Worker-side check shown and no default protection. A publicworkerUrlwith theevalWorker can therefore accept code and use isolate/resources without authentication. Mark production protection required, avoid labeling this option optional for deployments outside trusted infrastructure, and document the required Worker-side Auth or Cloudflare Access enforcement.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/code-mode/code-mode-isolates.md` around lines 90 - 103, Update the Cloudflare isolate driver documentation to require deployment-time authentication for production or untrusted infrastructure: describe Worker-side authorization or Cloudflare Access enforcement, and state that the workerUrl must not expose the eval Worker publicly without protection. Revise the authorization option’s description from optional to deployment-required, while preserving its role as the Authorization header configuration.docs/resumable-streams/advanced.md (1)
58-71: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winPair client usage with the required server endpoint.
docs/resumable-streams/advanced.md#L58-L71: add theoffset=-1GET handler or link to its exact complete example.docs/api/ai-preact.md#L27-L65: add a minimal POST/api/chatroute or link to an exact server/client example.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/resumable-streams/advanced.md` around lines 58 - 71, Pair the client examples with complete server endpoint guidance: in docs/resumable-streams/advanced.md lines 58-71, add the required offset=-1 GET handler or link to its exact complete example; in docs/api/ai-preact.md lines 27-65, add a minimal POST /api/chat route or link to an exact server/client example.Source: Coding guidelines
docs/tools/server-tools.md (1)
78-103: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winBound and validate the external API call.
fetch()can wait indefinitely, andresponse.json()runs for 4xx and 5xx responses. A provider timeout or non-JSON error can hang the tool loop or produce an uncontrolled tool error. Add a timeout, checkresponse.ok, and return a schema-compatible error.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/tools/server-tools.md` around lines 78 - 103, Update the server implementation of searchProducts to bound the external fetch with an AbortSignal timeout, validate response.ok before parsing, and return a schema-compatible error result for timeouts, non-2xx responses, or invalid JSON. Preserve the existing successful JSON response and server-only API_KEY usage.docs/media/text-to-speech.md (1)
248-260: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winRevoke generated Blob URLs.
SpeechPlayer.onResultcreates a new object URL for each result, but this example never callsURL.revokeObjectURL. Add cleanup withuseEffectwhenresultchanges and on unmount so URL reuses do not retain Blob data.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/media/text-to-speech.md` around lines 248 - 260, Update SpeechPlayer and its onResult handling to retain each generated Blob URL and use a useEffect tied to result changes that revokes the previous URL, also revoking the final URL during unmount. Preserve audio creation while ensuring every URL from URL.createObjectURL is eventually passed to URL.revokeObjectURL.docs/persistence/build-your-own-generation-adapter.md (1)
87-108: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winValidate persisted JSON before mapping it.
mapGenerationRunandmapBlobRecordcallJSON.parsedirectly on database columns. A truncated or corrupt row can makeget,findLatestForThread, or blob reads throw instead of returning a controlled result.Use a per-field type guard or Standard Schema parser. Handle invalid records explicitly before constructing the returned store record.
Based on learnings, persisted values must be narrowed or validated before use so corrupt records cannot surface as runtime failures.
Also applies to: 322-324
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/persistence/build-your-own-generation-adapter.md` around lines 87 - 108, Validate each persisted JSON field before mapping it in mapGenerationRun and mapBlobRecord, replacing direct JSON.parse calls with the established type guard or Standard Schema validation approach. Handle parse or validation failures explicitly so get, findLatestForThread, and blob reads return a controlled result rather than throwing, while preserving valid records and omitting or reporting invalid optional fields as appropriate.Source: Learnings
docs/api/ai-react.md (1)
15-68: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winShow both sides of each runnable flow.
Both pages show a client that calls a server endpoint but omit the matching server implementation. Add a concise server example or a direct link to a complete server/client example.
docs/api/ai-react.md#L15-L68: add the/api/chatendpoint that returns TanStack AI SSE.docs/interrupts/generic.md#L87-L96: add the server interrupt emission and resume-validation example.As per coding guidelines, documentation code samples should show both server and client sides when applicable.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/api/ai-react.md` around lines 15 - 68, Complete the runnable flow in docs/api/ai-react.md (lines 15-68) by adding a concise server implementation for /api/chat that returns TanStack AI SSE and matches the useChat/fetchServerSentEvents client example. Also update docs/interrupts/generic.md (lines 87-96) with the corresponding server interrupt emission and resume-validation example; both documented sites require direct changes.Source: Coding guidelines
docs/structured-outputs/multi-turn.md (1)
84-99: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMove the shared schema out of the route module.
The client imports
RecipeSchemaandRecipefrom the/api/structured-chatroute module, which also imports@tanstack/ai,@tanstack/ai-openai, and server utilities. PutRecipeSchemaandRecipein a shared module and import that module from both the server route and the client.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/structured-outputs/multi-turn.md` around lines 84 - 99, Move RecipeSchema and the Recipe type out of the api/structured-chat route module into a shared schema module, then update both the structured chat route and StructuredChatPage imports to use that shared module. Keep server-only dependencies confined to the route and preserve the existing schema and type usage.docs/structured-outputs/with-tools.md (1)
68-78: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winComplete the cross-boundary documentation examples.
These rewrites leave several server/client flows one-sided. Add the missing counterpart or link to an exact complete example.
docs/structured-outputs/with-tools.md#L68-L78: add the serverPOSThandler for/api/recommend.docs/structured-outputs/with-tools.md#L118-L137: add the server route used by the client-tool example.docs/community-adapters/mynth.md#L134-L150: add client consumption for the SSE image-generation endpoint.docs/api/ai-solid.md#L16-L66: add or link to the/api/chatserver handler.docs/api/ai-solid.md#L127-L138: add or link to the/api/chatserver handler.docs/api/ai-solid.md#L247-L288: add or link to the/api/chatserver handler for client tools.docs/code-mode/lazy-tools.md#L62-L88: add client consumption for the Code Mode SSE route.docs/code-mode/lazy-tools.md#L151-L171: add client consumption for the plainchat()SSE route.As per coding guidelines, documentation examples must show both server and client sides when applicable.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/structured-outputs/with-tools.md` around lines 68 - 78, Complete the cross-boundary documentation examples by adding the missing counterpart or linking to an exact complete example: in docs/structured-outputs/with-tools.md lines 68-78, add the server POST handler for /api/recommend; in lines 118-137, add the server route for the client-tool example; in docs/community-adapters/mynth.md lines 134-150, add client consumption for the SSE image-generation endpoint; in docs/api/ai-solid.md lines 16-66, 127-138, and 247-288, add or link to the /api/chat server handler, including the client-tools variant; and in docs/code-mode/lazy-tools.md lines 62-88 and 151-171, add client consumption for the respective Code Mode and plain chat() SSE routes. Ensure each applicable example shows both server and client sides.Source: Coding guidelines
🟠 Major comments (24)
docs/adapters/gemini.md-127-127 (1)
127-127: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winStore the first interaction before resuming it.
The text requires
store: truefor multi-turn interactions, but the firstchat()call at Lines 137-140 does not set it. AddmodelOptions: { store: true }to the first request before using its interaction ID.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/gemini.md` at line 127, Update the first chat() request in the stateful conversation example to include modelOptions with store enabled, ensuring its interaction ID is persisted before the subsequent request resumes it.docs/adapters/fal.md-142-143 (1)
142-143: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPoll until the video job reaches a terminal state.
The text describes a submit → poll → URL flow, but the example calls
getVideoJobStatus()only once. A pending job has no final URL. Loop untilcompletedorfailed, then handle the terminal result.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/fal.md` around lines 142 - 143, Update the video job example around getVideoJobStatus() to poll repeatedly until the job reaches the completed or failed terminal state, rather than checking status only once. Only access or handle the final video URL after completion, and preserve explicit failure handling for failed jobs.docs/adapters/acp-compatible.md-200-204 (2)
200-204: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd the client side of the session-resume flow.
This section requires capturing
<name>.session-idand sending it back inmodelOptions.sessionId, but it provides only server code. Add a client example that consumes the custom event and sends the next request.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/acp-compatible.md` around lines 200 - 204, Extend the “Session resume” section with a client-side example that listens for the <name>.session-id custom event, stores the received session ID, and includes it as modelOptions.sessionId on the next request while sending only the latest user message.Source: Coding guidelines
200-204: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftAdd client consumption to each server endpoint example.
The documentation rule requires both server and client sides when applicable.
docs/adapters/acp-compatible.md#L200-L204: add client handling for the session ID custom event and the next resume request.docs/adapters/anthropic.md#L57-L57: add a client for the basic SSE endpoint.docs/adapters/anthropic.md#L75-L75: add a client for the tool-enabled SSE endpoint.docs/adapters/gemini.md#L62-L62: add a client for the tool-enabled endpoint.docs/adapters/grok.md#L58-L58: add a client for the tool-enabled endpoint.docs/adapters/groq.md#L59-L59: add a client for the SSE endpoint.docs/adapters/mistral.md#L82-L82: add a client for the tool-enabled endpoint.docs/adapters/ollama.md#L68-L68: add a client for the tool-enabled endpoint.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/acp-compatible.md` around lines 200 - 204, Extend the server-only documentation with client consumption examples: in docs/adapters/acp-compatible.md lines 200-204, show handling the session-ID custom event and sending the next resume request with modelOptions.sessionId; add client examples for the basic and tool-enabled SSE endpoints at docs/adapters/anthropic.md lines 57 and 75, and for the tool-enabled endpoints at docs/adapters/gemini.md line 62, docs/adapters/grok.md line 58, docs/adapters/mistral.md line 82, and docs/adapters/ollama.md line 68; add a client example for the SSE endpoint at docs/adapters/groq.md line 59. Use each document’s existing endpoint and request conventions.Source: Coding guidelines
docs/adapters/byteplus.md-173-175 (1)
173-175: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse one exact model ID for structured output.
Line 175 names
dola-seed-2-0-lite-260228, but the model list at Lines 412-418 namesseed-2-0-lite-260228. Use the exact exported model ID so readers do not receive a model-not-found or unsupported-model error.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/byteplus.md` around lines 173 - 175, Update the structured output model reference in the “Structured output” documentation to use the exact exported ID `seed-2-0-lite-260228`, matching the model list and `BYTEPLUS_STRUCTURED_OUTPUT_CHAT_MODELS`; remove the incorrect `dola-` prefix.docs/adapters/acp-compatible.md-131-136 (1)
131-136: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRemove the
asassertion frommodelOptionsexamples.The
acpCompatible.mdexamples at lines 102 and 135 usemodelOptions: {} as { reasoningEffort?: ... }. Replace it with an assertion-free type-only shape (for example, use the adapter interface type only, or describe the custom options without providing a runtime empty object cast).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/acp-compatible.md` around lines 131 - 136, Update the modelOptions examples in the acp-compatible documentation, including the modelOptions field description, to remove the `as` type assertions. Describe the custom type-only options shape without presenting a runtime empty object cast, while preserving the documented typing behavior for chat({ modelOptions }).Source: Coding guidelines
docs/adapters/openai-compatible.md-82-88 (1)
82-88: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse current DeepSeek model IDs.
deepseek-chatanddeepseek-reasonerare retired on the DeepSeek API. Replace these examples, one-shot calls, model declarations, and the provider table entry (line:128) with active identifiers such asdeepseek-v4-flash/deepseek-v4-pro, and adjust the capability metadata accordingly.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/adapters/openai-compatible.md` around lines 82 - 88, Update all DeepSeek references in the documentation, including examples, one-shot calls, model declarations, and the provider table, to use active model IDs such as deepseek-v4-flash or deepseek-v4-pro instead of deepseek-chat and deepseek-reasoner. Adjust each createModel capability declaration to match the selected model’s supported features.Source: Coding guidelines
docs/persistence/build-your-own-adapter.md-120-120 (1)
120-120: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winLimit the conformance claim to declared capabilities.
The preceding example skips
generationRuns,artifacts, andblobs. A green result cannot prove drop-in support forwithGenerationPersistence. State that the result covers only unskipped capabilities, or remove those skips before claiming both integrations.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/persistence/build-your-own-adapter.md` at line 120, Update the conformance statement in the persistence adapter documentation to limit a green result to the capabilities actually tested, since the example skips generationRuns, artifacts, and blobs. Either state that the result covers only unskipped capabilities or remove those skips before claiming support for both withPersistence and withGenerationPersistence.docs/advanced/runtime-adapter-switching.md-31-36 (1)
31-36: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winValidate the provider before indexing
adapters.
body.forwardedProps?.provideris runtime JSON. TheProviderannotation does not validate it. An unknown value makesadapters[provider]()throw. Allowlist the value and return a400response or use the default. Apply the same validation to the full-route, image, and summarize examples.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/runtime-adapter-switching.md` around lines 31 - 36, Validate the runtime provider value before calling adapters[provider]() in handleRequest, rather than relying on the Provider annotation; allow only supported adapter keys and return a 400 response or fall back to the default for unknown values. Apply the same allowlist validation to the full-route, image, and summarize examples.docs/persistence/build-your-own-adapter.md-86-86 (1)
86-86: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDo not generalize retry safety from idempotent creates.
No cross-system transaction remains. Idempotent creates do not protect transcript overwrites, status transitions, or multi-store ordering. Document idempotency or transaction requirements for every operation, or describe compensation and conflict handling.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/persistence/build-your-own-adapter.md` at line 86, Update the transaction and retry-safety guidance in the persistence adapter documentation: do not imply that idempotent creates make all retries safe. Cover requirements for transcript overwrites, status transitions, and multi-store ordering, or document the required compensation and conflict-handling behavior for those operations.docs/persistence/client-persistence.md-160-160 (1)
160-160: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winMake corrupt persisted records fail safely.
The custom adapter above can throw from
JSON.parse, and its guard accepts anymessagesarray without validating message entries orresume. This contradicts the statement that wrong shapes fail silently and can breakuseChatduring hydration. Use a shipped adapter, or parse the complete record with a schema insidetry/catchand returnnullon failure.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/persistence/client-persistence.md` at line 160, Update the custom persistence adapter described in the surrounding documentation to validate the complete persisted record, including message entries and resume, inside a try/catch; return null for JSON.parse errors or schema mismatches so corrupt records fail safely during useChat hydration. Prefer the shipped adapter if it already provides this validation.Source: Learnings
docs/api/ai-vue.md-265-268 (1)
265-268: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winOther (CWE-20): Improper Input Validation
Reachability: External
Do not expose a generic localStorage writer to the model.
saveToStorageallows model-controlledkeyandvalueinputs, then callslocalStorage.setItem(input.key, input.value). An attacker or prompt injection can use this client tool to overwrite arbitrary same-origin storage keys.Replace it with application-specific setters, or allowlist only safe storage keys and reject session/credential/security-related keys.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/api/ai-vue.md` around lines 265 - 268, Update the tools supplied to useChat so saveToStorage cannot write arbitrary model-controlled localStorage keys or values. Replace it with application-specific setter tools, or enforce an explicit allowlist that rejects session, credential, and security-related keys before calling localStorage.setItem.docs/memory/custom-adapter.md-43-47 (1)
43-47: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReconcile the receipt rule with the scaffold.
The contract says one
SaveReceiptper write, butsave()inserts two rows and returns one receipt. Either return one receipt for each insert or change the contract wording and contract-suite expectation to one receipt persave()call.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/memory/custom-adapter.md` around lines 43 - 47, Reconcile the “one SaveReceipt per write” rule with the documented save scaffold: either update save() to return a receipt for each of its two inserts, or revise the rule and contract-suite expectation to require one receipt per save() call. Keep the chosen behavior consistent across the contract wording, save() implementation, and tests.docs/persistence/keep-generated-files.md-82-85 (1)
82-85: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winAuthorization Bypass (CWE-862): Missing Authorization
Reachability: External
Replace the hardcoded ownership result before publishing this example.
artifactIdcomes from the request, butconst owned = trueauthorizes every caller. This path can then retrieve and return another user’s persisted artifact bytes. Enforce authenticated tenant, thread, and run ownership, and keep the existing 404 response for non-owned artifacts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/persistence/keep-generated-files.md` around lines 82 - 85, Replace the hardcoded owned value in the artifact retrieval example with validation of the authenticated tenant, thread, and run against the requested artifactId and its persisted metadata. Return the existing 404 Response whenever ownership validation fails, and only retrieve or return artifact bytes after all ownership checks pass.docs/memory/adapters.md-101-113 (1)
101-113: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDocument Redis key escaping and migration status.
redis()still escapes:,\, and_in Redis scope values, so this does not match{prefix}:index:{tenantId|_}:{userId|_}:{threadId}and could miss existing literal_keys. Also state that older index layouts are not supported without migration.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/memory/adapters.md` around lines 101 - 113, Update the Redis key documentation near the index-key format to describe escaping of :, \, and _ in redis() scope values, including how escaped values distinguish literal underscores from missing dimensions. State that older Redis index layouts are unsupported unless explicitly migrated, while keeping the adapter scope table accurate.docs/memory/adapters.md-129-136 (1)
129-136: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winSensitive Data Exposure (CWE-532): Insertion of Sensitive Information into Log File
Reachability: External
Do not log the raw Hindsight recall query.
onToolRecallreceives the query string before filtering, and this example writes it to console logs with retrieved fragments. Log only non-sensitive event metadata, or redact the query before logging.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/memory/adapters.md` around lines 129 - 136, The onToolRecall example currently logs the raw recall query, which may contain sensitive data. Update the onToolRecall callback in the hindsight example to omit query from console output or replace it with a suitable redacted representation, while retaining only non-sensitive recall metadata such as fragment count.docs/media/image-generation.md-200-205 (1)
200-205: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMake the OpenAI inpaint example valid by default.
Lines 200-205 call
openaiImage('gpt-image-2')withoutallowUrlFetch, then pass HTTP(S)urlinputs. Because OpenAI image edits default to rejectinghttp:///https://sources and require real bytes, use data inputs here, or constructcreateOpenaiImagewithallowUrlFetch: true, matching the documentation above.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/media/image-generation.md` around lines 200 - 205, Update the OpenAI inpaint example using openaiImage('gpt-image-2') so its HTTP(S) photoUrl and maskUrl inputs are accepted by default: either convert them to data inputs containing real bytes, or configure createOpenaiImage with allowUrlFetch: true as documented above.docs/advanced/built-in-middleware.md-88-88 (1)
88-88: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winConnect the Redis client before using it.
createClient()returns a closed client. The example callsredis.get,redis.set, andredis.delwithoutawait redis.connect(), so the first cache operation fails. Connect the client during application startup or pass an already-connected client.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/built-in-middleware.md` at line 88, Update the Redis cache example to ensure the client returned by createClient() is connected with await redis.connect() during application startup before any chat() calls perform redis.get, redis.set, or redis.del; alternatively, document that the supplied storage client must already be connected.docs/sandbox/quick-start.md-23-23 (1)
23-23: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winInstall or verify the
grokCLI in the quick-start image.The example uses
node:22, but the setup does not installgrok. The latergrokBuildText('grok-build')call therefore cannot run as written. Use an image that contains the CLI, or add an installation and version check tosetup.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/sandbox/quick-start.md` at line 23, Update the quick-start sandbox setup around the node:22 image so the grok CLI is installed or verified before use. Ensure the setup step confirms the CLI is available, including a version check, before grokBuildText('grok-build') runs; alternatively use an image that already contains grok.docs/community-adapters/decart.md-71-105 (1)
71-105: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winBound the video polling loop.
If Decart never returns a terminal status,
for (;;)waits forever. Add a deadline or maximum attempt count and report a timeout error.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/community-adapters/decart.md` around lines 71 - 105, Bound the polling loop in createVideo by adding a deadline or maximum attempt count, and throw a clear timeout error when polling exceeds that limit without reaching completed or failed status. Preserve the existing 5-second polling interval and terminal-status handling.docs/persistence/build-your-own-chat-adapter.md-54-65 (1)
54-65: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftValidate persisted JSON before returning it to
useChat.The
createMessageStoreexample assignsJSON.parse(json)directly toArray<ModelMessage>. A corrupt row can throw during rehydration or return invalid message objects. Add a type guard or Standard Schema parser, and apply the same validation to usage, interrupt payloads, responses, and metadata.
Based on learnings, persistence examples must narrow or validate parsed values before use. <retrieved_learnings>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/persistence/build-your-own-chat-adapter.md` around lines 54 - 65, Update the createMessageStore example and its load, usage, interrupt, response, and metadata rehydration paths to validate parsed JSON before returning or using it. Add a type guard or Standard Schema parser that rejects malformed values, handles parse or validation failures safely, and ensures only validated ModelMessage arrays and associated persisted payloads reach useChat.Source: Learnings
docs/advanced/built-in-middleware.md-213-213 (1)
213-213: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winConsume the default stream in the OTel example.
chat()defaults to streaming.await chat(...)does not consume the returnedAsyncIterable, so the request and middleware spans may not run. Setstream: falsefor a one-shot result, or iterate the stream.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/advanced/built-in-middleware.md` at line 213, Update the OTel example’s chat invocation to explicitly set stream: false so awaiting chat() returns and consumes a one-shot result, ensuring the request and middleware spans execute without changing the example’s intended behavior.docs/resumable-streams/custom-adapter.md-120-125 (1)
120-125: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReject gaps in the upsert suffix.
The rule requires a contiguous suffix, but
makeUpsertonly rejects offsets at or beforetail. An offset attail + 2passes and creates a missing position. Later reads can then skip a chunk permanently.For each new entry, require
seq === tail + 1before advancingtail.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/resumable-streams/custom-adapter.md` around lines 120 - 125, Update makeUpsert’s batch validation to enforce a contiguous suffix: for each new entry, require its sequence offset to equal tail + 1 before advancing tail, rejecting gaps such as tail + 2 while preserving existing rejection of stale or duplicate offsets.docs/sandbox/events.md-148-167 (1)
148-167: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftHandle mixed tool-call messages before dropping sandbox results.
If an assistant message includes both sandbox and non-sandbox tool calls,
calls.every(isSandboxToolCall)keeps the message, but the matching sandbox result is later skipped. The restored history then pairs a non-sandbox assistant turn with dropped sandbox tool results. Filter only sandbox tool calls from mixed messages, keep non-sandbox calls, and track sandbox result IDs separately.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/sandbox/events.md` around lines 148 - 167, Update saveThread so messages containing mixed sandbox and non-sandbox tool calls retain only the non-sandbox calls instead of being kept unchanged. Track IDs only for removed sandbox calls, and continue skipping tool results whose toolCallId matches those IDs, while preserving messages containing no sandbox calls.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 105297e5-53aa-4ff8-bbe7-94c36889ea63
📒 Files selected for processing (142)
docs/adapters/acp-compatible.mddocs/adapters/anthropic.mddocs/adapters/bedrock.mddocs/adapters/byteplus.mddocs/adapters/claude-code.mddocs/adapters/codex.mddocs/adapters/elevenlabs.mddocs/adapters/fal.mddocs/adapters/gemini.mddocs/adapters/grok-build.mddocs/adapters/grok.mddocs/adapters/groq.mddocs/adapters/mistral.mddocs/adapters/ollama.mddocs/adapters/openai-compatible.mddocs/adapters/openai.mddocs/adapters/opencode.mddocs/adapters/openrouter.mddocs/advanced/built-in-middleware.mddocs/advanced/debug-logging.mddocs/advanced/extend-adapter.mddocs/advanced/locks.mddocs/advanced/middleware.mddocs/advanced/multimodal-content.mddocs/advanced/otel.mddocs/advanced/per-model-type-safety.mddocs/advanced/runtime-adapter-switching.mddocs/advanced/runtime-context.mddocs/advanced/tree-shaking.mddocs/advanced/typed-options.mddocs/api/ai-angular.mddocs/api/ai-client.mddocs/api/ai-preact.mddocs/api/ai-react.mddocs/api/ai-solid.mddocs/api/ai-svelte.mddocs/api/ai-vue.mddocs/api/ai.mddocs/architecture/approval-flow-processing.mddocs/chat/agentic-cycle.mddocs/chat/connection-adapters.mddocs/chat/streaming.mddocs/chat/structured-outputs.mddocs/chat/thinking-content.mddocs/code-mode/client-integration.mddocs/code-mode/code-mode-isolates.mddocs/code-mode/code-mode-with-skills.mddocs/code-mode/code-mode.mddocs/code-mode/lazy-tools.mddocs/community-adapters/cencori.mddocs/community-adapters/cloudflare.mddocs/community-adapters/decart.mddocs/community-adapters/guide.mddocs/community-adapters/mynth.mddocs/community-adapters/soniox.mddocs/comparison/vercel-ai-sdk.mddocs/config.jsondocs/getting-started/agent-skills.mddocs/getting-started/devtools.mddocs/getting-started/overview.mddocs/getting-started/quick-start-angular.mddocs/getting-started/quick-start-react-native.mddocs/getting-started/quick-start-server.mddocs/getting-started/quick-start-svelte.mddocs/getting-started/quick-start-vue.mddocs/getting-started/quick-start.mddocs/interrupts/generic.mddocs/interrupts/migration.mddocs/interrupts/multiple.mddocs/interrupts/overview.mddocs/interrupts/tool-approval.mddocs/mcp/apps.mddocs/media/audio-generation.mddocs/media/audio-recording.mddocs/media/generation-hooks.mddocs/media/generations.mddocs/media/image-generation.mddocs/media/realtime-chat.mddocs/media/text-to-speech.mddocs/media/transcription.mddocs/media/video-generation.mddocs/memory/adapters.mddocs/memory/custom-adapter.mddocs/memory/operating.mddocs/memory/overview.mddocs/memory/quickstart.mddocs/migration/ag-ui-compliance.mddocs/migration/migration-from-vercel-ai.mddocs/migration/migration.mddocs/migration/sampling-options-to-model-options.mddocs/persistence/build-a-sandbox-adapter.mddocs/persistence/build-your-own-adapter.mddocs/persistence/build-your-own-chat-adapter.mddocs/persistence/build-your-own-generation-adapter.mddocs/persistence/chat-persistence.mddocs/persistence/client-persistence.mddocs/persistence/controls.mddocs/persistence/generation-persistence.mddocs/persistence/id-map.mddocs/persistence/internals.mddocs/persistence/keep-generated-files.mddocs/persistence/migrations.mddocs/persistence/overview.mddocs/persistence/store-reference.mddocs/protocol/custom-events.mddocs/resumable-streams/advanced.mddocs/resumable-streams/custom-adapter.mddocs/resumable-streams/overview.mddocs/sandbox/cloudflare.mddocs/sandbox/durability.mddocs/sandbox/durable-runs.mddocs/sandbox/events.mddocs/sandbox/harnesses.mddocs/sandbox/journal.mddocs/sandbox/lifecycle.mddocs/sandbox/observability.mddocs/sandbox/overview.mddocs/sandbox/policy.mddocs/sandbox/providers.mddocs/sandbox/provisioning.mddocs/sandbox/quick-start.mddocs/sandbox/reaping.mddocs/sandbox/takeover.mddocs/sandbox/tools.mddocs/sandbox/workspace.mddocs/structured-outputs/multi-turn.mddocs/structured-outputs/one-shot.mddocs/structured-outputs/overview.mddocs/structured-outputs/streaming.mddocs/structured-outputs/with-tools.mddocs/tools/client-tools.mddocs/tools/lazy-tool-discovery.mddocs/tools/mcp-codegen.mddocs/tools/mcp-managed.mddocs/tools/mcp-manual.mddocs/tools/mcp.mddocs/tools/provider-skills.mddocs/tools/provider-tools.mddocs/tools/server-tools.mddocs/tools/tool-approval.mddocs/tools/tool-architecture.mddocs/tools/tools.md
Keep action-first prose; fold in structured-output finalization span behavior from #1055.
Rewrites every hand-written docs page for action-first clarity.
What changed
docs/config.json—updatedAtrefreshed on the 140 touched entries per the docs convention.Auto-generated reference docs (TypeDoc output) are untouched.
Notes
Docs-only — no source, no behavior change, so no changeset and no E2E additions. Worth a skim of a few pages you know well to check the compression didn't drop something load-bearing.
🤖 Generated with Claude Code
Summary by CodeRabbit