Work in progress: this documentation is still being written and reviewed. Check details against the source code.

Chat agent connection

Connect the Qt chat interface to RobotAgent on a background asyncio thread.

mtc_gui.agent_bridge · Source

Operator GUI · Guide · Symbol index

How it is used

MTCMainWindow creates AgentBridge, connects its signals, registers the task-document getter, then calls connect_agent(). The window submits messages with send_message() and calls disconnect() on closure. Agent coroutines run in the background; connected Qt slots update widgets on the GUI thread.

Queue proposals and execution requests reach the window through signals. In Run mode, execute_queue waits for the window to call notify_execution_complete(). Changing modes rebuilds the agent and resolves any pending execution wait as interrupted; it does not itself cancel the robot’s active goal.

Start here

Callable

Purpose

AgentBridge.connect_agent

Start a daemon thread that connects RobotAgent and then keeps an asyncio event loop running.

AgentBridge.send_message

Schedule a chat coroutine on the background loop when an agent is present.

AgentBridge.set_mode

Schedule mode validation and agent reconstruction on the background event loop.

AgentBridge.notify_execution_complete

Deliver the GUI execution result to a waiting execute_queue call and broadcast it through Qt.

AgentBridge.disconnect

Schedule asynchronous agent cleanup on a running loop and wait at most three seconds for its thread.

Example

Connect an existing chat panel to an already connected agent bridge on the GUI thread. The main window uses the same signals while also coordinating queue changes and execution results.

# panel: an existing ChatPanel; bridge: its connected AgentBridge.
panel.message_submitted.connect(panel.append_user)
panel.message_submitted.connect(bridge.send_message)
bridge.response_received.connect(panel.append_assistant)
bridge.thinking_changed.connect(panel.set_thinking)
bridge.error_occurred.connect(panel.append_error)

This wiring submits chat messages. In Run mode, agent tool requests may also request queue execution through the main window’s existing handlers.

AgentBridge

Own the chat agent, its background event loop, and the Qt signals used by the main window. Public methods schedule work; the _async_* methods and local-tool dispatcher run on the agent thread.

Inherits from: QObject.

AgentBridge.connect_agent()

Start a daemon thread that connects RobotAgent and then keeps an asyncio event loop running.

Lifecycle · Source

connect_agent(self)

Returns: None; connection completion is signaled through connected(tool_count).

Errors: Thread-start failures propagate; _async_connect catches connection failures. No guard prevents duplicate starts.

Side effects: Creates and starts _thread; asynchronous work subsequently updates _loop and _agent.

AgentBridge.send_message()

Schedule a chat coroutine on the background loop when an agent is present.

Entry point · Source

send_message(self, text: str)

Parameter

Meaning

text

User message passed unchanged to RobotAgent.chat.

Returns: None; the concurrent future from scheduling is intentionally not returned.

Errors: Emits error_occurred(“Agent not connected”) if the loop or agent is missing; coroutine-scheduling errors otherwise propagate.

Side effects: Queues _async_chat, which emits thinking, tool, response, and error signals.

AgentBridge.set_mode()

Schedule mode validation and agent reconstruction on the background event loop.

Method · Source

set_mode(self, mode: str)

Parameter

Meaning

mode

Requested GUI mode, normally “plan” or “run”; validated in _async_set_mode.

Returns: None.

Errors: Emits error_occurred when no loop exists; scheduling failures propagate.

Side effects: Queues _async_set_mode; no immediate mode-state mutation occurs here.

AgentBridge.notify_execution_complete()

Deliver the GUI execution result to a waiting execute_queue call and broadcast it through Qt.

Method · Source

notify_execution_complete(self, success: bool, error: str, completed: int, total: int)

Parameter

Meaning

success

Whether execution succeeded.

error

Execution failure detail, or an empty string for success.

completed

Count of completed task steps.

total

Total task-step count.

Returns: None.

Errors: No local exception handling; schedules set_result only when the observed pending future is unfinished.

Side effects: Uses call_soon_threadsafe to resolve the asyncio future with (success, error, completed, total); always emits execution_outcome with those four values.

AgentBridge.disconnect()

Schedule asynchronous agent cleanup on a running loop and wait at most three seconds for its thread.

Lifecycle · Source

disconnect(self)

Returns: None.

Errors: Scheduling/join errors propagate; asynchronous disconnect failures are not surfaced through an error signal here.

Side effects: Schedules _async_disconnect, joins the thread with a timeout, and clears _thread even if that timeout expires.

AgentBridge.__init__()

Create a disconnected chat bridge in Plan mode.

Lifecycle · Source

__init__(self, parent=None)

Parameter

Meaning

parent

Optional QObject parent controlling Qt object ownership.

Errors: Qt construction errors propagate.

Side effects: Initializes bridge state; starts no thread and makes no connection.

