/** * End-to-end test: verify all code paths that create providers * and ensure Ollama never hits echo mode. */ // Simulate no .env loaded (clean environment) delete process.env.OPC_LLM_API_KEY; delete process.env.OPC_LLM_BASE_URL; delete process.env.OPC_LLM_MODEL; delete process.env.OPC_LLM_PROVIDER; delete process.env.OPENAI_API_KEY; const { createProvider } = require('./dist/providers'); const tests: { name: string; pass: boolean; detail: string }[] = []; function test(name: string, fn: () => void) { try { fn(); tests.push({ name, pass: true, detail: 'OK' }); } catch (e: any) { tests.push({ name, pass: false, detail: e.message }); } } function assert(condition: boolean, msg: string) { if (!condition) throw new Error(msg); } // Test 1: createProvider('ollama', 'qwen2.5:7b') - the CLI chat path test('CLI chat: createProvider(ollama, qwen2.5:7b)', () => { const p = createProvider('ollama', 'qwen2.5:7b'); assert(p.name === 'ollama', `name should be ollama, got ${p.name}`); // Access private apiKey via any cast const key = (p as any).apiKey; assert(!!key, `apiKey is falsy: "${key}"`); assert(key !== '', `apiKey is empty string`); }); // Test 2: createProvider('ollama', 'qwen2.5:7b', undefined, undefined) - BaseAgent path test('BaseAgent: createProvider(ollama, qwen2.5:7b, undefined, undefined)', () => { const p = createProvider('ollama', 'qwen2.5:7b', undefined, undefined); const key = (p as any).apiKey; assert(!!key, `apiKey is falsy: "${key}"`); }); // Test 3: createProvider('auto') with no env vars - auto-detect path test('Auto-detect: createProvider(auto) no env', () => { const p = createProvider('auto'); // Should not crash assert(!!p, 'provider should exist'); }); // Test 4: createProvider('openai') with no API key - should echo test('OpenAI no key: should echo', () => { const p = createProvider('openai', 'gpt-4o-mini'); const key = (p as any).apiKey; // This SHOULD be falsy (no key configured) // Just verify it doesn't crash assert(!!p, 'provider should exist'); }); // Test 5: Simulate OAD spec object path test('OAD spec object: { provider: { default: ollama }, model: qwen2.5:7b }', () => { const p = createProvider({ provider: { default: 'ollama' }, model: 'qwen2.5:7b' }); const key = (p as any).apiKey; assert(!!key, `apiKey is falsy: "${key}"`); }); // Test 6: Verify chat() doesn't echo for ollama test('Ollama chat() should NOT return echo', async () => { const p = createProvider('ollama', 'qwen2.5:7b'); // We can't actually call Ollama (not installed here), but verify apiKey check const key = (p as any).apiKey; const baseUrl = (p as any).baseUrl; assert(!!key, `apiKey is falsy, would echo: "${key}"`); assert(baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1'), `baseUrl should be localhost, got: ${baseUrl}`); }); // Test 7: Verify with OPC_LLM_API_KEY="" (empty string in env) test('Empty OPC_LLM_API_KEY env should still work for ollama', () => { process.env.OPC_LLM_API_KEY = ''; const p = createProvider('ollama', 'qwen2.5:7b'); const key = (p as any).apiKey; assert(!!key, `apiKey is falsy with empty env: "${key}"`); delete process.env.OPC_LLM_API_KEY; }); // Test 8: Verify with OPC_LLM_API_KEY="your-api-key-here" (placeholder) test('Placeholder OPC_LLM_API_KEY should still work for ollama', () => { process.env.OPC_LLM_API_KEY = 'your-api-key-here'; const p = createProvider('ollama', 'qwen2.5:7b'); const key = (p as any).apiKey; assert(!!key, `apiKey is falsy with placeholder: "${key}"`); delete process.env.OPC_LLM_API_KEY; }); // Test 9: BaseAgent simulation test('BaseAgent full simulation', () => { const { BaseAgent } = require('./dist/core/agent'); const { InMemoryStore } = require('./dist/memory'); const agent = new BaseAgent({ name: 'test', systemPrompt: 'test', provider: 'ollama', model: 'qwen2.5:7b', memory: new InMemoryStore(), }); const provider = (agent as any)._provider; const key = (provider as any).apiKey; assert(!!key, `BaseAgent provider apiKey is falsy: "${key}"`); assert(provider.name === 'ollama', `provider name should be ollama, got ${provider.name}`); }); // Print results console.log('\n=== OPC Agent Provider Tests ===\n'); let passed = 0, failed = 0; for (const t of tests) { const icon = t.pass ? '✅' : '❌'; console.log(`${icon} ${t.name}: ${t.detail}`); if (t.pass) passed++; else failed++; } console.log(`\n${passed} passed, ${failed} failed\n`); if (failed > 0) process.exit(1);