Skip to content

smelt.session

Tier: UiHost - Requires a terminal UI; calling these from headless mode raises.

Visibility: Public - Stable Lua API intended for user config and plugins.

Current session metadata, turn list, message snapshots, rewind, and persisted session management. UiHost-only.

smelt.session._rewind_active_turn_if_clean

fun(opts: table?): boolean

Visibility: Internal - Runtime implementation detail. Bundled Lua may call it, but user config and plugins should not depend on it.

Cancel the active turn and restore its submitted user message into the prompt only if no assistant or tool output has started. Returns true when it rewound.

smelt.session.checkpoint

fun(spec: table): boolean?

Install a model-context checkpoint without deleting transcript history. Takes { kind?, summary, first_live_message_index, tokens_before?, guard? }; future model requests use the summary plus the original model-visible suffix starting at first_live_message_index. When guard from smelt.work.guard() is provided, the checkpoint is installed only if that lifecycle is still current; late callbacks after cancel or turn replacement return nil. Returns true when a checkpoint was installed, or nil when the boundary would be a no-op. Use smelt.session.model_messages() to read the model-visible messages after checkpointing.

smelt.session.context_note

fun(name: string, text: string?, opts: table?): nil

Set or clear a named hidden model-visible context note. context_note(name, text) creates or replaces that note for future turns; context_note(name, nil) clears it. Named notes do not replace each other, so plugins can maintain independent steering state. UiHost-only.

smelt.session.context_tokens

fun(): integer?

Latest non-background provider-reported active-context token count, or nil before the first usage report. While a request is in flight this may be the previous turn's reading until the provider sends a fresh usage update. Use status().context for stale markers; stale counts are display-only and are not used as authoritative request baselines.

smelt.session.context_window

fun(): integer?

Configured context-window size in tokens for the active model. nil when the model entry has no declared limit.

smelt.session.conversation

fun(opts: table?): table

Return user and assistant text from semantic history, excluding system messages, internal notes, and tool results. Rows are { role = 'user'|'assistant', content }. By default reads the latest bounded conversation tail; pass { limit = n }, { since_index = n }, or { all = true }. Read-only; intended for lightweight auxiliary prompts such as input prediction.

smelt.session.cost

fun(): number

Cumulative session cost in USD across every model call this session has made.

smelt.session.created_at_ms

fun(): integer

Unix-epoch timestamp (milliseconds) at which this session was started.

smelt.session.cwd

fun(): string

Current working directory. Updated when smelt enters a managed worktree.

smelt.session.delete

fun(id: string): nil

Delete the persisted session with id. Refuses to delete the currently active session.

smelt.session.dir

fun(): string

Absolute path of the current session directory. Ephemeral sessions return a temporary directory that is removed when Smelt exits.

smelt.session.enter_worktree

fun(opts: table?): table

Create or open a managed git worktree and request a coherent project-context transition. opts.name is required and is normalized to a safe lowercase folder/branch name. New worktrees are created under smelt.settings.worktree_root: relative roots are resolved inside the git root, absolute roots use a per-repository bucket. The transition updates Lua project config, process and engine cwd, session metadata, prompt inputs, permissions, and watcher roots together. The returned pending field is true until the Lua callback returns and the event loop reaches a safe point; an active turn delays that point until idle. Returns { name, branch, path, base, created, pending }.

smelt.session.fork

fun(): nil

Fork the current session: clone its messages into a new session id and switch to it. Useful for branching off an experiment without losing the original timeline.

smelt.session.history

fun(opts: table?): table

Return the semantic session history as compaction-safe items. Rows are { kind = 'system'|'user'|'assistant'|'note', ... }; assistant rows include invocations, and note rows include note_kind plus text. By default this returns a bounded tail; pass { all = true } for an explicit full read.

smelt.session.id

fun(): string

Stable session id (matches the on-disk session filename).

smelt.session.info

fun(): table

Return current session metadata as a table. Includes id, title, slug, timestamps, paths, ephemeral flag, parent id, model/mode, usage counts, and current worktree context.

smelt.session.list

fun(): table

List persisted SQLite sessions other than the current one. Available rows carry id, available = true, metadata fields, and size_bytes when known. Unavailable rows carry id, available = false, error_kind, and error.

smelt.session.load

