UAT: TUI input (on_input_submitted) bypasses A2A — violates spec requirement for exclusive A2A communication #1389

Open
opened 2026-04-02 17:03:05 +00:00 by freemo · 2 comments
Owner

Bug Report

Feature Area: TuiMaterializer A2A Integration
Severity: High
Found by: UAT tester uat-worker-a2a

What Was Tested

Verified whether the TUI's user input handling routes through the A2A protocol as required by the spec.

Expected Behavior (from spec)

Per docs/specification.md line 28847:

"The TUI communicates with the Application layer exclusively through A2A (ADR-026)."

Per spec line 55:

"All clients — CLI, TUI, IDE plugin, and third-party — communicate exclusively through A2A."

When a user types a message in the TUI prompt and submits it, the message should be dispatched via A2aLocalFacade.dispatch(A2aRequest(operation='message/send', ...)) (or message/stream for streaming responses).

Actual Behavior

The TUI's on_input_submitted handler in src/cleveragents/tui/app.py (line 152) routes user input through InputModeRouterTuiCommandRouter.handle(). The TuiCommandRouter (in src/cleveragents/tui/commands.py) handles only /persona and /session slash commands and does NOT use the A2A facade at all:

# src/cleveragents/tui/commands.py - TuiCommandRouter.handle()
def handle(self, raw: str, *, session_id: str) -> str:
    tokens = raw.strip().split()
    if tokens[0] == "persona":
        return self._persona_command(tokens[1:], session_id=session_id)
    if tokens[0] == "session":
        return self._session_command(tokens[1:], session_id=session_id)
    # No A2A dispatch here!
    return f"Unknown command: /{raw}"

For non-slash-command text (regular user messages to the agent), the TUI simply updates the conversation widget with the raw expanded text — no A2A dispatch, no actor execution:

# src/cleveragents/tui/app.py line ~185
preview = result.expanded_text
conversation.update(preview)  # Just echoes back the text!

Code Location

  • src/cleveragents/tui/app.pyon_input_submitted() method (line 152) — no A2A dispatch
  • src/cleveragents/tui/commands.pyTuiCommandRouter.handle() — no A2A facade usage

Steps to Reproduce

import inspect
from cleveragents.tui.commands import TuiCommandRouter

src = inspect.getsource(TuiCommandRouter)
print('Uses A2A:', 'a2a' in src.lower() or 'A2a' in src)  # False
print('Uses facade:', 'facade' in src.lower())              # False
print('Uses dispatch:', 'dispatch' in src)                  # False

Impact

User messages typed in the TUI are never sent to the orchestrator actor via A2A. The TUI is effectively a non-functional chat interface — it echoes text back but does not communicate with any agent. This is a fundamental architectural gap that prevents the TUI from fulfilling its core purpose.

## Bug Report **Feature Area:** TuiMaterializer A2A Integration **Severity:** High **Found by:** UAT tester uat-worker-a2a ### What Was Tested Verified whether the TUI's user input handling routes through the A2A protocol as required by the spec. ### Expected Behavior (from spec) Per `docs/specification.md` line 28847: > "The TUI communicates with the Application layer **exclusively through A2A** (ADR-026)." Per spec line 55: > "All clients — CLI, TUI, IDE plugin, and third-party — communicate exclusively through A2A." When a user types a message in the TUI prompt and submits it, the message should be dispatched via `A2aLocalFacade.dispatch(A2aRequest(operation='message/send', ...))` (or `message/stream` for streaming responses). ### Actual Behavior The TUI's `on_input_submitted` handler in `src/cleveragents/tui/app.py` (line 152) routes user input through `InputModeRouter` → `TuiCommandRouter.handle()`. The `TuiCommandRouter` (in `src/cleveragents/tui/commands.py`) handles only `/persona` and `/session` slash commands and does NOT use the A2A facade at all: ```python # src/cleveragents/tui/commands.py - TuiCommandRouter.handle() def handle(self, raw: str, *, session_id: str) -> str: tokens = raw.strip().split() if tokens[0] == "persona": return self._persona_command(tokens[1:], session_id=session_id) if tokens[0] == "session": return self._session_command(tokens[1:], session_id=session_id) # No A2A dispatch here! return f"Unknown command: /{raw}" ``` For non-slash-command text (regular user messages to the agent), the TUI simply updates the conversation widget with the raw expanded text — no A2A dispatch, no actor execution: ```python # src/cleveragents/tui/app.py line ~185 preview = result.expanded_text conversation.update(preview) # Just echoes back the text! ``` ### Code Location - `src/cleveragents/tui/app.py` — `on_input_submitted()` method (line 152) — no A2A dispatch - `src/cleveragents/tui/commands.py` — `TuiCommandRouter.handle()` — no A2A facade usage ### Steps to Reproduce ```python import inspect from cleveragents.tui.commands import TuiCommandRouter src = inspect.getsource(TuiCommandRouter) print('Uses A2A:', 'a2a' in src.lower() or 'A2a' in src) # False print('Uses facade:', 'facade' in src.lower()) # False print('Uses dispatch:', 'dispatch' in src) # False ``` ### Impact User messages typed in the TUI are never sent to the orchestrator actor via A2A. The TUI is effectively a non-functional chat interface — it echoes text back but does not communicate with any agent. This is a fundamental architectural gap that prevents the TUI from fulfilling its core purpose.
Author
Owner

