Skip to content

Index

strands_teams.display

Parameterized Rich TUI display for agent team runs.

The display core is domain-agnostic: panel title, mode label, phase spec (count + names), and discovery-extractor callable are all injected. Nothing here hardcodes a product name, a phase total, or codebase-specific tool keys.

EventConsumer

Bases: ABC

Protocol for consuming agent streaming events.

Implement this interface to create custom event consumers for different output formats (Rich terminal, JSON, web UI, etc.).

Events follow a lifecycle: run starts -> messages/tools -> run finishes.

Example

class LoggingConsumer(EventConsumer): ... async def on_run_started(self, thread_id: str, run_id: str) -> None: ... print(f"Run started: {run_id}")

on_run_started abstractmethod async

on_run_started(thread_id, run_id)

Handle run started event.

Parameters:

Name Type Description Default
thread_id str

Unique identifier for the conversation thread.

required
run_id str

Unique identifier for this agent run.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_run_started(self, thread_id: str, run_id: str) -> None:
    """Handle run started event.

    Args:
        thread_id: Unique identifier for the conversation thread.
        run_id: Unique identifier for this agent run.
    """

on_text_start abstractmethod async

on_text_start(message_id, role)

Handle start of a text message.

Parameters:

Name Type Description Default
message_id str

Unique identifier for the message.

required
role str

Message role (usually "assistant").

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_text_start(self, message_id: str, role: str) -> None:
    """Handle start of a text message.

    Args:
        message_id: Unique identifier for the message.
        role: Message role (usually "assistant").
    """

on_text_content abstractmethod async

on_text_content(message_id, delta)

Handle streaming text content.

Parameters:

Name Type Description Default
message_id str

Identifier of the message being streamed.

required
delta str

New text chunk to append.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_text_content(self, message_id: str, delta: str) -> None:
    """Handle streaming text content.

    Args:
        message_id: Identifier of the message being streamed.
        delta: New text chunk to append.
    """

on_text_end abstractmethod async

on_text_end(message_id)

Handle end of a text message.

Parameters:

Name Type Description Default
message_id str

Identifier of the completed message.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_text_end(self, message_id: str) -> None:
    """Handle end of a text message.

    Args:
        message_id: Identifier of the completed message.
    """

on_tool_start abstractmethod async

on_tool_start(tool_call_id, tool_name)

Handle start of tool execution.

Parameters:

Name Type Description Default
tool_call_id str

Unique identifier for this tool call.

required
tool_name str

Name of the tool being called.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_tool_start(self, tool_call_id: str, tool_name: str) -> None:
    """Handle start of tool execution.

    Args:
        tool_call_id: Unique identifier for this tool call.
        tool_name: Name of the tool being called.
    """

on_tool_args abstractmethod async

on_tool_args(tool_call_id, args_delta)

Handle streaming tool arguments.

Parameters:

Name Type Description Default
tool_call_id str

Identifier of the tool call.

required
args_delta str

JSON string chunk of tool arguments.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_tool_args(self, tool_call_id: str, args_delta: str) -> None:
    """Handle streaming tool arguments.

    Args:
        tool_call_id: Identifier of the tool call.
        args_delta: JSON string chunk of tool arguments.
    """

on_tool_result abstractmethod async

on_tool_result(tool_call_id, result)

Handle tool execution result.

Parameters:

Name Type Description Default
tool_call_id str

Identifier of the completed tool call.

required
result Any

Result returned by the tool.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_tool_result(self, tool_call_id: str, result: Any) -> None:
    """Handle tool execution result.

    Args:
        tool_call_id: Identifier of the completed tool call.
        result: Result returned by the tool.
    """

on_tool_end abstractmethod async

on_tool_end(tool_call_id)

Handle end of tool execution.

Parameters:

Name Type Description Default
tool_call_id str

Identifier of the completed tool call.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_tool_end(self, tool_call_id: str) -> None:
    """Handle end of tool execution.

    Args:
        tool_call_id: Identifier of the completed tool call.
    """

