10
10
11
11
import json #logging error
12
12
13
- from tokenizers import Tokenizer , models , pre_tokenizers , trainers
13
+ #from tokenizers import Tokenizer, models, pre_tokenizers, trainers # other tokenizer module
14
+
14
15
# setup openai
15
16
openai .api_key = config .openai_api_key
17
+ anthropic .api_key = config .anthropic_api_key
18
+
16
19
if config .openai_api_base is not None :
17
20
openai .api_base = config .openai_api_base
18
- logger = logging .getLogger (__name__ )
19
-
20
- anthropic .api_key = config .claude_api_key
21
21
22
22
OPENAI_COMPLETION_OPTIONS = {
23
23
"temperature" : 0.7 ,
28
28
"request_timeout" : 60.0 ,
29
29
}
30
30
31
- #GPT HELP 2
31
+ logger = logging .getLogger (__name__ )
32
+
33
+ def configure_logging ():
34
+ # Configure logging based on the enable_detailed_logging value
35
+ if config .enable_detailed_logging :
36
+ logging .basicConfig (level = logging .DEBUG , format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s' )
37
+ else :
38
+ logging .basicConfig (level = logging .CRITICAL , format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s' )
39
+
40
+ # Set the logger level based on configuration
41
+ logger .setLevel (logging .getLogger ().level )
42
+
43
+ configure_logging ()
44
+
32
45
def validate_payload (payload ): #maybe comment out
33
46
# Example validation: Ensure all messages have content that is a string
34
47
for message in payload .get ("messages" , []):
35
48
if not isinstance (message .get ("content" ), str ):
36
49
logger .error ("Invalid message content: Not a string" )
37
50
raise ValueError ("Message content must be a string" )
38
- #GPT HELP 2
39
-
40
51
52
+
41
53
class ChatGPT :
42
54
def __init__ (self , model = "gpt-4-1106-preview" ):
43
55
assert model in {"text-davinci-003" , "gpt-3.5-turbo-16k" , "gpt-3.5-turbo" , "gpt-4" , "gpt-4-1106-preview" , "gpt-4-vision-preview" , "gpt-4-turbo-2024-04-09" , "gpt-4o" , "claude-3-opus-20240229" , "claude-3-sonnet-20240229" , "claude-3-haiku-20240307" }, f"Unknown model: { model } "
44
56
self .model = model
45
57
self .is_claude_model = model .startswith ("claude" )
46
58
self .logger = logging .getLogger (__name__ )
47
59
self .headers = {
48
- "Authorization" : f"Bearer { config .claude_api_key if self .is_claude_model else config .openai_api_key } " ,
60
+ "Authorization" : f"Bearer { config .anthropic_api_key if self .is_claude_model else config .openai_api_key } " ,
49
61
"Content-Type" : "application/json" ,
50
62
}
51
63
@@ -64,7 +76,7 @@ async def send_message(self, message, dialog_messages=[], chat_mode="assistant")
64
76
if not prompt .strip ():
65
77
raise ValueError ("Generated prompt is empty" )
66
78
67
- client = anthropic .AsyncAnthropic (api_key = config .claude_api_key )
79
+ client = anthropic .AsyncAnthropic (api_key = config .anthropic_api_key )
68
80
response = await client .completions .create (
69
81
model = self .model ,
70
82
messages = [{"role" : "user" , "content" : prompt }],
@@ -147,7 +159,7 @@ async def send_message_stream(self, message, dialog_messages=[], chat_mode="assi
147
159
if not prompt .strip ():
148
160
raise ValueError ("Generated prompt is empty" )
149
161
150
- client = anthropic .AsyncAnthropic (api_key = config .claude_api_key )
162
+ client = anthropic .AsyncAnthropic (api_key = config .anthropic_api_key )
151
163
152
164
async with client .messages .stream (
153
165
model = self .model ,
@@ -393,52 +405,31 @@ def _generate_claude_prompt(self, message, dialog_messages, chat_mode, image_buf
393
405
combined_prompt += "\n \n Assistant:"
394
406
return combined_prompt
395
407
396
-
397
408
def _postprocess_answer (self , answer ):
398
409
self .logger .debug (f"Pre-processed answer: { answer } " )
399
410
answer = answer .strip ()
400
411
self .logger .debug (f"Post-processed answer: { answer } " )
401
412
return answer
402
413
403
414
def _count_tokens_from_messages (self , messages , answer , model = "gpt-4-1106-preview" ):
415
+
404
416
if model .startswith ("claude" ):
405
- tokenizer = self . _get_claude_tokenizer ( )
417
+ encoding = tiktoken . encoding_for_model ( "gpt-4-turbo-2024-04-09" )
406
418
else :
407
419
encoding = tiktoken .encoding_for_model (model )
408
420
409
421
tokens_per_message = 3
410
422
tokens_per_name = 1
411
423
412
- if model == "gpt-3.5-turbo-16k" :
413
- tokens_per_message = 4 # every message follows <im_start>{role/name}\n{content}<im_end>\n
414
- tokens_per_name = - 1 # if there's a name, the role is omitted
415
- elif model == "gpt-3.5-turbo" :
416
- tokens_per_message = 4
417
- tokens_per_name = - 1
418
- elif model == "gpt-4" :
419
- tokens_per_message = 3
420
- tokens_per_name = 1
421
- elif model == "gpt-4-1106-preview" :
422
- tokens_per_message = 3
423
- tokens_per_name = 1
424
- elif model == "gpt-4-vision-preview" :
425
- tokens_per_message = 3
426
- tokens_per_name = 1
427
- elif model == "gpt-4-turbo-2024-04-09" :
428
- tokens_per_message = 3
429
- tokens_per_name = 1
430
- elif model == "gpt-4o" :
424
+ if model .startswith ("gpt-3" ):
425
+ tokens_per_message = 4 # every message follows <im_start>{role/name}\n{content}<im_end>\n
426
+ tokens_per_name = - 1 # if there's a name, the role is omitted
427
+ elif model .startswith ("gpt-4" ):
431
428
tokens_per_message = 3
432
429
tokens_per_name = 1
433
- elif model == "claude-3-opus-20240229" :
434
- tokens_per_message = 3
435
- tokens_per_name = 1
436
- elif model == "claude-3-sonnet-20240229" :
430
+ elif model .startswith ("claude" ):
437
431
tokens_per_message = 3
438
432
tokens_per_name = 1
439
- elif model == "claude-3-haiku-20240307" :
440
- tokens_per_message = 3
441
- tokens_per_name = 1
442
433
else :
443
434
raise ValueError (f"Unknown model: { model } " )
444
435
@@ -450,49 +441,33 @@ def _count_tokens_from_messages(self, messages, answer, model="gpt-4-1106-previe
450
441
for sub_message in message ["content" ]:
451
442
if "type" in sub_message :
452
443
if sub_message ["type" ] == "text" :
453
- if model .startswith ("claude" ):
454
- n_input_tokens += len (tokenizer .encode (sub_message ["text" ]).tokens )
455
- else :
456
- n_input_tokens += len (encoding .encode (sub_message ["text" ]))
444
+ n_input_tokens += len (encoding .encode (sub_message ["text" ]))
457
445
elif sub_message ["type" ] == "image_url" :
458
446
pass
459
447
else :
460
448
if "type" in message :
461
449
if message ["type" ] == "text" :
462
- if model .startswith ("claude" ):
463
- n_input_tokens += len (tokenizer .encode (message ["text" ]).tokens )
464
- else :
465
- n_input_tokens += len (encoding .encode (message ["text" ]))
450
+ n_input_tokens += len (encoding .encode (message ["text" ]))
466
451
elif message ["type" ] == "image_url" :
467
452
pass
468
453
469
-
470
454
n_input_tokens += 2
471
455
472
456
# output
473
- if model .startswith ("claude" ):
474
- n_output_tokens = 1 + len (tokenizer .encode (answer ).tokens )
475
- else :
476
- n_output_tokens = 1 + len (encoding .encode (answer ))
457
+ n_output_tokens = 1 + len (encoding .encode (answer ))
477
458
478
459
return n_input_tokens , n_output_tokens
479
460
480
461
def _count_tokens_from_prompt (self , prompt , answer , model = "text-davinci-003" ):
481
462
if model .startswith ("claude" ):
482
- tokenizer = self ._get_claude_tokenizer ()
483
- n_input_tokens = len (tokenizer .encode (prompt ).tokens ) + 1
484
- n_output_tokens = len (tokenizer .encode (answer ).tokens )
463
+ encoding = tiktoken .encoding_for_model ("gpt-4-turbo-2024-04-09" )
485
464
else :
486
465
encoding = tiktoken .encoding_for_model (model )
487
- n_input_tokens = len (encoding .encode (prompt )) + 1
488
- n_output_tokens = len (encoding .encode (answer ))
489
466
490
- return n_input_tokens , n_output_tokens
467
+ n_input_tokens = len (encoding .encode (prompt )) + 1
468
+ n_output_tokens = len (encoding .encode (answer ))
491
469
492
- def _get_claude_tokenizer (self ):
493
- tokenizer = Tokenizer (models .BPE ())
494
- tokenizer .pre_tokenizer = pre_tokenizers .ByteLevel ()
495
- return tokenizer
470
+ return n_input_tokens , n_output_tokens
496
471
497
472
async def transcribe_audio (audio_file ) -> str :
498
473
r = await openai .Audio .atranscribe ("whisper-1" , audio_file )
@@ -501,6 +476,7 @@ async def transcribe_audio(audio_file) -> str:
501
476
502
477
async def generate_images (prompt , model = "dall-e-2" , n_images = 4 , size = "1024x1024" , quality = "standard" ):
503
478
"""Generate images using OpenAI's specified model, including DALL-E 3."""
479
+ #redundancy to make sure the api call isnt made wrong
504
480
if model == "dalle-2" :
505
481
model = "dall-e-2"
506
482
quality = "standard"
0 commit comments