Skip to content

Commit aab493c

Browse files
authored
Feature/OpenRouter (#3865)
add open router
1 parent d2fa430 commit aab493c

File tree

4 files changed

+196
-1
lines changed

4 files changed

+196
-1
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { INodeParams, INodeCredential } from '../src/Interface'
2+
3+
class OpenRouterAPIAuth implements INodeCredential {
4+
label: string
5+
name: string
6+
version: number
7+
description: string
8+
inputs: INodeParams[]
9+
10+
constructor() {
11+
this.label = 'OpenRouter API Key'
12+
this.name = 'openRouterApi'
13+
this.version = 1.0
14+
this.inputs = [
15+
{
16+
label: 'OpenRouter API Key',
17+
name: 'openRouterApiKey',
18+
type: 'password',
19+
description: 'API Key'
20+
}
21+
]
22+
}
23+
}
24+
25+
module.exports = { credClass: OpenRouterAPIAuth }

packages/components/nodes/chatmodels/ChatCerebras/ChatCerebras.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class ChatCerebras_ChatModels implements INode {
135135
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
136136
const cerebrasAIApiKey = getCredentialParam('cerebrasApiKey', credentialData, nodeData)
137137

138-
const obj: Partial<OpenAIChatInput> & BaseLLMParams & { cerebrasAIApiKey?: string } = {
138+
const obj: Partial<OpenAIChatInput> & BaseLLMParams = {
139139
temperature: parseFloat(temperature),
140140
modelName,
141141
openAIApiKey: cerebrasAIApiKey,
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { ChatOpenAI, OpenAIChatInput } from '@langchain/openai'
2+
import { BaseCache } from '@langchain/core/caches'
3+
import { BaseLLMParams } from '@langchain/core/language_models/llms'
4+
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
5+
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
6+
7+
class ChatOpenRouter_ChatModels implements INode {
8+
label: string
9+
name: string
10+
version: number
11+
type: string
12+
icon: string
13+
category: string
14+
description: string
15+
baseClasses: string[]
16+
credential: INodeParams
17+
inputs: INodeParams[]
18+
19+
constructor() {
20+
this.label = 'ChatOpenRouter'
21+
this.name = 'chatOpenRouter'
22+
this.version = 1.0
23+
this.type = 'ChatOpenRouter'
24+
this.icon = 'openRouter.svg'
25+
this.category = 'Chat Models'
26+
this.description = 'Wrapper around Open Router Inference API'
27+
this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
28+
this.credential = {
29+
label: 'Connect Credential',
30+
name: 'credential',
31+
type: 'credential',
32+
credentialNames: ['openRouterApi'],
33+
optional: true
34+
}
35+
this.inputs = [
36+
{
37+
label: 'Cache',
38+
name: 'cache',
39+
type: 'BaseCache',
40+
optional: true
41+
},
42+
{
43+
label: 'Model Name',
44+
name: 'modelName',
45+
type: 'string',
46+
placeholder: 'openai/gpt-3.5-turbo'
47+
},
48+
{
49+
label: 'Temperature',
50+
name: 'temperature',
51+
type: 'number',
52+
step: 0.1,
53+
default: 0.9,
54+
optional: true
55+
},
56+
{
57+
label: 'Streaming',
58+
name: 'streaming',
59+
type: 'boolean',
60+
default: true,
61+
optional: true,
62+
additionalParams: true
63+
},
64+
{
65+
label: 'Max Tokens',
66+
name: 'maxTokens',
67+
type: 'number',
68+
step: 1,
69+
optional: true,
70+
additionalParams: true
71+
},
72+
{
73+
label: 'Top Probability',
74+
name: 'topP',
75+
type: 'number',
76+
step: 0.1,
77+
optional: true,
78+
additionalParams: true
79+
},
80+
{
81+
label: 'Frequency Penalty',
82+
name: 'frequencyPenalty',
83+
type: 'number',
84+
step: 0.1,
85+
optional: true,
86+
additionalParams: true
87+
},
88+
{
89+
label: 'Presence Penalty',
90+
name: 'presencePenalty',
91+
type: 'number',
92+
step: 0.1,
93+
optional: true,
94+
additionalParams: true
95+
},
96+
{
97+
label: 'Timeout',
98+
name: 'timeout',
99+
type: 'number',
100+
step: 1,
101+
optional: true,
102+
additionalParams: true
103+
},
104+
{
105+
label: 'BasePath',
106+
name: 'basepath',
107+
type: 'string',
108+
optional: true,
109+
default: 'https://openrouter.ai/api/v1',
110+
additionalParams: true
111+
},
112+
{
113+
label: 'BaseOptions',
114+
name: 'baseOptions',
115+
type: 'json',
116+
optional: true,
117+
additionalParams: true
118+
}
119+
]
120+
}
121+
122+
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
123+
const temperature = nodeData.inputs?.temperature as string
124+
const modelName = nodeData.inputs?.modelName as string
125+
const maxTokens = nodeData.inputs?.maxTokens as string
126+
const topP = nodeData.inputs?.topP as string
127+
const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
128+
const presencePenalty = nodeData.inputs?.presencePenalty as string
129+
const timeout = nodeData.inputs?.timeout as string
130+
const streaming = nodeData.inputs?.streaming as boolean
131+
const basePath = (nodeData.inputs?.basepath as string) || 'https://openrouter.ai/api/v1'
132+
const baseOptions = nodeData.inputs?.baseOptions
133+
const cache = nodeData.inputs?.cache as BaseCache
134+
135+
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
136+
const openRouterApiKey = getCredentialParam('openRouterApiKey', credentialData, nodeData)
137+
138+
const obj: Partial<OpenAIChatInput> & BaseLLMParams = {
139+
temperature: parseFloat(temperature),
140+
modelName,
141+
openAIApiKey: openRouterApiKey,
142+
streaming: streaming ?? true
143+
}
144+
145+
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
146+
if (topP) obj.topP = parseFloat(topP)
147+
if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
148+
if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty)
149+
if (timeout) obj.timeout = parseInt(timeout, 10)
150+
if (cache) obj.cache = cache
151+
152+
let parsedBaseOptions: any | undefined = undefined
153+
154+
if (baseOptions) {
155+
try {
156+
parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions)
157+
} catch (exception) {
158+
throw new Error("Invalid JSON in the ChatCerebras's BaseOptions: " + exception)
159+
}
160+
}
161+
const model = new ChatOpenAI(obj, {
162+
basePath,
163+
baseOptions: parsedBaseOptions
164+
})
165+
return model
166+
}
167+
}
168+
169+
module.exports = { nodeClass: ChatOpenRouter_ChatModels }
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)