on_state_snapshot abstractmethod async

on_state_snapshot(snapshot)

Handle state snapshot event.

Parameters:

Name Type Description Default
snapshot dict[str, Any]

Complete state snapshot dictionary.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_state_snapshot(self, snapshot: dict[str, Any]) -> None:
    """Handle state snapshot event.

    Args:
        snapshot: Complete state snapshot dictionary.
    """

on_run_finished abstractmethod async

on_run_finished(thread_id, run_id)

Handle run finished event.

Parameters:

Name Type Description Default
thread_id str

Identifier of the conversation thread.

required
run_id str

Identifier of the completed run.

required
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_run_finished(self, thread_id: str, run_id: str) -> None:
    """Handle run finished event.

    Args:
        thread_id: Identifier of the conversation thread.
        run_id: Identifier of the completed run.
    """

on_error abstractmethod async

on_error(message, code=None)

Handle error event.

Parameters:

Name Type Description Default
message str

Error message description.

required
code str | None

Optional error code.

None
Source code in packages/strands-teams/src/strands_teams/display/base.py
@abstractmethod
async def on_error(self, message: str, code: str | None = None) -> None:
    """Handle error event.

    Args:
        message: Error message description.
        code: Optional error code.
    """

start async

start()

Initialize the consumer (optional).

Override to perform setup before events start streaming. Called before the first event is received.

Source code in packages/strands-teams/src/strands_teams/display/base.py
async def start(self) -> None:
    """Initialize the consumer (optional).

    Override to perform setup before events start streaming.
    Called before the first event is received.
    """

stop async

stop()

Cleanup the consumer (optional).

Override to perform cleanup after events stop streaming. Called after the last event is received or on error.

Source code in packages/strands-teams/src/strands_teams/display/base.py
async def stop(self) -> None:
    """Cleanup the consumer (optional).

    Override to perform cleanup after events stop streaming.
    Called after the last event is received or on error.
    """

QuietConsumer

QuietConsumer()

Bases: EventConsumer

Silent consumer that only writes errors to stderr.

Initialize quiet consumer.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
def __init__(self) -> None:
    """Initialize quiet consumer."""
    self._stderr = Console(stderr=True, no_color=True, highlight=False)

start async

start()

Initialize the consumer (optional).

Override to perform setup before events start streaming. Called before the first event is received.

Source code in packages/strands-teams/src/strands_teams/display/base.py
async def start(self) -> None:
    """Initialize the consumer (optional).

    Override to perform setup before events start streaming.
    Called before the first event is received.
    """

stop async

stop()

Cleanup the consumer (optional).

Override to perform cleanup after events stop streaming. Called after the last event is received or on error.

Source code in packages/strands-teams/src/strands_teams/display/base.py
async def stop(self) -> None:
    """Cleanup the consumer (optional).

    Override to perform cleanup after events stop streaming.
    Called after the last event is received or on error.
    """

on_run_started async

on_run_started(thread_id, run_id)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_run_started(self, thread_id: str, run_id: str) -> None:
    """No output."""

on_text_start async

on_text_start(message_id, role)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_text_start(self, message_id: str, role: str) -> None:
    """No output."""

on_text_content async

on_text_content(message_id, delta)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_text_content(self, message_id: str, delta: str) -> None:
    """No output."""

on_text_end async

on_text_end(message_id)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_text_end(self, message_id: str) -> None:
    """No output."""

on_tool_start async

on_tool_start(tool_call_id, tool_name)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_start(self, tool_call_id: str, tool_name: str) -> None:
    """No output."""

on_tool_args async

on_tool_args(tool_call_id, args_delta)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_args(self, tool_call_id: str, args_delta: str) -> None:
    """No output."""

on_tool_result async

on_tool_result(tool_call_id, result)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_result(self, tool_call_id: str, result: Any) -> None:
    """No output."""

on_tool_end async

on_tool_end(tool_call_id)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_end(self, tool_call_id: str) -> None:
    """No output."""

