TypeScriptADK-TS
Artifacts

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-bucket

Storage 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: GcsArtifactService or 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 TypeRead SpeedWrite SpeedDurabilityScalabilitySetup Complexity
InMemoryFastestFastestNoneRAM-limitedMinimal
GCSFastFastHighUnlimitedModerate
DatabaseModerateModerateHighHighHigh
RedisVery FastVery FastModerateHighModerate

Choose based on your specific requirements for performance, durability, and operational complexity.

How is this guide?