#Anyone an idea why dialyzer complains about this spec?

4 messages · Page 1 of 1 (latest)

hexed quartz
#

Following dialyzer error:

ExOpenAI.Chat.create_chat_completion(
  _msgs :: [
    %ExOpenAI.Components.ChatCompletionRequestMessage{
      :content => <<_::16>> | [112 | 115 | 117, ...],
      :name => nil,
      :role => :assistant | :user
    },
    ...
  ],
  <<103, 112, 116, 45, 51, 46, 53, 45, 116, 117, 114, 98, 111>>
)

will never return since the success typing is:
(
  [
    %ExOpenAI.Components.ChatCompletionRequestMessage{
      :content => binary(),
      :name => binary(),
      :role => :assistant | :system | :user
    }
  ],
  binary()
) ::
  {:error, _}
  | {:ok,
     %ExOpenAI.Components.CreateChatCompletionResponse{
       :choices => [map()],
       :created => integer(),
       :id => binary(),
       :model => binary(),
       :object => binary(),
       :usage => %{
         :completion_tokens => integer(),
         :prompt_tokens => integer(),
         :total_tokens => integer()
       }
     }}

and the contract is
([ExOpenAI.Components.ChatCompletionRequestMessage.t()], String.t()) ::
  {:ok, ExOpenAI.Components.CreateChatCompletionResponse.t()} | {:error, any()}

Usage:

    msgs = [
      %ExOpenAI.Components.ChatCompletionRequestMessage{
        role: :assistant,
        name: nil,
        content: "hi"
      },
      %ExOpenAI.Components.ChatCompletionRequestMessage{
        role: :user,
        name: nil,
        content: "sup"
      }
    ]

    ExOpenAI.Chat.create_chat_completion(msgs, "gpt-3.5-turbo")

Spec:

  @spec create_chat_completion(
          [ExOpenAI.Components.ChatCompletionRequestMessage.t()],
          String.t(),
          user: String.t(),
          top_p: float(),
          temperature: float(),
          stream: boolean(),
          stop: any(),
          presence_penalty: float(),
          n: integer(),
          max_tokens: integer(),
          logit_bias: map(),
          frequency_penalty: float()
        ) ::
          {:ok, ExOpenAI.Components.CreateChatCompletionResponse.t()}
          | {:error, any()}

I don't get what's breaking the contract here. Usage is exactly as described: list of structs, string, then keyword list

stone flume
#

content: 'sup' that is a charlist, not a string - single quotes are for charlists (lists of integers) and double quotes are for UTF-8 strings (in erlang binaries).

#

Plus, according to the dialyzer success typing, the name key should be a string, not nil.

hexed quartz
#

sorry the 'sup' thing was me sanitizing data by hand so I can copy-paste it here

but you were right about the name field, that was the issue, thanks for pointing it out!
name is not a required field so I assumed that it's fine to leave as nil, but you're absolutely correct that this breaks the spec. I guess it should be String.t() | nil