Thread history
ui.ThreadHistory is a component for past conversations: a search box and the threads grouped by when they were last updated (Today, Yesterday, This week, This month, Older). Each row shows the title, an optional detail (the model or the agent) and a delete button. threads are dicts or objects with id, title, updated (a time.time() timestamp) and detail; selected marks the open one. Picking a thread reports on_open and the trash button on_delete, both with the thread’s id in event.value. The component keeps the search text itself.
ui.ThreadHistory · Category: AI agents · Full reference →


import time
now = time.time()pz.container(ui.ThreadHistory(threads=[ {"id": "1", "title": "Add a login form", "updated": now - 60, "detail": "Claude"}, {"id": "2", "title": "Fix the failing tests", "updated": now - 900, "detail": "Claude"}, {"id": "3", "title": "Dark theme for the settings", "updated": now - 86400, "detail": "Gemini CLI"}, {"id": "4", "title": "Export the table to CSV", "updated": now - 4 * 86400}, {"id": "5", "title": "First steps", "updated": now - 60 * 86400},], selected="1", on_open=on_open, on_delete=on_delete), width=380, height=320)When to use
Section titled “When to use”- In a side panel or a popover of a chat app, to reopen an earlier conversation.
import pyzed as pzfrom pyzed import ui
class Chats(pz.App): def __init__(self): self.threads = load_threads() # [{"id", "title", "updated", "detail"}, ...] self.open_id = ""
def delete(self, ident): self.threads = [t for t in self.threads if t["id"] != ident]
def view(self): return ui.ThreadHistory(threads=self.threads, selected=self.open_id, on_open=lambda e: setattr(self, "open_id", e.value), on_delete=lambda e: self.delete(e.value))Variants
Section titled “Variants”The search ones are drawn with text typed in the box (the component keeps it).


Code
import time
now = time.time()threads = [ {"id": "1", "title": "Add a login form", "updated": now - 60, "detail": "Claude"}, {"id": "2", "title": "Fix the failing tests", "updated": now - 86400}, {"id": "3", "title": "Export the table to CSV", "updated": now - 4 * 86400},]pz.container(ui.ThreadHistory(threads=threads), width=320, height=260)

selected="2"Code
import time
now = time.time()threads = [ {"id": "1", "title": "Add a login form", "updated": now - 60, "detail": "Claude"}, {"id": "2", "title": "Fix the failing tests", "updated": now - 86400}, {"id": "3", "title": "Export the table to CSV", "updated": now - 4 * 86400},]pz.container(ui.ThreadHistory(threads=threads, selected="2"), width=320, height=260)

Code
pz.container(ui.ThreadHistory(threads=[]), width=320, height=110)

Code
import time
now = time.time()threads = [ {"id": "1", "title": "Add a login form", "updated": now - 60, "detail": "Claude"}, {"id": "2", "title": "Fix the failing tests", "updated": now - 86400}, {"id": "3", "title": "Export the table to CSV", "updated": now - 4 * 86400},]pz.container(ui.ThreadHistory(threads=threads), width=320, height=160)

Code
import time
now = time.time()threads = [ {"id": "1", "title": "Add a login form", "updated": now - 60, "detail": "Claude"}, {"id": "2", "title": "Fix the failing tests", "updated": now - 86400}, {"id": "3", "title": "Export the table to CSV", "updated": now - 4 * 86400},]pz.container(ui.ThreadHistory(threads=threads), width=320, height=110)Events
Section titled “Events”Thread history has 2 events of its own, listed below. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.
It is a pz.Component, so it also raises on_mount and on_unmount, and its handlers get a pz.Event whose value holds the data.
| Event | Handler gets | When |
|---|---|---|
on_open |
(event) |
A thread was picked (event.value is its id). |
on_delete |
(event) |
Delete was pressed on a thread. |
Handler gets is what Pyzed passes to your callable: () means nothing. Any handler can also be a message (a value that is not callable), which goes to update().
Handling the events
Section titled “Handling the events”The same events written three ways. Imperative: methods of the app change self. Declarative: the handlers produce messages and one update() decides. Functional: a pure function draws an immutable state and asks for changes with set_state(...). See Imperative, declarative and functional.
import time
class Chats(pz.App): def __init__(self): now = time.time() self.threads = [{"id": "1", "title": "Add a login form", "updated": now - 60}, {"id": "2", "title": "Fix the tests", "updated": now - 900}] self.open_id = "1"
def view(self): # event.value is the thread's id return ui.ThreadHistory(threads=self.threads, selected=self.open_id, on_open=lambda e: setattr(self, "open_id", e.value), on_delete=lambda e: self.delete(e.value))
def delete(self, ident): self.threads = [t for t in self.threads if t["id"] != ident]from dataclasses import dataclass
@dataclassclass OpenThread: ident: str
@dataclassclass DeleteThread: ident: str
class Chats(pz.App): threads = [{"id": "1", "title": "Add a login form", "updated": 0}] open_id = ""
def update(self, message): match message: case OpenThread(ident): self.open_id = ident case DeleteThread(ident): self.threads = [t for t in self.threads if t["id"] != ident]
def view(self): return ui.ThreadHistory(threads=self.threads, selected=self.open_id, on_open=lambda e: OpenThread(e.value), on_delete=lambda e: DeleteThread(e.value))from dataclasses import dataclass
@dataclass(frozen=True)class State: threads: tuple = ({"id": "1", "title": "Add a login form", "updated": 0},) open_id: str = ""
def view(state, set_state): return ui.ThreadHistory( threads=list(state.threads), selected=state.open_id, on_open=lambda e: set_state(open_id=e.value), on_delete=lambda e: set_state(threads=tuple(t for t in state.threads if t["id"] != e.value)))Properties and API
Section titled “Properties and API”ui.ThreadHistory
Section titled “ui.ThreadHistory”class ThreadHistoryA component for past conversations: a search box and the threads grouped by day (Today, Yesterday, This week, This month, Older), each with a delete button.
| Property | Default | Description |
|---|---|---|
threads |
None |
Dicts or objects with id, title, updated (a timestamp) and an optional detail. |
selected |
"" |
The id of the open thread. |
theme |
None |
Theme. |
Events: on_open, on_delete (events).