import { EventEmitter } from 'node:events'; import type { IncomingMessage, ServerResponse } from 'node:http'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { handleProviderRoutes, importCurrentUserModelConfig, normalizeImportedUserModelConfig, } from '@electron/api/routes/providers'; import type { ProviderAccount } from '@electron/shared/providers/types'; const providerServiceMock = vi.hoisted(() => ({ getAccount: vi.fn(), getAccountApiKey: vi.fn(), getDefaultAccountId: vi.fn(), updateAccount: vi.fn(), setDefaultAccount: vi.fn(), })); const proxyAwareFetchMock = vi.hoisted(() => vi.fn()); vi.mock('@electron/services/providers/provider-service', () => ({ getProviderService: () => providerServiceMock, })); vi.mock('@electron/utils/proxy-fetch', () => ({ proxyAwareFetch: (...args: unknown[]) => proxyAwareFetchMock(...args), })); function createRequest(method: string, body?: unknown): IncomingMessage { const request = new EventEmitter(); Object.assign(request, { method, headers: body === undefined ? {} : { 'content-type': 'application/json' }, [Symbol.asyncIterator]: async function* () { if (body !== undefined) yield Buffer.from(JSON.stringify(body)); }, }); return request as IncomingMessage; } function createResponse() { const chunks: string[] = []; const response = { statusCode: 0, setHeader: vi.fn(), end: vi.fn((chunk?: string) => { if (chunk) chunks.push(chunk); }), } as unknown as ServerResponse; return { response, get statusCode() { return response.statusCode; }, json: () => JSON.parse(chunks.join('')) as unknown, }; } function account(overrides: Partial = {}): ProviderAccount { return { id: 'account-1', vendorId: 'openai', label: 'OpenAI', authMode: 'api_key', enabled: true, isDefault: true, createdAt: '2026-08-24T00:00:00.000Z', updatedAt: '2026-08-24T00:00:00.000Z', ...overrides, }; } describe('provider host api routes', () => { const markProviderStale = vi.fn(); const context = { codingProducts: { conversations: { markProviderStale } }, } as never; beforeEach(() => { vi.clearAllMocks(); providerServiceMock.getAccount.mockResolvedValue(account()); providerServiceMock.getAccountApiKey.mockResolvedValue('stored-key'); providerServiceMock.updateAccount.mockResolvedValue(account({ updatedAt: '2026-08-24T01:00:00.000Z', })); providerServiceMock.getDefaultAccountId.mockResolvedValue('account-1'); providerServiceMock.setDefaultAccount.mockResolvedValue(undefined); }); it('normalizes optional Works model capabilities before storing the account', () => { expect(normalizeImportedUserModelConfig({ label: 'Makelore Models', base_url: 'https://gateway.test/v1', api_key: 'gateway-key', credential_mode: 'works_square_ai_gateway', models: ['deepseek/deepseek-v4-pro', 'qwen3.8-max'], model_capabilities: { 'deepseek/deepseek-v4-pro': { reasoning_efforts: ['max', 'low', 'medium', 'low'], reasoning_can_disable: true, }, 'qwen3.8-max': { reasoning_efforts: ['high'], reasoning_can_disable: false, }, 'not-provisioned': { reasoning_efforts: ['low'], reasoning_can_disable: true, }, }, })).toMatchObject({ models: ['deepseek-v4-pro', 'qwen3.8-max'], modelCapabilities: { 'deepseek-v4-pro': { reasoningEfforts: ['low', 'max'], reasoningCanDisable: true, }, 'qwen3.8-max': { reasoningEfforts: ['high'], reasoningCanDisable: false, }, }, }); }); it('preserves exact v2 public aliases and native effort values on import', () => { const config = normalizeImportedUserModelConfig({ base_url: 'https://gateway.test/v1', api_key: 'test', models: ['deepseek/public-model'], model_capabilities_v2: { schema_version: 2, models: { 'deepseek/public-model': { input_modalities: ['text', 'image'], reasoning: { supported: true, can_disable: true, effort_values: ['medium', 'xhigh', 'new-native'], control_format: 'qwen' } }, 'not-authorized': { input_modalities: ['image'] }, } }, }); expect(config.models).toEqual(['deepseek/public-model']); expect(Object.keys(config.modelCapabilitiesV2!.models)).toEqual(['deepseek/public-model']); expect(config.modelCapabilitiesV2!.models['deepseek/public-model']!.reasoning.effortValues) .toEqual(['medium', 'xhigh', 'new-native']); }); it('persists server capabilities and invalidates the runtime when they change', async () => { const existing = account({ id: 'niancode-user-models', vendorId: 'custom', model: 'deepseek-v4-pro', metadata: { customModels: ['deepseek-v4-pro'], worksSquareModelCapabilities: { 'deepseek-v4-pro': { reasoningEfforts: ['high'], reasoningCanDisable: false, }, }, }, }); providerServiceMock.getAccount.mockResolvedValue(existing); providerServiceMock.updateAccount.mockImplementation(async (_accountId: string, patch: Partial) => ({ ...existing, ...patch, })); proxyAwareFetchMock.mockResolvedValue(new Response(JSON.stringify({ label: 'Makelore Models', base_url: 'https://gateway.test/v1', api_key: 'gateway-key', credential_mode: 'api_key', models: ['deepseek/deepseek-v4-pro'], model_capabilities: { 'deepseek/deepseek-v4-pro': { reasoning_efforts: ['low', 'high', 'max'], reasoning_can_disable: true, }, }, model_capabilities_v2: { schema_version: 2, models: { 'deepseek/deepseek-v4-pro': { input_modalities: ['text'], reasoning: { supported: true, can_disable: true, effort_values: ['xhigh'] }, } } }, }), { status: 200, headers: { 'content-type': 'application/json' } })); const imported = await importCurrentUserModelConfig(context, 'access-token'); expect(imported.account.metadata?.worksSquareModelCapabilitiesV2?.models['deepseek/deepseek-v4-pro']?.reasoning.effortValues).toEqual(['xhigh']); expect(imported.account.metadata?.worksSquareModelCapabilities).toEqual({ 'deepseek-v4-pro': { reasoningEfforts: ['low', 'high', 'max'], reasoningCanDisable: true, }, }); expect(providerServiceMock.updateAccount).toHaveBeenCalledWith( 'niancode-user-models', expect.objectContaining({ metadata: expect.objectContaining({ worksSquareModelCapabilities: { 'deepseek-v4-pro': { reasoningEfforts: ['low', 'high', 'max'], reasoningCanDisable: true, }, }, }), }), 'gateway-key', ); expect(markProviderStale).toHaveBeenCalledTimes(1); }); it('clears a previous server capability override when the optional field is absent', async () => { const existing = account({ id: 'niancode-user-models', vendorId: 'custom', model: 'deepseek-v4-pro', metadata: { customModels: ['deepseek-v4-pro'], worksSquareModelCapabilities: { 'deepseek-v4-pro': { reasoningEfforts: ['max'], reasoningCanDisable: true, }, }, }, }); providerServiceMock.getAccount.mockResolvedValue(existing); providerServiceMock.updateAccount.mockImplementation(async (_accountId: string, patch: Partial) => ({ ...existing, ...patch, })); proxyAwareFetchMock.mockResolvedValue(new Response(JSON.stringify({ base_url: 'https://gateway.test/v1', api_key: 'gateway-key', models: ['deepseek/deepseek-v4-pro'], }), { status: 200, headers: { 'content-type': 'application/json' } })); const imported = await importCurrentUserModelConfig(context, 'access-token'); expect(imported.account.metadata).not.toHaveProperty('worksSquareModelCapabilities'); expect(providerServiceMock.updateAccount).toHaveBeenCalledWith( 'niancode-user-models', expect.objectContaining({ metadata: expect.not.objectContaining({ worksSquareModelCapabilities: expect.anything() }), }), 'gateway-key', ); }); it('marks Pi provider input stale after an account credential update', async () => { const result = createResponse(); const handled = await handleProviderRoutes( createRequest('PUT', { updates: {}, apiKey: 'sk-new' }), result.response, new URL('http://127.0.0.1/api/provider-accounts/account-1'), context, ); expect(handled).toBe(true); expect(result.statusCode).toBe(200); expect(providerServiceMock.updateAccount).toHaveBeenCalledWith('account-1', {}, 'sk-new'); expect(markProviderStale).toHaveBeenCalledTimes(1); }); it('does not invalidate provider input for an unchanged account', async () => { const result = createResponse(); await handleProviderRoutes( createRequest('PUT', { updates: {} }), result.response, new URL('http://127.0.0.1/api/provider-accounts/account-1'), context, ); expect(result.statusCode).toBe(200); expect(result.json()).toMatchObject({ success: true, noChange: true }); expect(providerServiceMock.updateAccount).not.toHaveBeenCalled(); expect(markProviderStale).not.toHaveBeenCalled(); }); it('invalidates provider input only when the default account changes', async () => { const unchanged = createResponse(); await handleProviderRoutes( createRequest('PUT', { accountId: 'account-1' }), unchanged.response, new URL('http://127.0.0.1/api/provider-accounts/default'), context, ); expect(markProviderStale).not.toHaveBeenCalled(); providerServiceMock.getDefaultAccountId.mockResolvedValue('account-2'); const changed = createResponse(); await handleProviderRoutes( createRequest('PUT', { accountId: 'account-1' }), changed.response, new URL('http://127.0.0.1/api/provider-accounts/default'), context, ); expect(providerServiceMock.setDefaultAccount).toHaveBeenCalledWith('account-1'); expect(markProviderStale).toHaveBeenCalledTimes(1); }); });