Class Agents

java.lang.Object
com.google.genkit.plugins.middleware.Agents

public final class Agents extends Object
Factory for sub-agent delegation tools.

Each configured sub-agent is exposed to the delegating model as a <prefix>_<name> tool (default prefix delegate_to, so delegate_to_<name>). When the model calls that tool with {"task": "..."}, the named sub-agent (resolved from the registry at /agent/<name>) is run for a single turn and its assistant text is returned as response. Any artifacts the sub-agent produces are namespaced (<invocationId>/<name>) and merged into the active parent session via AgentSessionContext.currentArtifactStore().

Pragmatic scope decision (tools-factory, not a generate hook)

This repo's generate pipeline has no first-class "wrap generate / inject system prompt" middleware seam that an agent's synthesized AgentFn runs through, but AgentConfig already exposes tools(List) and system(String). Agents is therefore implemented as a tool factory: delegationTools(AgentsOptions) returns the delegation tools and systemPromptFragment(AgentsOptions) returns a <sub-agents> system-prompt fragment. Callers wire them in via AgentConfig.tools(...) and AgentConfig.system(...). This achieves model-driven sub-agent delegation without modifying the generate pipeline.

History forwarding

Each (parent session, sub-agent) pair is delegated to through its own stable sub-session (see Delegation for the exact key derivation and mechanics). Repeated delegation calls to the SAME sub-agent within the SAME parent session see up to historyLength trailing messages of that sub-session's own accumulated history; historyLength <= 0 (the default) means task-only, no history forwarded. For client-managed sub-agents this is fully honored via an internal history ledger forwarded as AgentInit.state. For server-managed sub-agents (configured with a SessionStore), history is forwarded by resuming the sub-agent's own store-backed session via AgentInit.sessionId — the store's full accumulated history is used and historyLength trimming is not applied in that case (no seam exists to truncate a resolved session before the sub-agent's turn runs without mutating its own persisted snapshot).

Structured failure/interrupt propagation

A sub-agent turn that finishes INTERRUPTED causes the delegation tool to throw ToolInterruptException, carrying the sub-agent's interrupted tool name/input as metadata, so the parent's own generate loop pauses too (nested interrupt visibility). Resuming the parent's interrupt surfaces that information; it does not, by itself, re-invoke the sub-agent with a resume — full nested-resume is out of scope for this fix. A sub-agent turn that finishes FAILED (or whose runBidiJson call itself throws) causes the delegation tool to throw GenkitException carrying the sub-agent's error message, so the failure propagates like any other tool exception.

Other limitations (v1)

  • maxDelegations is enforced per delegationTools(...) invocation, shared across all delegation tools returned by that call (an in-memory counter).
  • Method Details

    • delegationTools

      public static List<Tool<?,?>> delegationTools(AgentsOptions options)
      Builds the delegation tools (one per configured sub-agent).

      The returned tools share a single delegation counter so that options.getMaxDelegations() is enforced across all of them for the lifetime of this call's result.

      Parameters:
      options - the options (must not be null; at least one agent)
      Returns:
      the delegation tools
    • toolName

      public static String toolName(String prefix, String agentName)
      Builds the tool name for a sub-agent given the configured prefix. An empty prefix yields the bare agent name.
      Parameters:
      prefix - the tool prefix
      agentName - the sub-agent name
      Returns:
      the delegation tool name
    • systemPromptFragment

      public static String systemPromptFragment(AgentsOptions options)
      Builds a <sub-agents> system-prompt fragment listing each delegation tool and the agent it delegates to.
      Parameters:
      options - the options (must not be null)
      Returns:
      the system-prompt fragment