CmdcTui.State (cmdc_tui v0.1.2)

Copy Markdown View Source

TUI 集中式状态。

所有 Panel 模块为纯渲染函数,读取此 state 并返回 widget 列表。 EventRouter 和 KeyHandler 接收事件后返回更新的 state。

Summary

Functions

追加消息到列表并自动滚动到底部。

单条消息估算行数(label 1 + 内容 + spacer 1)。

从 opts 创建初始 state。

向下滚动消息区域(限制在最大 item 索引)。

自动滚动到底部,让最新内容可见。

向上滚动消息区域(限制在 0)。

计算所有消息的总 item 数(用于 scroll_offset 边界,每条消息 3 items)。

估算所有历史消息的总行数(用于 Scrollbar content_length 显示)。

更新 token 用量并同步 cost。

更新或插入工具条目,超过 @max_tool_entries 时删除最早的已完成条目。

Types

approval_map()

@type approval_map() :: %{
  id: String.t(),
  tool: String.t(),
  args: map(),
  session_id: String.t(),
  hint: String.t(),
  requested_at: integer()
}

ask_map()

@type ask_map() :: %{
  session_id: String.t(),
  question: String.t(),
  options: [map()],
  ref: String.t(),
  input_ref: reference() | nil
}

message_entry()

@type message_entry() :: %{
  role: :user | :assistant | :system | :tool,
  content: String.t(),
  tool_name: String.t() | nil,
  timestamp: integer()
}

t()

@type t() :: %CmdcTui.State{
  agent_status: :idle | :running | :streaming,
  command_palette_input: reference() | nil,
  command_palette_open: boolean(),
  command_palette_query: String.t(),
  command_palette_selected: non_neg_integer(),
  cost_usd: float(),
  current_streaming: String.t(),
  current_thinking: String.t(),
  input_tokens: non_neg_integer(),
  message_scroll: non_neg_integer(),
  messages: [message_entry()],
  model_name: String.t() | nil,
  output_tokens: non_neg_integer(),
  pending_approval: approval_map() | nil,
  pending_ask: ask_map() | nil,
  session: pid() | nil,
  session_id: String.t() | nil,
  show_thinking: boolean(),
  sidebar_tab: :tools | :todos,
  slash_autocomplete: boolean(),
  slash_matches: [map()],
  slash_selected: non_neg_integer(),
  streaming_line_count: non_neg_integer(),
  textarea: reference() | nil,
  throbber_step: non_neg_integer(),
  todos: [map()],
  tools: [tool_entry()],
  total_tokens: non_neg_integer()
}

tool_entry()

@type tool_entry() :: %{
  name: String.t(),
  call_id: String.t(),
  args: map(),
  status: :running | :done | :error | :blocked,
  result: term(),
  started_at: integer(),
  finished_at: integer() | nil
}

Functions

append_message(state, entry)

@spec append_message(t(), message_entry()) :: t()

追加消息到列表并自动滚动到底部。

message_lines(arg1)

@spec message_lines(message_entry()) :: non_neg_integer()

单条消息估算行数(label 1 + 内容 + spacer 1)。

new(opts)

@spec new(keyword()) :: t()

从 opts 创建初始 state。

scroll_down(state, amount \\ 1)

@spec scroll_down(t(), pos_integer()) :: t()

向下滚动消息区域(限制在最大 item 索引)。

scroll_to_bottom(state)

@spec scroll_to_bottom(t()) :: non_neg_integer()

自动滚动到底部,让最新内容可见。

scroll_up(state, amount \\ 1)

@spec scroll_up(t(), pos_integer()) :: t()

向上滚动消息区域(限制在 0)。

total_message_items(state)

@spec total_message_items(t()) :: non_neg_integer()

计算所有消息的总 item 数(用于 scroll_offset 边界,每条消息 3 items)。

total_message_lines(state)

@spec total_message_lines(t()) :: non_neg_integer()

估算所有历史消息的总行数(用于 Scrollbar content_length 显示)。

update_tokens(state, usage)

@spec update_tokens(t(), CMDC.TokenUsage.t() | map()) :: t()

更新 token 用量并同步 cost。

接受 %CMDC.TokenUsage{} struct(v0.2 RFC B5)或历史 plain map (兼容 Anthropic 风格 input_tokens / OpenAI 风格 prompt_tokens)。

upsert_tool(state, call_id, updates)

@spec upsert_tool(t(), String.t(), map()) :: t()

更新或插入工具条目,超过 @max_tool_entries 时删除最早的已完成条目。