Service Implementations
Different artifact service backends and their configurations for various deployment scenarios
The artifact system is built around the BaseArtifactService interface, which allows you to choose different storage backends based on your requirements. Each implementation offers different trade-offs between performance, persistence, and scalability.
BaseArtifactService Interface
All artifact services implement the same core interface:
import type { Part } from '@google/genai';
interface BaseArtifactService {
saveArtifact(args: {
appName: string;
userId: string;
sessionId: string;
filename: string;
artifact: Part;
}): Promise<number>;
loadArtifact(args: {
appName: string;
userId: string;
sessionId: string;
filename: string;
version?: number;
}): Promise<Part | null>;
listArtifactKeys(args: {
appName: string;
userId: string;
sessionId: string;
}): Promise<string[]>;
deleteArtifact(args: {
appName: string;
userId: string;
sessionId: string;
filename: string;
}): Promise<void>;
listVersions(args: {
appName: string;
userId: string;
sessionId: string;
filename: string;
}): Promise<number[]>;
}This consistent interface allows you to switch between implementations without changing your agent code.
InMemoryArtifactService
Fast, temporary storage for development and testing scenarios.
Characteristics
- Storage: Artifacts stored in memory only
- Persistence: Data lost when process terminates
- Performance: Fastest access, no network latency
- Scalability: Limited by available RAM
- Use Cases: Development, testing, prototyping
Setup and Configuration
import { InMemoryArtifactService, Runner } from '@iqai/adk';
// Create the service (no configuration needed)
const artifactService = new InMemoryArtifactService();
// Use with Runner
const runner = new Runner({
appName: "my_app",
agent: myAgent,
sessionService: mySessionService,
artifactService
});Example Usage
import { InMemoryArtifactService } from '@iqai/adk';
const artifactService = new InMemoryArtifactService();
// Save an artifact
const textArtifact = {
inlineData: {
data: Buffer.from('Hello, World!').toString('base64'),
mimeType: 'text/plain'
}
};
const version = await artifactService.saveArtifact({
appName: 'test_app',
userId: 'user123',
sessionId: 'session456',
filename: 'greeting.txt',
artifact: textArtifact
});
console.log(`Saved version: ${version}`); // 0
// Load the artifact
const loaded = await artifactService.loadArtifact({
appName: 'test_app',
userId: 'user123',
sessionId: 'session456',
filename: 'greeting.txt'
});
if (loaded) {
const text = Buffer.from(loaded.inlineData.data, 'base64').toString();
console.log(`Loaded: ${text}`); // "Hello, World!"
}In-memory storage is great for development and tests. Data is lost on restart.
Data stored in InMemoryArtifactService is lost when the process restarts. Use only for development and testing.
GcsArtifactService
Production-ready artifact storage using Google Cloud Storage.
Characteristics
- Storage: Google Cloud Storage buckets
- Persistence: Durable, replicated storage
- Performance: Network-dependent, highly optimized
- Scalability: Virtually unlimited
- Use Cases: Production deployments, large-scale applications
Setup and Configuration
import { GcsArtifactService, Runner } from '@iqai/adk';
// Basic configuration
const artifactService = new GcsArtifactService('my-artifacts-bucket');
// Use with Runner
const runner = new Runner({
appName: "production_app",
agent: myAgent,
sessionService: mySessionService,
artifactService
});Google Cloud Setup (concise)
# Create bucket
gsutil mb gs://my-artifacts-bucket
# Auth (choose one)
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
gcloud auth application-default login
# Grant bucket permissions
gsutil iam ch serviceAccount:svc@project.iam.gserviceaccount.com:roles/storage.objectAdmin gs://my-artifacts-bucketStorage Structure
The GCS implementation organizes artifacts using a hierarchical structure:
my-artifacts-bucket/
├── app1/
│ ├── user123/
│ │ ├── session456/
│ │ │ ├── temp_file.txt/
│ │ │ │ ├── 0 (version 0)
│ │ │ │ └── 1 (version 1)
│ │ │ └── analysis.json/
│ │ │ └── 0
│ │ └── user/
│ │ └── user:profile.png/
│ │ ├── 0
│ │ └── 1
│ └── user456/
│ └── ...
└── app2/
└── ...Example Usage
import { GcsArtifactService } from '@iqai/adk';
const artifactService = new GcsArtifactService('my-artifacts-bucket');
// Save a large binary file
const imageData = Buffer.from(/* your image data */);
const imageArtifact = {
inlineData: {
data: imageData.toString('base64'),
mimeType: 'image/png'
}
};
try {
const version = await artifactService.saveArtifact({
appName: 'photo_app',
userId: 'user789',
sessionId: 'session123',
filename: 'user:profile_picture.png',
artifact: imageArtifact
});
console.log(`Image saved as version ${version}`);
// List all artifact filenames for this user/session
const artifactKeys = await artifactService.listArtifactKeys({
appName: 'photo_app',
userId: 'user789',
sessionId: 'session123'
});
console.log('Available artifacts:', artifactKeys);
// ['user:profile_picture.png', ...]
} catch (error) {
console.error('GCS operation failed:', error);
}Performance tips
- Batch saves with
Promise.all([...]) - Prefer JSON/text compression when feasible
- Consider chunking for very large payloads
See Troubleshooting for common GCS and service wiring issues.
Using StorageOptions
import { GcsArtifactService } from '@iqai/adk';
const artifactService = new GcsArtifactService('my-artifacts-bucket', {
projectId: 'my-project',
keyFilename: '/path/to/key.json' // optional; or rely on ADC
});The GCS service automatically handles retries for transient errors and provides built-in redundancy and durability.
Custom Service Implementation
You can implement your own artifact service by extending the BaseArtifactService interface for specific requirements like database storage or caching layers.
Service Selection Guide
Choose the appropriate artifact service based on your requirements:
Development and Testing
- Use:
InMemoryArtifactService - Reasons: Fast, simple setup, no external dependencies
- Limitations: Data lost on restart
Production Applications
- Use:
GcsArtifactServiceor custom database service - Reasons: Durable storage, scalability, backup/recovery
- Considerations: Network latency, cost, compliance requirements
Hybrid Scenarios
- Use: Combination approach with caching
- Implementation: Database/GCS for persistence + Redis for caching
- Benefits: Fast access with durability
Performance Comparison
| Service Type | Read Speed | Write Speed | Durability | Scalability | Setup Complexity |
|---|---|---|---|---|---|
| InMemory | Fastest | Fastest | None | RAM-limited | Minimal |
| GCS | Fast | Fast | High | Unlimited | Moderate |
| Database | Moderate | Moderate | High | High | High |
| Redis | Very Fast | Very Fast | Moderate | High | Moderate |
Choose based on your specific requirements for performance, durability, and operational complexity.
How is this guide?