Skip to content

Commit 2d49891

Browse files
Merge pull request #19 from unclecode/main
Auto PR from main to live
2 parents 3d906b3 + 0766116 commit 2d49891

14 files changed

+1365
-59
lines changed

app/libs/__init__.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from .context import Context
2+
from .base_handler import Handler, DefaultCompletionHandler, ExceptionHandler, FallbackHandler
3+
from .provider_handler import ProviderSelectionHandler
4+
from .vision_handler import ImageMessageHandler
5+
from .tools_handler import ToolExtractionHandler, ToolResponseHandler
6+
7+
__all__ = [
8+
"Context",
9+
"Handler",
10+
"DefaultCompletionHandler",
11+
"ExceptionHandler",
12+
"ProviderSelectionHandler",
13+
"ImageMessageHandler",
14+
"ToolExtractionHandler",
15+
"ToolResponseHandler",
16+
"FallbackHandler",
17+
]

app/libs/base_handler.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from abc import ABC, abstractmethod
2+
from .context import Context
3+
from fastapi.responses import JSONResponse
4+
import traceback
5+
6+
class Handler(ABC):
7+
"""Abstract Handler class for building the chain of handlers."""
8+
9+
_next_handler: "Handler" = None
10+
11+
def set_next(self, handler: "Handler") -> "Handler":
12+
self._next_handler = handler
13+
return handler
14+
15+
@abstractmethod
16+
async def handle(self, context: Context):
17+
if self._next_handler:
18+
try:
19+
return await self._next_handler.handle(context)
20+
except Exception as e:
21+
_exception_handler: "Handler" = ExceptionHandler()
22+
# Extract the stack trace and log the exception
23+
return await _exception_handler.handle(context, e)
24+
25+
26+
class DefaultCompletionHandler(Handler):
27+
async def handle(self, context: Context):
28+
if context.is_normal_chat:
29+
# Assuming context.client is set and has a method for creating chat completions
30+
completion = context.client.route(
31+
messages=context.messages,
32+
**context.client.clean_params(context.params),
33+
)
34+
context.response = completion.model_dump()
35+
return JSONResponse(content=context.response, status_code=200)
36+
37+
return await super().handle(context)
38+
39+
40+
class FallbackHandler(Handler):
41+
async def handle(self, context: Context):
42+
# This handler does not pass the request further down the chain.
43+
# It acts as a fallback when no other handler has processed the request.
44+
if not context.response:
45+
# The default action when no other handlers have processed the request
46+
context.response = {"message": "No suitable action found for the request."}
47+
return JSONResponse(content=context.response, status_code=400)
48+
49+
# If there's already a response set in the context, it means one of the handlers has processed the request.
50+
return JSONResponse(content=context.response, status_code=200)
51+
52+
53+
class ExceptionHandler(Handler):
54+
async def handle(self, context: Context, exception: Exception):
55+
print(f"Error processing the request: {exception}")
56+
print(traceback.format_exc())
57+
return JSONResponse(
58+
content={"error": "An unexpected error occurred. " + str(exception)},
59+
status_code=500,
60+
)
61+
62+

0 commit comments

Comments
 (0)