on_state_snapshot async

on_state_snapshot(snapshot)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_state_snapshot(self, snapshot: dict[str, Any]) -> None:
    """No output."""

on_run_finished async

on_run_finished(thread_id, run_id)

No output.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_run_finished(self, thread_id: str, run_id: str) -> None:
    """No output."""

on_error async

on_error(message, code=None)

Print error to stderr.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_error(self, message: str, code: str | None = None) -> None:
    """Print error to stderr."""
    error_text = f"[{code}] {message}" if code else message
    self._stderr.print(f"Error: {error_text}")

RichEventConsumer

RichEventConsumer(
    state,
    *,
    title,
    mode_label=None,
    discovery_extractor=None,
    console=None,
)

Bases: EventConsumer

Dashboard-style consumer for agent execution.

Shows a fixed-height panel with: - Timer and progress bar - Tool category breakdown with mini bars - Active tool with spinner - Recent tool history with timing and status - Phase indicator [i/N] where N comes from the injected phase spec - Discovery feed populated by the injected extractor

No streaming text display. The agent's reasoning is not shown — only tool execution status matters for a long-running analysis agent.

When teams have been dispatched the coordinator layout is rendered (adding a team-status table); otherwise the single-agent layout is used.

Initialize the dashboard consumer.

Parameters:

Name Type Description Default
state AgentDisplayState

Display state carrying the injected phase spec.

required
title str

Panel title (replaces the hardcoded product name).

required
mode_label str | None

Optional badge appended to the title (e.g. "FULL").

None
discovery_extractor Callable[[str, Any], DiscoveryEvent | None] | None

Callable mapping (tool_name, result) to a :class:DiscoveryEvent or None. Defaults to a no-op. The consumer guards the call so a raising extractor never crashes the display.

None
console Console | None

Optional Rich Console instance.

None
Source code in packages/strands-teams/src/strands_teams/display/rich.py
def __init__(
    self,
    state: AgentDisplayState,
    *,
    title: str,
    mode_label: str | None = None,
    discovery_extractor: Callable[[str, Any], DiscoveryEvent | None] | None = None,
    console: Console | None = None,
) -> None:
    """Initialize the dashboard consumer.

    Args:
        state: Display state carrying the injected phase spec.
        title: Panel title (replaces the hardcoded product name).
        mode_label: Optional badge appended to the title (e.g. ``"FULL"``).
        discovery_extractor: Callable mapping ``(tool_name, result)`` to a
            :class:`DiscoveryEvent` or ``None``. Defaults to a no-op. The
            consumer guards the call so a raising extractor never crashes
            the display.
        console: Optional Rich Console instance.
    """
    self.console = console or Console()
    self.state = state
    self._live: Live | None = None
    self._title = title
    self._mode_label = mode_label
    self._discovery_extractor = discovery_extractor or _no_discovery

start async

start()

Start the dashboard display.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def start(self) -> None:
    """Start the dashboard display."""
    self.state.reset()
    self._live = Live(
        self._build_display(),
        console=self.console,
        refresh_per_second=2,
        transient=True,
        vertical_overflow="ellipsis",
    )
    bind_live_renderable(self._live, self._build_display)
    self._live.start()

stop async

stop()

Stop the dashboard and print final summary.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def stop(self) -> None:
    """Stop the dashboard and print final summary."""
    if self._live:
        self._live.stop()
        self._live = None

    elapsed = self.state.get_elapsed_seconds()
    total = len(self.state.completed_tools)
    errors = self.state.tool_errors
    self.console.print(
        f"[dim]  {total} tools in {self._format_time(elapsed)}  ✓ {total - errors}  ✗ {errors}[/dim]",
    )

on_run_started async

on_run_started(thread_id, run_id)

Handle run started.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_run_started(self, thread_id: str, run_id: str) -> None:
    """Handle run started."""
    self.state.thread_id = thread_id
    self.state.run_id = run_id
    self.state.start_time = time.monotonic()

on_text_start async

on_text_start(message_id, role)