fun(id: string): nil

Switch the UI to the persisted session with id. Replays its message log and resets transient state.

smelt.session.model_messages

fun(): table

Return the model-visible message list for the next request. If the session has a context checkpoint, this is the checkpoint summary plus retained live tail; otherwise it is the persisted transcript. Read-only.

smelt.session.render_preview_into

fun(id: string, opts: table): table?

Render persisted session id into opts.buf using the same styled transcript projection as the live UI. opts.width controls wrapping; opts.height is the preview viewport height; opts.scroll_top renders an existing preview at that absolute row, otherwise the preview opens at the tail; opts.updated_at_ms lets cached previews render without reloading the session; opts.win receives the matching row materialization state when provided. Returns { total_rows, scroll_top }, or nil when the session is missing.

smelt.session.reset

fun(): nil

Cancel any in-flight agent and clear the session to a blank slate. Logs an agent_stop event with reason user_cancel_and_clear.

smelt.session.rewind_to

fun(block_idx: integer?, opts: table?): nil

Rewind the session to a prior user turn. block_idx = nil rewinds to before the first turn; opts.restore_vim_insert = true re-enters vim insert mode after the rewind.

smelt.session.set_fast_mode

fun(enabled: boolean): nil

Enable or disable accelerated inference for the current session.

smelt.session.set_title_for_history

fun(title: string, slug: string, history_len: integer): nil

Set the session title and slug for a specific history length. Intended for title/session metadata plugins that compute metadata for an already-submitted turn.

smelt.session.status

fun(): table

Return compact live status for prompt/status bars: { model, provider, api_base, mode = { name, pending, marker }, reasoning = { effort, pending, marker }, fast = { supported, active }, context = { tokens, window, stale, marker }, cost }. Markers are * for pending config and ? for stale readings.

smelt.session.switch_cwd

fun(path: string): table

Request a coherent project-context transition. Lua project config, process and engine cwd, session metadata, prompt inputs, permissions, and watcher roots commit together. The returned pending field is true until the Lua callback returns and the event loop reaches a safe point; an active turn delays that point until idle. Returns { cwd, pending }.

smelt.session.system

fun(): string

Currently-assembled system prompt sent on the next turn. Reflects the configured base prompt, skills, and instructions. Useful for auxiliary LLM calls that want to share the main turn's prompt-cache slot.

smelt.session.text

fun(id: string): string?

Return the searchable plain-text blob for session id (user + assistant text only; reasoning, tool output, and system messages excluded). Returns nil when the session is missing. Reads canonical SQLite without writing derived sidecars.

smelt.session.texts

fun(ids: string[]): table

Parallel batch read of session.text(id) for many ids. Returns a table keyed by id; missing sessions are omitted. Use this when a picker needs to search across all sessions. The heavy IO happens on a worker pool rather than serializing on the Lua thread.

smelt.session.tokens

fun(): table

Cumulative token usage across every turn this session has made. Returns a table with input (non-cached input), output, cache_read, cache_write, cached_input, input_total, reasoning (output detail), standard_total (input + output), and cache_hit_ratio (cache_read / (input + cache_read), nil if no input observed yet).

smelt.session.tree

fun(entries: table[], opts: table?): table[]

Arrange a flat list of session entries (as returned by smelt.session.list) into a DFS-ordered tree by parent_id. Each returned entry is a shallow copy with tree metadata: * depth - 0 for roots, 1 for first-level forks, ... * tree_prefix - printable tree gutter (├─ / └─ with ancestors) * tree_is_last - true when this entry is the last sibling * tree_has_children - true when this entry has visible children * tree_sort_value - max opts.sort_by value in this entry's subtree

Families sort by the newest descendant, so a resumed fork pulls its root conversation next to it instead of leaving the root behind in strict root-updated order. opts.order = "asc" is useful for bottom-anchored lists: old families render first, recent families end up at the bottom, while each parent still renders before its children. Entries whose parent_id references an id not present in entries are treated as roots.

smelt.session.turns

fun(): table

Return user turns as { block_idx, label } rows where label is the first line of the user message. Used by the rewind dialog.

smelt.session.worktrees

fun(): table

List smelt-managed git worktrees for the current repository. Rows are { name, branch, path, base, current } and are sorted by name.