Skip to content

Commit dd5c9f1

Browse files
committed
added submodule OSbot-Fast-API
simproved start-local-server.sh major change where LLMs_Chat_Completion now uses @DataClass (via GPT_Prompt_Simple) added prompt example to Swagger for /chat/completion
1 parent 76ad4b0 commit dd5c9f1

22 files changed

+81
-49
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "modules/OSBot-Fast-API"]
2+
path = modules/OSBot-Fast-API
3+
url = [email protected]:owasp-sbot/OSBot-Fast-API.git

modules/OSBot-Fast-API

Submodule OSBot-Fast-API added at e3cd3b1

osbot_llms/backend/s3_minio/S3_DB__Chat_Threads.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def save_chat_completion__user_request(self, llm_chat_completion: LLMs__Chat_Com
4242
chat_thread_id = chat_thread_id ,
4343
llm_request_id = llm_request_id ,
4444
timestamp = timestamp_utc_now() ,
45-
llm_chat_completion = llm_chat_completion.model_dump())
45+
llm_chat_completion = llm_chat_completion.json())
4646
s3_key = self.s3_key(chat_thread_id=chat_thread_id, llm_request_id=llm_request_id, request_type=request_type)
4747
s3_key_items = s3_key.split('/')
4848
public_chat_id = '/'.join(s3_key_items[2:6])
@@ -62,7 +62,7 @@ def save_chat_completion__user_response(self, llm_chat_completion: LLMs__Chat_Co
6262
chat_thread_id = llm_chat_completion.chat_thread_id
6363
llm_request_id = request_id
6464
s3_key = self.s3_key(chat_thread_id=chat_thread_id, llm_request_id=llm_request_id, request_type=request_type)
65-
data = llm_chat_completion.model_dump()
65+
data = llm_chat_completion.json()
6666
metadata = {'request_id' : request_id ,
6767
'request_type' : request_type }
6868
if self.s3_save_data(data=data, s3_key=s3_key, metadata=metadata):

osbot_llms/fast_api/routes/Routes__Chat.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
import traceback
33

44
from fastapi import Request
5+
from fastapi.params import Header, Body
6+
from osbot_utils.utils.Dev import pprint
57
from starlette.responses import StreamingResponse
68
from osbot_fast_api.api.Fast_API_Routes import Fast_API_Routes
79
from osbot_utils.context_managers.capture_duration import capture_duration
810
from osbot_llms.OSBot_LLMs__Shared_Objects import osbot_llms__shared_objects
911
from osbot_llms.fast_api.routes.Routes__OpenAI import Routes__OpenAI
1012
from osbot_llms.llms.chats.LLM__Chat_Completion__Resolve_Engine import LLM__Chat_Completion__Resolve_Engine
1113
from osbot_llms.llms.storage.Chats_Storage__S3_Minio import Chats_Storage__S3_Minio
12-
from osbot_llms.models.LLMs__Chat_Completion import LLMs__Chat_Completion
14+
from osbot_llms.models.LLMs__Chat_Completion import LLMs__Chat_Completion, SWAGGER_EXAMPLE__LLMs__Chat_Completion
1315

1416
ROUTES_PATHS__CONFIG = ['/config/status', '/config/version']
1517
HEADER_NAME__CHAT_ID = 'osbot-llms-chat-id'
@@ -70,7 +72,7 @@ async def simulated_api_call(): # Simulating the respons
7072
traceback.print_exc()
7173

7274

73-
async def completion(self, llm_chat_completion: LLMs__Chat_Completion, request: Request):
75+
async def completion(self, request: Request, llm_chat_completion: LLMs__Chat_Completion = SWAGGER_EXAMPLE__LLMs__Chat_Completion):
7476
request_id = self.request_id(request)
7577
chat_save_result = self.chats_storage_s3_minio.save_user_request(llm_chat_completion, request_id)
7678

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1+
from osbot_utils.base_classes.Type_Safe import Type_Safe
12
from osbot_fast_api.api.Fast_API_Routes import Fast_API_Routes
23

3-
from osbot_llms.utils.Version import version__osbot_llms
4-
4+
from osbot_llms.utils.Version import version__osbot_llms
5+
from dataclasses import dataclass
56

67
class Routes__Info(Fast_API_Routes):
78
tag : str = 'info'
89

910
def version(self):
1011
return {"version" : version__osbot_llms }
1112

12-
def ping(self):
13-
return {"it_is" : "pong" }
14-
1513
def setup_routes(self):
16-
self.add_route_get(self.version)
17-
self.add_route_get(self.ping )
14+
self.add_route_get(self.version)

osbot_llms/fast_api/routes/Routes__OpenAI.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ async def streamer():
9797
gpt_response += answer
9898
yield f"{answer}\n"
9999

100-
llm_chat_completion = LLMs__Chat_Completion(**gpt_prompt_with_system_and_history.model_dump())
100+
llm_chat_completion = LLMs__Chat_Completion(**gpt_prompt_with_system_and_history.json())
101101
llm_chat_completion.llm_answer = gpt_response
102102

103103
self.chats_storage_s3_minio.save_user_response(llm_chat_completion, request_id)
Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
from dataclasses import dataclass, field
12
from decimal import Decimal
2-
from typing import Optional
3+
from typing import Optional, List
4+
5+
from osbot_utils.base_classes.Type_Safe import Type_Safe
36
from pydantic import BaseModel
47
DEFAULT_USER_PROMPT = 'Hi'
58
DEFAULT_TEMPERATURE = 0.0
69
DEFAULT_SEED = 42
710

8-
class GPT_Prompt_Simple(BaseModel):
9-
chat_thread_id: Optional[str] = None
10-
user_prompt : str = DEFAULT_USER_PROMPT
11-
images : list[str] = []
12-
temperature : Decimal = Decimal(DEFAULT_TEMPERATURE)
13-
seed : int = DEFAULT_SEED
14-
max_tokens : Optional[int] = None
15-
user_data : Optional[dict] = None
16-
stream : Optional[bool] = True
11+
@dataclass
12+
class GPT_Prompt_Simple(Type_Safe):
13+
images : list = field(default_factory=list)
14+
chat_thread_id: Optional[str] = field(default='')
15+
user_prompt : str = DEFAULT_USER_PROMPT
16+
temperature : float = float(DEFAULT_TEMPERATURE)
17+
seed : int = DEFAULT_SEED
18+
max_tokens : Optional[int] = None
19+
user_data : Optional[dict] = None
20+
stream : Optional[bool] = True
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from dataclasses import dataclass
12
from typing import Optional
23

34
from osbot_llms.models.GPT_Prompt_Simple import GPT_Prompt_Simple
45

5-
6+
@dataclass
67
class GPT_Prompt_With_System(GPT_Prompt_Simple):
78
system_prompts: Optional[list[str]] = None
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
from dataclasses import dataclass
12
from typing import Optional
23

34
from osbot_llms.models.GPT_History import GPT_History
45
from osbot_llms.models.GPT_Prompt_With_System import GPT_Prompt_With_System
56

6-
7+
@dataclass
78
class GPT_Prompt_With_System_And_History(GPT_Prompt_With_System):
89
histories : Optional[list[GPT_History]] = None

osbot_llms/models/LLMs__Chat_Completion.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
from dataclasses import dataclass
12
from typing import Optional
23

4+
from fastapi.params import Body
5+
36
from osbot_llms.models.GPT_Prompt_With_System_And_History import GPT_Prompt_With_System_And_History
47

8+
SWAGGER_EXAMPLE__LLMs__Chat_Completion = Body(..., example=dict(user_prompt ='Good morning, what is 44-2?',
9+
system_prompts = ['use emojis in the answer' ],
10+
#temperature = 0.0 ,
11+
seed = 42 ,
12+
stream = False ))
513

14+
@dataclass
615
class LLMs__Chat_Completion(GPT_Prompt_With_System_And_History):
716
llm_platform: Optional[str] = None
817
llm_provider: Optional[str] = None

server.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

server__fastapi__llms.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from osbot_llms.OSBot_LLMs__Server_Config import osbot_llms__server_config
2+
from osbot_llms.fast_api.Fast_API__LLMs import Fast_API__LLMs
3+
4+
osbot_llms__server_config.s3_log_requests = True
5+
llm_fast_api = Fast_API__LLMs().setup()
6+
app = llm_fast_api.app()
7+

start-local-server.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
uvicorn server:app --reload
1+
uvicorn server__fastapi__llms:app --reload --host 0.0.0.0 --port 5010

tests/integration/backend/s3_minio/test_S3_DB__Chat_Threads.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def test_save_chat_completion__user_request(self):
9797
'seed' : 42 ,
9898
'stream' : True ,
9999
'system_prompts' : None ,
100-
'temperature' : '0' ,
100+
'temperature' : 0.0 ,
101101
'user_data' : None ,
102102
'user_prompt' : user_prompt },
103103
"llm_request_id" : llm_request_id ,

