Skip to main content

Overview

The AgentBuilder class provides a fluent interface for creating AI agents with different capabilities. It simplifies agent creation with chainable methods, automatic session management, and support for multiple agent types (LLM, Sequential, Parallel, Loop, and LangGraph). Location: @iqai/adk package, exported from packages/adk/src/agents/agent-builder.ts:217

Constructor

The constructor is private. Use static factory methods instead.

Static Factory Methods

create()

Creates a new AgentBuilder instance.
name
string
default:"default_agent"
The name of the agent
Returns: AgentBuilder<string, false>
const builder = AgentBuilder.create("research-agent");

withModel()

Convenience method to start building with a model directly.
model
string | BaseLlm | LanguageModel
required
The model identifier (e.g., “gemini-2.5-flash”, “gpt-4”)
Returns: AgentBuilder<string, false>
const builder = AgentBuilder.withModel("gemini-2.5-flash");

withAgent()

Wraps an existing agent instance.
agent
BaseAgent
required
The agent instance to wrap
Returns: AgentBuilder<string, false>
Further definition-mutating calls (model/tools/instruction/etc.) will be ignored with a dev warning when using this method.
const existingAgent = new LlmAgent({ name: "my-agent", model: "gpt-4" });
const builder = AgentBuilder.withAgent(existingAgent);

Configuration Methods

All configuration methods return this for method chaining.

withModel()

Sets the model for the agent.
model
string | BaseLlm | LanguageModel
required
The model identifier or instance
builder.withModel("gemini-2.5-flash");

withDescription()

Sets the agent description.
description
string
required
Agent description used by parent agents to delegate control
builder.withDescription("A research assistant that can search and analyze information");

withInstruction()

Sets the system instruction for the agent.
instruction
string
required
System instruction guiding the agent’s behavior
builder.withInstruction("You are a helpful research assistant. Always cite sources.");

withTools()

Adds tools to the agent.
...tools
BaseTool[]
required
Variable number of tool instances
import { createTool } from "@iqai/adk";

const searchTool = createTool({
  name: "search",
  description: "Search for information",
  fn: async (query: string) => {
    // Search implementation
    return results;
  }
});

builder.withTools(searchTool, anotherTool);

withPlanner()

Sets the planner for the agent to enable step-by-step planning.
planner
BasePlanner
required
The planner instance
builder.withPlanner(new MyPlanner());

withCodeExecutor()

Sets the code executor for running code.
codeExecutor
BaseCodeExecutor
required
The code executor instance
import { LocalCodeExecutor } from "@iqai/adk";

builder.withCodeExecutor(new LocalCodeExecutor());

withSubAgents()

Adds sub-agents for multi-agent workflows.
subAgents
BaseAgent[]
required
Array of sub-agent instances
const agent1 = new LlmAgent({ name: "writer", model: "gpt-4" });
const agent2 = new LlmAgent({ name: "editor", model: "gpt-4" });

builder.withSubAgents([agent1, agent2]);

withPlugins()

Adds plugins for lifecycle hooks and behavior extensions.
...plugins
BasePlugin[]
required
Variable number of plugin instances
import { LoggingPlugin, MetricsPlugin } from "@iqai/adk";

builder.withPlugins(
  new LoggingPlugin(),
  new MetricsPlugin()
);

withFallbackModels()

Configures fallback models for rate limit handling.
...models
string[]
required
Fallback model names in priority order
builder
  .withModel("gpt-4o")
  .withFallbackModels("gpt-3.5-turbo", "gemini-2.0-flash");

withInputSchema()

Sets the input schema for validation.
schema
ZodSchema
required
Zod schema for input validation
import { z } from "zod";

const inputSchema = z.object({
  query: z.string(),
  maxResults: z.number().optional()
});

builder.withInputSchema(inputSchema);

withOutputSchema()

Sets the output schema for structured responses.
schema
ZodType<T>
required
Zod schema for output validation
Returns: AgentBuilderWithSchema<T, TMulti>
Cannot be used with sequential or parallel agents. Apply output schemas to individual sub-agents instead.
import { z } from "zod";

const outputSchema = z.object({
  capital: z.string(),
  country: z.string(),
  population: z.number().optional(),
  funFact: z.string()
});

const { runner } = await AgentBuilder
  .withModel("gemini-2.5-flash")
  .withOutputSchema(outputSchema)
  .build();

const result = await runner.ask("What is the capital of France?");
// result is typed as { capital: string; country: string; ... }

withOutputKey()

Sets the output key in session state to store agent output.
outputKey
string
required
The key name in session state
builder.withOutputKey("research_results");

