Return a closure-bound say tool.
The closure captures agent_client once at registration; the resulting FunctionTool is stable across turns (no nested allocation in the hot path). The LLM-facing parameter is client: AgentClientInject — the framework resolves it from context.dependencies when the tool runs inside a notify handler; the closure binding is the fallback for direct invocation.
Source code in autogen/beta/network/client/tools/say.py
| def make_say_tool(agent_client: "AgentClient") -> object:
"""Return a closure-bound ``say`` tool.
The closure captures ``agent_client`` once at registration; the
resulting ``FunctionTool`` is stable across turns (no nested
allocation in the hot path). The LLM-facing parameter is
``client: AgentClientInject`` — the framework resolves it from
``context.dependencies`` when the tool runs inside a notify
handler; the closure binding is the fallback for direct invocation.
"""
@tool
async def say(
content: str,
*,
audience: list[str] | None = None,
channel_id: str | None = None,
channel: ChannelInject = None,
client: AgentClientInject = None,
) -> str:
"""Post a text envelope into the current (or specified) channel.
``audience``: list of peer **names**. ``None`` broadcasts within
the channel. The tool resolves names to agent ids via the hub.
Returns the hub-stamped envelope_id, or an error string if the
send fails.
"""
# Resolve the channel handle.
target_channel = channel
actual_client = client if client is not None else agent_client
if target_channel is None:
if channel_id is None:
return "Error: no current channel and no channel_id provided"
try:
metadata = await actual_client._hub_client.get_channel(channel_id)
except Exception as exc:
return f"Error: channel {channel_id!r} not found: {exc}"
target_channel = Channel(metadata=metadata, client=actual_client)
# Resolve audience names → agent ids.
audience_ids: list[str] | None = None
if audience is not None:
audience_ids = []
for name in audience:
try:
passport = await actual_client._hub_client.get_agent(name)
except Exception:
return f"Error: peer {name!r} not found"
if passport.agent_id is None:
return f"Error: peer {name!r} has no agent_id"
audience_ids.append(passport.agent_id)
try:
envelope_id = await target_channel.send(content, audience=audience_ids)
except Exception as exc:
return f"Error: send failed: {exc}"
return f"posted envelope {envelope_id}"
return say
|