Skip to content

Add useGraphCha#11

Merged
cantemizyurek merged 3 commits intomainfrom
cantemizyurek/use-chat
Jan 22, 2026
Merged

Add useGraphCha#11
cantemizyurek merged 3 commits intomainfrom
cantemizyurek/use-chat

Conversation

@cantemizyurek
Copy link
Owner

@cantemizyurek cantemizyurek commented Jan 22, 2026

Summary by CodeRabbit

  • New Features
    • React integration for graph-based chat via a new hook for easy wiring into React apps
    • Automatic management and exposure of graph execution state and active node tracking
    • Lifecycle event hooks for state updates, node start/end, and suspense notifications
    • Utilities to detect and strip graph-specific data from message streams

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Jan 22, 2026

🦋 Changeset detected

Latest commit: ff3580d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
ai-sdk-graph Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

This change adds a React integration for the AI SDK: a new useGraphChat hook (exported via ./react) that wraps @ai-sdk/react's useChat, manages graph-specific data parts and lifecycle events, and exposes state and activeNodes. Utilities to identify and strip graph data parts and package metadata updates are included.

Changes

Cohort / File(s) Summary
Changeset & Configuration
\.changeset/react-integration.md, package.json
Adds ./react export (types/import/require), updates build script to include src/react.ts, bumps ai to ^6.0.48, adds react and @ai-sdk/react dev deps, adds peer dependency on react (`^18
React Integration
src/react.ts
New useGraphChat<State, UI_MESSAGE> hook that composes useChat, supplies a custom transport and onData handler, parses graph data parts (state, node start/end, suspense), updates state and activeNodes, and supports callbacks onStateChange, onNodeStart, onNodeEnd, onNodeSuspense, plus transport customization.
Utilities
src/utils.ts
Adds GRAPH_DATA_PART_TYPES constant, GraphDataPartType type, isGraphDataPart(part) to detect graph data parts, and stripGraphDataParts(parts) to remove graph-specific parts from messages.

Sequence Diagram

sequenceDiagram
    participant Client as React Component
    participant Hook as useGraphChat Hook
    participant Transport as Chat Transport
    participant Server as AI Server
    participant Data as Data Handler

    Client->>Hook: initialize(options)
    Hook->>Transport: create with prepareSendMessagesRequest (uses stripGraphDataParts)
    
    Client->>Hook: send message
    Hook->>Transport: prepareSendMessagesRequest
    Transport->>Transport: strip graph data parts
    Transport->>Server: send cleaned message
    
    Server-->>Hook: stream response (parts)
    Hook->>Data: handleData(parts)
    
    alt data-state
        Data->>Hook: update graph state
        Hook->>Client: call onStateChange & expose state
    else data-node-start / data-node-end
        Data->>Hook: update activeNodes
        Hook->>Client: call onNodeStart/onNodeEnd & expose activeNodes
    else data-node-suspense
        Data->>Client: call onNodeSuspense
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A hook hops in with careful art,

State and nodes play each their part,
Messages pruned, the stream runs neat,
Callbacks chirp with steady beat,
Graphs converse — a joyful start! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The pull request title 'Add useGraphCha' is incomplete and appears to be truncated, failing to clearly convey the purpose of adding the useGraphChat hook and React integration. Complete the title to 'Add useGraphChat hook for React integration' or similar to clearly describe the new React hook functionality being introduced.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cantemizyurek/use-chat

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/react.ts`:
- Around line 54-75: handleData closes over activeNodes causing stale updates;
replace direct references to activeNodes in the callback with functional state
updates so the latest state is used without adding activeNodes to the dependency
array: in the 'data-node-start' branch use setActiveNodes(prev => [...prev,
nodeId]) and in the 'data-node-end' branch use setActiveNodes(prev =>
prev.filter(node => node !== nodeId)); keep the existing useCallback
dependencies ([onStateChange, onNodeStart, onNodeEnd, onNodeSuspense]) and
ensure handleData, setActiveNodes, activeNodes, onNodeStart, onNodeEnd are the
referenced symbols when making the change.
🧹 Nitpick comments (3)
src/utils.ts (1)

17-22: Type assertion may not preserve all properties of extended UIMessage types.

The spread operator {...msg} creates a shallow copy, but the as T[] assertion could hide type mismatches if T extends UIMessage with additional required properties that aren't being properly preserved. This is generally safe for this use case since you're only modifying parts, but worth noting.

src/react.ts (2)

101-105: Type assertion may indicate API mismatch.

The as UseChatOptions<UI_MESSAGE> cast suggests the types don't align perfectly. This could hide type errors if the APIs evolve. Consider investigating whether the types can be reconciled without the assertion, or add a comment explaining why it's necessary.


68-72: Minor: Remove extra blank line.

There's an unnecessary blank line before the closing brace of the data-node-suspense block.

Suggested fix
             } else if (dataPart.type === 'data-node-suspense') {
                 const { nodeId, data } = dataPart.data as { nodeId: string; data: unknown }
                 onNodeSuspense?.(nodeId, data)
-
             }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/react.ts`:
- Around line 77-105: The prepareSendMessagesRequest currently returns only {
body: ... } and must include the required api field (and optional
headers/credentials) per DefaultChatTransport; update the
prepareSendMessagesRequest inside the useMemo that creates DefaultChatTransport
so both the customPrepareRequest branch and the default branch return an object
shaped { api, headers?, credentials?, body? }—e.g., pull api from
requestOptions.api or fallback to transportOptions.api (or a configured default)
and include it in the returned object, ensuring stripGraphDataParts is still
applied to messages and that customPrepareRequest is passed/returned an object
that contains api as well.

Comment on lines +77 to +105
const transport = useMemo(() => {
return new DefaultChatTransport<UI_MESSAGE>({
...transportOptions,
prepareSendMessagesRequest: (requestOptions) => {
const strippedMessages = stripGraphDataParts(requestOptions.messages)

if (customPrepareRequest) {
return customPrepareRequest({
...requestOptions,
messages: strippedMessages,
})
}

return {
body: {
id: requestOptions.id,
messages: strippedMessages,
trigger: requestOptions.trigger,
},
}
},
})
}, [transportOptions, customPrepareRequest])

const chatHelpers = useChat<UI_MESSAGE>({
...chatInitOptions,
transport,
onData: handleData,
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

ai package v6.0.48 DefaultChatTransport prepareSendMessagesRequest return shape

💡 Result:

prepareSendMessagesRequest should return an object describing the HTTP request — typically some subset of { api, headers, credentials, body } (e.g. { api: string, headers?: HeadersInit, credentials?: RequestCredentials, body?: Record<string,any> }). [1][2]

Sources:

  • AI SDK (v6) Transport docs — DefaultChatTransport / prepareSendMessagesRequest. [1]
  • AI SDK transport examples / migration docs showing prepareSendMessagesRequest returning { body, headers, credentials, api }. [2]

Transport implementation incomplete—missing api field in prepareSendMessagesRequest return.

The prepareSendMessagesRequest should return { api, headers?, credentials?, body? } according to DefaultChatTransport v6.0.48. The current code returns only { body: {...} }, omitting the api field which is required to specify the endpoint. While the message stripping and delegation flow are solid, add the api field (or ensure it's handled elsewhere in transportOptions) to complete the transport configuration.

🤖 Prompt for AI Agents
In `@src/react.ts` around lines 77 - 105, The prepareSendMessagesRequest currently
returns only { body: ... } and must include the required api field (and optional
headers/credentials) per DefaultChatTransport; update the
prepareSendMessagesRequest inside the useMemo that creates DefaultChatTransport
so both the customPrepareRequest branch and the default branch return an object
shaped { api, headers?, credentials?, body? }—e.g., pull api from
requestOptions.api or fallback to transportOptions.api (or a configured default)
and include it in the returned object, ensuring stripGraphDataParts is still
applied to messages and that customPrepareRequest is passed/returned an object
that contains api as well.

@cantemizyurek cantemizyurek merged commit 5f4d2f8 into main Jan 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant