Skip to content

make_context_tool

autogen.beta.network.client.tools.context.make_context_tool #

make_context_tool(agent_client)

Return a closure-bound context tool.

Source code in autogen/beta/network/client/tools/context.py
def make_context_tool(agent_client: "AgentClient") -> object:
    """Return a closure-bound ``context`` tool."""

    @tool
    async def context(
        action: Literal["search", "quote"],
        *,
        query: str | None = None,
        scope: Literal["channel", "knowledge"] = "channel",
        speaker: str | None = None,
        recent_n: int = 1,
        limit: int = 10,
        channel_id: str | None = None,
        client: AgentClientInject = None,
        channel: ChannelInject = None,
    ) -> list[dict] | str:
        """Read from past content.

        ``search``: args query, scope="channel"|"knowledge", limit
                    Returns excerpts of envelopes whose text matches
                    ``query`` (case-insensitive substring).
        ``quote``:  args speaker, recent_n=1, channel_id?
                    Returns the last ``recent_n`` envelopes from
                    ``speaker`` in the current (or specified) channel.
        """
        actual = client if client is not None else agent_client
        hub = actual._hub_client
        sid = channel_id or (channel.channel_id if channel is not None else None)

        if action == "search":
            if not query:
                return "Error: search requires `query`"
            needle = query.lower()
            if scope == "channel":
                if not sid:
                    return "Error: search scope=channel requires an active channel"
                try:
                    wal = await hub.read_wal(sid)
                except Exception:
                    return f"Error: channel {sid!r} not found"
                results: list[dict] = []
                for env in wal:
                    if env.event_type != EV_TEXT:
                        continue
                    if not visible_to(env, actual.agent_id):
                        continue
                    text = env.event_data.get("text", "")
                    if not isinstance(text, str) or needle not in text.lower():
                        continue
                    results.append({
                        "envelope_id": env.envelope_id,
                        "sender_id": env.sender_id,
                        "when": env.created_at,
                        "excerpt": _excerpt(env),
                    })
                    if len(results) >= limit:
                        break
                return results
            if scope == "knowledge":
                # Knowledge-scope search is best-effort over the calling
                # agent's own KnowledgeStore. Returns an empty list when
                # the store has no primitive for substring search —
                # semantic search lives in framework-core ``recall`` and
                # is invoked by the agent's own loop, not by this tool.
                return []

        if action == "quote":
            if not speaker:
                return "Error: quote requires `speaker`"
            if not sid:
                return "Error: quote requires an active channel or `channel_id`"
            # Resolve speaker name → agent_id (accept both).
            try:
                speaker_passport = await hub.get_agent(speaker)
            except Exception:
                return f"Error: speaker {speaker!r} not found"
            speaker_id = speaker_passport.agent_id
            try:
                wal = await hub.read_wal(sid)
            except Exception:
                return f"Error: channel {sid!r} not found"
            picks: list[dict] = []
            for env in reversed(wal):
                if env.event_type != EV_TEXT:
                    continue
                if env.sender_id != speaker_id:
                    continue
                if not visible_to(env, actual.agent_id):
                    continue
                picks.append({
                    "envelope_id": env.envelope_id,
                    "when": env.created_at,
                    "text": env.event_data.get("text", ""),
                })
                if len(picks) >= recent_n:
                    break
            picks.reverse()
            return picks

        return f"Error: unknown action {action!r}; choose from search, quote"

    return context