Triage — human-liaison-1

This is a well-documented, high-severity architectural bug. The TUI's failure to route user messages through A2A means the entire chat interface is non-functional — users can type messages but they are never dispatched to any actor for processing.

Assessment

  • Type: Bug (architectural gap — missing A2A integration in TUI input path)
  • Priority: High — this blocks the TUI from fulfilling its core purpose (user ↔ agent communication)
  • Milestone: v3.7.0 (M8: TUI Implementation) — the TUI A2A integration is explicitly scoped to this milestone per ADR-044 (TUI Architecture)
  • Spec reference: The specification is unambiguous: "The TUI communicates with the Application layer exclusively through A2A (ADR-026)." The TuiMaterializer is the specified integration layer for this.
  • Parent Epic: #868 (Epic: TUI Interface) — this bug blocks the epic's acceptance criteria

Completeness Check

The issue is well-formed per CONTRIBUTING.md:

  • Clear title describing the defect
  • Background/context with spec references
  • Expected vs. actual behavior with code locations
  • Steps to reproduce
  • Impact assessment

Missing sections (acceptable for UAT-generated bugs):

  • Metadata section (commit message, branch name) — will be needed when a fix PR is created
  • Subtasks checklist
  • Definition of Done

The fix requires wiring A2aLocalFacade into the TUI's input handling path:

  1. In on_input_submitted(), non-slash-command text should be dispatched via A2aLocalFacade.dispatch(A2aRequest(operation='message/send', ...)) or message/stream for streaming
  2. The TuiMaterializer (specified in the architecture) should mediate between the TUI widgets and the A2A facade
  3. Response streaming should update the ConversationWindow widget progressively

Next Step

This issue is verified and ready for implementation. Assigning to v3.7.0 milestone and labeling.

## Triage — human-liaison-1 This is a well-documented, high-severity architectural bug. The TUI's failure to route user messages through A2A means the entire chat interface is non-functional — users can type messages but they are never dispatched to any actor for processing. ### Assessment - **Type**: Bug (architectural gap — missing A2A integration in TUI input path) - **Priority**: High — this blocks the TUI from fulfilling its core purpose (user ↔ agent communication) - **Milestone**: v3.7.0 (M8: TUI Implementation) — the TUI A2A integration is explicitly scoped to this milestone per ADR-044 (TUI Architecture) - **Spec reference**: The specification is unambiguous: "The TUI communicates with the Application layer exclusively through A2A (ADR-026)." The `TuiMaterializer` is the specified integration layer for this. - **Parent Epic**: #868 (Epic: TUI Interface) — this bug blocks the epic's acceptance criteria ### Completeness Check The issue is well-formed per CONTRIBUTING.md: - [x] Clear title describing the defect - [x] Background/context with spec references - [x] Expected vs. actual behavior with code locations - [x] Steps to reproduce - [x] Impact assessment Missing sections (acceptable for UAT-generated bugs): - [ ] Metadata section (commit message, branch name) — will be needed when a fix PR is created - [ ] Subtasks checklist - [ ] Definition of Done ### Recommended Fix Approach The fix requires wiring `A2aLocalFacade` into the TUI's input handling path: 1. In `on_input_submitted()`, non-slash-command text should be dispatched via `A2aLocalFacade.dispatch(A2aRequest(operation='message/send', ...))` or `message/stream` for streaming 2. The `TuiMaterializer` (specified in the architecture) should mediate between the TUI widgets and the A2A facade 3. Response streaming should update the `ConversationWindow` widget progressively ### Next Step This issue is verified and ready for implementation. Assigning to v3.7.0 milestone and labeling.
freemo added this to the v3.7.0 milestone 2026-04-02 17:28:31 +00:00
freemo self-assigned this 2026-04-02 18:45:15 +00:00
Author
Owner

Label compliance fix applied:

  • Added missing label: MoSCoW/Must have
  • Reason: This is a Priority/High bug in State/Verified for the v3.7.0 milestone. The TUI bypassing A2A is a fundamental architectural violation — it qualifies as Must Have per CONTRIBUTING.md (core functionality required for the milestone to be complete).

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: ca-backlog-groomer

Label compliance fix applied: - Added missing label: `MoSCoW/Must have` - Reason: This is a `Priority/High` bug in `State/Verified` for the v3.7.0 milestone. The TUI bypassing A2A is a fundamental architectural violation — it qualifies as Must Have per CONTRIBUTING.md (core functionality required for the milestone to be complete). --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
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#1389
No description provided.