Handle text start — no display action.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_text_start(self, message_id: str, role: str) -> None:
    """Handle text start — no display action."""
    self.state.active_message_id = message_id

on_text_content async

on_text_content(message_id, delta)

Handle text delta — silently accumulate (not displayed).

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_text_content(self, message_id: str, delta: str) -> None:
    """Handle text delta — silently accumulate (not displayed)."""
    self.state.text_buffer += delta

on_text_end async

on_text_end(message_id)

Handle text end — increment turn counter.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_text_end(self, message_id: str) -> None:
    """Handle text end — increment turn counter."""
    self.state.active_message_id = None
    self.state.turn_count += 1
    self.state.text_buffer = ""

on_tool_start async

on_tool_start(tool_call_id, tool_name)

Handle tool start — show in active spinner.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_start(self, tool_call_id: str, tool_name: str) -> None:
    """Handle tool start — show in active spinner."""
    self.state.active_tool = ToolCallState(
        tool_call_id=tool_call_id,
        tool_name=tool_name,
    )
    self.state.tool_start_time = time.monotonic()
    self._detect_phase(tool_name)

on_tool_args async

on_tool_args(tool_call_id, args_delta)

Handle tool args — silently accumulate.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_args(self, tool_call_id: str, args_delta: str) -> None:
    """Handle tool args — silently accumulate."""
    if self.state.active_tool and self.state.active_tool.tool_call_id == tool_call_id:
        self.state.active_tool.args_buffer += args_delta

on_tool_result async

on_tool_result(tool_call_id, result)

Handle tool result — check for errors and extract discoveries.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_result(self, tool_call_id: str, result: Any) -> None:
    """Handle tool result — check for errors and extract discoveries."""
    if self.state.active_tool and self.state.active_tool.tool_call_id == tool_call_id:
        self.state.active_tool.result = result
        if (isinstance(result, str) and "error" in result.lower()) or (
            isinstance(result, dict) and result.get("error")
        ):
            self.state.tool_errors += 1
        discovery = self._extract_discovery(self.state.active_tool.tool_name, result)
        if discovery:
            self.state.add_discovery(discovery)

on_tool_end async

on_tool_end(tool_call_id)

Handle tool end — move to completed list.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_tool_end(self, tool_call_id: str) -> None:
    """Handle tool end — move to completed list."""
    if self.state.active_tool and self.state.active_tool.tool_call_id == tool_call_id:
        self.state.complete_active_tool()

on_state_snapshot async

on_state_snapshot(snapshot)

Handle state snapshot.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_state_snapshot(self, snapshot: dict[str, Any]) -> None:
    """Handle state snapshot."""
    self.state.state_snapshot = snapshot
    if "phase" in snapshot:
        self.state.current_phase = str(snapshot["phase"])

on_run_finished async

on_run_finished(thread_id, run_id)

Handle run finished.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_run_finished(self, thread_id: str, run_id: str) -> None:
    """Handle run finished."""
    self.state.completed = True

on_error async

on_error(message, code=None)

Handle error.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
async def on_error(self, message: str, code: str | None = None) -> None:
    """Handle error."""
    error_text = f"[{code}] {message}" if code else message
    self.state.error = error_text

AgentDisplayState

Bases: StrictModel

Mutable state for agent display rendering.

This class tracks all state needed to render an agent's progress in a terminal or UI. It accumulates streaming text, tracks active and completed tool calls, phase progression, discoveries, dispatched teams, and error state. Phase identity is resolved against the injected phase_spec.

Attributes:

Name Type Description
phase_spec PhaseSpec

Injected phase specification (names, count, tool map).

current_phase str

Description of the current phase.

text_buffer str

Accumulated streaming text from the agent.

active_message_id str | None

ID of currently streaming message.

active_tool ToolCallState | None

Currently executing tool state (if any).

completed_tools list[ToolCallState]

List of completed tool executions.

state_snapshot dict[str, Any]

Latest state snapshot from the agent.

error str | None

