Robot agent client
Use an Anthropic-compatible Hermes client and stdio MCP sessions for a serial tool-use conversation loop. Tool callbacks can dispatch local GUI tools; API requests are synchronous even though chat is async.
beambot.agent.robot_agent · Source
Clients and integrations · Guide · Symbol index
How it is used
The command-line client and GUI bridge use RobotAgent to connect model responses to configured MCP tools. The lifecycle is connect() → repeated chat() calls → disconnect(); clear_history() starts a new conversation without reopening the connections.
GUI integrations can supply local tool definitions, an async dispatcher, and a tool filter. chat() is async but makes synchronous model requests and executes tool calls serially; text callbacks receive the final response, not a stream.
Start here
Callable |
Purpose |
|---|---|
Read the explicit or discovered MCP config, enter the exit stack, connect each listed stdio server and finally register caller-supplied local tools. Remote server failures do not stop later servers. |
|
Append a user message and repeatedly call the synchronous model API, store text/tool-use blocks, execute requested tools serially and append their results until stop_reason is end_turn. on_text receives the final concatenated text once; this is not streaming. |
|
Close the AsyncExitStack that owns MCP sessions and stdio processes. |
|
Replace conversation history with a new empty list, retaining prompt, tools and connections. |
RobotAgent
Conversation client that owns model history, MCP sessions, and tool routing. Callers manage its connection lifecycle and may extend the available tools through constructor arguments; it is not a ROS action server.
RobotAgent.connect()
Read the explicit or discovered MCP config, enter the exit stack, connect each listed stdio server and finally register caller-supplied local tools. Remote server failures do not stop later servers.
Lifecycle · Source
async connect(self)
Returns: None after attempted connections and registration.
Errors: Raises FileNotFoundError if no config is found; JSON/file errors propagate. Per-server exceptions are logged and suppressed. Malformed extra tool definitions can raise.
Side effects: Starts MCP subprocess sessions, populates tools/routing mappings and logs totals. Repeated calls do not clear prior registrations; duplicate names overwrite routing while remaining in the tools list.
RobotAgent.chat()
Append a user message and repeatedly call the synchronous model API, store text/tool-use blocks, execute requested tools serially and append their results until stop_reason is end_turn. on_text receives the final concatenated text once; this is not streaming.
Method · Source
async chat(self, user_message: str, on_tool_call=None, on_text=None) -> str
Parameter |
Meaning |
|---|---|
|
User request text appended to persistent conversation history. |
|
Optional synchronous callback(tool_name, arguments, result_text) after each executed tool. |
|
Optional synchronous callback receiving final text when end_turn is returned. |
Returns: Final concatenated text string from the end_turn response.
Errors: Model/API and callback exceptions propagate; tool dispatch errors normally become result strings. There is no iteration cap, and a non-end_turn response without tool calls repeats the loop.
Side effects: Sends prompt/history/tool metadata to the configured model service, grows messages, may invoke robot tools and blocks the event loop during synchronous API calls.
RobotAgent.disconnect()
Close the AsyncExitStack that owns MCP sessions and stdio processes.
Lifecycle · Source
async disconnect(self)
Returns: None after asynchronous resource cleanup.
Errors: Context-manager cleanup exceptions propagate.
Side effects: Closes sessions and subprocess transport contexts. Does not clear tool/history mappings or explicitly close the Anthropic client.
RobotAgent.clear_history()
Replace conversation history with a new empty list, retaining prompt, tools and connections.
Method · Source
clear_history(self)
Returns: None.
Errors: No explicit failure handling.
Side effects: Discards this agent’s message-history reference.
RobotAgent.__init__()
Create the API client, load/prepend the operation prompt and initialize history, MCP exit stack and local-tool/filter settings.
Lifecycle · Source
__init__(
self,
model = None,
mcp_config_path = None,
system_prompt_prefix: str = '',
extra_tools: Optional[list] = None,
extra_dispatch: Optional[Callable[[str, dict], Awaitable[str]]] = None,
tool_filter: Optional[Callable[[str, str], bool]] = None,
)
Parameter |
Meaning |
|---|---|
|
Optional model override; falsy values use the environment/default model. |
|
Optional MCP JSON configuration filename; None triggers cwd-parent search during connect. |
|
Optional text prepended to the shared prompt with a Markdown separator. |
|
Optional Anthropic-format local tool definitions, shallow-copied into an internal list. |
|
Optional async (tool_name, arguments) dispatcher returning tool-result text for local tools. |
|
Optional (server_name, tool_name) predicate deciding which remote tools to register. |
Errors: Authentication environment, prompt file and API client initialization errors propagate.
Side effects: Reads configuration environment and prompt file, allocates API client/exit stack; no MCP subprocesses are started until connect.
Internal callbacks and helpers
RobotAgent._connect_server()
Start a configured stdio MCP process, initialize a ClientSession, list tools and register those accepted by the optional filter in Anthropic tool format.
Internal helper · Source
async _connect_server(self, name, server_cfg)
Parameter |
Meaning |
|---|---|
|
Configuration server name used in logs and filter calls. |
|
Mapping with required command and optional args/env passed to StdioServerParameters. |
Returns: None.
Errors: Process/protocol/filter errors propagate to connect’s per-server handler.
Side effects: Starts a subprocess, retains process/session contexts in the exit stack and appends tool definitions/routing entries; duplicate names replace the routing mapping.
Referenced in source (1)
RobotAgent.connect— beambot.agent.robot_agent
RobotAgent._call_tool()
Route a name to its local async dispatcher or MCP session; collect remote textual content joined by newlines, falling back to str(result) when no text exists.
Internal helper · Source
async _call_tool(self, name: str, arguments: dict) -> str
Parameter |
Meaning |
|---|---|
|
Registered tool name. |
|
Tool argument mapping forwarded unchanged. |
Returns: Tool-result text, or an Error-prefixed string for unknown tool, missing local dispatcher or caught dispatch failure.
Errors: Catches ordinary local/remote dispatch exceptions and converts them to text; does not interpret remote isError separately.
Side effects: Invokes a registered tool, potentially controlling robot hardware or local GUI state.
Referenced in source (1)
RobotAgent.chat— beambot.agent.robot_agent
RobotAgent._find_mcp_config()
Search cwd and up to nine further ancestors for the first existing .mcp.json path, stopping at filesystem root.
Internal helper · Source
_find_mcp_config(self)
Returns: Filename string, or None if none is found. Existence is checked, not whether it is a regular file.
Errors: Path/cwd filesystem errors propagate.
Side effects: Reads cwd and checks ancestor filesystem entries.
Referenced in source (1)
RobotAgent.connect— beambot.agent.robot_agent
Functions
Internal callbacks and helpers
_create_client()
Construct an Anthropic client at HERMES_ENDPOINT plus /anthropic using AIFAPIM_API_KEY; return the BEAMBOT_MODEL selection alongside it.
Internal helper · Source
_create_client()
Returns: (client, model_name), defaulting to the Hermes NSLS-II endpoint and claude-sonnet-4-6.
Errors: Missing API key raises KeyError; Anthropic import/client-construction errors propagate.
Side effects: Reads environment variables and initializes a network client; does not itself make a model request.
Referenced in source (1)
RobotAgent.__init__— beambot.agent.robot_agent