16
16
ParsedChatCompletionMessage ,
17
17
)
18
18
import rich
19
- import petname
19
+ import petname # type: ignore[import-untyped]
20
20
from typer import Typer
21
21
import uuid
22
22
30
30
Confirmation ,
31
31
DoneFlag ,
32
32
Writefile ,
33
- get_is_waiting_user_input ,
34
33
get_tool_output ,
35
34
SHELL ,
36
35
start_shell ,
@@ -92,29 +91,22 @@ def parse_user_message_special(msg: str) -> ChatCompletionUserMessageParam:
92
91
if line .startswith ("%" ):
93
92
args = line [1 :].strip ().split (" " )
94
93
command = args [0 ]
95
- assert command == ' image'
94
+ assert command == " image"
96
95
image_path = args [1 ]
97
- with open (image_path , 'rb' ) as f :
96
+ with open (image_path , "rb" ) as f :
98
97
image_bytes = f .read ()
99
98
image_b64 = base64 .b64encode (image_bytes ).decode ("utf-8" )
100
99
image_type = mimetypes .guess_type (image_path )[0 ]
101
- dataurl = f'data:{ image_type } ;base64,{ image_b64 } '
102
- parts .append ({
103
- 'type' : 'image_url' ,
104
- 'image_url' : {
105
- 'url' : dataurl ,
106
- 'detail' : 'auto'
107
- }
108
- })
100
+ dataurl = f"data:{ image_type } ;base64,{ image_b64 } "
101
+ parts .append (
102
+ {"type" : "image_url" , "image_url" : {"url" : dataurl , "detail" : "auto" }}
103
+ )
109
104
else :
110
- if len (parts ) > 0 and parts [- 1 ][' type' ] == ' text' :
111
- parts [- 1 ][' text' ] += ' \n ' + line
105
+ if len (parts ) > 0 and parts [- 1 ][" type" ] == " text" :
106
+ parts [- 1 ][" text" ] += " \n " + line
112
107
else :
113
- parts .append ({'type' : 'text' , 'text' : line })
114
- return {
115
- 'role' : 'user' ,
116
- 'content' : parts
117
- }
108
+ parts .append ({"type" : "text" , "text" : line })
109
+ return {"role" : "user" , "content" : parts }
118
110
119
111
120
112
app = Typer (pretty_exceptions_show_locals = False )
@@ -146,7 +138,7 @@ def loop(
146
138
if history [1 ]["role" ] != "user" :
147
139
raise ValueError ("Invalid history file, second message should be user" )
148
140
first_message = ""
149
- waiting_for_assistant = history [- 1 ][' role' ] != ' assistant'
141
+ waiting_for_assistant = history [- 1 ][" role" ] != " assistant"
150
142
151
143
my_dir = os .path .dirname (__file__ )
152
144
config_file = os .path .join (my_dir , ".." , ".." , "config.toml" )
@@ -161,9 +153,6 @@ def loop(
161
153
enc = tiktoken .encoding_for_model (
162
154
config .model if not config .model .startswith ("o1" ) else "gpt-4o"
163
155
)
164
- is_waiting_user_input = get_is_waiting_user_input (
165
- config .model , config .cost_file [config .model ]
166
- )
167
156
168
157
tools = [
169
158
openai .pydantic_function_tool (
@@ -290,7 +279,7 @@ def loop(
290
279
)
291
280
system_console .print (f"\n Total cost: { config .cost_unit } { cost :.3f} " )
292
281
output_toks += output_toks_
293
-
282
+
294
283
_histories .append (item )
295
284
for tool_call_id , toolcallargs in tool_call_args_by_id .items ():
296
285
for toolindex , tool_args in toolcallargs .items ():
@@ -300,7 +289,7 @@ def loop(
300
289
enc ,
301
290
limit - cost ,
302
291
loop ,
303
- is_waiting_user_input ,
292
+ max_tokens = 2048 ,
304
293
)
305
294
except Exception as e :
306
295
output_or_done = (
@@ -322,42 +311,49 @@ def loop(
322
311
f"\n Total cost: { config .cost_unit } { cost :.3f} "
323
312
)
324
313
return output_or_done .task_output , cost
325
-
314
+
326
315
output = output_or_done
327
316
328
317
if isinstance (output , ImageData ):
329
318
randomId = petname .Generate (2 , "-" )
330
319
if not image_histories :
331
- image_histories .extend ([
332
- {
333
- 'role' : 'assistant' ,
334
- 'content' : f'Share images with ids: { randomId } '
335
-
336
- },
337
- {
338
- 'role' : 'user' ,
339
- 'content' : [{
340
- 'type' : 'image_url' ,
341
- 'image_url' : {
342
- 'url' : output .dataurl ,
343
- 'detail' : 'auto'
344
- }
345
- }]
346
- }]
320
+ image_histories .extend (
321
+ [
322
+ {
323
+ "role" : "assistant" ,
324
+ "content" : f"Share images with ids: { randomId } " ,
325
+ },
326
+ {
327
+ "role" : "user" ,
328
+ "content" : [
329
+ {
330
+ "type" : "image_url" ,
331
+ "image_url" : {
332
+ "url" : output .dataurl ,
333
+ "detail" : "auto" ,
334
+ },
335
+ }
336
+ ],
337
+ },
338
+ ]
347
339
)
348
340
else :
349
- image_histories [0 ]['content' ] += ', ' + randomId
350
- image_histories [1 ]["content" ].append ({ # type: ignore
351
- 'type' : 'image_url' ,
352
- 'image_url' : {
353
- 'url' : output .dataurl ,
354
- 'detail' : 'auto'
341
+ image_histories [0 ]["content" ] += ", " + randomId
342
+ second_content = image_histories [1 ]["content" ]
343
+ assert isinstance (second_content , list )
344
+ second_content .append (
345
+ {
346
+ "type" : "image_url" ,
347
+ "image_url" : {
348
+ "url" : output .dataurl ,
349
+ "detail" : "auto" ,
350
+ },
355
351
}
356
- } )
352
+ )
357
353
358
354
item = {
359
355
"role" : "tool" ,
360
- "content" : f' Ask user for image id: { randomId } ' ,
356
+ "content" : f" Ask user for image id: { randomId } " ,
361
357
"tool_call_id" : tool_call_id + str (toolindex ),
362
358
}
363
359
else :
0 commit comments