Error message if the run failed.

completed bool

Whether the run has finished.

thread_id str | None

Current thread identifier.

run_id str | None

Current run identifier.

Example

state = AgentDisplayState(phase_spec=my_spec) state.text_buffer += "Analyzing repository..."

clear_text_buffer

clear_text_buffer()

Clear and return the text buffer.

Returns:

Type Description
str

The text buffer contents before clearing.

Source code in packages/strands-teams/src/strands_teams/display/state.py
def clear_text_buffer(self) -> str:
    """Clear and return the text buffer.

    Returns:
        The text buffer contents before clearing.
    """
    text = self.text_buffer
    self.text_buffer = ""
    return text

complete_active_tool

complete_active_tool(result=None)

Mark the active tool as completed and move to history.

Parameters:

Name Type Description Default
result Any

Optional result to store with the tool call.

None
Source code in packages/strands-teams/src/strands_teams/display/state.py
def complete_active_tool(self, result: Any = None) -> None:
    """Mark the active tool as completed and move to history.

    Args:
        result: Optional result to store with the tool call.
    """
    if self.active_tool:
        self.active_tool.status = "completed"
        self.active_tool.result = result
        self.completed_tools.append(self.active_tool)
        self.active_tool = None

record_tool

record_tool(*, tool_id, tool_name, status, result)

Record a tool call's start or completion for the dashboard.

Called by ToolDisplayHook on both the before- and after-tool-call events. A running status opens a new active tool (and advances the phase resolved from the tool name); any other status closes it and moves it to history, counting errors.

Parameters:

Name Type Description Default
tool_id str

The tool-use identifier from the event.

required
tool_name str

Name of the tool being executed.

required
status str

"running" to open the call, "completed"/"error" to close it.

required
result str

Truncated result string to store when closing the call.

required
Source code in packages/strands-teams/src/strands_teams/display/state.py
def record_tool(self, *, tool_id: str, tool_name: str, status: str, result: str) -> None:
    """Record a tool call's start or completion for the dashboard.

    Called by ``ToolDisplayHook`` on both the before- and after-tool-call
    events. A ``running`` status opens a new active tool (and advances the
    phase resolved from the tool name); any other status closes it and moves
    it to history, counting errors.

    Args:
        tool_id: The tool-use identifier from the event.
        tool_name: Name of the tool being executed.
        status: ``"running"`` to open the call, ``"completed"``/``"error"`` to close it.
        result: Truncated result string to store when closing the call.
    """
    if status == "running":
        self.active_tool = ToolCallState(tool_call_id=tool_id, tool_name=tool_name, status="running")
        self.tool_start_time = time.monotonic()
        phase = self.phase_spec.resolve(tool_name)
        if phase is not None:
            self.advance_phase(phase)
        return

    if self.active_tool is not None:
        self.active_tool.status = status
        self.active_tool.result = result
        self.completed_tools.append(self.active_tool)
        self.active_tool = None
    else:
        self.completed_tools.append(
            ToolCallState(tool_call_id=tool_id, tool_name=tool_name, status=status, result=result)
        )
    if status == "error":
        self.tool_errors += 1
    self.tool_start_time = None

get_recent_tools

get_recent_tools(count=5)

Get the most recent completed tools.

Parameters:

Name Type Description Default
count int

Maximum number of tools to return.

5

Returns:

Type Description
list[ToolCallState]

List of recently completed tool states.

Source code in packages/strands-teams/src/strands_teams/display/state.py
def get_recent_tools(self, count: int = 5) -> list[ToolCallState]:
    """Get the most recent completed tools.

    Args:
        count: Maximum number of tools to return.

    Returns:
        List of recently completed tool states.
    """
    return self.completed_tools[-count:]

get_tool_stats

get_tool_stats()

Get tool call counts grouped by prefix.

Groups tools by their name prefix (e.g., lsp_*, git_*) for display in the TUI dashboard.

Returns:

Type Description
dict[str, int]

Dictionary mapping tool prefixes to call counts.

