mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
Merge PR #2600: fix(ai): add chat touchpoint to litellm proxy recipe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> # Conflicts: # src/core/ai/recipes/litellm-proxy.ts
This commit is contained in:
@@ -20,6 +20,15 @@ export const litellmProxy: Recipe = {
|
||||
setup_url: 'https://docs.litellm.ai/docs/proxy/quick_start',
|
||||
},
|
||||
touchpoints: {
|
||||
chat: {
|
||||
// Models depend on the proxy's config; the openai-compat tier accepts
|
||||
// user-provided IDs and lets the proxied backend validate them.
|
||||
models: [],
|
||||
supports_tools: true,
|
||||
supports_subagent_loop: false,
|
||||
supports_prompt_cache: false,
|
||||
price_last_verified: '2026-04-20',
|
||||
},
|
||||
embedding: {
|
||||
// Models depend on the proxy's config; declare empties so wizard prompts user.
|
||||
models: [],
|
||||
@@ -42,5 +51,5 @@ export const litellmProxy: Recipe = {
|
||||
supports_multimodal: true,
|
||||
},
|
||||
},
|
||||
setup_hint: 'Run LiteLLM (https://docs.litellm.ai) in front of any provider; set LITELLM_BASE_URL (include the /v1 suffix if your proxy serves the OpenAI route there, e.g. http://localhost:4000/v1) + pass --embedding-model litellm:<model> and --embedding-dimensions <N>.',
|
||||
setup_hint: 'Run LiteLLM (https://docs.litellm.ai) in front of any provider; set LITELLM_BASE_URL (include the /v1 suffix if your proxy serves the OpenAI route there, e.g. http://localhost:4000/v1), optionally set LITELLM_API_KEY, and use litellm:<model> for chat. For embeddings, also pass --embedding-model litellm:<model> and --embedding-dimensions <N>.',
|
||||
};
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { defaultResolveAuth } from '../../src/core/ai/gateway.ts';
|
||||
import { assertTouchpoint } from '../../src/core/ai/model-resolver.ts';
|
||||
import { getRecipe } from '../../src/core/ai/recipes/index.ts';
|
||||
|
||||
describe('recipe: litellm proxy', () => {
|
||||
test('registered with expected openai-compatible shape', () => {
|
||||
const r = getRecipe('litellm');
|
||||
expect(r).toBeDefined();
|
||||
expect(r!.id).toBe('litellm');
|
||||
expect(r!.tier).toBe('openai-compat');
|
||||
expect(r!.implementation).toBe('openai-compatible');
|
||||
expect(r!.base_url_default).toBe('http://localhost:4000');
|
||||
expect(r!.auth_env?.required ?? []).toEqual([]);
|
||||
expect(r!.auth_env?.optional ?? []).toContain('LITELLM_BASE_URL');
|
||||
expect(r!.auth_env?.optional ?? []).toContain('LITELLM_API_KEY');
|
||||
});
|
||||
|
||||
test('chat touchpoint accepts arbitrary proxied model IDs', () => {
|
||||
const r = getRecipe('litellm')!;
|
||||
expect(r.touchpoints.chat).toBeDefined();
|
||||
expect(r.touchpoints.chat!.models).toEqual([]);
|
||||
expect(r.touchpoints.chat!.supports_tools).toBe(true);
|
||||
expect(r.touchpoints.chat!.supports_subagent_loop).toBe(false);
|
||||
expect(() => assertTouchpoint(r, 'chat', 'gpt-4o')).not.toThrow();
|
||||
expect(() => assertTouchpoint(r, 'chat', 'deepseek-v4-pro')).not.toThrow();
|
||||
});
|
||||
|
||||
test('embedding touchpoint still uses user-provided models and dimensions', () => {
|
||||
const r = getRecipe('litellm')!;
|
||||
expect(r.touchpoints.embedding).toBeDefined();
|
||||
expect(r.touchpoints.embedding!.models).toEqual([]);
|
||||
expect(r.touchpoints.embedding!.user_provided_models).toBe(true);
|
||||
expect(r.touchpoints.embedding!.default_dims).toBe(0);
|
||||
expect(r.touchpoints.embedding!.no_batch_cap).toBe(true);
|
||||
});
|
||||
|
||||
test('default auth honors LITELLM_API_KEY and ignores URL-only config', () => {
|
||||
const r = getRecipe('litellm')!;
|
||||
|
||||
const noAuth = defaultResolveAuth(r, {}, 'chat');
|
||||
expect(noAuth.headerName).toBe('Authorization');
|
||||
expect(noAuth.token).toBe('Bearer unauthenticated');
|
||||
|
||||
const urlOnly = defaultResolveAuth(r, { LITELLM_BASE_URL: 'http://proxy.example' }, 'chat');
|
||||
expect(urlOnly.token).toBe('Bearer unauthenticated');
|
||||
|
||||
const withKey = defaultResolveAuth(r, {
|
||||
LITELLM_BASE_URL: 'http://proxy.example',
|
||||
LITELLM_API_KEY: 'sk-litellm-fake',
|
||||
}, 'chat');
|
||||
expect(withKey.token).toBe('Bearer sk-litellm-fake');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user