tests/integration/fast_api/routes/test__api__Routes__Chat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test__completion__save_chat_completion__user_request(self):
2727
"selected_model" : "llama3-70b-8192" }
2828
server_name = osbot_llms__server_config.server_name
2929
llm_chat_completion = LLMs__Chat_Completion(user_prompt=user_prompt, chat_thread_id=chat_thread_id, user_data=user_data)
30-
json_data = json_load(llm_chat_completion.model_dump_json())
30+
json_data = llm_chat_completion.json()
3131
response = self.client.post('/chat/completion', json=json_data) # submit chat request
3232
request_id = response.headers.get('fast-api-request-id')
3333
when_str = self.s3_db_chat_threads.s3_key_generator.path__for_date_time__now_utc()
@@ -63,7 +63,7 @@ def test__view(self):
6363
'seed': 42,
6464
'stream': True,
6565
'system_prompts': None,
66-
'temperature': '0',
66+
'temperature': 0.0,
6767
'user_data': None,
6868
'user_prompt': user_prompt}
6969

tests/integration/fast_api/routes/test__int__Routes__Chat.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def test_handle_other_llms__groq(self):
5858

5959
def test_completion(self):
6060
self.llm_chat_completion.stream = True
61-
streaming_response = invoke_async_function(self.routes_chat.completion(self.llm_chat_completion, self.request))
61+
streaming_response = invoke_async_function(self.routes_chat.completion(self.request, self.llm_chat_completion))
6262
items = invoke_async_function(self.collect_body_iterator(streaming_response.body_iterator))
6363
answer = ''.join(items)
6464

