import { DyFM_Error } from '@futdevpro/fsm-dynamo'; import { DyFM_AI_ModelInfo, DyFM_AI_ModelType, DyFM_AI_Provider } from '@futdevpro/fsm-dynamo/ai'; import { DyNTS_AI_ModelConfig_Validator } from './ai-model-config-validator.util'; describe('| DyNTS_AI_ModelConfig_Validator (FR-048 validate-mode)', () => { const registry: DyFM_AI_ModelInfo[] = [ { id: 'reasoning-model', provider: DyFM_AI_Provider.OpenAI, modelType: DyFM_AI_ModelType.Chat, capabilities: {} as any, settingsSchema: { unsupported: ['temperature', 'topP'] }, }, { id: 'opus-model', provider: DyFM_AI_Provider.Anthropic, modelType: DyFM_AI_ModelType.Chat, capabilities: {} as any, settingsSchema: { unsupported: ['temperature'] }, }, { id: 'plain-model', provider: DyFM_AI_Provider.OpenAI, modelType: DyFM_AI_ModelType.Chat, capabilities: {} as any, }, { id: 'constrained-model', provider: DyFM_AI_Provider.OpenAI, modelType: DyFM_AI_ModelType.Chat, capabilities: {} as any, settingsSchema: { supported: ['maxTokens', 'reasoningEffort'], constraints: { reasoningEffort: { allowed: ['low', 'medium', 'high'] }, maxTokens: { min: 10, max: 100 }, }, }, }, ]; it('| nem tamogatott param → provider-faithful DyFM_Error', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'reasoning-model', config: { temperature: 0.5 }, registry: registry, }); expect(error instanceof DyFM_Error).toBe(true); expect(error.message).toContain('unsupported_parameter:temperature'); }); it('| csak tamogatott paramok → null (OK)', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'reasoning-model', config: { maxTokens: 100 }, registry: registry, }); expect(error).toBeNull(); }); it('| Anthropic provider → anthropic-alaku hiba-body', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'anthropic', model: 'opus-model', config: { temperature: 0.5 }, registry: registry, }); expect(error.message).toContain('invalid_request_error:temperature'); }); it('| schema-mentes modell → null (permisszi­v, nem talalgat)', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'plain-model', config: { temperature: 0.5 }, registry: registry, }); expect(error).toBeNull(); }); it('| ismeretlen modell → null (permisszi­v)', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'nincs-ilyen', config: { temperature: 0.5 }, registry: registry, }); expect(error).toBeNull(); }); it('| constraints.allowed megsertve → invalid_value hiba', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'constrained-model', config: { reasoningEffort: 'ultra' }, registry: registry, }); expect(error instanceof DyFM_Error).toBe(true); expect(error.message).toContain('invalid_value:reasoningEffort'); }); it('| constraints.allowed betartva → null', () => { expect(DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'constrained-model', config: { reasoningEffort: 'medium' }, registry: registry, })).toBeNull(); }); it('| constraints min/max megsertve → invalid_value hiba', () => { const tooHigh: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'constrained-model', config: { maxTokens: 5000 }, registry: registry, }); expect(tooHigh.message).toContain('invalid_value:maxTokens'); }); it('| constraints tartomanyon belul → null', () => { expect(DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'constrained-model', config: { maxTokens: 50 }, registry: registry, })).toBeNull(); }); it('| config nelkul → null', () => { const error: DyFM_Error = DyNTS_AI_ModelConfig_Validator.validate({ provider: 'open-ai', model: 'reasoning-model', registry: registry, }); expect(error).toBeNull(); }); });