withSessionService()

Configures session management.
service
BaseSessionService
required
Session service instance
options
SessionOptions
default:"{}"
Session configuration options
SessionOptions:
  • userId?: string - User ID (auto-generated if not provided)
  • appName?: string - Application name (auto-generated if not provided)
  • state?: Record<string, any> - Initial session state
  • sessionId?: string - Specific session ID to use
import { InMemorySessionService } from "@iqai/adk";

const sessionService = new InMemorySessionService();

builder.withSessionService(sessionService, {
  userId: "user-123",
  appName: "my-app"
});

withSession()

Configures with an existing session instance.
session
Session
required
Existing session to use
Requires withSessionService() to be called first.
const session = await sessionService.createSession("app", "user-123");
builder.withSession(session);

withQuickSession()

Configures an in-memory session with custom IDs.
options
SessionOptions
default:"{}"
Session configuration options
In-memory sessions are created automatically by default. Use this only if you need custom appName/userId.
builder.withQuickSession({
  userId: "test-user",
  appName: "test-app"
});

withMemory()

Configures memory service for conversation history.
memoryService
MemoryService
required
Memory service instance
import { MemoryService, InMemoryStorageProvider } from "@iqai/adk";

const memoryService = new MemoryService({
  storage: new InMemoryStorageProvider()
});

builder.withMemory(memoryService);

withArtifactService()

Configures artifact service for file management.
artifactService
BaseArtifactService
required
Artifact service instance
import { InMemoryArtifactService } from "@iqai/adk";

builder.withArtifactService(new InMemoryArtifactService());

withRunConfig()

Configures runtime behavior for agent runs.
config
RunConfig | Partial<RunConfig>
required
Runtime configuration
import { RunConfig } from "@iqai/adk";

builder.withRunConfig(new RunConfig({
  maxLlmCalls: 10
}));

withEventsCompaction()

Configures automatic event history compaction.
config
EventsCompactionConfig
required
Event compaction configuration
EventsCompactionConfig:
  • compactionInterval: number - Compact every N invocations
  • overlapSize: number - Include N prior invocations
builder.withEventsCompaction({
  compactionInterval: 10,
  overlapSize: 2
});

withContextCacheConfig()

Configures context caching behavior.
config
ContextCacheConfig
required
Context cache configuration
import { ContextCacheConfig } from "@iqai/adk";

builder.withContextCacheConfig(new ContextCacheConfig());

Agent Type Configuration

asSequential()

Configures as a sequential agent that executes sub-agents in order.
subAgents
BaseAgent[]
required
Sub-agents to execute sequentially
Returns: AgentBuilder<TOut, true>
const agent = await AgentBuilder
  .create("workflow")
  .asSequential([researchAgent, writerAgent, editorAgent])
  .build();

asParallel()

Configures as a parallel agent that executes sub-agents concurrently.
subAgents
BaseAgent[]
required
Sub-agents to execute in parallel
Returns: AgentBuilder<TOut, true>
const agent = await AgentBuilder
  .create("multi-search")
  .asParallel([searchAgent1, searchAgent2, searchAgent3])
  .build();

asLoop()

Configures as a loop agent that executes sub-agents iteratively.
subAgents
BaseAgent[]
required
Sub-agents to execute in a loop
maxIterations
number
default:"3"
Maximum number of iterations
const agent = await AgentBuilder
  .create("iterative-refiner")
  .asLoop([generatorAgent, reviewerAgent], 5)
  .build();

asLangGraph()

Configures as a LangGraph agent with graph-based workflow.
nodes
LangGraphNode[]
required
Graph nodes defining the workflow
rootNode
string
required
The starting node name
const nodes = [
  { name: "start", agent: startAgent, next: "process" },
  { name: "process", agent: processAgent, next: "end" },
  { name: "end", agent: endAgent }
];

const agent = await AgentBuilder
  .create("graph-workflow")
  .asLangGraph(nodes, "start")
  .build();

Callback Configuration

withBeforeAgentCallback()

Sets callback invoked before agent execution.
callback
BeforeAgentCallback
required
Single callback or array of callbacks
builder.withBeforeAgentCallback(async (ctx) => {
  console.log("Agent starting:", ctx.agent.name);
  // Return undefined to continue, or Content to skip agent run
  return undefined;
});

withAfterAgentCallback()

Sets callback invoked after agent execution.
callback
AfterAgentCallback
required
Single callback or array of callbacks
builder.withAfterAgentCallback(async (ctx) => {
  console.log("Agent completed:", ctx.agent.name);
  return undefined;
});

withBeforeModelCallback()

