ai-functions
Version:
Core AI primitives for building intelligent applications
151 lines (150 loc) โข 6.05 kB
JavaScript
/**
* Manual E2E Test for Google GenAI (Gemini) Flex Tier Processing
*
* Run with your Google API key:
*
* GOOGLE_API_KEY=... npx tsx test/e2e-google-manual.ts
*
* Or:
*
* GEMINI_API_KEY=... npx tsx test/e2e-google-manual.ts
*/
import { configure, resetContext, getExecutionTier, isFlexAvailable, getProvider } from '../src/context.js';
import { googleFlexAdapter } from '../src/batch/google.js';
// Gemini models
const GEMINI_FLASH = 'gemini-2.0-flash';
const GEMINI_PRO = 'gemini-1.5-pro';
async function main() {
console.log('\n๐งช E2E Google GenAI (Gemini) Flex Tier Test\n');
// Check for API key
const apiKey = process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY;
if (!apiKey) {
console.error('โ Google API key required');
console.error(' Set GOOGLE_API_KEY or GEMINI_API_KEY');
console.error(' Get one at: https://aistudio.google.com/app/apikey');
process.exit(1);
}
console.log('โ
Google API key found');
// Configure
configure({
provider: 'google',
model: GEMINI_FLASH,
batchMode: 'auto',
flexThreshold: 3,
batchThreshold: 500,
});
console.log(`โ
Configured: provider=${getProvider()}, flexAvailable=${isFlexAvailable()}`);
// Test 1: Basic flex processing with Gemini 2.0 Flash
console.log('\n๐ Test 1: Basic Flex Processing (Gemini 2.0 Flash)');
console.log(' Creating 3 simple prompts...');
const items = [
{ id: 'test_1', prompt: 'What is 2 + 2? Reply with just the number.', status: 'pending' },
{ id: 'test_2', prompt: 'What is 3 + 3? Reply with just the number.', status: 'pending' },
{ id: 'test_3', prompt: 'What is 4 + 4? Reply with just the number.', status: 'pending' },
];
console.log(' Submitting via flex adapter...');
const startTime = Date.now();
try {
const results = await googleFlexAdapter.submitFlex(items, { model: GEMINI_FLASH });
const duration = Date.now() - startTime;
console.log(` โ
Completed in ${duration}ms`);
console.log(' Results:');
results.forEach((result) => {
const status = result.status === 'completed' ? 'โ
' : 'โ';
console.log(` ${status} ${result.id}: "${result.result}"`);
if (result.error) {
console.log(` Error: ${result.error}`);
}
});
}
catch (error) {
console.error(` โ Error: ${error}`);
process.exit(1);
}
// Test 2: Token usage
console.log('\n๐ Test 2: Token Usage Tracking');
const usageItems = [
{ id: 'usage', prompt: 'Count from 1 to 5', status: 'pending' },
];
try {
const results = await googleFlexAdapter.submitFlex(usageItems, { model: GEMINI_FLASH });
const usage = results[0].usage;
if (usage) {
console.log(` Prompt tokens: ${usage.promptTokens}`);
console.log(` Completion tokens: ${usage.completionTokens}`);
console.log(` Total tokens: ${usage.totalTokens}`);
console.log(' โ
Token usage tracking works');
}
else {
console.log(' โ ๏ธ No usage data returned');
}
}
catch (error) {
console.error(` โ Error: ${error}`);
}
// Test 3: Structured output (JSON)
console.log('\n๐ Test 3: Structured Output (JSON)');
const jsonItems = [
{
id: 'json_test',
prompt: 'Generate a JSON object with name "Alice" and age 30. Return only valid JSON, no markdown.',
schema: { name: 'string', age: 'number' },
status: 'pending',
},
];
try {
const results = await googleFlexAdapter.submitFlex(jsonItems, { model: GEMINI_FLASH });
console.log(` Result: ${JSON.stringify(results[0].result)}`);
console.log(' โ
Structured output works');
}
catch (error) {
console.error(` โ Error: ${error}`);
}
// Test 4: Concurrent processing
console.log('\n๐ Test 4: Concurrent Processing (10 items)');
const concurrentItems = Array.from({ length: 10 }, (_, i) => ({
id: `concurrent_${i}`,
prompt: `What is ${i + 1} * 2? Reply with just the number.`,
status: 'pending',
}));
try {
const startTime = Date.now();
const results = await googleFlexAdapter.submitFlex(concurrentItems, { model: GEMINI_FLASH });
const duration = Date.now() - startTime;
const successCount = results.filter((r) => r.status === 'completed').length;
console.log(` โ
Processed ${successCount}/10 items in ${duration}ms`);
console.log(` Average: ${Math.round(duration / 10)}ms per item`);
results.forEach((result) => {
console.log(` ${result.id}: "${result.result}"`);
});
}
catch (error) {
console.error(` โ Error: ${error}`);
}
// Test 5: Gemini 1.5 Pro
console.log('\n๐ Test 5: Gemini 1.5 Pro');
const proItems = [
{ id: 'pro_test', prompt: 'Write a haiku about AI.', status: 'pending' },
];
try {
const results = await googleFlexAdapter.submitFlex(proItems, { model: GEMINI_PRO });
console.log(` โ
Gemini 1.5 Pro response:`);
console.log(` ${results[0].result}`);
}
catch (error) {
console.error(` โ Error: ${error}`);
}
// Test 6: Tier selection
console.log('\n๐ Test 6: Execution Tier Selection');
console.log(` 1 item โ ${getExecutionTier(1)} (expected: immediate)`);
console.log(` 3 items โ ${getExecutionTier(3)} (expected: flex)`);
console.log(` 10 items โ ${getExecutionTier(10)} (expected: flex)`);
console.log(` 500 items โ ${getExecutionTier(500)} (expected: batch)`);
console.log('\nโจ E2E Tests Complete!\n');
resetContext();
}
main().catch((error) => {
console.error('Fatal error:', error);
process.exit(1);
});