Skip to content

Commit 6abbf02

Browse files
authored
Merge pull request #149 from aiapienthusiast/cheaperinference-provider
feat: add Cheaper Inference as AI provider
2 parents 1e500cf + 6c223f7 commit 6abbf02

6 files changed

Lines changed: 100 additions & 2 deletions

File tree

‎.env.example‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ db_mode=json
2020
########################################
2121
# LLM Core Settings
2222
########################################
23-
LLM_PROVIDER=gemini # gemini | openai | claude | grok | ollama | openrouter | requesty | minimax | apiroute
23+
LLM_PROVIDER=gemini # gemini | openai | claude | grok | ollama | openrouter | requesty | cheaperinference | minimax | apiroute
2424
EMB_PROVIDER=openai # openai | gemini | ollama etc.
2525
LLM_TEMP=1
2626
LLM_MAXTOK=16384
@@ -65,6 +65,15 @@ REQUESTY_EMBED_MODEL=openai/text-embedding-3-large
6565
# EU region: https://router.eu.requesty.ai/v1
6666
REQUESTY_BASE_URL="https://router.requesty.ai/v1"
6767

68+
########################################
69+
# Cheaper Inference (https://cheaperinference.com)
70+
########################################
71+
# Get a key at https://cheaperinference.com/signup
72+
# Embeddings use the OpenAI settings above
73+
CHEAPER_INFERENCE_API_KEY=
74+
CHEAPER_INFERENCE_MODEL=gpt-5.4-mini
75+
CHEAPER_INFERENCE_BASE_URL="https://api.cheaperinference.com/v1"
76+
6877
########################################
6978
# Grok (xAI)
7079
########################################

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ The platform provides a modern interface for students, educators, and researcher
7979

8080
### Supported AI Models
8181

82-
- Google Gemini • OpenAI GPT • Anthropic Claude • xAI Grok • [MiniMax](https://www.minimax.io/) • [API Route](https://www.api-route.com) • Ollama (local) • OpenRouter • [Requesty](https://requesty.ai)
82+
- Google Gemini • OpenAI GPT • Anthropic Claude • xAI Grok • [MiniMax](https://www.minimax.io/) • [API Route](https://www.api-route.com) • Ollama (local) • OpenRouter • [Requesty](https://requesty.ai) • [Cheaper Inference](https://cheaperinference.com)
8383

8484
### Embedding Providers
8585

‎backend/src/config/env.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export const config = {
1414
requesty_model: process.env.REQUESTY_MODEL || 'openai/gpt-4o-mini',
1515
requesty_embed_model: process.env.REQUESTY_EMBED_MODEL || 'openai/text-embedding-3-large',
1616
requesty_base: process.env.REQUESTY_BASE_URL || 'https://router.requesty.ai/v1',
17+
cheaperinference: process.env.CHEAPER_INFERENCE_API_KEY || '',
18+
cheaperinference_model: process.env.CHEAPER_INFERENCE_MODEL || 'gpt-5.4-mini',
19+
cheaperinference_base: process.env.CHEAPER_INFERENCE_BASE_URL || 'https://api.cheaperinference.com/v1',
1720
gemini: process.env.gemini || process.env.GOOGLE_API_KEY || '',
1821
gemini_model: process.env.gemini_model || 'gemini-1.5-pro',
1922
gemini_embed_model: process.env.gemini_embed_model || 'text-embedding-004',
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest'
2+
3+
vi.mock('@langchain/openai', () => {
4+
const MockChatOpenAI = vi.fn(function (this: any, opts: any) {
5+
this.invoke = vi.fn().mockResolvedValue({ content: 'mock response' })
6+
this._opts = opts
7+
})
8+
const MockOpenAIEmbeddings = vi.fn(function (this: any, opts: any) {
9+
this.embedDocuments = vi.fn().mockResolvedValue([[0.1, 0.2]])
10+
this.embedQuery = vi.fn().mockResolvedValue([0.1, 0.2])
11+
this._opts = opts
12+
})
13+
return { ChatOpenAI: MockChatOpenAI, OpenAIEmbeddings: MockOpenAIEmbeddings }
14+
})
15+
16+
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai'
17+
import { makeLLM, makeEmbeddings } from '../cheaperinference'
18+
19+
describe('Cheaper Inference LLM provider', () => {
20+
beforeEach(() => {
21+
vi.clearAllMocks()
22+
})
23+
24+
it('should create a ChatOpenAI instance with Cheaper Inference defaults', () => {
25+
const llm = makeLLM({ cheaperinference: 'test-key' })
26+
27+
expect(ChatOpenAI).toHaveBeenCalledWith(
28+
expect.objectContaining({
29+
model: 'gpt-5.4-mini',
30+
apiKey: 'test-key',
31+
configuration: { baseURL: 'https://api.cheaperinference.com/v1' },
32+
}),
33+
)
34+
expect(typeof llm.invoke).toBe('function')
35+
expect(typeof llm.call).toBe('function')
36+
})
37+
38+
it('should use configured model and base URL', () => {
39+
makeLLM({
40+
cheaperinference: 'key',
41+
cheaperinference_model: 'claude-sonnet-5',
42+
cheaperinference_base: 'https://gateway.example.test/v1',
43+
})
44+
45+
expect(ChatOpenAI).toHaveBeenCalledWith(
46+
expect.objectContaining({
47+
model: 'claude-sonnet-5',
48+
configuration: { baseURL: 'https://gateway.example.test/v1' },
49+
}),
50+
)
51+
})
52+
53+
it('should create embeddings with the OpenAI settings', () => {
54+
makeEmbeddings({ openai: 'openai-key' })
55+
56+
expect(OpenAIEmbeddings).toHaveBeenCalledWith(
57+
expect.objectContaining({
58+
model: 'text-embedding-3-large',
59+
apiKey: 'openai-key',
60+
}),
61+
)
62+
})
63+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai'
2+
import { wrapChat } from './util'
3+
import type { MkLLM, MkEmb, EmbeddingsLike } from './types'
4+
5+
export const makeLLM: MkLLM = (cfg: any) => {
6+
const m = new ChatOpenAI({
7+
model: cfg.cheaperinference_model || 'gpt-5.4-mini',
8+
apiKey: cfg.cheaperinference || '',
9+
configuration: { baseURL: cfg.cheaperinference_base || 'https://api.cheaperinference.com/v1' },
10+
temperature: cfg.temp ?? 0.7,
11+
maxTokens: cfg.max_tokens,
12+
})
13+
return wrapChat(m)
14+
}
15+
16+
export const makeEmbeddings: MkEmb = (cfg: any): EmbeddingsLike => {
17+
return new OpenAIEmbeddings({
18+
model: cfg.openai_embed_model || 'text-embedding-3-large',
19+
apiKey: cfg.openai || process.env.OPENAI_API_KEY,
20+
})
21+
}

‎backend/src/utils/llm/models/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as grok from './grok'
55
import * as claude from './claude'
66
import * as openrouter from './openrouter'
77
import * as requesty from './requesty'
8+
import * as cheaperinference from './cheaperinference'
89
import * as minimax from './minimax'
910
import * as apiroute from './apiroute'
1011
import { config } from '../../../config/env'
@@ -21,6 +22,7 @@ function pick(p: string) {
2122
case 'claude': return claude
2223
case 'openrouter': return openrouter
2324
case 'requesty': return requesty
25+
case 'cheaperinference': return cheaperinference
2426
case 'minimax': return minimax
2527
case 'apiroute':
2628
case 'api_route':

0 commit comments

Comments
 (0)