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
Document Processing Tool
For end-to-end document handling examples, see the recipe collection:
- Text extraction (plain text)
- Simple summarization
- Format conversion
Report Generation
See Recipes for JSON and CSV report generation with concise code.
File Processing
See the end-to-end file processing flow in the Recipes page.
Media Creation
See Recipes for a minimal SVG/image generation and save workflow.
Context integration provides a convenient abstraction over the artifact service, handling session scoping and error management automatically.
How is this guide?