CallbackContext
Mutable state and artifact operations for agent lifecycle callbacks.
CallbackContext extends ReadonlyContext with the ability to write to session state and interact with the artifact service. ADK-TS passes it to every agent lifecycle callback — beforeAgentCallback, afterAgentCallback, beforeModelCallback, and afterModelCallback.
import { CallbackContext } from "@iqai/adk";Added properties
state
A mutable State object that replaces the frozen read-only snapshot from ReadonlyContext. Writes are tracked as a delta and flushed to the session store at the end of the turn.
get state(): StateYou can use bracket notation or the set / get methods interchangeably:
// Bracket assignment (tracked automatically)
ctx.state["user:name"] = "Alice";
// Equivalent method call
ctx.state.set("user:name", "Alice");
// Reading back
const name = ctx.state["user:name"];
// or
const name = ctx.state.get("user:name");eventActions
The EventActions instance for this callback turn. Normally you don't need to access this directly — the framework reads it after the callback returns. It is exposed for advanced use cases such as setting skipSummarization on function response callbacks.
get eventActions(): EventActionsinvocationContext
The underlying InvocationContext for this invocation, provided for advanced scenarios where you need direct service access inside a callback.
get invocationContext(): InvocationContextArtifact methods
Both methods throw if no artifact service is configured in the runner.
loadArtifact()
Loads a previously saved artifact. Omit version to retrieve the latest.
async loadArtifact(filename: string, version?: number): Promise<Part | undefined>saveArtifact()
Saves an artifact and registers it in the event delta so the session reflects the new version. Returns the version number assigned to this save (starting at 0).
async saveArtifact(filename: string, artifact: Part): Promise<number>Artifacts are Part objects from @google/genai. A text artifact is { text: "..." }. For binary data use { inlineData: { mimeType, data } }. See
the Artifacts section for details.
State scoping
ADK-TS uses key prefixes to scope state to different lifetimes. Choose the prefix that matches how long you need the value to persist:
| Prefix | Scope | Example |
|---|---|---|
| (no prefix) | Current session | ctx.state["currentTask"] |
user: | Across all sessions for this user | ctx.state["user:name"] |
app: | Shared across all users of this app | ctx.state["app:version"] |
temp: | Current turn only (cleared after response) | ctx.state["temp:draft"] |
Common callback patterns
Before-agent callback — enrich context
A beforeAgentCallback runs before each agent call. Use it to hydrate state from an artifact, increment counters, or inject metadata the agent needs:
import {
AgentBuilder,
CallbackContext,
InMemoryArtifactService,
} from "@iqai/adk";
const { runner } = await AgentBuilder.create("assistant")
.withModel("gemini-2.5-flash")
.withArtifactService(new InMemoryArtifactService())
.withBeforeAgentCallback(async (ctx: CallbackContext) => {
// Track how many times this agent has been called
const callCount = ((ctx.state["agentCalls"] as number) ?? 0) + 1;
ctx.state["agentCalls"] = callCount;
// Load a user profile saved in a previous session
const profile = await ctx.loadArtifact("user-profile.json");
if (profile?.text) {
ctx.state["user:profile"] = JSON.parse(profile.text);
}
return undefined; // Returning undefined lets execution continue normally
})
.build();After-agent callback — persist results
An afterAgentCallback runs after the agent produces its response. Use it to save a summary or checkpoint before the turn closes:
import {
AgentBuilder,
CallbackContext,
InMemoryArtifactService,
} from "@iqai/adk";
const { runner } = await AgentBuilder.create("summarizer")
.withModel("gemini-2.5-flash")
.withArtifactService(new InMemoryArtifactService())
.withAfterAgentCallback(async (ctx: CallbackContext) => {
const summary = {
invocationId: ctx.invocationId,
agentName: ctx.agentName,
timestamp: new Date().toISOString(),
callCount: ctx.state["agentCalls"],
};
await ctx.saveArtifact("session-summary.json", {
text: JSON.stringify(summary, null, 2),
});
return undefined;
})
.build();