TypeScriptADK-TS

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(): State

You 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(): EventActions

invocationContext

The underlying InvocationContext for this invocation, provided for advanced scenarios where you need direct service access inside a callback.

get invocationContext(): InvocationContext

Artifact 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:

PrefixScopeExample
(no prefix)Current sessionctx.state["currentTask"]
user:Across all sessions for this userctx.state["user:name"]
app:Shared across all users of this appctx.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();

Next steps