import test from 'node:test'; import assert from 'node:assert/strict'; import { probeVisionProvider, resolveVisionConfig } from '../src/vision-config.js'; test('selfhost profile defaults to a loopback OpenAI-compatible server and no remote processor', () => { const config = resolveVisionConfig({ TIMMY_VISION_PROFILE: 'selfhost' }); assert.equal(config.profile, 'selfhost'); assert.equal(config.baseUrl, 'http://127.0.0.1:8080/v1'); assert.equal(config.model, 'SmolVLM2-2.2B-Instruct'); assert.equal(config.processor, 'self-hosted'); assert.equal(config.apiKey, 'local-selfhost'); assert.equal(config.requestTimeoutMs, 120_000); }); test('hosted profile remains explicit and never leaks its API key through public status', () => { const config = resolveVisionConfig({ TIMMY_VISION_PROFILE: 'hosted', TIMMY_VISION_API_KEY: 'top-secret', }); assert.equal(config.profile, 'hosted'); assert.equal(config.baseUrl, 'http://127.0.0.1:8645/v1'); assert.equal(config.apiKey, 'top-secret'); assert.deepEqual(config.publicStatus(), { enabled: true, profile: 'hosted', processor: 'third-party', model: 'stepfun/step-3.7-flash:free', }); }); test('provider probe checks the models endpoint and reports bounded readiness', async () => { let captured; const status = await probeVisionProvider(resolveVisionConfig({ TIMMY_VISION_PROFILE: 'selfhost' }), async (url, options) => { captured = { url, options }; return { ok: true, json: async () => ({ data: [{ id: 'SmolVLM2-2.2B-Instruct' }] }) }; }); assert.equal(captured.url, 'http://127.0.0.1:8080/v1/models'); assert.match(captured.options.headers.authorization, /^Bearer /); assert.deepEqual(status, { ready: true, modelSeen: true }); }); test('provider probe fails closed without exposing upstream errors', async () => { const status = await probeVisionProvider(resolveVisionConfig({ TIMMY_VISION_PROFILE: 'selfhost' }), async () => { throw new Error('private upstream detail'); }); assert.deepEqual(status, { ready: false, modelSeen: false }); });