rotate chat TUI conversation id per launch / clear-chat
This commit is contained in:
parent
80e3ae0280
commit
188d35023f
3 changed files with 11 additions and 2 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
- Bump `haiku.skills>=0.17.1` and `pydantic-ai-slim>=1.100.0` (the last pre-2.0 release). Migrate off two APIs slated for removal in pydantic-ai 2.0: `Agent(tool_retries=, output_retries=)` → `Agent(retries={"tools": …, "output": …})` in the LLM-as-judge evaluator, and `Evaluator.evaluation_name` class attribute → overriding `get_default_evaluation_name()` on `CitationMRREvaluator` / `CitationMAPEvaluator`.
|
- Bump `haiku.skills>=0.17.1` and `pydantic-ai-slim>=1.100.0` (the last pre-2.0 release). Migrate off two APIs slated for removal in pydantic-ai 2.0: `Agent(tool_retries=, output_retries=)` → `Agent(retries={"tools": …, "output": …})` in the LLM-as-judge evaluator, and `Evaluator.evaluation_name` class attribute → overriding `get_default_evaluation_name()` on `CitationMRREvaluator` / `CitationMAPEvaluator`.
|
||||||
- Drop the `item.annotations` fallback in `_picture_description_text`. Docling's `PictureItem` runs a `@model_validator(mode="after")` on load that migrates the deprecated `annotations` field into `meta.description`, so reading `meta.description.text` covers both legacy and current blobs. Tests in `test_converters.py` switched to `meta.description.text` for the same reason.
|
- Drop the `item.annotations` fallback in `_picture_description_text`. Docling's `PictureItem` runs a `@model_validator(mode="after")` on load that migrates the deprecated `annotations` field into `meta.description`, so reading `meta.description.text` covers both legacy and current blobs. Tests in `test_converters.py` switched to `meta.description.text` for the same reason.
|
||||||
|
- Chat TUI now generates a stable per-launch `thread_id` (rotated on "Clear chat") instead of hardcoding `"tui"`. AGUIAdapter forwards it as the `gen_ai.conversation.id` OTel attribute, so multi-turn TUI sessions group into one Logfire conversation instead of collapsing every launch into a single bucket.
|
||||||
- Documentation generator swapped from `mkdocs-material` to `zensical`. Drops `mkdocs` / `mkdocs-material` dev deps, replaces `mkdocs.yml` with `zensical.toml`, adds `overrides/main.html` (OG/Twitter share meta) and `docs/stylesheets/extra.css`. `build-docs` workflow now runs `uv run zensical build` and publishes via the GitHub Pages artifact actions instead of `mkdocs gh-deploy`.
|
- Documentation generator swapped from `mkdocs-material` to `zensical`. Drops `mkdocs` / `mkdocs-material` dev deps, replaces `mkdocs.yml` with `zensical.toml`, adds `overrides/main.html` (OG/Twitter share meta) and `docs/stylesheets/extra.css`. `build-docs` workflow now runs `uv run zensical build` and publishes via the GitHub Pages artifact actions instead of `mkdocs gh-deploy`.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,10 @@ class ChatApp(App):
|
||||||
self._is_processing = False
|
self._is_processing = False
|
||||||
self._current_worker: Worker[None] | None = None
|
self._current_worker: Worker[None] | None = None
|
||||||
self._document_filter: list[str] = []
|
self._document_filter: list[str] = []
|
||||||
|
# Stable per-launch id so multi-turn chats land in one Logfire
|
||||||
|
# conversation. AGUIAdapter reads run_input.thread_id and exports it
|
||||||
|
# as the `gen_ai.conversation.id` OTel attribute on every agent run.
|
||||||
|
self._conversation_id = str(uuid.uuid4())
|
||||||
|
|
||||||
def compose(self) -> "ComposeResult":
|
def compose(self) -> "ComposeResult":
|
||||||
"""Compose the UI layout."""
|
"""Compose the UI layout."""
|
||||||
|
|
@ -207,7 +211,7 @@ class ChatApp(App):
|
||||||
await chat_history.show_thinking()
|
await chat_history.show_thinking()
|
||||||
|
|
||||||
run_input = RunAgentInput(
|
run_input = RunAgentInput(
|
||||||
thread_id="tui",
|
thread_id=self._conversation_id,
|
||||||
run_id=str(uuid.uuid4()),
|
run_id=str(uuid.uuid4()),
|
||||||
messages=self._messages,
|
messages=self._messages,
|
||||||
state=self._state,
|
state=self._state,
|
||||||
|
|
@ -375,6 +379,8 @@ class ChatApp(App):
|
||||||
# Reset state
|
# Reset state
|
||||||
if self._toolset:
|
if self._toolset:
|
||||||
self._state = self._toolset.build_state_snapshot()
|
self._state = self._toolset.build_state_snapshot()
|
||||||
|
# Cleared chat starts a fresh Logfire conversation.
|
||||||
|
self._conversation_id = str(uuid.uuid4())
|
||||||
|
|
||||||
def action_focus_input(self) -> None:
|
def action_focus_input(self) -> None:
|
||||||
"""Focus the input field, or cancel if processing."""
|
"""Focus the input field, or cancel if processing."""
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ async def test_chat_history_thinking_indicator(temp_db_path: Path):
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_clear_chat_resets_state(temp_db_path: Path):
|
async def test_clear_chat_resets_state(temp_db_path: Path):
|
||||||
"""Test that clearing chat resets state and messages."""
|
"""Test that clearing chat resets state, messages, and conversation id."""
|
||||||
from haiku.rag.chat.widgets.chat_history import ChatHistory
|
from haiku.rag.chat.widgets.chat_history import ChatHistory
|
||||||
|
|
||||||
app, mock_client = _make_app(temp_db_path)
|
app, mock_client = _make_app(temp_db_path)
|
||||||
|
|
@ -232,10 +232,12 @@ async def test_clear_chat_resets_state(temp_db_path: Path):
|
||||||
await chat_history.add_message("assistant", "Hi there")
|
await chat_history.add_message("assistant", "Hi there")
|
||||||
assert len(chat_history.messages) == 2
|
assert len(chat_history.messages) == 2
|
||||||
|
|
||||||
|
previous_conversation_id = app._conversation_id
|
||||||
await app.action_clear_chat()
|
await app.action_clear_chat()
|
||||||
await pilot.pause()
|
await pilot.pause()
|
||||||
|
|
||||||
assert len(chat_history.messages) == 0
|
assert len(chat_history.messages) == 0
|
||||||
|
assert app._conversation_id != previous_conversation_id
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue