hendrik/tui/app.py
2026-06-10 15:12:50 +07:00

75 lines
2.1 KiB
Python

import curses
import threading
from .render import init_colors, draw
from .input import handle_key
from .agent import log, WELCOME_ART
class HendrikTUI:
def __init__(self, llm_client, tools_definition, TOOLS, TOOL_HANDLERS,
build_system_prompt, agent_max_iterations):
self.llm = llm_client
self.tools_def = tools_definition
self.TOOLS = TOOLS
self.TOOL_HANDLERS = TOOL_HANDLERS
self.build_system_prompt = build_system_prompt
self.agent_max_iterations = agent_max_iterations
self.messages = None
self.log = []
self.input_buffer = [""]
self.input_line = 0
self.input_col = 0
self.scroll = 0
self.processing = False
self.running = True
self.h, self.w = 0, 0
self.agent_thread: threading.Thread | None = None
self.agent_done = threading.Event()
def run(self):
try:
curses.wrapper(self._main)
except KeyboardInterrupt:
pass
def _main(self, stdscr):
curses.use_default_colors()
init_colors()
stdscr.keypad(True)
stdscr.refresh()
self.messages = [{"role": "system", "content": self.build_system_prompt(tools_definition=self.tools_def)}]
log(self, "welcome", WELCOME_ART)
while self.running:
self.h, self.w = stdscr.getmaxyx()
if self.h < 14 or self.w < 40:
stdscr.erase()
stdscr.addstr(0, 0, "Terminal too small (min 40x14)")
stdscr.refresh()
stdscr.getch()
continue
draw(self, stdscr)
curses.curs_set(2)
if self.processing:
stdscr.timeout(100)
else:
stdscr.timeout(-1)
try:
key = stdscr.getch()
except KeyboardInterrupt:
break
handle_key(self, stdscr, key)
if self.agent_done.is_set():
self.agent_thread.join()
self.agent_done.clear()
self.processing = False
self.agent_thread = None