Session state for the Textual app.
| 1648 | |
| 1649 | |
| 1650 | class TextualSessionState: |
| 1651 | """Session state for the Textual app.""" |
| 1652 | |
| 1653 | def __init__( |
| 1654 | self, |
| 1655 | *, |
| 1656 | auto_approve: bool = False, |
| 1657 | thread_id: str | None = None, |
| 1658 | ) -> None: |
| 1659 | """Initialize session state. |
| 1660 | |
| 1661 | Args: |
| 1662 | auto_approve: Whether to auto-approve tool calls |
| 1663 | thread_id: Optional thread ID (generates UUID7 if not provided) |
| 1664 | """ |
| 1665 | self.auto_approve = auto_approve |
| 1666 | self.approval_mode_key: str | None = None |
| 1667 | self.turn_number = 0 |
| 1668 | """1-based user-turn count for the thread (coding-agent-v1 turn_number).""" |
| 1669 | self.turn_id: str | None = None |
| 1670 | """Stable id for the current user turn (coding-agent-v1 turn_id).""" |
| 1671 | # Assign the backing field directly: the setter reads `self._thread_id` |
| 1672 | # to detect a thread change, and it isn't set yet. |
| 1673 | self._thread_id = thread_id or _new_thread_id() |
| 1674 | |
| 1675 | @property |
| 1676 | def thread_id(self) -> str: |
| 1677 | """Active LangGraph thread id for the session.""" |
| 1678 | return self._thread_id |
| 1679 | |
| 1680 | @thread_id.setter |
| 1681 | def thread_id(self, value: str) -> None: |
| 1682 | # Per-thread turn markers (coding-agent-v1): restart on every thread |
| 1683 | # change so traces never inherit the prior thread's sequence. |
| 1684 | if value != self._thread_id: |
| 1685 | self.turn_number = 0 |
| 1686 | self.turn_id = None |
| 1687 | self._thread_id = value |
| 1688 | |
| 1689 | def advance_turn(self) -> tuple[str, int]: |
| 1690 | """Begin a new user turn, advancing the per-thread turn markers. |
| 1691 | |
| 1692 | Generates a fresh `turn_id` and increments `turn_number`. Call once per |
| 1693 | user prompt, before building the stream config. |
| 1694 | |
| 1695 | Returns: |
| 1696 | The `(turn_id, turn_number)` for the new turn. |
| 1697 | """ |
| 1698 | from uuid import uuid4 |
| 1699 | |
| 1700 | self.turn_number += 1 |
| 1701 | self.turn_id = str(uuid4()) |
| 1702 | return self.turn_id, self.turn_number |
| 1703 | |
| 1704 | def reset_thread(self) -> str: |
| 1705 | """Reset to a new thread. |
| 1706 | |
| 1707 | Returns: |
no outgoing calls