UAT: PersonaState missing cycle_persona() method for tab-based persona cycling #1345

Open
opened 2026-04-02 16:56:47 +00:00 by freemo · 0 comments
Owner

Bug Report: [tui/persona] — PersonaState has no cycle_persona() method

Severity Assessment

  • Impact: High. The tab key is supposed to cycle through personas, but PersonaState has no method to perform this cycling. Even if the TUI app adds a tab binding (see #1336), there is no backend method to call.
  • Likelihood: 100% reproducible — the method does not exist.
  • Priority: High

Location

  • File: src/cleveragents/tui/persona/state.pyPersonaState class (entire file, 69 lines)

Description

The specification (§Persona Cycling and ADR-045 §Tab Cycling Behavior) defines tab as cycling through personas in the configured cycle list:

tab:       persona_1 → persona_2 → persona_3 → persona_1 → ...

The cycle list is the set of personas with cycle_order > 0, sorted by cycle_order. Personas with cycle_order: 0 exist but are not part of the tab cycle — they can only be selected explicitly via /persona:set <name>.

Actual Behavior

PersonaState only has cycle_preset() for cycling argument presets. There is no cycle_persona() method:

# PersonaState methods:
# - active_name(session_id)
# - active_persona(session_id)
# - set_active_persona(session_id, persona_name)
# - current_preset(session_id)
# - cycle_preset(session_id)       ← exists (for ctrl+tab)
# - effective_arguments(session_id)
# MISSING: cycle_persona(session_id)  ← needed for tab

Verified:

from cleveragents.tui.persona.state import PersonaState
methods = [m for m in dir(PersonaState) if not m.startswith('_')]
print('cycle_persona' in methods)  # False

Expected Behavior (from spec)

PersonaState should have a cycle_persona() method that:

  1. Gets all personas with cycle_order > 0 from the registry, sorted by cycle_order
  2. Finds the current persona's position in that list
  3. Advances to the next persona (wrapping around)
  4. Calls set_active_persona() with the new persona name
  5. Returns the new active Persona object

Example implementation sketch:

def cycle_persona(self, session_id: str) -> Persona:
    cycle_personas = sorted(
        [p for p in self.registry.list_personas() if p.cycle_order > 0],
        key=lambda p: p.cycle_order
    )
    if not cycle_personas:
        return self.active_persona(session_id)
    current_name = self.active_name(session_id)
    names = [p.name for p in cycle_personas]
    if current_name not in names:
        idx = 0
    else:
        idx = (names.index(current_name) + 1) % len(names)
    return self.set_active_persona(session_id, names[idx])

Steps to Reproduce

from cleveragents.tui.persona.state import PersonaState
import inspect
methods = [m for m in dir(PersonaState) if not m.startswith('_')]
assert 'cycle_persona' in methods, "cycle_persona method missing"
# AssertionError: cycle_persona method missing
  • #1336 (UAT: TUI MainScreen missing tab-based persona cycling — tab key not bound)
  • #1315 (Refactor TUI to Align with ADR-44 and ADR-45)

References

  • Spec §Persona Cycling (line ~29088)
  • ADR-045 §Tab Cycling Behavior
  • src/cleveragents/tui/persona/state.py
## Bug Report: [tui/persona] — `PersonaState` has no `cycle_persona()` method ### Severity Assessment - **Impact**: High. The `tab` key is supposed to cycle through personas, but `PersonaState` has no method to perform this cycling. Even if the TUI app adds a `tab` binding (see #1336), there is no backend method to call. - **Likelihood**: 100% reproducible — the method does not exist. - **Priority**: High ### Location - **File**: `src/cleveragents/tui/persona/state.py` — `PersonaState` class (entire file, 69 lines) ### Description The specification (§Persona Cycling and ADR-045 §Tab Cycling Behavior) defines `tab` as cycling through personas in the configured cycle list: ``` tab: persona_1 → persona_2 → persona_3 → persona_1 → ... ``` > The cycle list is the set of personas with `cycle_order > 0`, sorted by `cycle_order`. Personas with `cycle_order: 0` exist but are not part of the tab cycle — they can only be selected explicitly via `/persona:set <name>`. ### Actual Behavior `PersonaState` only has `cycle_preset()` for cycling argument presets. There is no `cycle_persona()` method: ```python # PersonaState methods: # - active_name(session_id) # - active_persona(session_id) # - set_active_persona(session_id, persona_name) # - current_preset(session_id) # - cycle_preset(session_id) ← exists (for ctrl+tab) # - effective_arguments(session_id) # MISSING: cycle_persona(session_id) ← needed for tab ``` Verified: ```python from cleveragents.tui.persona.state import PersonaState methods = [m for m in dir(PersonaState) if not m.startswith('_')] print('cycle_persona' in methods) # False ``` ### Expected Behavior (from spec) `PersonaState` should have a `cycle_persona()` method that: 1. Gets all personas with `cycle_order > 0` from the registry, sorted by `cycle_order` 2. Finds the current persona's position in that list 3. Advances to the next persona (wrapping around) 4. Calls `set_active_persona()` with the new persona name 5. Returns the new active `Persona` object Example implementation sketch: ```python def cycle_persona(self, session_id: str) -> Persona: cycle_personas = sorted( [p for p in self.registry.list_personas() if p.cycle_order > 0], key=lambda p: p.cycle_order ) if not cycle_personas: return self.active_persona(session_id) current_name = self.active_name(session_id) names = [p.name for p in cycle_personas] if current_name not in names: idx = 0 else: idx = (names.index(current_name) + 1) % len(names) return self.set_active_persona(session_id, names[idx]) ``` ### Steps to Reproduce ```python from cleveragents.tui.persona.state import PersonaState import inspect methods = [m for m in dir(PersonaState) if not m.startswith('_')] assert 'cycle_persona' in methods, "cycle_persona method missing" # AssertionError: cycle_persona method missing ``` ### Related Issues - #1336 (UAT: TUI MainScreen missing tab-based persona cycling — tab key not bound) - #1315 (Refactor TUI to Align with ADR-44 and ADR-45) ### References - Spec §Persona Cycling (line ~29088) - ADR-045 §Tab Cycling Behavior - `src/cleveragents/tui/persona/state.py`
freemo self-assigned this 2026-04-02 18:45:20 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#1345
No description provided.