haiku.rag/haiku_rag_slim/haiku/rag/chat/widgets/context_modal.py
2026-01-26 16:41:13 +02:00

76 lines
2 KiB
Python

from typing import TYPE_CHECKING
from textual.app import ComposeResult
from textual.binding import Binding
from textual.containers import Vertical, VerticalScroll
from textual.screen import ModalScreen
from textual.widgets import Markdown, Static
if TYPE_CHECKING:
from haiku.rag.agents.chat.state import ChatSessionState
class ContextModal(ModalScreen): # pragma: no cover
"""Modal screen for displaying session context."""
BINDINGS = [
Binding("escape", "dismiss", "Close", show=True),
Binding("ctrl+o", "dismiss", "Close", show=True),
]
CSS = """
ContextModal {
align: center middle;
background: rgba(0, 0, 0, 0.5);
}
#context-container {
width: auto;
min-width: 40;
max-width: 80;
height: auto;
max-height: 20;
background: $surface;
border: tall $primary;
padding: 1 2;
}
#context-header {
height: auto;
margin-bottom: 1;
}
#context-content {
height: 1fr;
scrollbar-gutter: stable;
}
"""
def __init__(self, session_state: "ChatSessionState | None"):
super().__init__()
self.session_state = session_state
def compose(self) -> ComposeResult:
with Vertical(id="context-container"):
yield Static("[bold]Session Context[/bold]", id="context-header")
with VerticalScroll(id="context-content"):
yield Markdown(self._get_content())
def _get_content(self) -> str:
if not self.session_state:
return "*No session state.*"
if not self.session_state.session_context:
return "*No session context yet. Ask a question first.*"
ctx = self.session_state.session_context
updated = (
ctx.last_updated.strftime("%Y-%m-%d %H:%M:%S")
if ctx.last_updated
else "unknown"
)
return f"**Last updated:** {updated}\n\n---\n\n{ctx.summary}"
async def action_dismiss(self, result=None) -> None:
self.app.pop_screen()