Skip to content

ChatCompletions create() doesn't type-check enums as role #1300

@npip99

Description

@npip99

Confirm this is a feature request for the Python library and not the underlying OpenAI API.

  • This is a feature request for the Python library

Describe the feature or improvement you're requesting

This was discussed previously @ #911, but just opening a new issue so that it's in the issue tracker.

The Bug

When calling,

role: Literal["system", "user", "assistant"] = ...
completion = await client.chat.completions.create(
    model="gpt-4",
    messages={"role": role, "content": "Hi"}
)

Reason

The main issue is that it's defined as an enum of typed dicts,

ChatCompletionMessageParam = Union[
    ChatCompletionSystemMessageParam,
    ChatCompletionUserMessageParam,
    ChatCompletionAssistantMessageParam,
    ChatCompletionToolMessageParam,
    ChatCompletionFunctionMessageParam,
]

Of course, for tooling & functions, we need to know exactly whether or not it's a user or assistant message. But role: str, content: str is the most common use-case, so it would be nice if system/user/assistant can all use that kind of interface when necessary.

Additional context

Potential Solution

From #911 (comment),

I think a very simple solution would be to add another type to the ChatCompletionMessageParam union.

Currently, we have

ChatCompletionMessageParam = Union[
    ChatCompletionSystemMessageParam,
    ChatCompletionUserMessageParam,
    ChatCompletionAssistantMessageParam,
    ChatCompletionToolMessageParam,
    ChatCompletionFunctionMessageParam,
]

If instead we had,

ChatCompletionMessageParam = Union[
    ChatCompletionSystemMessageParam,
    ChatCompletionUserMessageParam,
    ChatCompletionAssistantMessageParam,
    ChatCompletionToolMessageParam,
    ChatCompletionFunctionMessageParam,
    ChatCompletionGenericMessageParam,
]

Where ChatCompletionGenericMessageParam was,

class ChatCompletionGenericMessageParam(TypedDict, total=False):
    content: Required[Optional[str]]
    role: Required[Literal["system", "user", "assistant"]]
  • Under my understanding, adding an option to a Union does not break compatibility with anybody (Lmk if I'm wrong)
  • This handles all possible situations (pydantic model, custom TypedDict with Literal, a mixture of both, etc).
  • And, if the user wants to pass in a tool/FunctionCall/ChatCompletionContentPartParam, then obviously they need to use the other types and prove that it's specifically a system/user/etc.
  • OpenAI can still internally type check safely, because it can write a type-safe function to convert ChatCompletionGenericMessageParam into a Union[ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam,ChatCompletionAssistantMessageParam].

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions