ReadonlyContext
Read-only access to invocation identity and session state — used in instruction providers and monitoring callbacks.
ReadonlyContext is the base context class in ADK-TS. It exposes everything your code needs to observe an invocation — who is running, what session it belongs to, and what the current state contains — without exposing any way to change that state. This makes it safe to pass to instruction providers, analytics hooks, and any other code that should read but never write.
import type { ReadonlyContext } from "@iqai/adk";Properties
userContent
The original message that triggered this invocation. Undefined for system-initiated operations.
get userContent(): Content | undefinedinvocationId
A unique identifier for this invocation, generated at the start of each runner.run() call. Use it to correlate logs and events.
get invocationId(): stringagentName
The name of the agent currently executing within this context.
get agentName(): stringappName
The application name configured in the runner.
get appName(): stringuserId
The user ID associated with the current session.
get userId(): stringsessionId
The ID of the current session.
get sessionId(): stringstate
A frozen snapshot of the current session state. Because the object is frozen, any attempt to write to it will throw a TypeError at runtime — a safety net that makes instruction providers safe by design.
get state(): Readonly<Record<string, any>>To write to state, use CallbackContext or ToolContext. Both expose a
mutable State object in place of this frozen snapshot.
Instruction providers
The most common use of ReadonlyContext is inside instruction provider functions. ADK-TS calls your function before each LLM request and uses the returned string as the system instruction. The function receives a ReadonlyContext so it can tailor the instructions to the current session without accidentally mutating anything.
This example greets the user by name, falls back gracefully if the name hasn't been set yet, and includes the invocation ID for traceability:
import { LlmAgent } from "@iqai/adk";
import type { ReadonlyContext } from "@iqai/adk";
const agent = new LlmAgent({
name: "greeter",
description: "Greets users by name using session state",
model: "gemini-2.5-flash",
instruction: (ctx: ReadonlyContext) => {
const name = ctx.state["user:name"] ?? "there";
const taskCount = (ctx.state["user:taskCount"] as number) ?? 0;
return [
`You are a helpful assistant. The user's name is ${name}.`,
taskCount > 0
? `They have completed ${taskCount} tasks so far.`
: "This is their first session.",
].join(" ");
},
});Conditional instructions
Use the context to branch instruction content based on state. Each branch should return a complete, self-contained instruction string:
import type { ReadonlyContext } from "@iqai/adk";
function buildInstruction(ctx: ReadonlyContext): string {
const role = ctx.state["user:role"] as string | undefined;
if (role === "admin") {
return "You are an admin assistant. You may discuss internal configuration and user management.";
}
if (role === "premium") {
return "You are a premium assistant with access to advanced features. Help the user leverage them fully.";
}
return "You are a helpful assistant. Answer questions clearly and concisely.";
}