Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added extra env variable to control DALLE additional parameters #186

Open
wants to merge 16 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ The following variables cluster all deployments into the groups of deployments w
|---|---|---|
|DALLE3_DEPLOYMENTS|``|Comma-separated list of deployments that support DALL-E 3 API. Example: `dall-e-3,dalle3,dall-e`|
|DALLE3_AZURE_API_VERSION|2024-02-01|The version API for requests to Azure DALL-E-3 API|
|DALLE_EXTRA_PARAMETERS|`{}`|JSON formated list of extra parameters, example: '{"size": "1024x1024", "quality": "hd", "style": "vivid"}'|
|GPT4_VISION_DEPLOYMENTS|``|Comma-separated list of deployments that support GPT-4V API. Example: `gpt-4-vision-preview,gpt-4-vision`|
|GPT4_VISION_MAX_TOKENS|1024|Default value of `max_tokens` parameter for GPT-4V when it wasn't provided in the request|
|MISTRAL_DEPLOYMENTS|``|Comma-separated list of deployments that support Mistral Large Azure API. Example: `mistral-large-azure,mistral-large`|
Expand Down
18 changes: 17 additions & 1 deletion aidial_adapter_openai/dalle3.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json
import os
from typing import Any, AsyncIterator, Optional

import aiohttp
Expand All @@ -19,10 +21,24 @@
async def generate_image(
api_url: str, creds: OpenAICreds, user_prompt: str
) -> JSONResponse | Any:

extra_params = {}
try:
extra_params = json.loads(os.getenv("DALLE_EXTRA_PARAMETERS", "{}"))
except json.JSONDecodeError:
# Log or handle the case where the environment variable is not valid JSON
extra_params = {}

payload = {
"prompt": user_prompt,
"response_format": "b64_json",
**extra_params, # Add extra parameters
}

async with aiohttp.ClientSession() as session:
async with session.post(
api_url,
json={"prompt": user_prompt, "response_format": "b64_json"},
json=payload,
headers=get_auth_headers(creds),
) as response:
status_code = response.status
Expand Down
13 changes: 3 additions & 10 deletions aidial_adapter_openai/exception_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
ResponseWrapper,
parse_adapter_exception,
)
from aidial_adapter_openai.utils.log_config import logger


def to_adapter_exception(exc: Exception) -> AdapterException:
Expand All @@ -33,7 +32,7 @@ def to_adapter_exception(exc: Exception) -> AdapterException:

return parse_adapter_exception(
status_code=r.status_code,
headers=httpx_headers,
headers=dict(httpx_headers.items()),
content=r.text,
)

Expand Down Expand Up @@ -72,12 +71,6 @@ def to_adapter_exception(exc: Exception) -> AdapterException:


def adapter_exception_handler(
request: FastAPIRequest, e: Exception
request: FastAPIRequest, exc: Exception
) -> FastAPIResponse:
adapter_exception = to_adapter_exception(e)

logger.error(
f"Caught exception: {type(e).__module__}.{type(e).__name__}. "
f"Converted to the adapter exception: {adapter_exception!r}"
)
return adapter_exception.to_fastapi_response()
return to_adapter_exception(exc).to_fastapi_response()
16 changes: 5 additions & 11 deletions aidial_adapter_openai/gpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,12 @@
from aidial_adapter_openai.utils.auth import OpenAICreds
from aidial_adapter_openai.utils.parsers import chat_completions_parser
from aidial_adapter_openai.utils.reflection import call_with_extra_body
from aidial_adapter_openai.utils.streaming import (
chunk_to_dict,
debug_print,
generate_stream,
map_stream,
)
from aidial_adapter_openai.utils.streaming import (chunk_to_dict, debug_print,
generate_stream, map_stream)
from aidial_adapter_openai.utils.tokenizer import PlainTextTokenizer
from aidial_adapter_openai.utils.truncate_prompt import (
DiscardedMessages,
TruncatedTokens,
truncate_prompt,
)
from aidial_adapter_openai.utils.truncate_prompt import (DiscardedMessages,
TruncatedTokens,
truncate_prompt)