Referenced in source (1)

AgentBridge.set_config_getter()

Store the callable used by get_current_tasks to read the GUI configuration.

Method · Source

set_config_getter(self, fn)

Parameter

Meaning

fn

Zero-argument callable returning a mapping with tasks and start_gripper. It is invoked directly from the agent loop thread, so the caller supplies any thread-safety guarantees.

Returns: None.

Errors: No callable validation.

Side effects: Replaces _get_config_fn.

AgentBridge.clear_history()

Clear the current RobotAgent conversation when an agent exists.

Method · Source

clear_history(self)

Returns: None.

Errors: No local exception handling or synchronization is added around the agent call.

Side effects: Mutates the agent’s conversation history; does nothing while disconnected.

Internal callbacks and helpers

AgentBridge.connect_agent._run_loop()

Run the agent’s asyncio event loop inside its daemon thread.

Internal helper · Source

_run_loop()

Returns: None when the event loop stops.

Errors: Loop creation/running errors are not caught here; connection failures are handled by _async_connect.

Side effects: Sets _loop and the thread-local event loop; performs agent connection and runs the loop.

Referenced in source (1)

AgentBridge._async_connect()

Construct RobotAgent with the current banner, local schemas, dispatch callback, and MCP filter, then connect it.

Internal helper · Source

async _async_connect(self)

Returns: None.

Errors: Catches Exception and emits “Connection failed: …”; an assigned but unsuccessfully connected agent is not cleared.

Side effects: Imports RobotAgent, assigns _agent, opens its connections, and emits connected(len(tools)) on success.

Referenced in source (1)

AgentBridge._async_chat()

Run one agent conversation turn while exposing progress and final text to Qt.

Internal helper · Source

async _async_chat(self, text: str)

Parameter

Meaning

text

User message sent unchanged to the agent.

Returns: None.

Errors: Catches Exception and emits error_occurred(str(error)); thinking_changed(False) is emitted in finally.

Side effects: Emits thinking_changed(True), tool_called events from the nested callback, response_received on success, and thinking_changed(False).

Referenced in source (1)

AgentBridge._async_chat.on_tool()

Convert an agent tool callback into the compact chat-log signal.

Callback · Source

on_tool(name, args, result)

Parameter

Meaning

name

Tool name shown by the chat panel.

args

JSON-serializable tool-argument object; serialized output is truncated to 200 characters.

result

Tool-result text; false values become an empty string, and displayed text is limited to 500 characters.

Returns: None.

Errors: Serialization/type errors escape to the surrounding _async_chat exception handler.

Side effects: Emits tool_called(name, args_json_prefix, result_prefix).

Referenced in source (1)

AgentBridge._async_disconnect()

Disconnect and release the agent, then stop the background event loop.

Internal helper · Source

async _async_disconnect(self)

Returns: None.

Errors: Agent disconnect exceptions propagate, but loop.stop still runs in finally; _agent is cleared only after a successful disconnect.

Side effects: Closes agent connections, clears _agent on success, and stops _loop.

Referenced in source (1)

AgentBridge._async_set_mode()

Rebuild the agent for the selected mode and interrupt any pending execution-result wait.

Internal helper · Source

async _async_set_mode(self, mode: str)

Parameter

Meaning

mode

“plan” or “run”; requesting the current mode simply re-emits mode_changed.

Returns: None.

Errors: Unsupported modes emit error_occurred and mode_changed(current_mode). Teardown/reconnect exceptions become error signals; mode_changed(requested_mode) still fires after a reconnect failure.

Side effects: May resolve the pending future to (False, “Mode changed mid-execution”, 0, 0), disconnect the old agent, update _mode/_agent, reconnect, and emit connected and mode_changed.

Referenced in source (1)

AgentBridge._local_dispatch()

Handle the agent’s local queue tools and route queue changes or execution requests to the window.

Callback · Source

async _local_dispatch(self, name: str, arguments: dict) -> str

Parameter

Meaning

name

Exact local tool name; unrecognized names produce an error string.

arguments

Tool argument mapping. propose_tasks uses tasks (false values become []), optional start_gripper, poses, and replace (default True); get_current_tasks and execute_queue ignore arguments.

Returns: Human-readable tool-result text, except get_current_tasks returns indented JSON containing start_gripper and tasks. execute_queue waits and returns “Execution succeeded/failed (completed/total steps)[: error]”.

Errors: propose_tasks checks only that the normalized tasks value is a list. Missing config getter, non-Run execute requests, and duplicate pending executions return explanatory strings. All Exception failures become “Local dispatch error in name: …”.

Side effects: Emits tasks_proposed(tasks, options), tasks_cleared(), or execution_requested(); calls the config getter directly; creates and clears an awaited execution future. Task-proposal signals are not awaited.

Referenced in source (2)