Source code in packages/strands-teams/src/strands_teams/display/state.py
def get_tool_stats(self) -> dict[str, int]:
    """Get tool call counts grouped by prefix.

    Groups tools by their name prefix (e.g., ``lsp_*``, ``git_*``) for
    display in the TUI dashboard.

    Returns:
        Dictionary mapping tool prefixes to call counts.
    """
    stats: dict[str, int] = {}
    for tool in self.completed_tools:
        parts = tool.tool_name.split("_")
        prefix = parts[0] + "_*" if len(parts) > 1 else tool.tool_name
        stats[prefix] = stats.get(prefix, 0) + 1
    return stats

get_elapsed_seconds

get_elapsed_seconds()

Get elapsed time since the run started.

Returns:

Type Description
float

Elapsed seconds, or 0.0 if not started.

Source code in packages/strands-teams/src/strands_teams/display/state.py
def get_elapsed_seconds(self) -> float:
    """Get elapsed time since the run started.

    Returns:
        Elapsed seconds, or 0.0 if not started.
    """
    if self.start_time is None:
        return 0.0
    return time.monotonic() - self.start_time

get_tool_elapsed_seconds

get_tool_elapsed_seconds()

Get elapsed time for the current tool.

Returns:

Type Description
float

Elapsed seconds for the active tool, or 0.0 if no active tool.

Source code in packages/strands-teams/src/strands_teams/display/state.py
def get_tool_elapsed_seconds(self) -> float:
    """Get elapsed time for the current tool.

    Returns:
        Elapsed seconds for the active tool, or 0.0 if no active tool.
    """
    if self.tool_start_time is None:
        return 0.0
    return time.monotonic() - self.tool_start_time

get_success_count

get_success_count()

Get count of successful tool calls.

Returns:

Type Description
int

Number of completed tools minus errors.

Source code in packages/strands-teams/src/strands_teams/display/state.py
def get_success_count(self) -> int:
    """Get count of successful tool calls.

    Returns:
        Number of completed tools minus errors.
    """
    return len(self.completed_tools) - self.tool_errors

advance_phase

advance_phase(phase)

Advance to a new phase if it is higher than the current one.

Phase name and description are resolved from the injected phase_spec.

Parameters:

Name Type Description Default
phase int

1-based phase index to advance to.

required
Source code in packages/strands-teams/src/strands_teams/display/state.py
def advance_phase(self, phase: int) -> None:
    """Advance to a new phase if it is higher than the current one.

    Phase name and description are resolved from the injected
    ``phase_spec``.

    Args:
        phase: 1-based phase index to advance to.
    """
    # Don't regress to a lower phase
    if self.phases and phase <= self.phases[-1].phase:
        return

    now = time.monotonic()
    if self.phases and not self.phases[-1].is_complete:
        self.phases[-1].completed_at = now

    self.phases.append(
        PhaseState(
            phase=phase,
            name=self.phase_spec.name(phase),
            description=self.phase_spec.description(phase),
            started_at=now,
        ),
    )
    self.current_phase_index = len(self.phases) - 1

add_discovery

add_discovery(event)

Add a discovery event, evicting oldest if at capacity.

Parameters:

Name Type Description Default
event DiscoveryEvent

DiscoveryEvent to add.

required
Source code in packages/strands-teams/src/strands_teams/display/state.py
def add_discovery(self, event: DiscoveryEvent) -> None:
    """Add a discovery event, evicting oldest if at capacity.

    Args:
        event: DiscoveryEvent to add.
    """
    self.discoveries.append(event)
    while len(self.discoveries) > self.max_discoveries:
        self.discoveries.pop(0)

start_team

start_team(team_id, mandate, agent_count=0)

Register a newly dispatched team.

Parameters:

Name Type Description Default
team_id str

Unique team identifier.

required
mandate str

One-line description of the team's focus.

required
agent_count int

Number of agents in the team.