def plain_text_truncate_prompt(
Expand Down
46 changes: 14 additions & 32 deletions aidial_adapter_openai/gpt4_multi_modal/chat_completion.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,31 @@
import os
from typing import (
Any,
AsyncIterator,
Callable,
Dict,
List,
Optional,
Tuple,
TypeVar,
cast,
)
from typing import (Any, AsyncIterator, Callable, Dict, List, Optional, Tuple,
TypeVar, cast)

import aiohttp
from aidial_sdk.exceptions import HTTPException as DialException
from aidial_sdk.exceptions import RequestValidationError
from fastapi.responses import JSONResponse, Response

from aidial_adapter_openai.dial_api.storage import FileStorage
from aidial_adapter_openai.gpt4_multi_modal.gpt4_vision import (
convert_gpt4v_to_gpt4_chunk,
)
from aidial_adapter_openai.gpt4_multi_modal.gpt4_vision import \
convert_gpt4v_to_gpt4_chunk
from aidial_adapter_openai.gpt4_multi_modal.transformation import (
SUPPORTED_FILE_EXTS,
ResourceProcessor,
)
SUPPORTED_FILE_EXTS, ResourceProcessor)
from aidial_adapter_openai.utils.auth import OpenAICreds, get_auth_headers
from aidial_adapter_openai.utils.chat_completion_response import (
ChatCompletionBlock,
)
from aidial_adapter_openai.utils.chat_completion_response import \
ChatCompletionBlock
from aidial_adapter_openai.utils.log_config import logger
from aidial_adapter_openai.utils.multi_modal_message import MultiModalMessage
from aidial_adapter_openai.utils.sse_stream import parse_openai_sse_stream
from aidial_adapter_openai.utils.streaming import (
create_response_from_chunk,
create_stage_chunk,
generate_stream,
map_stream,
prepend_to_stream,
)
from aidial_adapter_openai.utils.streaming import (create_response_from_chunk,
create_stage_chunk,
generate_stream, map_stream,
prepend_to_stream)
from aidial_adapter_openai.utils.tokenizer import MultiModalTokenizer
from aidial_adapter_openai.utils.truncate_prompt import (
DiscardedMessages,
TruncatedTokens,
truncate_prompt,
)
from aidial_adapter_openai.utils.truncate_prompt import (DiscardedMessages,
TruncatedTokens,
truncate_prompt)

# The built-in default max_tokens is 16 tokens,
# which is too small for most image-to-text use cases.
Expand Down
17 changes: 6 additions & 11 deletions aidial_adapter_openai/utils/adapter_exception.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import Any, MutableMapping
from typing import Any, Dict

from aidial_sdk.exceptions import HTTPException as DialException
from fastapi.responses import Response as FastAPIResponse
Expand All @@ -8,14 +8,14 @@
class ResponseWrapper(Exception):
content: Any
status_code: int
headers: MutableMapping[str, str] | None
headers: Dict[str, str] | None

def __init__(
self,
*,
content: Any,
status_code: int,
headers: MutableMapping[str, str] | None,
headers: Dict[str, str] | None,
) -> None:
super().__init__(str(content))
self.content = content
Expand Down Expand Up @@ -51,7 +51,7 @@ def json_error(self) -> dict:


def _parse_dial_exception(
*, status_code: int, headers: MutableMapping[str, str], content: Any
*, status_code: int, headers: Dict[str, str], content: Any
) -> DialException | None:
if isinstance(content, str):
try:
Expand All @@ -61,11 +61,6 @@ def _parse_dial_exception(
else:
obj = content

# The content length is invalidated as soon as
# the original content is lost
if "Content-Length" in headers:
del headers["Content-Length"]

if (
isinstance(obj, dict)
and (error := obj.get("error"))
Expand All @@ -84,14 +79,14 @@ def _parse_dial_exception(
param=param,
code=code,
display_message=display_message,
headers=dict(headers.items()),
headers=headers,
)

return None


def parse_adapter_exception(
*, status_code: int, headers: MutableMapping[str, str], content: Any
*, status_code: int, headers: Dict[str, str], content: Any
) -> AdapterException:
return _parse_dial_exception(
status_code=status_code, headers=headers, content=content
Expand Down
10 changes: 6 additions & 4 deletions aidial_adapter_openai/utils/sse_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ async def to_openai_sse_stream(
async for chunk in stream:
yield format_chunk(chunk)
except Exception as e:
adapter_exception = to_adapter_exception(e)

logger.exception(
f"Caught exception while streaming: {type(e).__module__}.{type(e).__name__}. "
f"Converted to the adapter exception: {adapter_exception!r}"
f"caught exception while streaming: {type(e).__module__}.{type(e).__name__}"
)

adapter_exception = to_adapter_exception(e)
logger.error(
f"converted to the adapter exception: {adapter_exception!r}"
)

yield format_chunk(adapter_exception.json_error())
Expand Down
4 changes: 1 addition & 3 deletions aidial_adapter_openai/utils/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
from pydantic import BaseModel

from aidial_adapter_openai.utils.chat_completion_response import (
ChatCompletionResponse,
ChatCompletionStreamingChunk,
)
ChatCompletionResponse, ChatCompletionStreamingChunk)
from aidial_adapter_openai.utils.log_config import logger
from aidial_adapter_openai.utils.sse_stream import to_openai_sse_stream

Expand Down
5 changes: 2 additions & 3 deletions aidial_adapter_openai/utils/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
from aidial_sdk.exceptions import InternalServerError
from tiktoken import Encoding, encoding_for_model

from aidial_adapter_openai.utils.chat_completion_response import (
ChatCompletionResponse,
)
from aidial_adapter_openai.utils.chat_completion_response import \
ChatCompletionResponse
from aidial_adapter_openai.utils.image_tokenizer import ImageTokenizer
from aidial_adapter_openai.utils.multi_modal_message import MultiModalMessage
from aidial_adapter_openai.utils.text import truncate_string
Expand Down
Loading