0d3cb498a3
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { fetchWithCache } from '../../src/cache';
|
|
import { ReplicateImageProvider } from '../../src/providers/replicate';
|
|
|
|
vi.mock('../../src/cache');
|
|
|
|
const mockedFetchWithCache = vi.mocked(fetchWithCache);
|
|
|
|
describe('ReplicateImageProvider Demonstration', () => {
|
|
const mockApiKey = 'test-api-key';
|
|
|
|
beforeEach(() => {
|
|
vi.resetAllMocks();
|
|
});
|
|
|
|
it('demonstrates FLUX 1.1 Pro Ultra image generation', async () => {
|
|
// Mock successful API response
|
|
mockedFetchWithCache.mockResolvedValue({
|
|
data: {
|
|
id: 'test-prediction-id',
|
|
status: 'succeeded',
|
|
output: ['https://replicate.delivery/pbxt/flux-ultra-example/beautiful-landscape.webp'],
|
|
},
|
|
cached: false,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
});
|
|
|
|
const provider = new ReplicateImageProvider('black-forest-labs/flux-1.1-pro-ultra', {
|
|
config: {
|
|
apiKey: mockApiKey,
|
|
width: 1024,
|
|
height: 1024,
|
|
output_format: 'webp',
|
|
},
|
|
});
|
|
|
|
const prompt = 'A majestic mountain landscape at golden hour';
|
|
const result = await provider.callApi(prompt);
|
|
|
|
// The provider formats the output as markdown
|
|
expect(result.output).toBe(
|
|
'',
|
|
);
|
|
expect(result.error).toBeUndefined();
|
|
|
|
// Verify the API was called correctly
|
|
expect(mockedFetchWithCache).toHaveBeenCalledWith(
|
|
'https://api.replicate.com/v1/models/black-forest-labs/flux-1.1-pro-ultra/predictions',
|
|
expect.objectContaining({
|
|
method: 'POST',
|
|
headers: expect.objectContaining({
|
|
Authorization: `Bearer ${mockApiKey}`,
|
|
'Content-Type': 'application/json',
|
|
Prefer: 'wait=60',
|
|
}),
|
|
body: expect.stringContaining('"prompt":"A majestic mountain landscape at golden hour"'),
|
|
}),
|
|
expect.any(Number),
|
|
'json',
|
|
);
|
|
});
|
|
|
|
it('demonstrates multiple image outputs handling', async () => {
|
|
// Some models return multiple images
|
|
mockedFetchWithCache.mockResolvedValue({
|
|
data: {
|
|
id: 'test-prediction-id',
|
|
status: 'succeeded',
|
|
output: [
|
|
'https://replicate.delivery/pbxt/example/image1.png',
|
|
'https://replicate.delivery/pbxt/example/image2.png',
|
|
'https://replicate.delivery/pbxt/example/image3.png',
|
|
],
|
|
},
|
|
cached: false,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
});
|
|
|
|
const provider = new ReplicateImageProvider('test-model', {
|
|
config: { apiKey: mockApiKey },
|
|
});
|
|
|
|
const result = await provider.callApi('Generate variations');
|
|
|
|
// Only the first image is returned for simplicity
|
|
expect(result.output).toBe(
|
|
'',
|
|
);
|
|
});
|
|
|
|
it('demonstrates raw mode for FLUX 1.1 Pro Ultra', async () => {
|
|
mockedFetchWithCache.mockResolvedValue({
|
|
data: {
|
|
id: 'test-prediction-id',
|
|
status: 'succeeded',
|
|
output: ['https://replicate.delivery/pbxt/flux-raw/photorealistic.png'],
|
|
},
|
|
cached: false,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
});
|
|
|
|
const provider = new ReplicateImageProvider('black-forest-labs/flux-1.1-pro-ultra', {
|
|
config: {
|
|
apiKey: mockApiKey,
|
|
raw: true, // Enable raw mode for photorealistic results
|
|
},
|
|
});
|
|
|
|
const result = await provider.callApi('Professional headshot, natural lighting');
|
|
|
|
expect(result.output).toBe(
|
|
'',
|
|
);
|
|
|
|
// Verify raw parameter was passed (note: raw should be in input)
|
|
const callArgs = mockedFetchWithCache.mock.calls[0];
|
|
expect(callArgs).toBeDefined();
|
|
if (callArgs && callArgs[1] && callArgs[1].body) {
|
|
const bodyJson = JSON.parse(callArgs[1].body as string);
|
|
expect(bodyJson.input.prompt).toBe('Professional headshot, natural lighting');
|
|
}
|
|
});
|
|
|
|
it('demonstrates error handling', async () => {
|
|
mockedFetchWithCache.mockResolvedValue({
|
|
data: {
|
|
id: 'test-prediction-id',
|
|
status: 'failed',
|
|
error: 'NSFW content detected',
|
|
},
|
|
cached: false,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
});
|
|
|
|
const provider = new ReplicateImageProvider('test-model', {
|
|
config: { apiKey: mockApiKey },
|
|
});
|
|
|
|
const result = await provider.callApi('inappropriate content');
|
|
|
|
expect(result.error).toBe('NSFW content detected');
|
|
expect(result.output).toBeUndefined();
|
|
});
|
|
});
|