@@ -67,20 +67,20 @@ def test_completion(self):
6767
assert '42' in answer
6868

6969
self.llm_chat_completion.stream = False
70-
response_str = invoke_async_function(self.routes_chat.completion(self.llm_chat_completion, self.request))
70+
response_str = invoke_async_function(self.routes_chat.completion(self.request, self.llm_chat_completion))
7171
assert type(response_str) is str
7272
assert '42' in response_str
7373

7474
def test_completion__openai(self):
7575
user_data = dict(selected_platform = 'Groq (Free)' ,
7676
selected_provider = '1. Meta' ,
7777
selected_model = 'llama3-70b-8192')
78-
self.llm_chat_completion.llm_platform = None
79-
self.llm_chat_completion.llm_provider = None
80-
self.llm_chat_completion.llm_model = None
78+
# self.llm_chat_completion.llm_platform = None
79+
# self.llm_chat_completion.llm_provider = None
80+
# self.llm_chat_completion.llm_model = None
8181
self.llm_chat_completion.user_data = user_data
8282
self.llm_chat_completion.stream = True
83-
streaming_response = invoke_async_function(self.routes_chat.completion(self.llm_chat_completion, self.request))
83+
streaming_response = invoke_async_function(self.routes_chat.completion(self.request, self.llm_chat_completion))
8484
items = invoke_async_function(self.collect_body_iterator(streaming_response.body_iterator))
8585
answer = ''.join(items)
8686

tests/integration/fast_api/test_Fast_API__Chat_Threads.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test__prompt_with_system__stream__save_chat_completion__user_request(self):
3737

3838
llm_chat_completion = LLMs__Chat_Completion(user_prompt=user_prompt, chat_thread_id=chat_thread_id,
3939
user_data=user_data)
40-
json_data = json_load(llm_chat_completion.model_dump_json())
40+
json_data = llm_chat_completion.json()
4141
response = self.client.post('chat/completion', json=json_data)
4242

4343
assert response.status_code == 200

tests/integration/fast_api/test_Fast_API__via_Http.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
from fastapi import FastAPI
33
from osbot_fast_api.utils.Fast_API_Server import Fast_API_Server
44
from osbot_utils.context_managers.print_duration import print_duration
5+
from osbot_utils.testing.Stdout import Stdout
6+
from osbot_utils.utils.Dev import pprint
7+
8+
from osbot_llms.models.LLMs__Chat_Completion import LLMs__Chat_Completion
59
from osbot_llms.utils.Version import version__osbot_llms
610
from tests.llm_fast_api__for_tests import llm_fast_api, llm_fast_api__app
711

