11#!/usr/bin/env python3
22from openai import AsyncOpenAI
3- from openai .types .beta .assistant_stream_event import ThreadMessageInProgress
4- from openai .types .beta .threads import MessageDeltaEvent , TextDeltaBlock
53
64from nicegui import ui
75
86client = AsyncOpenAI (api_key = 'provide your OpenAI API key here' )
97
108
11- @ui .page ('/' )
12- async def main ():
13- assistant = await client .beta .assistants .create (
14- name = 'NiceGUI Assistant' ,
15- instructions = '''
16- You are a personal assistant for NiceGUI developers.
17- Your sole focus is to help with questions about the NiceGUI framework.
18- You are precise and concise.
19- Stay on the topic.
20- Very short answers are preferred, but always be friendly and polite.
21- ''' ,
22- tools = [{'type' : 'code_interpreter' }],
23- model = 'gpt-4o-mini' ,
24- )
25-
26- thread = await client .beta .threads .create ()
9+ async def root ():
10+ messages = []
2711
2812 async def send () -> None :
13+ messages .append ({'role' : 'user' , 'content' : question .value })
14+
2915 response .content = ''
3016 spinner = ui .spinner (size = '5em' , type = 'comment' ).classes ('mx-auto' )
31- await client .beta .threads .messages .create (
32- thread_id = thread .id ,
33- role = 'user' ,
34- content = question .value ,
35- )
36- stream = await client .beta .threads .runs .create (
37- assistant_id = assistant .id ,
38- thread_id = thread .id ,
17+
18+ stream = await client .chat .completions .create (
19+ model = 'gpt-4o-mini' ,
20+ messages = [
21+ {
22+ 'role' : 'system' ,
23+ 'content' : '''
24+ You are a personal assistant for NiceGUI developers.
25+ Your sole focus is to help with questions about the NiceGUI framework.
26+ You are precise and concise.
27+ Stay on the topic.
28+ Very short answers are preferred, but always be friendly and polite.
29+ ''' ,
30+ },
31+ * messages ,
32+ ],
3933 stream = True ,
4034 )
35+
36+ spinner .delete ()
37+ assistant_message = ''
38+
4139 async for chunk in stream :
42- if isinstance (chunk , ThreadMessageInProgress ):
43- spinner .delete ()
44- # NOTE: the stream contains a lot of different types so we need to filter out the ones we don't need
45- if not isinstance (chunk .data , MessageDeltaEvent ) or not chunk .data .delta .content :
46- continue
47- content = chunk .data .delta .content [0 ]
48- if not isinstance (content , TextDeltaBlock ) or content .text is None or content .text .value is None :
49- continue
50- response .content += content .text .value
40+ if chunk .choices and chunk .choices [0 ].delta .content :
41+ content = chunk .choices [0 ].delta .content
42+ assistant_message += content
43+ response .content += content
44+
45+ messages .append ({'role' : 'assistant' , 'content' : assistant_message })
5146
5247 with ui .column ().classes ('mx-auto w-full max-w-xl my-16' ):
5348 ui .label ('NiceGUI Assistant' ).classes ('text-2xl font-bold mx-auto' )
@@ -57,4 +52,4 @@ async def send() -> None:
5752 response = ui .markdown ().classes ('mx-4 mt-2' )
5853 ui .timer (0 , send , once = True ) # NOTE: we send the prepared demo question immediately
5954
60- ui .run ()
55+ ui .run (root = root )
0 commit comments