ExLLM.Providers.Shared.MessageFormatter (ex_llm v0.8.1)

View Source

Shared message formatting utilities for ExLLM adapters.

Provides common message transformations and validations used across different LLM providers. Each provider has slightly different message formats, but this module provides the common patterns.

Summary

Functions

Add a system message to the beginning of the messages list.

Ensure messages alternate between user and assistant roles.

Count tokens in messages (rough estimate).

Extract system message from messages list if present.

Format a function/tool call message for the provider.

Format a function result message for the provider.

Ensure all messages have string keys (some providers require this).

Truncate messages to fit within a token limit.

Validate messages have required fields and proper structure.

Functions

add_system_message(messages, system_prompt)

@spec add_system_message([ExLLM.Types.message()], String.t() | nil) :: [
  ExLLM.Types.message()
]

Add a system message to the beginning of the messages list.

Handles cases where system message might already exist.

Examples

MessageFormatter.add_system_message(messages, "You are a helpful assistant")

ensure_alternating_roles(list)

@spec ensure_alternating_roles([ExLLM.Types.message()]) :: [ExLLM.Types.message()]

Ensure messages alternate between user and assistant roles.

Some providers require strict alternation. This function adds empty assistant messages where needed.

estimate_token_count(messages)

@spec estimate_token_count([ExLLM.Types.message()]) :: integer()

Count tokens in messages (rough estimate).

This is a very rough estimate - actual token count depends on the specific tokenizer used by each model.

extract_system_message(messages)

@spec extract_system_message([ExLLM.Types.message()]) ::
  {String.t() | nil, [ExLLM.Types.message()]}

Extract system message from messages list if present.

Returns {system_message, remaining_messages}.

format_function_call(function_call, arg2)

@spec format_function_call(map(), atom()) :: map()

Format a function/tool call message for the provider.

Each provider has different formats for function calls.

format_function_result(result, arg2)

@spec format_function_result(map(), atom()) :: map()

Format a function result message for the provider.

stringify_message_keys(messages)

@spec stringify_message_keys([map()]) :: [map()]

Ensure all messages have string keys (some providers require this).

Examples

MessageFormatter.stringify_message_keys([
  %{role: :user, content: "Hello"}
])
# => [%{"role" => "user", "content" => "Hello"}]

truncate_messages(messages, max_tokens)

@spec truncate_messages([ExLLM.Types.message()], integer()) :: [ExLLM.Types.message()]

Truncate messages to fit within a token limit.

Keeps most recent messages, preserving system message if present.

validate_messages(messages)

@spec validate_messages([ExLLM.Types.message()]) :: :ok | {:error, term()}

Validate messages have required fields and proper structure.

Examples

MessageFormatter.validate_messages([
  %{role: "user", content: "Hello"},
  %{role: "assistant", content: "Hi there!"}
])
# => :ok