Skip to content

Commit be28b0c

Browse files
[Docs] Add AI Chat API documentation and endpoint metadata (#7828)
1 parent c661a48 commit be28b0c

File tree

8 files changed

+412
-98
lines changed

8 files changed

+412
-98
lines changed

apps/portal/src/app/Header.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ const apisLinks = [
142142
];
143143

144144
const aiLinks = [
145+
{
146+
href: "/ai/chat",
147+
name: "Chat API",
148+
},
145149
{
146150
href: "/ai/mcp",
147151
name: "MCP",
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
type APIParameter,
3+
ApiEndpoint,
4+
} from "@/components/Document/APIEndpointMeta/ApiEndpoint";
5+
import { secretKeyHeaderParameter } from "../../../components/Document/APIEndpointMeta/common";
6+
7+
const contextFilterType = `\
8+
{
9+
from: string | null;
10+
chain_ids: string[] | null;
11+
session_id: string | null;
12+
}`;
13+
14+
const contextParameter: APIParameter = {
15+
description: "Provide additional context information along with the message",
16+
name: "context",
17+
required: false,
18+
type: contextFilterType,
19+
example: {
20+
from: "0x2247d5d238d0f9d37184d8332aE0289d1aD9991b",
21+
chain_ids: [8453],
22+
},
23+
};
24+
25+
const response200Example = `\
26+
{
27+
"message": "I've prepared a native ETH transfer as requested. Would you like to proceed with executing this transfer?",
28+
"session_id": "123",
29+
"request_id": "456",
30+
"actions": [
31+
{
32+
"type": "sign_transaction",
33+
"data": {
34+
"chainId": 8453,
35+
"to": "0x1234567890123456789012345678901234567890",
36+
"value": "10000000000000000",
37+
"data": "0x"
38+
},
39+
"session_id": "123",
40+
"request_id": "456",
41+
"source": "model",
42+
"tool_name": null,
43+
"description": null,
44+
"kwargs": null
45+
}
46+
]
47+
}`;
48+
49+
export function EndpointMetadata() {
50+
return (
51+
<ApiEndpoint
52+
metadata={{
53+
description:
54+
"Send requests to the thirdweb AI model and receive a responses.",
55+
method: "POST",
56+
origin: "https://api.thirdweb.com",
57+
path: "/ai/chat",
58+
request: {
59+
bodyParameters: [
60+
{
61+
description: "The message to be processed.",
62+
example: [
63+
{
64+
role: "user",
65+
content: "Transfer 10 USDC to vitalik.eth",
66+
},
67+
],
68+
name: "messages",
69+
required: true,
70+
type: "array",
71+
},
72+
{
73+
description: "Whether to stream the response or not",
74+
example: false,
75+
name: "stream",
76+
required: false,
77+
type: "boolean",
78+
},
79+
contextParameter,
80+
],
81+
headers: [secretKeyHeaderParameter],
82+
pathParameters: [],
83+
},
84+
responseExamples: {
85+
200: response200Example,
86+
},
87+
title: "Chat via HTTP API",
88+
}}
89+
/>
90+
);
91+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Response Handling
2+
3+
## Streamed vs non-streamed responses
4+
5+
- **Streamed Responses**: This method streams data in real-time, providing immediate feedback as the response is generated. Set the `stream` parameter to `true` in your request, the API delivers responses via Server-Sent Events (SSE).
6+
- **Non-Streamed Responses**: When the `stream` parameter is set to `false`, the API returns the complete response in a single JSON payload after processing is complete.
7+
8+
## Handling Streamed Responses
9+
10+
For `stream:true`, you'll need to handle the following event types:
11+
12+
- `init`: Initializes the stream and provides session information
13+
- `presence`: Provides backend status updates about worker processing
14+
- `delta`: Contains chunks of the response message text
15+
- `action`: Contains blockchain transaction or action data
16+
- `image`: Contains image data
17+
- `context`: Contains context data
18+
- `error`: Contains error information if something goes wrong
19+
20+
**Example SSE Stream:**
21+
22+
```http
23+
event: init
24+
data: {
25+
"session_id": "f4b45429-9570-4ee8-8c8f-8b267429915a",
26+
"request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
27+
"type": "init",
28+
"source": "model",
29+
}
30+
31+
event: presence
32+
data: {
33+
"session_id": "c238c379-9875-4729-afb2-bf3c26081e24",
34+
"request_id": "8b0e733a-89fd-4585-8fac-b4334208eada",
35+
"source": "model",
36+
"type": "presence",
37+
"data": "Need to convert 0.00001 ETH to wei, then prepare native transfer to `0x2247d5d238d0f9d37184d8332aE0289d1aD9991b`."
38+
}
39+
40+
event: presence
41+
data: {
42+
"session_id": "f4b45429-9570-4ee8-8c8f-8b267429915a",
43+
"request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
44+
"type": "presence",
45+
"source": "model",
46+
"data": "Now that I have the wei value (10,000,000,000,000), I will prepare a native transfer to the recipient."
47+
}
48+
49+
event: delta
50+
data: {"v": "To send 0.0001 ETH on the Sepolia network"}
51+
52+
event: delta
53+
data: {"v": " to the address associated with"}
54+
55+
event: action
56+
data: {
57+
"session_id": "f4b45429-9570-4ee8-8c8f-8b267429915a",
58+
"request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
59+
"type": "sign_transaction",
60+
"source": "executor",
61+
"data": "{\"chainId\": 11155111, \"to\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\", \"data\": \"0x\", \"value\": \"0x5af3107a4000\"}"
62+
}
63+
```
64+
65+
### TypeScript Example
66+
67+
We recommend using the `fetch-event-stream` package to handle the event stream in TypeScript. This gives you an easy way to handle each event type.
68+
69+
```jsx
70+
import { stream } from "fetch-event-stream";
71+
72+
const events = await stream(`https://api.thirdweb.com/ai/chat`, {
73+
body: JSON.stringify({
74+
messages: [
75+
{
76+
role: "user",
77+
content: "Transfer 10 USDC to vitalik.eth",
78+
},
79+
],
80+
}),
81+
headers: {
82+
"Content-Type": "application/json",
83+
"x-secret-key": "<your-secret-key>",
84+
},
85+
method: "POST",
86+
});
87+
88+
// process the event stream
89+
for await (const event of events) {
90+
if (!event.data) {
91+
continue;
92+
}
93+
switch (event.event) {
94+
case "init": {
95+
console.log("Init event", event.data);
96+
// handle init event (session id and request id)
97+
break;
98+
}
99+
case "presence": {
100+
console.log("Presence event", event.data);
101+
// handle intermediate thinking steps
102+
break;
103+
}
104+
case "delta": {
105+
console.log("Delta event", event.data);
106+
// handle delta event (streamed output text response)
107+
break;
108+
}
109+
case "action": {
110+
const data = JSON.parse(event.data);
111+
112+
// handle transaction signing
113+
if (data.type === "sign_transaction") {
114+
const transactionData = JSON.parse(data.data);
115+
console.log("Sign transaction event", transactionData);
116+
}
117+
118+
// handle swap signing
119+
if (data.type === "sign_swap") {
120+
const swapData = JSON.parse(data.data);
121+
console.log("Sign swap event", swapData);
122+
}
123+
124+
break;
125+
}
126+
case "image": {
127+
const data = JSON.parse(event.data);
128+
// handle image rendering
129+
console.log("Image data", data);
130+
break;
131+
}
132+
case "context": {
133+
console.log("Context event", event.data);
134+
// handle context changes (chain ids, wallet address, etc)
135+
break;
136+
}
137+
case "error": {
138+
console.log("Error event", event.data);
139+
// handle error event (error message)
140+
break;
141+
}
142+
}
143+
}
144+
```
145+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { EndpointMetadata } from "./EndpointMetadata";
2+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@doc";
3+
4+
# Chat API
5+
6+
The thirdweb AI chat API is a standard OpenAI-compatible chat completion API that allows you to interact with the thirdweb AI model, specialized for blockchain interactions.
7+
8+
The thirdweb proprietary model is optimized for blockchain interactions and can:
9+
10+
- Query real-time data from the blockchain
11+
- Analyze transactions
12+
- Fetch token balances, prices and metadata
13+
- Prepare any contract call or transaction for signing
14+
- Prepare swaps from any token pair
15+
- Deploy contracts
16+
- Generate images
17+
- Search the web for information
18+
- And more!
19+
20+
You can use the API with the API directly, or with any OpenAI-compatible client library.
21+
22+
<Tabs defaultValue="api">
23+
<TabsList>
24+
<TabsTrigger value="api">HTTP API</TabsTrigger>
25+
<TabsTrigger value="openai">OpenAI Client</TabsTrigger>
26+
</TabsList>
27+
<TabsContent value="api">
28+
<EndpointMetadata />
29+
</TabsContent>
30+
<TabsContent value="openai">
31+
32+
### Using the OpenAI Client
33+
34+
You can use the standard OpenAI client library to interact with the thirdweb AI model.
35+
36+
```python
37+
from openai import OpenAI
38+
39+
client = OpenAI(
40+
base_url="https://api.thirdweb.com/ai",
41+
api_key="<your-project-secret-key>",
42+
)
43+
chat_completion = client.chat.completions.create(
44+
model="t0",
45+
messages=[{"role": "user", "content": "Transfer 10 USDC to vitalik.eth"}],
46+
stream=False,
47+
extra_body={ "context": { "from": "0x...", "chain_ids": [8453] }}
48+
)
49+
50+
print(chat_completion)
51+
```
52+
</TabsContent>
53+
</Tabs>

apps/portal/src/app/ai/layout.tsx

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,16 @@
11
import { createMetadata } from "@doc";
2-
import { BookIcon, ZapIcon } from "lucide-react";
32
import { DocLayout } from "@/components/Layouts/DocLayout";
3+
import { sidebar } from "./sidebar";
44

55
export default async function Layout(props: { children: React.ReactNode }) {
66
return (
7-
<DocLayout
8-
editPageButton={true}
9-
sideBar={{
10-
links: [
11-
{
12-
name: "MCP Server",
13-
icon: <ZapIcon />,
14-
href: "/ai/mcp",
15-
},
16-
{
17-
name: "llms.txt",
18-
icon: <BookIcon />,
19-
href: "/ai/llm-txt",
20-
},
21-
],
22-
name: "AI",
23-
}}
24-
>
7+
<DocLayout editPageButton={true} sideBar={sidebar}>
258
<div>{props.children}</div>
269
</DocLayout>
2710
);
2811
}
2912

3013
export const metadata = createMetadata({
31-
description: "AI tools for agents and LLM clients.",
14+
description: "AI tools for apps, agents and LLM clients.",
3215
title: "thirdweb AI",
3316
});

apps/portal/src/app/ai/sidebar.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { BookIcon, ZapIcon } from "lucide-react";
2+
import type { SideBar } from "@/components/Layouts/DocLayout";
3+
4+
export const sidebar: SideBar = {
5+
links: [
6+
{
7+
name: "Chat API",
8+
isCollapsible: false,
9+
links: [
10+
{
11+
name: "Get Started",
12+
href: "/ai/chat",
13+
icon: <ZapIcon />,
14+
},
15+
{
16+
name: "Response Handling",
17+
href: "/ai/chat/handling-responses",
18+
},
19+
{
20+
name: "API Reference",
21+
href: "https://api.thirdweb-dev.com/reference#tag/ai/post/ai/chat",
22+
},
23+
],
24+
},
25+
{ separator: true },
26+
{
27+
name: "MCP Server",
28+
icon: <ZapIcon />,
29+
href: "/ai/mcp",
30+
},
31+
{
32+
name: "llms.txt",
33+
icon: <BookIcon />,
34+
href: "/ai/llm-txt",
35+
},
36+
],
37+
name: "AI",
38+
};

0 commit comments

Comments
 (0)