-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from unclecode/main
Auto PR from main to live
- Loading branch information
Showing
14 changed files
with
1,365 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from .context import Context | ||
from .base_handler import Handler, DefaultCompletionHandler, ExceptionHandler, FallbackHandler | ||
from .provider_handler import ProviderSelectionHandler | ||
from .vision_handler import ImageMessageHandler | ||
from .tools_handler import ToolExtractionHandler, ToolResponseHandler | ||
|
||
__all__ = [ | ||
"Context", | ||
"Handler", | ||
"DefaultCompletionHandler", | ||
"ExceptionHandler", | ||
"ProviderSelectionHandler", | ||
"ImageMessageHandler", | ||
"ToolExtractionHandler", | ||
"ToolResponseHandler", | ||
"FallbackHandler", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from abc import ABC, abstractmethod | ||
from .context import Context | ||
from fastapi.responses import JSONResponse | ||
import traceback | ||
|
||
class Handler(ABC): | ||
"""Abstract Handler class for building the chain of handlers.""" | ||
|
||
_next_handler: "Handler" = None | ||
|
||
def set_next(self, handler: "Handler") -> "Handler": | ||
self._next_handler = handler | ||
return handler | ||
|
||
@abstractmethod | ||
async def handle(self, context: Context): | ||
if self._next_handler: | ||
try: | ||
return await self._next_handler.handle(context) | ||
except Exception as e: | ||
_exception_handler: "Handler" = ExceptionHandler() | ||
# Extract the stack trace and log the exception | ||
return await _exception_handler.handle(context, e) | ||
|
||
|
||
class DefaultCompletionHandler(Handler): | ||
async def handle(self, context: Context): | ||
if context.is_normal_chat: | ||
# Assuming context.client is set and has a method for creating chat completions | ||
completion = context.client.route( | ||
messages=context.messages, | ||
**context.client.clean_params(context.params), | ||
) | ||
context.response = completion.model_dump() | ||
return JSONResponse(content=context.response, status_code=200) | ||
|
||
return await super().handle(context) | ||
|
||
|
||
class FallbackHandler(Handler): | ||
async def handle(self, context: Context): | ||
# This handler does not pass the request further down the chain. | ||
# It acts as a fallback when no other handler has processed the request. | ||
if not context.response: | ||
# The default action when no other handlers have processed the request | ||
context.response = {"message": "No suitable action found for the request."} | ||
return JSONResponse(content=context.response, status_code=400) | ||
|
||
# If there's already a response set in the context, it means one of the handlers has processed the request. | ||
return JSONResponse(content=context.response, status_code=200) | ||
|
||
|
||
class ExceptionHandler(Handler): | ||
async def handle(self, context: Context, exception: Exception): | ||
print(f"Error processing the request: {exception}") | ||
print(traceback.format_exc()) | ||
return JSONResponse( | ||
content={"error": "An unexpected error occurred. " + str(exception)}, | ||
status_code=500, | ||
) | ||
|
||
|
Oops, something went wrong.