Skip to content

Commit 6ef2f3b

Browse files
[AI SDK Provider] Auto handle session ids (#7956)
1 parent 596aaa5 commit 6ef2f3b

File tree

6 files changed

+131
-165
lines changed

6 files changed

+131
-165
lines changed

.changeset/pink-hands-find.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@thirdweb-dev/ai-sdk-provider": patch
3+
---
4+
5+
Auto handle session ids

apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
"use client";
22

3-
import { useChat } from "@ai-sdk/react";
3+
import { type UseChatHelpers, useChat } from "@ai-sdk/react";
44
import type { ThirdwebAiMessage } from "@thirdweb-dev/ai-sdk-provider";
5-
import { DefaultChatTransport } from "ai";
5+
import {
6+
DefaultChatTransport,
7+
lastAssistantMessageIsCompleteWithToolCalls,
8+
} from "ai";
69
import { useMemo, useState } from "react";
710
import { defineChain, prepareTransaction } from "thirdweb";
811
import {
@@ -31,30 +34,19 @@ import { Loader } from "../../../../components/loader";
3134
import { THIRDWEB_CLIENT } from "../../../../lib/client";
3235

3336
export function ChatContainer() {
34-
const [sessionId, setSessionId] = useState("");
35-
3637
const { messages, sendMessage, status, addToolResult } =
3738
useChat<ThirdwebAiMessage>({
3839
transport: new DefaultChatTransport({
3940
api: "/api/chat",
4041
}),
41-
onFinish: ({ message }) => {
42-
setSessionId(message.metadata?.session_id ?? "");
43-
},
42+
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
4443
});
4544
const [input, setInput] = useState("");
4645

4746
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
4847
e.preventDefault();
4948
if (input.trim()) {
50-
sendMessage(
51-
{ text: input },
52-
{
53-
body: {
54-
sessionId,
55-
},
56-
},
57-
);
49+
sendMessage({ text: input });
5850
setInput("");
5951
}
6052
};
@@ -101,7 +93,6 @@ export function ChatContainer() {
10193
addToolResult={addToolResult}
10294
sendMessage={sendMessage}
10395
toolCallId={part.toolCallId}
104-
sessionId={sessionId}
10596
/>
10697
);
10798
case "tool-sign_swap":
@@ -113,7 +104,6 @@ export function ChatContainer() {
113104
addToolResult={addToolResult}
114105
sendMessage={sendMessage}
115106
toolCallId={part.toolCallId}
116-
sessionId={sessionId}
117107
/>
118108
);
119109
default:
@@ -158,14 +148,13 @@ type SignTransactionButtonProps = {
158148
{ type: "tool-sign_transaction" }
159149
>["input"]
160150
| undefined;
161-
addToolResult: ReturnType<typeof useChat<ThirdwebAiMessage>>["addToolResult"];
151+
addToolResult: UseChatHelpers<ThirdwebAiMessage>["addToolResult"];
152+
sendMessage: UseChatHelpers<ThirdwebAiMessage>["sendMessage"];
162153
toolCallId: string;
163-
sendMessage: ReturnType<typeof useChat<ThirdwebAiMessage>>["sendMessage"];
164-
sessionId: string;
165154
};
166155

167156
const SignTransactionButton = (props: SignTransactionButtonProps) => {
168-
const { input, addToolResult, toolCallId, sendMessage, sessionId } = props;
157+
const { input, addToolResult, toolCallId, sendMessage } = props;
169158
const transactionData: {
170159
chain_id: number;
171160
to: string;
@@ -209,21 +198,9 @@ const SignTransactionButton = (props: SignTransactionButtonProps) => {
209198
chain_id: transaction.chain.id,
210199
},
211200
});
212-
sendMessage(undefined, {
213-
body: {
214-
sessionId,
215-
},
216-
});
217201
}}
218202
onError={(error) => {
219-
sendMessage(
220-
{ text: `Transaction failed: ${error.message}` },
221-
{
222-
body: {
223-
sessionId,
224-
},
225-
},
226-
);
203+
sendMessage({ text: `Transaction failed: ${error.message}` });
227204
}}
228205
>
229206
Sign Transaction
@@ -241,13 +218,12 @@ type SignSwapButtonProps = {
241218
{ type: "tool-sign_swap" }
242219
>["input"]
243220
| undefined;
244-
addToolResult: ReturnType<typeof useChat<ThirdwebAiMessage>>["addToolResult"];
221+
addToolResult: UseChatHelpers<ThirdwebAiMessage>["addToolResult"];
222+
sendMessage: UseChatHelpers<ThirdwebAiMessage>["sendMessage"];
245223
toolCallId: string;
246-
sendMessage: ReturnType<typeof useChat<ThirdwebAiMessage>>["sendMessage"];
247-
sessionId: string;
248224
};
249225
const SignSwapButton = (props: SignSwapButtonProps) => {
250-
const { input, addToolResult, toolCallId, sendMessage, sessionId } = props;
226+
const { input, addToolResult, toolCallId, sendMessage } = props;
251227
const transactionData: {
252228
chain_id: number;
253229
to: string;
@@ -293,21 +269,9 @@ const SignSwapButton = (props: SignSwapButtonProps) => {
293269
chain_id: transaction.chain.id,
294270
},
295271
});
296-
sendMessage(undefined, {
297-
body: {
298-
sessionId,
299-
},
300-
});
301272
}}
302273
onError={(error) => {
303-
sendMessage(
304-
{ text: `Transaction failed: ${error.message}` },
305-
{
306-
body: {
307-
sessionId,
308-
},
309-
},
310-
);
274+
sendMessage({ text: `Transaction failed: ${error.message}` });
311275
}}
312276
>
313277
Sign swap