Sets callback invoked before LLM calls.
callback
BeforeModelCallback
required
Single callback or array of callbacks
builder.withBeforeModelCallback(async ({ llmRequest }) => {
  console.log("Calling LLM with:", llmRequest);
  // Return LlmResponse to override, null/undefined to continue
  return null;
});

withAfterModelCallback()

Sets callback invoked after LLM calls.
callback
AfterModelCallback
required
Single callback or array of callbacks
builder.withAfterModelCallback(async ({ llmResponse }) => {
  console.log("LLM responded:", llmResponse);
  return null;
});

withBeforeToolCallback()

Sets callback invoked before tool execution.
callback
BeforeToolCallback
required
Single callback or array of callbacks
builder.withBeforeToolCallback(async (tool, args, ctx) => {
  console.log(`Calling tool ${tool.name} with:`, args);
  // Return modified args, null, or undefined
  return null;
});

withAfterToolCallback()

Sets callback invoked after tool execution.
callback
AfterToolCallback
required
Single callback or array of callbacks
builder.withAfterToolCallback(async (tool, args, ctx, response) => {
  console.log(`Tool ${tool.name} returned:`, response);
  // Return modified response, null, or undefined
  return null;
});

Build and Execution

build()

Builds the agent and creates runner and session. Returns: Promise<BuiltAgent<T, TMulti>>
agent
BaseAgent
The created agent instance
runner
EnhancedRunner<T, TMulti>
The runner instance for executing the agent
session
Session
The session instance
sessionService
BaseSessionService
The session service instance
memoryService
MemoryService | undefined
The memory service instance if configured
const { agent, runner, session } = await AgentBuilder
  .withModel("gemini-2.5-flash")
  .withTools(searchTool)
  .build();

const response = await runner.ask("Search for AI news");

buildWithSchema()

Type-safe build method for agents with output schemas. Returns: Promise<BuiltAgent<T, TMulti>>
const outputSchema = z.object({
  answer: z.string(),
  confidence: z.number()
});

const { runner } = await AgentBuilder
  .withModel("gpt-4")
  .withOutputSchema(outputSchema)
  .buildWithSchema<z.infer<typeof outputSchema>>();

const result = await runner.ask("What is 2+2?");
// result is fully typed

ask()

Quick execution helper - builds and runs a message.
message
string | FullMessage
required
Message to send to the agent
Returns: Promise<RunnerAskReturn<TOut, TMulti>>
const response = await AgentBuilder
  .withModel("gemini-2.5-flash")
  .ask("What is the capital of France?");

console.log(response); // "Paris"

EnhancedRunner Interface

The runner returned by build() provides:

runner.ask()

message
string | FullMessage | LlmRequest
required
The message to send
Returns: Promise<RunnerAskReturn<T, M>>
  • For single agents: returns T (string or parsed schema type)
  • For multi-agents (sequential/parallel): returns MultiAgentResponse[]

runner.runAsync()

params
object
required
Execution parameters
Parameters:
  • userId: string - User ID
  • sessionId: string - Session ID
  • newMessage: FullMessage - The message
  • runConfig?: RunConfig - Optional runtime configuration
Returns: AsyncIterable<Event>
for await (const event of runner.runAsync({
  userId: session.userId,
  sessionId: session.id,
  newMessage: { parts: [{ text: "Hello" }] }
})) {
  console.log(event);
}

runner.rewind()

Rewinds conversation history.
params
object
required
Rewind parameters
Parameters:
  • userId: string - User ID
  • sessionId: string - Session ID
  • rewindBeforeInvocationId: string - Invocation ID to rewind before

runner.setSession()

Sets the session for subsequent ask() calls.
session
Session
required
The session instance

runner.getSession()

Gets the current session. Returns: Session

Complete Examples

import { AgentBuilder } from "@iqai/adk";

const response = await AgentBuilder
  .withModel("gemini-2.5-flash")
  .ask("What is the meaning of life?");

console.log(response);

Type Definitions

type AgentType = "llm" | "sequential" | "parallel" | "loop" | "langgraph";

type MultiAgentResponse = { agent: string; response: string }[];

type RunnerAskReturn<T, M extends boolean> = M extends true
  ? MultiAgentResponse
  : T;

interface BuiltAgent<T = string, M extends boolean = false> {
  agent: BaseAgent;
  runner: EnhancedRunner<T, M>;
  session: Session;
  sessionService: BaseSessionService;
  memoryService?: MemoryService;
}

interface SessionOptions {
  userId?: string;
  appName?: string;
  state?: Record<string, any>;
  sessionId?: string;
}

See Also

Build docs developers (and LLMs) love