Skip to content

Commit 1663483

Browse files
committed
Implement basic playground using @axflow/models
1 parent b3122ec commit 1663483

4 files changed

Lines changed: 125 additions & 0 deletions

File tree

app/api/openai/chat/route.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { OpenAIChat } from '@axflow/models/openai/chat';
2+
import { StreamingJsonResponse, type MessageType } from '@axflow/models/shared';
3+
4+
export const runtime = 'edge';
5+
6+
/**
7+
* Streaming OpenAI chat on the edge using @axflow/models.
8+
*
9+
* POST /api/openai/chat
10+
*/
11+
export async function POST(request: Request) {
12+
const { messages } = await request.json();
13+
14+
const stream = await OpenAIChat.streamTokens(
15+
{
16+
model: 'gpt-4',
17+
messages: messages.map((msg: MessageType) => ({ role: msg.role, content: msg.content })),
18+
},
19+
{
20+
apiKey: process.env.OPENAI_API_KEY!,
21+
},
22+
);
23+
24+
return new StreamingJsonResponse(stream);
25+
}

app/playground/page.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use client';
2+
3+
import { CounterClockwiseClockIcon } from '@radix-ui/react-icons';
4+
5+
import { Button } from '@/components/ui/button';
6+
import { Textarea } from '@/components/ui/textarea';
7+
8+
import { useChat } from '@axflow/models/react';
9+
import type { MessageType } from '@axflow/models/shared';
10+
11+
const API_URL = '/api/openai/chat';
12+
13+
export default function Playground() {
14+
const { input, onChange, onSubmit, messages } = useChat({ url: API_URL });
15+
16+
return (
17+
<div className="pt-[52px]">
18+
<div className="flex justify-center gap-8">
19+
<Form input={input} onChange={onChange} onSubmit={onSubmit} />
20+
<Messages messages={messages} />
21+
</div>
22+
</div>
23+
);
24+
}
25+
26+
type FormPropsType = {
27+
input: string;
28+
onSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
29+
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
30+
};
31+
32+
function Form(props: FormPropsType) {
33+
return (
34+
<section>
35+
<form onSubmit={props.onSubmit}>
36+
<div className="h-[600px] w-[500px]">
37+
<Textarea
38+
className="h-full"
39+
placeholder="Enter message here"
40+
value={props.input}
41+
onChange={props.onChange}
42+
></Textarea>
43+
</div>
44+
<div className="flex items-center space-x-2 pt-4">
45+
<Button type="submit">Submit</Button>
46+
<Button variant="secondary">
47+
<span className="sr-only">Show history</span>
48+
<CounterClockwiseClockIcon className="h-4 w-4" />
49+
</Button>
50+
</div>
51+
</form>
52+
</section>
53+
);
54+
}
55+
56+
function Messages(props: { messages: MessageType[] }) {
57+
return (
58+
<section>
59+
<div className="h-[600px] w-[500px] bg-muted bg-zinc-900 text-sm px-3 py-2 rounded space-y-4">
60+
{props.messages.map((msg) => (
61+
<p key={msg.id}>
62+
{msg.data && (
63+
<span className="block mt-2 text-xs">Has {msg.data.length} data items</span>
64+
)}
65+
{msg.content}
66+
</p>
67+
))}
68+
</div>
69+
</section>
70+
);
71+
}

package-lock.json

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12+
"@axflow/models": "^0.0.1-beta.2",
1213
"@radix-ui/react-alert-dialog": "^1.0.4",
1314
"@radix-ui/react-icons": "^1.3.0",
1415
"@radix-ui/react-label": "^2.0.2",

0 commit comments

Comments
 (0)