apps/playground-web/src/app/ai/ai-sdk/page.tsx

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function Page() {
2929
icon={BotIcon}
3030
title={title}
3131
description={description}
32-
docsLink="https://portal.thirdweb.com/ai/chat?utm_source=playground"
32+
docsLink="https://portal.thirdweb.com/ai/chat/ai-sdk?utm_source=playground"
3333
>
3434
<ChatExample />
3535
<div className="h-8" />
@@ -69,12 +69,10 @@ const thirdwebAI = createThirdwebAI({
6969
});
7070
7171
export async function POST(req: Request) {
72-
const { messages, sessionId } = await req.json();
73-
72+
const { messages, id } = await req.json();
7473
const result = streamText({
75-
model: thirdwebAI.chat({
74+
model: thirdwebAI.chat(id, {
7675
context: {
77-
session_id: sessionId, // session id for continuity
7876
chain_ids: [8453], // optional chain ids
7977
from: "0x...", // optional from address
8078
auto_execute_transactions: true, // optional, defaults to false
@@ -86,14 +84,6 @@ export async function POST(req: Request) {
8684
8785
return result.toUIMessageStreamResponse({
8886
sendReasoning: true, // optional, to send reasoning steps to the client
89-
messageMetadata({ part }) {
90-
// record session id for continuity
91-
if (part.type === "finish-step") {
92-
return {
93-
session_id: part.response.id,
94-
};
95-
}
96-
},
9787
});
9888
}
9989
@@ -122,33 +112,19 @@ import { useState } from 'react';
122112
import { ThirdwebAiMessage } from '@thirdweb-dev/ai-sdk-provider';
123113
124114
export default function Page() {
125-
const [sessionId, setSessionId] = useState('');
126-
const { messages, sendMessage, status } = useChat<ThirdwebAiMessage>({
115+
const { messages, sendMessage } = useChat<ThirdwebAiMessage>({
127116
transport: new DefaultChatTransport({
128117
// see server implementation below
129118
api: '/api/chat',
130119
}),
131-
onFinish: ({ message }) => {
132-
// record session id for continuity
133-
setSessionId(message.metadata?.session_id ?? '');
134-
},
135120
});
136121
137-
const send = (message: string) => {
138-
sendMessage({ text: message }, {
139-
body: {
140-
// send session id for continuity
141-
sessionId,
142-
},
143-
});
144-
}
145-
146122
return (
147123
<>
148124
{messages.map(message => (
149125
<RenderMessage message={message} />
150126
))}
151-
<ChatInputBox send={send} />
127+
<ChatInputBox send={sendMessage} />
152128
</>
153129
);
154130
}`}

apps/playground-web/src/app/api/chat/route.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,15 @@ const thirdwebAI = createThirdwebAI({
1111

1212
export async function POST(req: Request) {
1313
const body = await req.json();
14-
const { messages, sessionId }: { messages: UIMessage[]; sessionId: string } =
15-
body;
14+
const { messages, id }: { messages: UIMessage[]; id: string } = body;
1615

1716
const result = streamText({
18-
model: thirdwebAI.chat({
19-
context: {
20-
session_id: sessionId,
21-
},
22-
}),
17+
model: thirdwebAI.chat(id),
2318
messages: convertToModelMessages(messages),
2419
tools: thirdwebAI.tools(),
2520
});
2621

2722
return result.toUIMessageStreamResponse({
2823
sendReasoning: true,
29-
messageMetadata({ part }) {
30-
if (part.type === "finish-step") {
31-
return {
32-
session_id: part.response.id,
33-
};
34-
}
35-
},
3624
});
3725
}

0 commit comments

Comments
 (0)