204 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			204 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								import { expect, tap } from '@push.rocks/tapbundle';
							 | 
						||
| 
								 | 
							
								import * as qenv from '@push.rocks/qenv';
							 | 
						||
| 
								 | 
							
								import * as smartai from '../ts/index.js';
							 | 
						||
| 
								 | 
							
								import * as path from 'path';
							 | 
						||
| 
								 | 
							
								import { promises as fs } from 'fs';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const testQenv = new qenv.Qenv('./', './.nogit/');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let openaiProvider: smartai.OpenAiProvider;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Helper function to save image results
							 | 
						||
| 
								 | 
							
								async function saveImageResult(testName: string, result: any) {
							 | 
						||
| 
								 | 
							
								  const sanitizedName = testName.replace(/[^a-z0-9]/gi, '_').toLowerCase();
							 | 
						||
| 
								 | 
							
								  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
							 | 
						||
| 
								 | 
							
								  const filename = `openai_${sanitizedName}_${timestamp}.json`;
							 | 
						||
| 
								 | 
							
								  const filepath = path.join('.nogit', 'testresults', 'images', filename);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await fs.mkdir(path.dirname(filepath), { recursive: true });
							 | 
						||
| 
								 | 
							
								  await fs.writeFile(filepath, JSON.stringify(result, null, 2), 'utf-8');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log(`  💾 Saved to: ${filepath}`);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Also save the actual image if b64_json is present
							 | 
						||
| 
								 | 
							
								  if (result.images && result.images[0]?.b64_json) {
							 | 
						||
| 
								 | 
							
								    const imageFilename = `openai_${sanitizedName}_${timestamp}.png`;
							 | 
						||
| 
								 | 
							
								    const imageFilepath = path.join('.nogit', 'testresults', 'images', imageFilename);
							 | 
						||
| 
								 | 
							
								    await fs.writeFile(imageFilepath, Buffer.from(result.images[0].b64_json, 'base64'));
							 | 
						||
| 
								 | 
							
								    console.log(`  🖼️  Image saved to: ${imageFilepath}`);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image Generation: should initialize provider', async () => {
							 | 
						||
| 
								 | 
							
								  const openaiToken = await testQenv.getEnvVarOnDemand('OPENAI_TOKEN');
							 | 
						||
| 
								 | 
							
								  expect(openaiToken).toBeTruthy();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  openaiProvider = new smartai.OpenAiProvider({
							 | 
						||
| 
								 | 
							
								    openaiToken,
							 | 
						||
| 
								 | 
							
								    imageModel: 'gpt-image-1'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await openaiProvider.start();
							 | 
						||
| 
								 | 
							
								  expect(openaiProvider).toBeInstanceOf(smartai.OpenAiProvider);
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: Basic generation with gpt-image-1', async () => {
							 | 
						||
| 
								 | 
							
								  const result = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'A cute robot reading a book in a cozy library, digital art style',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    quality: 'medium',
							 | 
						||
| 
								 | 
							
								    size: '1024x1024'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('Basic gpt-image-1 Generation:');
							 | 
						||
| 
								 | 
							
								  console.log('- Images generated:', result.images.length);
							 | 
						||
| 
								 | 
							
								  console.log('- Model used:', result.metadata?.model);
							 | 
						||
| 
								 | 
							
								  console.log('- Quality:', result.metadata?.quality);
							 | 
						||
| 
								 | 
							
								  console.log('- Size:', result.metadata?.size);
							 | 
						||
| 
								 | 
							
								  console.log('- Tokens used:', result.metadata?.tokensUsed);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('basic_generation_gptimage1', result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(result.images).toBeTruthy();
							 | 
						||
| 
								 | 
							
								  expect(result.images.length).toEqual(1);
							 | 
						||
| 
								 | 
							
								  expect(result.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								  expect(result.metadata?.model).toEqual('gpt-image-1');
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: High quality with transparent background', async () => {
							 | 
						||
| 
								 | 
							
								  const result = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'A simple geometric logo of a mountain peak, minimal design, clean lines',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    quality: 'high',
							 | 
						||
| 
								 | 
							
								    size: '1024x1024',
							 | 
						||
| 
								 | 
							
								    background: 'transparent',
							 | 
						||
| 
								 | 
							
								    outputFormat: 'png'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('High Quality Transparent:');
							 | 
						||
| 
								 | 
							
								  console.log('- Quality:', result.metadata?.quality);
							 | 
						||
| 
								 | 
							
								  console.log('- Background: transparent');
							 | 
						||
| 
								 | 
							
								  console.log('- Format:', result.metadata?.outputFormat);
							 | 
						||
| 
								 | 
							
								  console.log('- Tokens used:', result.metadata?.tokensUsed);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('high_quality_transparent', result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(result.images.length).toEqual(1);
							 | 
						||
| 
								 | 
							
								  expect(result.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: WebP format with compression', async () => {
							 | 
						||
| 
								 | 
							
								  const result = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'A futuristic cityscape at sunset with flying cars, photorealistic',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    quality: 'high',
							 | 
						||
| 
								 | 
							
								    size: '1536x1024',
							 | 
						||
| 
								 | 
							
								    outputFormat: 'webp',
							 | 
						||
| 
								 | 
							
								    outputCompression: 85
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('WebP with Compression:');
							 | 
						||
| 
								 | 
							
								  console.log('- Format:', result.metadata?.outputFormat);
							 | 
						||
| 
								 | 
							
								  console.log('- Compression: 85%');
							 | 
						||
| 
								 | 
							
								  console.log('- Size:', result.metadata?.size);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('webp_compression', result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(result.images.length).toEqual(1);
							 | 
						||
| 
								 | 
							
								  expect(result.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: Text rendering with gpt-image-1', async () => {
							 | 
						||
| 
								 | 
							
								  const result = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'A vintage cafe sign that says "COFFEE & CODE" in elegant hand-lettered typography, warm colors',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    quality: 'high',
							 | 
						||
| 
								 | 
							
								    size: '1024x1024'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('Text Rendering:');
							 | 
						||
| 
								 | 
							
								  console.log('- Prompt includes text: "COFFEE & CODE"');
							 | 
						||
| 
								 | 
							
								  console.log('- gpt-image-1 has superior text rendering');
							 | 
						||
| 
								 | 
							
								  console.log('- Tokens used:', result.metadata?.tokensUsed);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('text_rendering', result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(result.images.length).toEqual(1);
							 | 
						||
| 
								 | 
							
								  expect(result.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: Multiple images generation', async () => {
							 | 
						||
| 
								 | 
							
								  const result = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'Abstract colorful geometric patterns, modern minimalist art',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    n: 2,
							 | 
						||
| 
								 | 
							
								    quality: 'medium',
							 | 
						||
| 
								 | 
							
								    size: '1024x1024'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('Multiple Images:');
							 | 
						||
| 
								 | 
							
								  console.log('- Images requested: 2');
							 | 
						||
| 
								 | 
							
								  console.log('- Images generated:', result.images.length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('multiple_images', result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(result.images.length).toEqual(2);
							 | 
						||
| 
								 | 
							
								  expect(result.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								  expect(result.images[1].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: Low moderation setting', async () => {
							 | 
						||
| 
								 | 
							
								  const result = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'A fantasy battle scene with warriors and dragons',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    moderation: 'low',
							 | 
						||
| 
								 | 
							
								    quality: 'medium'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('Low Moderation:');
							 | 
						||
| 
								 | 
							
								  console.log('- Moderation: low (less restrictive filtering)');
							 | 
						||
| 
								 | 
							
								  console.log('- Tokens used:', result.metadata?.tokensUsed);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('low_moderation', result);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(result.images.length).toEqual(1);
							 | 
						||
| 
								 | 
							
								  expect(result.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image Editing: edit with gpt-image-1', async () => {
							 | 
						||
| 
								 | 
							
								  // First, generate a base image
							 | 
						||
| 
								 | 
							
								  const baseResult = await openaiProvider.imageGenerate({
							 | 
						||
| 
								 | 
							
								    prompt: 'A simple white cat sitting on a red cushion',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    quality: 'low',
							 | 
						||
| 
								 | 
							
								    size: '1024x1024'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const baseImageBuffer = Buffer.from(baseResult.images[0].b64_json!, 'base64');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Now edit it
							 | 
						||
| 
								 | 
							
								  const editResult = await openaiProvider.imageEdit({
							 | 
						||
| 
								 | 
							
								    image: baseImageBuffer,
							 | 
						||
| 
								 | 
							
								    prompt: 'Change the cat to orange and add stylish sunglasses',
							 | 
						||
| 
								 | 
							
								    model: 'gpt-image-1',
							 | 
						||
| 
								 | 
							
								    quality: 'medium'
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  console.log('Image Editing:');
							 | 
						||
| 
								 | 
							
								  console.log('- Base image created');
							 | 
						||
| 
								 | 
							
								  console.log('- Edit: change color and add sunglasses');
							 | 
						||
| 
								 | 
							
								  console.log('- Result images:', editResult.images.length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await saveImageResult('image_edit', editResult);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  expect(editResult.images.length).toEqual(1);
							 | 
						||
| 
								 | 
							
								  expect(editResult.images[0].b64_json).toBeTruthy();
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								tap.test('OpenAI Image: should clean up provider', async () => {
							 | 
						||
| 
								 | 
							
								  await openaiProvider.stop();
							 | 
						||
| 
								 | 
							
								  console.log('OpenAI image provider stopped successfully');
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default tap.start();
							 |