TypeScriptADK-TS
Artifacts

Context Integration

Using artifacts through CallbackContext and ToolContext for file management and data processing

Artifacts are accessed through context objects that provide convenient methods for storing and retrieving binary data. Different context types offer varying levels of functionality depending on your use case.

Auto-save input blobs

When saveInputBlobsAsArtifacts is enabled in the run config, the runner saves any incoming user inlineData parts as artifacts automatically before appending the event. Enable it via withRunConfig({ saveInputBlobsAsArtifacts: true }) on your agent builder, or per run. An artifactService on the Runner is required.

Prefer createTool

Use createTool for concise, schema-validated tools instead of subclassing. See Recipes for examples.

CallbackContext Access

The CallbackContext provides basic artifact operations available in agent callbacks.

Available Methods

class CallbackContext {
  // Load an artifact by filename, optionally specifying version
  async loadArtifact(filename: string, version?: number): Promise<Part | undefined>

  // Save an artifact and record it as a delta for the session
  async saveArtifact(filename: string, artifact: Part): Promise<number>
}

Basic Usage in Callbacks

import { LlmAgent, CallbackContext } from '@iqai/adk';

const beforeAgentCallback = async (callbackContext: CallbackContext) => {
  try {
    // Load user preferences
    const prefsArtifact = await callbackContext.loadArtifact('user:preferences.json');

    if (prefsArtifact) {
      const preferences = JSON.parse(
        Buffer.from(prefsArtifact.inlineData.data, 'base64').toString()
      );

      // Apply user preferences to session state
      callbackContext.state.set('user_preferences', preferences);
      callbackContext.state.set('theme', preferences.theme || 'light');
    }

    // Load conversation history if available
    const historyArtifact = await callbackContext.loadArtifact('conversation_history.json');

    if (historyArtifact) {
      const history = JSON.parse(
        Buffer.from(historyArtifact.inlineData.data, 'base64').toString()
      );

      callbackContext.state.set('conversation_count', history.length);
    }

  } catch (error) {
    console.warn('Failed to load user data:', error);
  }

  return undefined;
};

const afterAgentCallback = async (callbackContext: CallbackContext) => {
  try {
    // Save updated conversation history
    const currentHistory = callbackContext.state.get('conversation_history') || [];
    const historyArtifact = {
      inlineData: {
        data: Buffer.from(JSON.stringify(currentHistory)).toString('base64'),
        mimeType: 'application/json'
      }
    };

    await callbackContext.saveArtifact('conversation_history.json', historyArtifact);

    // Save session summary
    const summary = callbackContext.state.get('session_summary');
    if (summary) {
      const summaryArtifact = {
        inlineData: {
          data: Buffer.from(JSON.stringify(summary)).toString('base64'),
          mimeType: 'application/json'
        }
      };

      await callbackContext.saveArtifact('session_summary.json', summaryArtifact);
    }

  } catch (error) {
    console.error('Failed to save session data:', error);
  }

  return undefined;
};

Model Callback Integration

const beforeModelCallback = async ({ callbackContext }: { callbackContext: CallbackContext }) => {
  try {
    // Load model configuration
    const configArtifact = await callbackContext.loadArtifact('model_config.json');

    if (configArtifact) {
      const config = JSON.parse(
        Buffer.from(configArtifact.inlineData.data, 'base64').toString()
      );

      // Apply model-specific settings
      callbackContext.state.set('temperature', config.temperature || 0.7);
      callbackContext.state.set('max_tokens', config.maxTokens || 1000);
    }

    // Load context files for the model
    const contextArtifact = await callbackContext.loadArtifact('context_data.txt');

    if (contextArtifact) {
      const contextText = Buffer.from(contextArtifact.inlineData.data, 'base64').toString();

      // Add context to the request (implementation depends on your setup)
      callbackContext.state.set('additional_context', contextText);
    }

  } catch (error) {
    console.warn('Failed to load model configuration:', error);
  }

  return undefined;
};

const afterModelCallback = async ({ callbackContext }: { callbackContext: CallbackContext }) => {
  try {
    // Save model response metadata
    const responseMetadata = {
      timestamp: new Date().toISOString(),
      model: callbackContext.state.get('current_model'),
      tokens_used: callbackContext.state.get('tokens_used')
    };

    const metadataArtifact = {
      inlineData: {
        data: Buffer.from(JSON.stringify(responseMetadata)).toString('base64'),
        mimeType: 'application/json'
      }
    };

    await callbackContext.saveArtifact('response_metadata.json', metadataArtifact);

  } catch (error) {
    console.error('Failed to save response metadata:', error);
  }

  return undefined;
};

ToolContext Access

The ToolContext extends CallbackContext with additional artifact management capabilities.

Enhanced Methods

class ToolContext extends CallbackContext {
  // Inherited from CallbackContext
  async loadArtifact(filename: string, version?: number): Promise<Part | undefined>
  async saveArtifact(filename: string, artifact: Part): Promise<number>

  // Additional tool-specific methods
  async listArtifacts(): Promise<string[]>
}

File Processing Tools

See focused, production-ready examples in the Recipes page:

  • Upload → process → save results
  • Generate media → save + reuse
  • Cache expensive outputs

Open recipes

Document Processing Tool

For end-to-end document handling examples, see the recipe collection:

  • Text extraction (plain text)
  • Simple summarization
  • Format conversion

Open recipes

Report Generation

See Recipes for JSON and CSV report generation with concise code.

Open recipes

File Processing

See the end-to-end file processing flow in the Recipes page.

Open recipes

Media Creation

See Recipes for a minimal SVG/image generation and save workflow.

Open recipes

Context integration provides a convenient abstraction over the artifact service, handling session scoping and error management automatically.

How is this guide?