PromptVault (PromptVault v0.1.0)

View Source

PromptVault provides an immutable, token-aware context management system for LLM prompts.

The main entry point is new/1 to create a new context, followed by functions to add messages, manage tokens, render templates, and compact message history.

Example

iex> PromptVault.new(model: :gpt4, temperature: 0.7)
%PromptVault.Context{model: :gpt4, temperature: 0.7, messages: [], token_count: 0}

Summary

Functions

Adds a media message to the context.

Adds a message to the context.

Adds a tool call message to the context.

Compacts the context using the specified or configured compaction strategy.

Counts tokens and returns an updated context with the cached count.

Creates a new PromptVault context with the given options.

Updates the model for the given context.

Updates multiple options for the given context.

Renders all messages in the context to iodata.

Counts tokens in the context using the configured token counter.

Functions

add_media(context, mime_type, url, opts \\ [])

@spec add_media(PromptVault.Context.t(), String.t(), String.t(), keyword()) ::
  {:ok, PromptVault.Context.t()} | {:error, reason :: any()}

Adds a media message to the context.

Parameters

  • context - The PromptVault context
  • mime_type - MIME type of the media (string)
  • url - URL or data URI of the media (string)
  • opts - Options including :size, :template, :engine, :assigns, :raw

Examples

iex> context = PromptVault.new()
iex> {:ok, updated} = PromptVault.add_media(context, "image/jpeg", "https://example.com/img.jpg")
iex> length(updated.messages)
1

add_message(context, role, raw, opts \\ [])

@spec add_message(PromptVault.Context.t(), atom(), any(), keyword()) ::
  {:ok, PromptVault.Context.t()} | {:error, reason :: any()}

Adds a message to the context.

Parameters

  • context - The PromptVault context
  • role - Message role (:system, :user, or :assistant)
  • raw - The raw message content
  • opts - Options including :template, :engine, :assigns

Examples

iex> context = PromptVault.new()
iex> {:ok, updated} = PromptVault.add_message(context, :user, "Hello")
iex> length(updated.messages)
1

add_tool_call(context, tool, args, response_schema, opts \\ [])

@spec add_tool_call(
  PromptVault.Context.t(),
  atom() | String.t(),
  map(),
  map() | String.t() | nil,
  keyword()
) :: {:ok, PromptVault.Context.t()} | {:error, reason :: any()}

Adds a tool call message to the context.

Parameters

  • context - The PromptVault context
  • tool - Tool name (atom or string)
  • args - Tool arguments (map)
  • response_schema - Expected response schema (map or string)
  • opts - Options including :template, :engine, :assigns, :raw

Examples

iex> context = PromptVault.new()
iex> {:ok, updated} = PromptVault.add_tool_call(context, :weather, %{city: "NYC"}, nil)
iex> length(updated.messages)
1

compact(context, strategy \\ nil, opts \\ [])

@spec compact(PromptVault.Context.t(), module() | nil, keyword()) ::
  {:ok, PromptVault.Context.t()} | {:error, reason :: any()}

Compacts the context using the specified or configured compaction strategy.

Parameters

  • context - The PromptVault context
  • strategy - Compaction strategy module or nil to use configured strategy
  • opts - Options to pass to the compaction strategy

Examples

iex> summarizer = fn msgs -> "Summary of " <> Integer.to_string(length(msgs)) <> " messages" end
iex> context = PromptVault.new()
iex> {:ok, context} = PromptVault.add_message(context, :user, "Hello")
iex> {:ok, compacted} = PromptVault.compact(context, PromptVault.Compaction.SummarizeHistory, summarizer: summarizer)
iex> length(compacted.messages)
1

count_and_cache_tokens(context)

@spec count_and_cache_tokens(PromptVault.Context.t()) ::
  {:ok, PromptVault.Context.t()} | {:error, reason :: any()}

Counts tokens and returns an updated context with the cached count.

Examples

iex> context = PromptVault.new(token_counter: PromptVault.TokenCounter.PretendTokenizer)
iex> {:ok, context} = PromptVault.add_message(context, :user, "Hello")
iex> {:ok, updated_context} = PromptVault.count_and_cache_tokens(context)
iex> updated_context.token_count >= 0
true

new(opts \\ [])

@spec new(keyword()) :: PromptVault.Context.t()

Creates a new PromptVault context with the given options.

Options

  • :model - The LLM model to use (atom or string)
  • :temperature - Temperature setting for the model
  • :max_tokens - Maximum tokens for the model
  • :token_counter - Module implementing TokenCounter behaviour
  • :compaction_strategy - Module or {module, opts} for compaction

Examples

iex> PromptVault.new(model: :gpt4, temperature: 0.7)
%PromptVault.Context{model: :gpt4, temperature: 0.7, messages: [], token_count: 0}

put_model(context, model)

@spec put_model(PromptVault.Context.t(), atom() | String.t()) ::
  PromptVault.Context.t()

Updates the model for the given context.

Examples

iex> PromptVault.new() |> PromptVault.put_model(:gpt4)
%PromptVault.Context{model: :gpt4, messages: [], token_count: 0}

put_opts(context, opts)

Updates multiple options for the given context.

Accepts the same options as new/1.

Examples

iex> PromptVault.new() |> PromptVault.put_opts(temperature: 0.5, max_tokens: 1000)
%PromptVault.Context{temperature: 0.5, max_tokens: 1000, messages: [], token_count: 0}

render(context, assigns \\ %{})

@spec render(PromptVault.Context.t(), map()) :: iodata()

Renders all messages in the context to iodata.

Processes each message in order, calling their rendered/2 callbacks with the message's assigns merged with any provided assigns.

Examples

iex> context = PromptVault.new()
iex> {:ok, context} = PromptVault.add_message(context, :user, "Hello")
iex> rendered = PromptVault.render(context)
iex> is_binary(IO.iodata_to_binary(rendered))
true

token_count(context)

@spec token_count(PromptVault.Context.t()) ::
  {:ok, non_neg_integer()} | {:error, reason :: any()}

Counts tokens in the context using the configured token counter.

Returns the cached token count if available, otherwise renders all messages and counts tokens.

Examples

iex> context = PromptVault.new(token_counter: PromptVault.TokenCounter.PretendTokenizer)
iex> {:ok, context} = PromptVault.add_message(context, :user, "Hello")
iex> {:ok, count} = PromptVault.token_count(context)
iex> count >= 0
true