0
Source code in packages/strands-teams/src/strands_teams/display/state.py
def start_team(self, team_id: str, mandate: str, agent_count: int = 0) -> None:
    """Register a newly dispatched team.

    Args:
        team_id: Unique team identifier.
        mandate: One-line description of the team's focus.
        agent_count: Number of agents in the team.
    """
    self.teams.append(
        TeamDispatchState(
            team_id=team_id,
            mandate=mandate,
            agent_count=agent_count,
            status="running",
            started_at=time.monotonic(),
        ),
    )

complete_team

complete_team(team_id, status='done')

Mark a team as completed.

Parameters:

Name Type Description Default
team_id str

Team identifier to mark complete.

required
status str

Final status ("done" or "error").

'done'
Source code in packages/strands-teams/src/strands_teams/display/state.py
def complete_team(self, team_id: str, status: str = "done") -> None:
    """Mark a team as completed.

    Args:
        team_id: Team identifier to mark complete.
        status: Final status ("done" or "error").
    """
    for team in self.teams:
        if team.team_id == team_id:
            team.status = status
            if team.started_at is not None:
                team.duration_seconds = time.monotonic() - team.started_at
            break

reset

reset()

Reset state for a new run (preserves the injected phase_spec).

Source code in packages/strands-teams/src/strands_teams/display/state.py
def reset(self) -> None:
    """Reset state for a new run (preserves the injected ``phase_spec``)."""
    self.current_phase = ""
    self.text_buffer = ""
    self.active_message_id = None
    self.active_tool = None
    self.completed_tools = []
    self.state_snapshot = {}
    self.error = None
    self.completed = False
    self.start_time = None
    self.turn_count = 0
    self.tool_errors = 0
    self.tool_start_time = None
    self.phases = []
    self.current_phase_index = -1
    self.discoveries = []
    self.teams = []

DiscoveryEvent

Bases: FrozenModel

A notable discovery made during a run.

kind is a free-form string tag supplied by the use case's discovery extractor (e.g. "files_discovered"); the framework imposes no enum.

PhaseState

Bases: StrictModel

Mutable runtime state for a single run phase.

The phase index and name/description are resolved against the injected :class:~strands_teams.phases.PhaseSpec when the phase is entered.

is_complete property

is_complete

Whether this phase has completed.

elapsed_seconds property

elapsed_seconds

Seconds elapsed since phase started (or total if completed).

TeamDispatchState

Bases: StrictModel

State for a dispatched specialist team.

Attributes:

Name Type Description
team_id str

Unique identifier for the team (e.g., "security", "architecture").

mandate str

One-line description of the team's investigation focus.

agent_count int

Number of agents in the team swarm.

status str

Current status ("running", "done", "error").

started_at float | None

Monotonic timestamp when the team was dispatched.

duration_seconds float

Total elapsed seconds (set when completed).

ToolCallState

Bases: StrictModel

State for a single tool call.

Attributes:

Name Type Description
tool_call_id str

Unique identifier for the tool call.

tool_name str

Name of the tool being executed.

agent_name str

Name of the agent that invoked this tool.

args_buffer str

Accumulated tool arguments (streaming).

result Any

Tool execution result (when complete).

status str

Current status ("running", "completed", "error").

bind_live_renderable

bind_live_renderable(live, builder)

Point Rich Live's auto-refresh at a custom display builder.

Rich calls get_renderable() on each refresh tick. Replacing it with builder lets the dashboard show fresh state (timer, tool elapsed, etc.) without manually calling live.update() on every change.

Source code in packages/strands-teams/src/strands_teams/display/rich.py
def bind_live_renderable(live: Live, builder: Callable[[], RenderableType]) -> None:
    """Point Rich Live's auto-refresh at a custom display builder.

    Rich calls ``get_renderable()`` on each refresh tick. Replacing it with
    *builder* lets the dashboard show fresh state (timer, tool elapsed, etc.)
    without manually calling ``live.update()`` on every change.
    """
    live.get_renderable = builder  # type: ignore[assignment]  # ty: ignore[invalid-assignment]