Skip to content

Commit 1933c3f

Browse files
[AI SDK Provider] Auto handle session ids
1 parent 89eeac1 commit 1933c3f

File tree

6 files changed

+119
-160
lines changed

6 files changed

+119
-160
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: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import { 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:
@@ -160,12 +150,10 @@ type SignTransactionButtonProps = {
160150
| undefined;
161151
addToolResult: ReturnType<typeof useChat<ThirdwebAiMessage>>["addToolResult"];
162152
toolCallId: string;
163-
sendMessage: ReturnType<typeof useChat<ThirdwebAiMessage>>["sendMessage"];
164-
sessionId: string;
165153
};
166154

167155
const SignTransactionButton = (props: SignTransactionButtonProps) => {
168-
const { input, addToolResult, toolCallId, sendMessage, sessionId } = props;
156+
const { input, addToolResult, toolCallId, sendMessage } = props;
169157
const transactionData: {
170158
chain_id: number;
171159
to: string;
@@ -209,21 +197,9 @@ const SignTransactionButton = (props: SignTransactionButtonProps) => {
209197
chain_id: transaction.chain.id,
210198
},
211199
});
212-
sendMessage(undefined, {
213-
body: {
214-
sessionId,
215-
},
216-
});
217200
}}
218201
onError={(error) => {
219-
sendMessage(
220-
{ text: `Transaction failed: ${error.message}` },
221-
{
222-
body: {
223-
sessionId,
224-
},
225-
},
226-
);
202+
sendMessage({ text: `Transaction failed: ${error.message}` });
227203
}}
228204
>
229205
Sign Transaction
@@ -243,11 +219,9 @@ type SignSwapButtonProps = {
243219
| undefined;
244220
addToolResult: ReturnType<typeof useChat<ThirdwebAiMessage>>["addToolResult"];
245221
toolCallId: string;
246-
sendMessage: ReturnType<typeof useChat<ThirdwebAiMessage>>["sendMessage"];
247-
sessionId: string;
248222
};
249223
const SignSwapButton = (props: SignSwapButtonProps) => {
250-
const { input, addToolResult, toolCallId, sendMessage, sessionId } = props;
224+
const { input, addToolResult, toolCallId, sendMessage } = props;
251225
const transactionData: {
252226
chain_id: number;
253227
to: string;
@@ -293,21 +267,9 @@ const SignSwapButton = (props: SignSwapButtonProps) => {
293267
chain_id: transaction.chain.id,
294268
},
295269
});
296-
sendMessage(undefined, {
297-
body: {
298-
sessionId,
299-
},
300-
});
301270
}}
302271
onError={(error) => {
303-
sendMessage(
304-
{ text: `Transaction failed: ${error.message}` },
305-
{
306-
body: {
307-
sessionId,
308-
},
309-
},
310-
);
272+
sendMessage({ text: `Transaction failed: ${error.message}` });
311273
}}
312274
>
313275
Sign swap

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

Lines changed: 3 additions & 28 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,9 @@ const thirdwebAI = createThirdwebAI({
6969
});
7070
7171
export async function POST(req: Request) {
72-
const { messages, sessionId } = await req.json();
73-
7472
const result = streamText({
7573
model: thirdwebAI.chat({
7674
context: {
77-
session_id: sessionId, // session id for continuity
7875
chain_ids: [8453], // optional chain ids
7976
from: "0x...", // optional from address
8077
auto_execute_transactions: true, // optional, defaults to false
@@ -86,14 +83,6 @@ export async function POST(req: Request) {
8683
8784
return result.toUIMessageStreamResponse({
8885
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-
},
9786
});
9887
}
9988
@@ -122,33 +111,19 @@ import { useState } from 'react';
122111
import { ThirdwebAiMessage } from '@thirdweb-dev/ai-sdk-provider';
123112
124113
export default function Page() {
125-
const [sessionId, setSessionId] = useState('');
126-
const { messages, sendMessage, status } = useChat<ThirdwebAiMessage>({
114+
const { messages, sendMessage } = useChat<ThirdwebAiMessage>({
127115
transport: new DefaultChatTransport({
128116
// see server implementation below
129117
api: '/api/chat',
130118
}),
131-
onFinish: ({ message }) => {
132-
// record session id for continuity
133-
setSessionId(message.metadata?.session_id ?? '');
134-
},
135119
});
136120
137-
const send = (message: string) => {
138-
sendMessage({ text: message }, {
139-
body: {
140-
// send session id for continuity
141-
sessionId,
142-
},
143-
});
144-
}
145-
146121
return (
147122
<>
148123
{messages.map(message => (
149124
<RenderMessage message={message} />
150125
))}
151-
<ChatInputBox send={send} />
126+
<ChatInputBox send={sendMessage} />
152127
</>
153128
);
154129
}`}

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[] } = 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)