@@ -30,4 +34,13 @@ def test_version(self):
3034
with self.llm_fast_api as _:
3135
version__fast_api = _.version__fast_api_server()
3236
assert self.fast_api_server.requests_get('/config/version').json() == {'version': version__fast_api }
33-
assert self.fast_api_server.requests_get('/info/version' ).json() == {'version': version__osbot_llms }
37+
assert self.fast_api_server.requests_get('/info/version' ).json() == {'version': version__osbot_llms }
38+
39+
def test__chat__completion(self):
40+
with self.llm_fast_api as _:
41+
llm_chat_completion = LLMs__Chat_Completion(user_prompt='51-9')
42+
response = self.fast_api_server.requests_post('/chat/completion', data=llm_chat_completion)
43+
assert '42' in response.text
44+
45+
46+

tests/integration/llms/chats/storage/test_Chats_Storage__S3_Minio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def test_save_user_request(self):
4343
assert s3_file_contents.chat_thread_id == chat_thread_id
4444
assert s3_file_contents.llm_request_id == request_id
4545
assert s3_file_contents.llm_chat_completion.images == []
46-
assert s3_file_contents.llm_chat_completion.temperature == '0'
46+
assert s3_file_contents.llm_chat_completion.temperature == 0.0
4747
assert s3_file_contents.llm_chat_completion.seed == 42
4848
assert s3_file_contents.llm_chat_completion.user_prompt == user_prompt
4949

tests/integration/llms/chats/test_LLM__Chat_Completion__Resolve_Engine.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def test_map_provider(self):
1818

1919
llm_chat_completion = LLMs__Chat_Completion(**kwargs)
2020
response = self.llm_resolve_engine.map_provider(llm_chat_completion)
21-
assert response.json() == { 'llm_chat_completion': { 'chat_thread_id': None,
21+
assert response.json() == { 'llm_chat_completion': { 'chat_thread_id': '',
2222
'histories': None,
2323
'images': [],
2424
'llm_answer': None,
@@ -29,7 +29,7 @@ def test_map_provider(self):
2929
'seed': 42,
3030
'stream': True,
3131
'system_prompts': None,
32-
'temperature': Decimal('0'),
32+
'temperature': 0.0,
3333
'user_data': { 'selected_model': 'phi3',
3434
'selected_platform': 'Ollama (Local)',
3535
'selected_provider': 'Microsoft'},

tests/integration/llms/chats/test_LLM__Platform_Engine__Mistral.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def setUpClass(cls):
1515
cls.llm_model = MISTRAL__DEFAULT_MODEL
1616
cls.system_prompt = 'just reply with the answer in one word'
1717
cls.user_prompt = '1+2'
18-
cls.llm_chat_completion = LLMs__Chat_Completion(user_prompt=cls.user_prompt, system_prompt=cls.system_prompt)
18+
cls.llm_chat_completion = LLMs__Chat_Completion(user_prompt=cls.user_prompt, system_prompts=[cls.system_prompt])
1919
cls.kwargs = dict(llm_platform=cls.llm_platform, llm_provider=cls.llm_provider, llm_model=cls.llm_model, llm_chat_completion=cls.llm_chat_completion)
2020
cls.llm_engine_groq = LLM__Platform_Engine__Mistral(**cls.kwargs)
2121

tests/integration/llms/test_API_Perplexity.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from osbot_llms.models.GPT_History import GPT_History
66

77

8-
#@pytest.mark.skip("Re-enable when adding offical support to TCB to the Perplexity API")
8+
#@pytest.mark.skip("Re-enable when adding ofical support to TCB to the Perplexity API")
99
class test_API_Perplexity(TestCase):
1010

1111
def setUp(self):
@@ -33,15 +33,14 @@ def test_ask_using_messages__async_mode(self):
3333
def test_ask_using_messages__sync_mode(self):
3434
model = "mistral-7b-instruct"
3535
system_prompt = "act like a calculator, just reply with the answer"
36-
user_prompt = "40+2"
37-
expected_response = '42'
36+
user_prompt = "1+2"
3837
async_mode = False
3938
messages = [ { "role" : "system" ,
4039
"content" : system_prompt },
4140
{ "role" : "user",
4241
"content" : user_prompt}]
4342
response = self.api_perplexity.ask_using_messages(messages, model=model, async_mode=async_mode)
44-
assert '42' in response
43+
assert '3' in response
4544

4645

4746
def test_ask_using_system_prompts(self):

0 commit comments

Comments
 (0)