Download packages/agent-core-v2/test/llm-adapter/protocol/protocolAdapterRegistry.test.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 11.7 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/test/llm-adapter/protocol/protocolAdapterRegistry.test.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/agent-core-v2/test/llm-adapter/protocol/protocolAdapterRegistry.test.ts
-
curl -L -o protocolAdapterRegistry.test.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/agent-core-v2/test/llm-adapter/protocol/protocolAdapterRegistry.test.ts
11.7 kB
| import { beforeEach, afterEach, describe, expect, it } from 'vitest'; | |
| import { isUnknownCapability } from '#/llm-adapter/contract/capability'; | |
| import { thinkingMetadataOf } from '#human/llm/thinking'; | |
| import type { Model } from '#/llm-adapter/model/catalog'; | |
| import { ProtocolAdapterRegistry } from '#/llm-adapter/protocol/protocolAdapterRegistry'; | |
| import { | |
| getProviderDefinition, | |
| getProviderDefinitions, | |
| hasProviderDefinition, | |
| registerProviderDefinition, | |
| resolveProviderEndpoint, | |
| } from '#/llm-adapter/provider/provider-definition'; | |
| const ENV_KEYS = [ | |
| 'OPENAI_API_KEY', | |
| 'OPENAI_BASE_URL', | |
| 'KIMI_API_KEY', | |
| 'KIMI_BASE_URL', | |
| 'GOOGLE_API_KEY', | |
| 'VERTEXAI_API_KEY', | |
| ] as const; | |
| let envSnapshot: Record<string, string | undefined>; | |
| beforeEach(() => { | |
| envSnapshot = {}; | |
| for (const key of ENV_KEYS) { | |
| envSnapshot[key] = process.env[key]; | |
| delete process.env[key]; | |
| } | |
| }); | |
| afterEach(() => { | |
| for (const key of ENV_KEYS) { | |
| const value = envSnapshot[key]; | |
| if (value === undefined) { | |
| delete process.env[key]; | |
| } else { | |
| process.env[key] = value; | |
| } | |
| } | |
| }); | |
| registerProviderDefinition({ | |
| id: 'cap-vendor', | |
| baseProtocol: 'openai', | |
| capability: (modelName: string) => | |
| modelName === 'special-model' | |
| ? { | |
| image_in: true, | |
| video_in: false, | |
| audio_in: false, | |
| thinking: false, | |
| tool_use: true, | |
| } | |
| : undefined, | |
| }); | |
| const registry = new ProtocolAdapterRegistry(); | |
| function modelWith(spec: { | |
| readonly protocol: Model['protocol']; | |
| readonly providerType?: string; | |
| readonly providerOptions?: Model['providerOptions']; | |
| readonly reasoningKey?: string; | |
| readonly supportEfforts?: readonly string[]; | |
| }): Model { | |
| return { | |
| id: 'm1', | |
| name: 'wire-model', | |
| aliases: [], | |
| protocol: spec.protocol, | |
| headers: {}, | |
| capabilities: { | |
| image_in: false, | |
| video_in: false, | |
| audio_in: false, | |
| thinking: false, | |
| tool_use: true, | |
| max_context_tokens: 128000, | |
| }, | |
| maxContextSize: 128000, | |
| alwaysThinking: false, | |
| providerType: spec.providerType, | |
| providerName: spec.providerType ?? spec.protocol, | |
| reasoningKey: spec.reasoningKey, | |
| supportEfforts: spec.supportEfforts, | |
| providerOptions: spec.providerOptions, | |
| }; | |
| } | |
| describe('supportedProtocols', () => { | |
| it('lists the four wire protocols and contains neither kimi nor vertexai', () => { | |
| const protocols = registry.supportedProtocols(); | |
| expect(protocols).toHaveLength(4); | |
| expect([...protocols].toSorted()).toEqual( | |
| ['anthropic', 'google-genai', 'openai', 'openai_responses'].toSorted(), | |
| ); | |
| expect(protocols).not.toContain('kimi'); | |
| expect(protocols).not.toContain('vertexai'); | |
| }); | |
| }); | |
| describe('resolveAdapterIdentity', () => { | |
| it('resolves the kimi pair registrations to their vendor traits', () => { | |
| expect(registry.resolveAdapterIdentity('openai', 'kimi').baseId).toBe('openai'); | |
| expect(registry.resolveAdapterIdentity('openai', 'kimi').trait).toBeDefined(); | |
| expect(registry.resolveAdapterIdentity('anthropic', 'kimi').baseId).toBe('anthropic'); | |
| expect(registry.resolveAdapterIdentity('anthropic', 'kimi').trait).toBeDefined(); | |
| expect(registry.resolveAdapterIdentity('openai_responses', 'kimi').baseId).toBe( | |
| 'openai_responses', | |
| ); | |
| expect(registry.resolveAdapterIdentity('openai_responses', 'kimi').trait).toBeUndefined(); | |
| }); | |
| it('resolves unregistered pairs to the protocol itself with no vendor trait', () => { | |
| const google = registry.resolveAdapterIdentity('google-genai', 'kimi'); | |
| expect(google.baseId).toBe('google-genai'); | |
| expect(google.trait).toBeUndefined(); | |
| const unknown = registry.resolveAdapterIdentity('openai', 'no-such-vendor'); | |
| expect(unknown.baseId).toBe('openai'); | |
| expect(unknown.trait).toBeUndefined(); | |
| }); | |
| it('resolves the no-providerType branch identically', () => { | |
| const identity = registry.resolveAdapterIdentity('openai'); | |
| expect(identity.baseId).toBe('openai'); | |
| expect(identity.trait).toBeUndefined(); | |
| }); | |
| }); | |
| describe('resolveProviderBaseId', () => { | |
| it('returns the pair registration’s baseProtocol — the protocol itself by construction', () => { | |
| expect(registry.resolveProviderBaseId('openai', 'kimi')).toBe('openai'); | |
| expect(registry.resolveProviderBaseId('anthropic', 'kimi')).toBe('anthropic'); | |
| }); | |
| it('returns the protocol itself otherwise', () => { | |
| expect(registry.resolveProviderBaseId('google-genai', 'kimi')).toBe('google-genai'); | |
| expect(registry.resolveProviderBaseId('openai', 'no-such-vendor')).toBe('openai'); | |
| expect(registry.resolveProviderBaseId('openai')).toBe('openai'); | |
| }); | |
| }); | |
| describe('resolveCapability', () => { | |
| it('falls back to trait capability hooks before the base catalog', () => { | |
| const fromTrait = registry.resolveCapability('openai', 'special-model', 'cap-vendor'); | |
| expect(fromTrait.image_in).toBe(true); | |
| const fromBase = registry.resolveCapability('openai', 'gpt-4o', 'cap-vendor'); | |
| expect(fromBase.image_in).toBe(true); | |
| }); | |
| it('falls back to the base catalog and then to UNKNOWN', () => { | |
| expect(registry.resolveCapability('openai', 'gpt-4o').image_in).toBe(true); | |
| expect(isUnknownCapability(registry.resolveCapability('openai', 'mystery-model'))).toBe(true); | |
| expect(registry.resolveCapability('anthropic', 'claude-opus-4-1').thinking).toBe(true); | |
| }); | |
| it('kimi declares no vendor-level capability — the base catalog answers instead', () => { | |
| expect(isUnknownCapability(registry.resolveCapability('openai', 'kimi-for-coding', 'kimi'))).toBe( | |
| true, | |
| ); | |
| expect(registry.resolveCapability('openai', 'gpt-4o', 'kimi').image_in).toBe(true); | |
| }); | |
| }); | |
| describe('resolve gateway routes', () => { | |
| it('routes kimi+openai to the kimi trait with the video upload media', () => { | |
| const resolved = registry.resolve(modelWith({ protocol: 'openai', providerType: 'kimi' })); | |
| expect(resolved.protocol).toBe('openai'); | |
| expect(resolved.model.provider).toBe('openai'); | |
| expect(resolved.model.model).toBe('wire-model'); | |
| expect(typeof resolved.media?.uploadVideo).toBe('function'); | |
| expect(typeof resolved.media?.uploadImage).toBe('function'); | |
| }); | |
| it('routes plain openai without the upload media', () => { | |
| const resolved = registry.resolve(modelWith({ protocol: 'openai' })); | |
| expect(resolved.protocol).toBe('openai'); | |
| expect(resolved.media?.uploadVideo).toBeUndefined(); | |
| expect(resolved.media?.uploadImage).toBeUndefined(); | |
| }); | |
| it('reports the wire protocol regardless of beta or vertex provider options', () => { | |
| const beta = registry.resolve( | |
| modelWith({ protocol: 'anthropic', providerOptions: { betaApi: true } }), | |
| ); | |
| expect(beta.protocol).toBe('anthropic'); | |
| const vertex = registry.resolve( | |
| modelWith({ | |
| protocol: 'google-genai', | |
| providerOptions: { vertexai: true, project: 'p', location: 'l' }, | |
| }), | |
| ); | |
| expect(vertex.protocol).toBe('google-genai'); | |
| }); | |
| it('routes kimi+anthropic through the kimi anthropic trait with media', () => { | |
| const resolved = registry.resolve(modelWith({ protocol: 'anthropic', providerType: 'kimi' })); | |
| expect(resolved.protocol).toBe('anthropic'); | |
| expect(typeof resolved.media?.uploadVideo).toBe('function'); | |
| expect(typeof resolved.media?.uploadImage).toBe('function'); | |
| }); | |
| it('carries thinking metadata and model limits onto the resolved LlmModel', () => { | |
| const resolved = registry.resolve( | |
| modelWith({ | |
| protocol: 'anthropic', | |
| supportEfforts: ['low', 'high'], | |
| providerOptions: { supportEfforts: ['low', 'high'], adaptiveThinking: true }, | |
| }), | |
| ); | |
| expect(resolved.model.maxContextSize).toBe(128000); | |
| expect(thinkingMetadataOf(resolved.model)).toMatchObject({ | |
| supportEfforts: ['low', 'high'], | |
| adaptiveThinking: true, | |
| }); | |
| }); | |
| }); | |
| describe('resolveProviderEndpoint', () => { | |
| it('resolves the kimi endpoint chain from process.env', () => { | |
| process.env['KIMI_API_KEY'] = 'sk-kimi-env'; | |
| expect(resolveProviderEndpoint('kimi')).toEqual({ | |
| apiKey: 'sk-kimi-env', | |
| baseUrl: 'https://api.moonshot.ai/v1', | |
| }); | |
| }); | |
| it('reads a caller-supplied env bag instead of process.env', () => { | |
| process.env['KIMI_API_KEY'] = 'sk-kimi-env'; | |
| expect(resolveProviderEndpoint('kimi', { KIMI_BASE_URL: 'https://example.com/v1' })).toEqual({ | |
| baseUrl: 'https://example.com/v1', | |
| }); | |
| }); | |
| it('aggregates the google-genai chain with the legacy vertex precedence', () => { | |
| expect( | |
| resolveProviderEndpoint('google-genai', { | |
| VERTEXAI_API_KEY: 'vertex-env-key', | |
| GOOGLE_API_KEY: 'google-env-key', | |
| }), | |
| ).toEqual({ apiKey: 'vertex-env-key' }); | |
| expect(resolveProviderEndpoint('google-genai', { GOOGLE_API_KEY: 'google-env-key' })).toEqual({ | |
| apiKey: 'google-env-key', | |
| }); | |
| expect( | |
| resolveProviderEndpoint('google-genai', { | |
| GOOGLE_VERTEX_BASE_URL: 'https://vertex.example.test', | |
| GOOGLE_GEMINI_BASE_URL: 'https://gemini.example.test', | |
| }), | |
| ).toEqual({ baseUrl: 'https://vertex.example.test' }); | |
| expect( | |
| resolveProviderEndpoint('google-genai', { | |
| GOOGLE_GEMINI_BASE_URL: 'https://gemini.example.test', | |
| }), | |
| ).toEqual({ baseUrl: 'https://gemini.example.test' }); | |
| }); | |
| it('returns {} for unregistered vendors', () => { | |
| expect(resolveProviderEndpoint('no-such-vendor')).toEqual({}); | |
| }); | |
| }); | |
| describe('kimi provider definitions', () => { | |
| it('registers one definition per transport, with shared vendor-level facts', () => { | |
| const native = getProviderDefinition('kimi', 'openai'); | |
| const anthropic = getProviderDefinition('kimi', 'anthropic'); | |
| const responses = getProviderDefinition('kimi', 'openai_responses'); | |
| expect(native?.baseProtocol).toBe('openai'); | |
| expect(native?.trait).toBeDefined(); | |
| expect(anthropic?.baseProtocol).toBe('anthropic'); | |
| expect(anthropic?.trait).toBeDefined(); | |
| expect(responses?.baseProtocol).toBe('openai_responses'); | |
| expect(responses?.trait).toBeUndefined(); | |
| for (const definition of [native, anthropic, responses]) { | |
| expect(definition?.endpoint).toEqual({ | |
| apiKeyEnv: 'KIMI_API_KEY', | |
| baseUrlEnv: 'KIMI_BASE_URL', | |
| defaultBaseUrl: 'https://api.moonshot.ai/v1', | |
| }); | |
| expect(definition?.hostHeaders).toBe('full'); | |
| expect(definition?.modelSource).toBe('oauth-catalog'); | |
| } | |
| }); | |
| it('answers id-level queries and reports unregistered pairs', () => { | |
| expect(getProviderDefinition('kimi')?.baseProtocol).toBe('openai'); | |
| expect(getProviderDefinitions('kimi')).toHaveLength(3); | |
| expect(hasProviderDefinition('kimi')).toBe(true); | |
| expect(hasProviderDefinition('no-such-vendor')).toBe(false); | |
| expect(getProviderDefinition('kimi', 'google-genai')).toBeUndefined(); | |
| }); | |
| it('allows the same id on several protocols but rejects a duplicate (id, baseProtocol) pair', () => { | |
| registerProviderDefinition({ | |
| id: 'pair-vendor', | |
| baseProtocol: 'openai', | |
| }); | |
| registerProviderDefinition({ | |
| id: 'pair-vendor', | |
| baseProtocol: 'anthropic', | |
| }); | |
| expect(getProviderDefinition('pair-vendor', 'openai')).toBeDefined(); | |
| expect(getProviderDefinition('pair-vendor', 'anthropic')).toBeDefined(); | |
| expect(() => | |
| registerProviderDefinition({ | |
| id: 'pair-vendor', | |
| baseProtocol: 'openai', | |
| }), | |
| ).toThrow(/already registered/); | |
| expect(() => | |
| registerProviderDefinition({ | |
| id: 'kimi', | |
| baseProtocol: 'openai', | |
| }), | |
| ).toThrow(/already registered/); | |
| }); | |
| }); | |