Location: chat_session_controller.py
Primary class managing a stateful chat session (conversation history, cost, model config).
ChatSessionController(
provider: str,
model: str,
*,
system_prompt: Optional[str] = None,
workspace_root: Optional[Path] = None,
audit_logger: Optional[AuditLogger] = None,
permission_mode: PermissionMode = PermissionMode.PROMPT,
budget_cents: Optional[float] = None,
tool_registry: Optional[ToolRegistry] = None,
)async def send_message(
self,
user_message: str,
*,
on_chunk: Optional[Callable[[str], None]] = None,
) -> str- Pre: Controller is initialized and not exceeded budget.
- Post: User message and assistant response appended to
conversation_history. - Returns: Full assistant response string.
- Raises:
BudgetExceededErrorifbudget_centsis set and exceeded. - Side effects: Fires tool calls if LLM requests them; records audit events.
def get_conversation_history(self) -> list[dict[str, Any]]
# Returns: [{'role': 'user'|'assistant', 'content': str}, ...]def get_cost_summary(self) -> dict[str, Any]
# Returns: {'total_cost_cents': float, 'input_tokens': int, 'output_tokens': int}def reset(self) -> None
# Clears conversation history and resets cost counters.async def close(self) -> None
# Fires session end hooks; persists session state if configured.Location: cli/_handlers/_chat.py
def chat_command(args: argparse.Namespace) -> intDispatcher:
args.task— initial task string (may be empty)- (removed) —
--no-tuiwas documented but never implemented - TTY detected →
TUIApp(initial_task=args.task).run() - No TTY →
run_chat_completion(args)(single shot)
def run_chat_repl(args: argparse.Namespace) -> intLine-buffered REPL. Reads from stdin, sends to ChatSessionController.send_message(), prints to stdout. Supports /quit, /reset, /history slash commands.
{'role': 'user' | 'assistant', 'content': str}{
'total_cost_cents': float,
'input_tokens': int,
'output_tokens': int,
'turn_count': int,
}