Eai. Chat
(eai v1.0.0)
Copy Markdown
Main conversation GenServer managing multi-session chat history and async LLM tasks.
Summary
Functions
Returns a specification to start this module under a supervisor.
Explicitly close a chat session and release its history.
Ensure a chat session exists in state.sessions. If the session
already exists, this is a no-op (returns :ok and state is
unchanged). If the session does NOT exist, an empty session is
materialized in state.sessions and :ok is returned.
Export chat session history to a gzip file.
Get full message history for a chat session.
Force interrupt current LLM task (async mode only).
List all active chat sessions with message count and status.
Load chat history from a gzip file and replace session's messages.
Send a message to LLM and get response (or enter interactive mode).
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Explicitly close a chat session and release its history.
Cannot close "default" session.
Options
name(string) — Session name to close.
Returns
:ok on success.
{:error, :cannot_close_default} when closing the "default" session.
{:error, :not_found} when the session does not exist.
{:error, :busy, message} when a task is still running in the session.
Example
iex> Eai.Chat.close_chat_session("research")
:ok
Ensure a chat session exists in state.sessions. If the session
already exists, this is a no-op (returns :ok and state is
unchanged). If the session does NOT exist, an empty session is
materialized in state.sessions and :ok is returned.
This is used by Eai.System.restore_from_gzip/1 to PRE-CREATE every
session in the snapshot before writing any messages, so that
Eai.Chat.list_chat_sessions/0 sees the full set of sessions
during the restore window. Without this pre-create, sessions
appear one-by-one as replace_history/3 is called, and a
concurrent observer could see an inconsistent state.
Options
chat_session(string) — Session name. Default:"default".
Returns
:ok
Export chat session history to a gzip file.
Called by LLM tool export_chat_session_context or manually.
Options
file_path(string) — Destination file path.chat_session(string) — Session to export. Default:"default"
Returns
`{:ok, info}` or `{:error, reason}`Example
iex> Eai.Chat.export_history("/tmp/session.gz", "work")
{:ok, %{size_bytes: 5432, message_count: 42}}
Get full message history for a chat session.
Options
chat_session(string) — Session name. Default:"default"
Returns
List of Eai.Message.t() in conversation order.
Force interrupt current LLM task (async mode only).
Sets interrupt flag; next task poll injects Ctrl+C to running PTY process.
Only works in async :human mode (sync mode blocks IEx).
Options
chat_session(string) — Session to interrupt. Default:"default"
Example
iex> Eai.Chat.interrupt!("work")
:ok
List all active chat sessions with message count and status.
Returns
`[{session_name, message_count, status}, ...]`
where status is `:idle` or `:busy`
Load chat history from a gzip file and replace session's messages.
Options
file_path(string) — Source gzip file path.chat_session(string) — Target session. Default:"default"format(string) — Message format. Default:"converse""converse"— already inEai.MessageIR format"openai"— needs OpenAI adapter conversion"anthropic"— needs Anthropic adapter conversion
Returns
`{:ok, info}` or `{:error, reason}`Example
iex> Eai.Chat.replace_history("/tmp/session.gz", "work_restored")
{:ok, %{message_count: 42, chat_session: "work_restored"}}
Send a message to LLM and get response (or enter interactive mode).
Options
:content(string) — User message. Required for:functionmode.:mod(:function|:human) — Execution mode. Default::human:function— one-shot, synchronous, returns{:ok, reply}or{:error, reason}:human— interactive, type/sto send,/cto cancel
:timeout(integer) — Max wait for reply in milliseconds. Default::infinity:model(atom) — Model name::deepseek,:claude_opus,:gpt4o, etc.Default: `:deepseek`:prompt(atom) — System prompt::coder,:analyst,:momoka, etc.Default: `:momoka`:chara_card(atom) — Override model + prompt with character card.Example: `:backend_engineer`. Overrides `:model` and `:prompt`.:chat_session(string) — Conversation history isolation. Default:"default":pty_session_id(string) — PTY sandbox isolation. Default: same as:chat_session:temperature(float | integer | nil) — Sampling temperature forwarded to the LLM provider as the"temperature"field in the HTTP body. Default: nil (provider default).:top_p(float | nil) — Nucleus sampling cutoff (Anthropic / OpenAI / BedrockinferenceConfig.topP). Default: nil (provider default).:top_k(integer | nil) — Top-K sampling (Anthropic / BedrockinferenceConfig.topK). OpenAI does NOT support — dropped at the OpenAI adapter. Default: nil (provider default).:min_p(float | nil) — Min-P sampling. Reserved for future adapter support; no current adapter emits this field. Default: nil (provider default).:max_tokens(integer | nil) — Maximum output tokens (Anthropic / OpenAI / BedrockinferenceConfig.maxTokens). Default: nil (provider default).:repetition_penalty(float | nil) — Repetition penalty. Reserved for future adapter support; no current adapter emits this field. Default: nil (provider default).:frequency_penalty(float | nil) — OpenAI frequency penalty. Anthropic and Bedrock do NOT support — dropped at those adapters. Default: nil (provider default).:presence_penalty(float | nil) — OpenAI presence penalty. Anthropic and Bedrock do NOT support — dropped at those adapters. Default: nil (provider default).:stop_sequences(list of strings | nil) — Custom stop sequences (Anthropicstop_sequences, OpenAIstop, BedrockinferenceConfig.stopSequences). Default: nil (provider default).:seed(integer | nil) — Random seed for reproducibility (OpenAI; BedrockinferenceConfig.seed). Anthropic does NOT support. Default: nil (provider default).:anthropic_beta(list of strings | nil) — Optional list of Anthropic beta header strings to send (e.g.["output-128k-2025-02-19"]). When multiple are given, joined with ", " per Anthropic's convention. Default: nil (no beta header sent — provider's default cap applies). Currently consumed only by:anthropicprovider calls; harmless on other providers (the adapter does not read the value).
Precedence (per field, all 10 sampler fields + :anthropic_beta):
talk/1 explicit opt > config/models/<name>.exs value > nil/omit. Step 7
stores the defaults in model config files (NOT in chara cards).
Examples
# Interactive
iex> Eai.Chat.talk()
# One-shot, defaults
iex> Eai.Chat.talk(content: "what time is it?", mod: :function)
# With model + prompt
iex> Eai.Chat.talk(content: "refactor", mod: :function, model: :claude_opus, prompt: :coder, timeout: 60_000)
# Multi-session isolation
iex> Eai.Chat.talk(content: "analyze", chat_session: "research", pty_session_id: "isolated")
# With chara card (overrides model + prompt)
iex> Eai.Chat.talk(content: "code review", mod: :function, chara_card: :backend_engineer)Available Models, Prompts & Cards
iex> Eai.Models.names() # => [:deepseek, :claude_opus, :gpt4o, ...]
iex> Eai.Prompts.names() # => [:momoka, :coder, :analyst]
iex> Eai.Card.names() # => [:backend_engineer, :frontend_dev, ...]Returns
:functionmode —{:ok, reply}on success,{:error, reason}on failure. When the chat session is currently busy, returns{:error, :busy, message}(note the 3-tuple shape, unified with:humanmode).:humanmode —:okafter the interactive session ends, or{:error, :busy, message}if the session is already busy.{:error, :invalid_mod}for an unknown:modvalue.