Skip to content

Commit 626b3c6

Browse files
committed
add support for openRouter and AI/ML (previously required filling in the URL via the custom model option)
1 parent b769d94 commit 626b3c6

File tree

5 files changed

+168
-1
lines changed

5 files changed

+168
-1
lines changed

src/background/index.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { generateAnswersWithAzureOpenaiApi } from '../services/apis/azure-openai
1515
import { generateAnswersWithClaudeApi } from '../services/apis/claude-api.mjs'
1616
import { generateAnswersWithChatGLMApi } from '../services/apis/chatglm-api.mjs'
1717
import { generateAnswersWithWaylaidwandererApi } from '../services/apis/waylaidwanderer-api.mjs'
18+
import { generateAnswersWithOpenRouterApi } from '../services/apis/openrouter-api.mjs'
19+
import { generateAnswersWithAimlApi } from '../services/apis/aiml-api.mjs'
1820
import {
1921
defaultConfig,
2022
getUserConfig,
@@ -33,6 +35,8 @@ import {
3335
isUsingClaudeWebModel,
3436
isUsingMoonshotApiModel,
3537
isUsingMoonshotWebModel,
38+
isUsingOpenRouterApiModel,
39+
isUsingAimlApiModel,
3640
} from '../config/index.mjs'
3741
import '../_locales/i18n'
3842
import { openUrl } from '../utils/open-url'
@@ -144,6 +148,10 @@ async function executeApi(session, port, config) {
144148
await generateAnswersWithChatGLMApi(port, session.question, session)
145149
} else if (isUsingOllamaApiModel(session)) {
146150
await generateAnswersWithOllamaApi(port, session.question, session)
151+
} else if (isUsingOpenRouterApiModel(session)) {
152+
await generateAnswersWithOpenRouterApi(port, session.question, session, config.openRouterApiKey)
153+
} else if (isUsingAimlApiModel(session)) {
154+
await generateAnswersWithAimlApi(port, session.question, session, config.aimlApiKey)
147155
} else if (isUsingAzureOpenAiApiModel(session)) {
148156
await generateAnswersWithAzureOpenaiApi(port, session.question, session)
149157
} else if (isUsingGptCompletionApiModel(session)) {

src/config/index.mjs

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,33 @@ export const poeWebModelKeys = [
9494
'poeAiWeb_Llama_2_13b',
9595
'poeAiWeb_Llama_2_70b',
9696
]
97-
export const moonshotApiModelKeys = ['moonshot_v1_8k', 'moonshot_v1_32k', 'moonshot_v1_128k']
97+
export const moonshotApiModelKeys = [
98+
'moonshot_k2',
99+
'moonshot_kimi_latest',
100+
'moonshot_v1_8k',
101+
'moonshot_v1_32k',
102+
'moonshot_v1_128k',
103+
]
104+
export const openRouterApiModelKeys = [
105+
'openRouter_anthropic_claude_sonnet4',
106+
'openRouter_anthropic_claude_3_7_sonnet',
107+
'openRouter_google_gemini_2_5_pro',
108+
'openRouter_google_gemini_2_5_flash',
109+
'openRouter_openai_o3',
110+
'openRouter_openai_gpt_4_1_mini',
111+
'openRouter_deepseek_deepseek_chat_v3_0324_free',
112+
]
113+
export const aimlApiModelKeys = [
114+
'aiml_anthropic_claude_opus_4',
115+
'aiml_anthropic_claude_sonnet_4',
116+
'aiml_claude_3_7_sonnet_20250219',
117+
'aiml_google_gemini_2_5_pro_preview_05_06',
118+
'aiml_google_gemini_2_5_flash_preview',
119+
'aiml_openai_o3_2025_04_16',
120+
'aiml_openai_gpt_4_1_2025_04_14',
121+
'aiml_deepseek_deepseek_chat',
122+
'aiml_moonshot_kimi_k2_preview',
123+
]
98124

99125
export const AlwaysCustomGroups = [
100126
'ollamaApiModelKeys',
@@ -157,6 +183,14 @@ export const ModelGroups = {
157183
value: githubThirdPartyApiModelKeys,
158184
desc: 'Github Third Party Waylaidwanderer (API)',
159185
},
186+
openRouterApiModelKeys: {
187+
value: openRouterApiModelKeys,
188+
desc: 'OpenRouter (API)',
189+
},
190+
aimlModelKeys: {
191+
value: aimlApiModelKeys,
192+
desc: 'AI/ML (API)',
193+
},
160194
customApiModelKeys: {
161195
value: customApiModelKeys,
162196
desc: 'Custom Model',
@@ -294,6 +328,72 @@ export const Models = {
294328
value: 'moonshot-v1-128k',
295329
desc: 'Kimi.Moonshot (128k)',
296330
},
331+
332+
openRouter_anthropic_claude_sonnet4: {
333+
value: 'anthropic/claude-sonnet-4',
334+
desc: 'OpenRouter (Claude Sonnet 4)',
335+
},
336+
openRouter_anthropic_claude_3_7_sonnet: {
337+
value: 'anthropic/claude-3.7-sonnet',
338+
desc: 'OpenRouter (Claude 3.7 Sonnet)',
339+
},
340+
openRouter_google_gemini_2_5_pro: {
341+
value: 'google/gemini-2.5-pro',
342+
desc: 'OpenRouter (Gemini 2.5 Pro)',
343+
},
344+
openRouter_google_gemini_2_5_flash: {
345+
value: 'google/gemini-2.5-flash',
346+
desc: 'OpenRouter (Gemini 2.5 Flash)',
347+
},
348+
openRouter_openai_o3: {
349+
value: 'openai/o3',
350+
desc: 'OpenRouter (GPT-o3)',
351+
},
352+
openRouter_openai_gpt_4_1_mini: {
353+
value: 'openai/gpt-4.1-mini',
354+
desc: 'OpenRouter (GPT-4.1 Mini)',
355+
},
356+
openRouter_deepseek_deepseek_chat_v3_0324_free: {
357+
value: 'deepseek/deepseek-chat-v3-0324:free',
358+
desc: 'OpenRouter (DeepSeek Chat v3 Free)',
359+
},
360+
361+
aiml_anthropic_claude_opus_4: {
362+
value: 'anthropic/claude-opus-4',
363+
desc: 'AIML (Claude Opus 4)',
364+
},
365+
aiml_anthropic_claude_sonnet_4: {
366+
value: 'anthropic/claude-sonnet-4',
367+
desc: 'AIML (Claude Sonnet 4)',
368+
},
369+
aiml_claude_3_7_sonnet_20250219: {
370+
value: 'claude-3-7-sonnet-20250219',
371+
desc: 'AIML (Claude 3.7 Sonnet)',
372+
},
373+
aiml_google_gemini_2_5_pro_preview_05_06: {
374+
value: 'google/gemini-2.5-pro-preview-05-06',
375+
desc: 'AIML (Gemini 2.5 Pro)',
376+
},
377+
aiml_google_gemini_2_5_flash_preview: {
378+
value: 'google/gemini-2.5-flash-preview',
379+
desc: 'AIML (Gemini 2.5 Flash)',
380+
},
381+
aiml_openai_o3_2025_04_16: {
382+
value: 'openai/o3-2025-04-16',
383+
desc: 'AIML (GPT-o3)',
384+
},
385+
aiml_openai_gpt_4_1_2025_04_14: {
386+
value: 'openai/gpt-4.1-2025-04-14',
387+
desc: 'AIML (GPT-4.1)',
388+
},
389+
aiml_deepseek_deepseek_chat: {
390+
value: 'deepseek/deepseek-chat',
391+
desc: 'AIML (DeepSeek Chat)',
392+
},
393+
aiml_moonshot_kimi_k2_preview: {
394+
value: 'moonshot/kimi-k2-preview',
395+
desc: 'AIML (Kimi K2)',
396+
},
297397
}
298398

299399
for (const modelName in Models) {
@@ -359,6 +459,9 @@ export const defaultConfig = {
359459
ollamaApiKey: '',
360460
ollamaKeepAliveTime: '5m',
361461

462+
openRouterApiKey: '',
463+
aimlApiKey: '',
464+
362465
// advanced
363466

364467
maxResponseTokenLength: 2000,
@@ -536,6 +639,14 @@ export function isUsingMoonshotApiModel(configOrSession) {
536639
return isInApiModeGroup(moonshotApiModelKeys, configOrSession)
537640
}
538641

642+
export function isUsingOpenRouterApiModel(configOrSession) {
643+
return isInApiModeGroup(openRouterApiModelKeys, configOrSession)
644+
}
645+
646+
export function isUsingAimlApiModel(configOrSession) {
647+
return isInApiModeGroup(aimlApiModelKeys, configOrSession)
648+
}
649+
539650
export function isUsingChatGLMApiModel(configOrSession) {
540651
return isInApiModeGroup(chatglmApiModelKeys, configOrSession)
541652
}

src/popup/sections/GeneralPart.jsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
TriggerMode,
2323
isUsingMoonshotApiModel,
2424
Models,
25+
isUsingOpenRouterApiModel,
26+
isUsingAimlApiModel,
2527
} from '../../config/index.mjs'
2628
import Browser from 'webextension-polyfill'
2729
import { languageList } from '../../config/language.mjs'
@@ -417,6 +419,28 @@ export function GeneralPart({ config, updateConfig, setTabIndex }) {
417419
}}
418420
/>
419421
)}
422+
{isUsingOpenRouterApiModel(config) && (
423+
<input
424+
type="password"
425+
value={config.openRouterApiKey}
426+
placeholder={t('API Key')}
427+
onChange={(e) => {
428+
const apiKey = e.target.value
429+
updateConfig({ openRouterApiKey: apiKey })
430+
}}
431+
/>
432+
)}
433+
{isUsingAimlApiModel(config) && (
434+
<input
435+
type="password"
436+
value={config.aimlApiKey}
437+
placeholder={t('API Key')}
438+
onChange={(e) => {
439+
const apiKey = e.target.value
440+
updateConfig({ aimlApiKey: apiKey })
441+
}}
442+
/>
443+
)}
420444
{isUsingAzureOpenAiApiModel(config) && (
421445
<input
422446
type="password"

src/services/apis/aiml-api.mjs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { generateAnswersWithChatgptApiCompat } from './openai-api.mjs'
2+
3+
/**
4+
* @param {Browser.Runtime.Port} port
5+
* @param {string} question
6+
* @param {Session} session
7+
* @param {string} apiKey
8+
*/
9+
export async function generateAnswersWithAimlApi(port, question, session, apiKey) {
10+
const baseUrl = 'https://api.aimlapi.com/v1'
11+
return generateAnswersWithChatgptApiCompat(baseUrl, port, question, session, apiKey)
12+
}

src/services/apis/openrouter-api.mjs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { generateAnswersWithChatgptApiCompat } from './openai-api.mjs'
2+
3+
/**
4+
* @param {Browser.Runtime.Port} port
5+
* @param {string} question
6+
* @param {Session} session
7+
* @param {string} apiKey
8+
*/
9+
export async function generateAnswersWithOpenRouterApi(port, question, session, apiKey) {
10+
const baseUrl = 'https://openrouter.ai/api/v1'
11+
return generateAnswersWithChatgptApiCompat(baseUrl, port, question, session, apiKey)
12+
}

0 commit comments

Comments
 (0)