Skip to content

Commit

Permalink
MalformedMessageError sentinel exception (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesbraza authored Sep 11, 2024
1 parent 7ef511c commit 90fceea
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
27 changes: 24 additions & 3 deletions src/aviary/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import json
from collections.abc import Iterable
from typing import TYPE_CHECKING, ClassVar
from typing import TYPE_CHECKING, ClassVar, Self

from pydantic import BaseModel, Field, field_validator, model_validator

from aviary.utils import encode_image_to_base64

if TYPE_CHECKING:
from logging import LogRecord

import numpy as np


Expand Down Expand Up @@ -118,7 +120,7 @@ def create_message(
role: str = DEFAULT_ROLE,
text: str | None = None,
image: np.ndarray | None = None,
) -> Message:
) -> Self:
# Assume no image, and update to image if present
content: str | list[dict] | None = text
if image is not None:
Expand All @@ -130,7 +132,7 @@ def create_message(
]
if text is not None:
content.append({"type": "text", "text": text})
return Message(role=role, content=content)
return cls(role=role, content=content)


def join(
Expand All @@ -139,3 +141,22 @@ def join(
return delimiter.join(
f"{f'{m.role}: ' if include_roles else ''}{m.content or ''}" for m in msgs
)


class MalformedMessageError(ValueError):
"""Error to throw if some aspect of a Message variant is malformed."""

@classmethod
def common_retryable_errors_log_filter(cls, record: LogRecord) -> bool:
"""
Filter out common parsing failures not worth looking into from logs.
Returns:
False if the LogRecord should be filtered out, otherwise True to keep it.
"""
# NOTE: match both this Exception type's name and its content, to be robust
return not all(x in record.msg for x in (cls.__name__, EMPTY_CONTENT_BASE_MSG))


# Define separately so we can filter out this message type
EMPTY_CONTENT_BASE_MSG = "No content in message"
4 changes: 2 additions & 2 deletions src/aviary/tools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from pydantic import BaseModel, Field

from aviary.message import Message
from aviary.message import MalformedMessageError, Message

from .base import (
MessagesAdapter,
Expand Down Expand Up @@ -61,7 +61,7 @@ async def __call__(
len(model_response.choices) != 1
or model_response.choices[0].finish_reason != "tool_calls"
):
raise NotImplementedError(
raise MalformedMessageError(
f"Unexpected shape of LiteLLM model response {model_response}."
)
usage = model_response.usage
Expand Down

0 comments on commit 90fceea

Please sign in to comment.