From fc392859cf2a8911e737ec093990a5413e0bd0be Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 17 Dec 2025 22:49:50 +0000
Subject: [PATCH 1/5] Initial plan
From 1fbd4e2378a8270c442230ed233c476606a7a58d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 17 Dec 2025 22:56:08 +0000
Subject: [PATCH 2/5] Add AI Badgr provider with chat model and embeddings
support
Co-authored-by: miguelmanlyx <220451577+miguelmanlyx@users.noreply.github.com>
---
.../credentials/AIBadgrApi.credential.ts | 23 +++++
.../chatmodels/ChatAIBadgr/ChatAIBadgr.ts | 90 ++++++++++++++++++
.../nodes/chatmodels/ChatAIBadgr/aibadgr.png | Bin 0 -> 1598 bytes
.../AIBadgrEmbedding/AIBadgrEmbedding.ts | 68 +++++++++++++
.../embeddings/AIBadgrEmbedding/aibadgr.png | Bin 0 -> 1598 bytes
5 files changed, 181 insertions(+)
create mode 100644 packages/components/credentials/AIBadgrApi.credential.ts
create mode 100644 packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
create mode 100644 packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.png
create mode 100644 packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
create mode 100644 packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.png
diff --git a/packages/components/credentials/AIBadgrApi.credential.ts b/packages/components/credentials/AIBadgrApi.credential.ts
new file mode 100644
index 00000000000..3f1842ed3fe
--- /dev/null
+++ b/packages/components/credentials/AIBadgrApi.credential.ts
@@ -0,0 +1,23 @@
+import { INodeParams, INodeCredential } from '../src/Interface'
+
+class AIBadgrApi implements INodeCredential {
+ label: string
+ name: string
+ version: number
+ inputs: INodeParams[]
+
+ constructor() {
+ this.label = 'AI Badgr API'
+ this.name = 'aiBadgrApi'
+ this.version = 1.0
+ this.inputs = [
+ {
+ label: 'AI Badgr Api Key',
+ name: 'aiBadgrApiKey',
+ type: 'password'
+ }
+ ]
+ }
+}
+
+module.exports = { credClass: AIBadgrApi }
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
new file mode 100644
index 00000000000..084de77e5e5
--- /dev/null
+++ b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
@@ -0,0 +1,90 @@
+import { BaseCache } from '@langchain/core/caches'
+import { ChatOpenAI } from '@langchain/openai'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+
+class ChatAIBadgr_ChatModels implements INode {
+ label: string
+ name: string
+ version: number
+ type: string
+ icon: string
+ category: string
+ description: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+
+ constructor() {
+ this.label = 'ChatAIBadgr'
+ this.name = 'chatAIBadgr'
+ this.version = 1.0
+ this.type = 'ChatAIBadgr'
+ this.icon = 'aibadgr.png'
+ this.category = 'Chat Models'
+ this.description = 'Wrapper around AI Badgr large language models'
+ this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['aiBadgrApi']
+ }
+ this.inputs = [
+ {
+ label: 'Cache',
+ name: 'cache',
+ type: 'BaseCache',
+ optional: true
+ },
+ {
+ label: 'Model Name',
+ name: 'modelName',
+ type: 'string',
+ placeholder: 'gpt-4o',
+ description: 'Refer to models page'
+ },
+ {
+ label: 'Temperature',
+ name: 'temperature',
+ type: 'number',
+ step: 0.1,
+ default: 0.9,
+ optional: true
+ },
+ {
+ label: 'Streaming',
+ name: 'streaming',
+ type: 'boolean',
+ default: true,
+ optional: true
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const modelName = nodeData.inputs?.modelName as string
+ const cache = nodeData.inputs?.cache as BaseCache
+ const temperature = nodeData.inputs?.temperature as string
+ const streaming = nodeData.inputs?.streaming as boolean
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const aiBadgrApiKey = getCredentialParam('aiBadgrApiKey', credentialData, nodeData)
+
+ const obj: any = {
+ model: modelName,
+ temperature: parseFloat(temperature),
+ openAIApiKey: aiBadgrApiKey,
+ streaming: streaming ?? true,
+ configuration: {
+ baseURL: 'https://aibadgr.com/api/v1'
+ }
+ }
+ if (cache) obj.cache = cache
+
+ const model = new ChatOpenAI(obj)
+ return model
+ }
+}
+
+module.exports = { nodeClass: ChatAIBadgr_ChatModels }
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.png b/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.png
new file mode 100644
index 0000000000000000000000000000000000000000..371103f6f83cc8a3efe7784ae7e0177ca5f245c7
GIT binary patch
literal 1598
zcmZ{kc~DbV6vkgL88k?100UUjq5&i8V~@D72*!ZHfJh^V21vqE!lFS)2n>`>l)`|>
zAZT%o0u}*T98^Rck%AjZ-pflOpeQP+KvWD3Tc38OGo4On?!Di9=iJ|%`R*ULkP$%D
z$FITz0H9CX=@W!%1-eU@E@BS0H8%nS#JR#1q6U`7675jlHXk&=6E7%uR1cqU$6qZR9FsxE2V3|y*KooLVIxv91kZfQ;4#^;?R3?!i
z5CqAjDg=?EcjR)JRH{UfXD9+eDg^>bBuXX9!OxTmguy|Xdrk82^l~dH>S$54#r&Rqz%0iM@
zv003)4
z^YIE!Q+}vc2uHx>dD)&_<(07=UgxA4iDR9Uv$qxv>0vQ6n@w%;A6t#Ji56#0Q!qv6
zjquCwf#`a;n_+_+y_#mRyxT9tds8p*O2u)P^Ou`V7;=*6exBt4x23_IBT?9&)?tW=
zq!E4NY%-z!fTMXcCntEzS-sxiTW?43eXb|dPFPJ*3rkctj_rlIl7gojOTEs<88n94
zwANup^sBP4YVO^oTZ|ndC~?|G!%iJC!KRF~cg&h4&_8KaK%oO110uaF_%@CqW(^q8
zps=nlR^pdauaC#*fC-=S@Cp0&fxQMeaX7Jm&ce(}ZCdB~#ii{t=ko{a6)SBVY#Y^h
z#t7Unlvr|i-rQnMV(aX(=D|aTS6XLH%bJIU(QQW9ONydg?nbgp2G)HtxqqwvxBU24
z;l^WrDH*EsCi#IT#7~A@ew~_kgagKzydq9z39zGXeU39b=w`~P0wDjR+_KN;KKnKf
z3?28#3K5gbr-`0~EdJ`YZI(N1p0oX*8Xna#F=NWiYlV7DJNVjLWG*OdDEzuenGnvD
zxvUN;4*8bLcZGd16W|2cR_!rZuu|W-K+>*JAYb=BseL?vZGbg9j!*!X!W95GPi^;Rs@7b@ji3@mIMdSvM$aFN9$?*Y-A7
zH(0(J$LOqK$0@hmb6uj%jZcqmcVneStGs}NwXcQBh@4;q8_lchLDk90GS
zQh6f5D0|z$-3a^pFED`sb^hh~9w-_b&)YV>aWw(Q=<>`Kx~@}c)P-^HUR9DZe{Q>;o&nXZ}DIq
z3G$D5CmF8LY*6Es9qX1oPuoojuWx85)CuYIob*1kd2cn>tuI*tg}q}J$&&^*0Zm
zgEAy$Mb`aS3l8R-i>3)YcMLrpKbErniQNT{p5#>TWOiwk0DIX3I9OgD`F=3Ll^
zQOLCPxy4gV6FYNPJ$b~nKNBYspxCU
zbm$ZOE{hy=Z!z4&OCKZ8#$W$ali@SZf|J;>zn$Gr-i7tXx=OE;ow{$?&!l-&KUGDd
zala;B`_e=FMA8_#${hV}0Smq_lh2OebKIj2aZmvqK}Tm>(8U&X4t8*J2OZpac$SyhL^^SMdLU07rX+0_1-t@MC$L!~6(d(tjCer@x0-N?cSZ1JHZ}d>Xu2
Gzx)LY`}5`i
literal 0
HcmV?d00001
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
new file mode 100644
index 00000000000..c8130c7d7c8
--- /dev/null
+++ b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
@@ -0,0 +1,68 @@
+import { OpenAIEmbeddings, OpenAIEmbeddingsParams } from '@langchain/openai'
+import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
+import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
+
+class AIBadgrEmbedding_Embeddings implements INode {
+ label: string
+ name: string
+ version: number
+ type: string
+ icon: string
+ category: string
+ description: string
+ baseClasses: string[]
+ inputs: INodeParams[]
+ credential: INodeParams
+
+ constructor() {
+ this.label = 'AIBadgrEmbedding'
+ this.name = 'aiBadgrEmbedding'
+ this.version = 1.0
+ this.type = 'AIBadgrEmbedding'
+ this.icon = 'aibadgr.png'
+ this.category = 'Embeddings'
+ this.description = 'AI Badgr Embedding models to generate embeddings for a given text'
+ this.baseClasses = [this.type, ...getBaseClasses(OpenAIEmbeddings)]
+ this.credential = {
+ label: 'Connect Credential',
+ name: 'credential',
+ type: 'credential',
+ credentialNames: ['aiBadgrApi']
+ }
+ this.inputs = [
+ {
+ label: 'Cache',
+ name: 'cache',
+ type: 'BaseCache',
+ optional: true
+ },
+ {
+ label: 'Model Name',
+ name: 'modelName',
+ type: 'string',
+ placeholder: 'text-embedding-3-small',
+ description: 'Refer to embedding models page'
+ }
+ ]
+ }
+
+ async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const modelName = nodeData.inputs?.modelName as string
+
+ const credentialData = await getCredentialData(nodeData.credential ?? '', options)
+ const aiBadgrApiKey = getCredentialParam('aiBadgrApiKey', credentialData, nodeData)
+
+ const obj: Partial = {
+ modelName: modelName,
+ openAIApiKey: aiBadgrApiKey,
+ configuration: {
+ baseURL: 'https://aibadgr.com/api/v1'
+ }
+ }
+
+ const model = new OpenAIEmbeddings(obj)
+ return model
+ }
+}
+
+module.exports = { nodeClass: AIBadgrEmbedding_Embeddings }
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.png b/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.png
new file mode 100644
index 0000000000000000000000000000000000000000..371103f6f83cc8a3efe7784ae7e0177ca5f245c7
GIT binary patch
literal 1598
zcmZ{kc~DbV6vkgL88k?100UUjq5&i8V~@D72*!ZHfJh^V21vqE!lFS)2n>`>l)`|>
zAZT%o0u}*T98^Rck%AjZ-pflOpeQP+KvWD3Tc38OGo4On?!Di9=iJ|%`R*ULkP$%D
z$FITz0H9CX=@W!%1-eU@E@BS0H8%nS#JR#1q6U`7675jlHXk&=6E7%uR1cqU$6qZR9FsxE2V3|y*KooLVIxv91kZfQ;4#^;?R3?!i
z5CqAjDg=?EcjR)JRH{UfXD9+eDg^>bBuXX9!OxTmguy|Xdrk82^l~dH>S$54#r&Rqz%0iM@
zv003)4
z^YIE!Q+}vc2uHx>dD)&_<(07=UgxA4iDR9Uv$qxv>0vQ6n@w%;A6t#Ji56#0Q!qv6
zjquCwf#`a;n_+_+y_#mRyxT9tds8p*O2u)P^Ou`V7;=*6exBt4x23_IBT?9&)?tW=
zq!E4NY%-z!fTMXcCntEzS-sxiTW?43eXb|dPFPJ*3rkctj_rlIl7gojOTEs<88n94
zwANup^sBP4YVO^oTZ|ndC~?|G!%iJC!KRF~cg&h4&_8KaK%oO110uaF_%@CqW(^q8
zps=nlR^pdauaC#*fC-=S@Cp0&fxQMeaX7Jm&ce(}ZCdB~#ii{t=ko{a6)SBVY#Y^h
z#t7Unlvr|i-rQnMV(aX(=D|aTS6XLH%bJIU(QQW9ONydg?nbgp2G)HtxqqwvxBU24
z;l^WrDH*EsCi#IT#7~A@ew~_kgagKzydq9z39zGXeU39b=w`~P0wDjR+_KN;KKnKf
z3?28#3K5gbr-`0~EdJ`YZI(N1p0oX*8Xna#F=NWiYlV7DJNVjLWG*OdDEzuenGnvD
zxvUN;4*8bLcZGd16W|2cR_!rZuu|W-K+>*JAYb=BseL?vZGbg9j!*!X!W95GPi^;Rs@7b@ji3@mIMdSvM$aFN9$?*Y-A7
zH(0(J$LOqK$0@hmb6uj%jZcqmcVneStGs}NwXcQBh@4;q8_lchLDk90GS
zQh6f5D0|z$-3a^pFED`sb^hh~9w-_b&)YV>aWw(Q=<>`Kx~@}c)P-^HUR9DZe{Q>;o&nXZ}DIq
z3G$D5CmF8LY*6Es9qX1oPuoojuWx85)CuYIob*1kd2cn>tuI*tg}q}J$&&^*0Zm
zgEAy$Mb`aS3l8R-i>3)YcMLrpKbErniQNT{p5#>TWOiwk0DIX3I9OgD`F=3Ll^
zQOLCPxy4gV6FYNPJ$b~nKNBYspxCU
zbm$ZOE{hy=Z!z4&OCKZ8#$W$ali@SZf|J;>zn$Gr-i7tXx=OE;ow{$?&!l-&KUGDd
zala;B`_e=FMA8_#${hV}0Smq_lh2OebKIj2aZmvqK}Tm>(8U&X4t8*J2OZpac$SyhL^^SMdLU07rX+0_1-t@MC$L!~6(d(tjCer@x0-N?cSZ1JHZ}d>Xu2
Gzx)LY`}5`i
literal 0
HcmV?d00001
From 000c515da757ed3a9167e9cc8e8fcbf6eff17dfa Mon Sep 17 00:00:00 2001
From: miguelmanlyx
Date: Thu, 18 Dec 2025 13:53:21 +1000
Subject: [PATCH 3/5] Aibadgr SVG
---
.../chatmodels/ChatAIBadgr/ChatAIBadgr.ts | 2 +-
.../nodes/chatmodels/ChatAIBadgr/aibadgr.png | Bin 1598 -> 0 bytes
.../nodes/chatmodels/ChatAIBadgr/aibadgr.svg | 174 ++++++++++++++++++
.../AIBadgrEmbedding/AIBadgrEmbedding.ts | 2 +-
.../embeddings/AIBadgrEmbedding/aibadgr.png | Bin 1598 -> 0 bytes
.../embeddings/AIBadgrEmbedding/aibadgr.svg | 174 ++++++++++++++++++
6 files changed, 350 insertions(+), 2 deletions(-)
delete mode 100644 packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.png
create mode 100644 packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.svg
delete mode 100644 packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.png
create mode 100644 packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.svg
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
index 084de77e5e5..b64071d6a90 100644
--- a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
+++ b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
@@ -20,7 +20,7 @@ class ChatAIBadgr_ChatModels implements INode {
this.name = 'chatAIBadgr'
this.version = 1.0
this.type = 'ChatAIBadgr'
- this.icon = 'aibadgr.png'
+ this.icon = 'aibadgr.svg'
this.category = 'Chat Models'
this.description = 'Wrapper around AI Badgr large language models'
this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.png b/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.png
deleted file mode 100644
index 371103f6f83cc8a3efe7784ae7e0177ca5f245c7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1598
zcmZ{kc~DbV6vkgL88k?100UUjq5&i8V~@D72*!ZHfJh^V21vqE!lFS)2n>`>l)`|>
zAZT%o0u}*T98^Rck%AjZ-pflOpeQP+KvWD3Tc38OGo4On?!Di9=iJ|%`R*ULkP$%D
z$FITz0H9CX=@W!%1-eU@E@BS0H8%nS#JR#1q6U`7675jlHXk&=6E7%uR1cqU$6qZR9FsxE2V3|y*KooLVIxv91kZfQ;4#^;?R3?!i
z5CqAjDg=?EcjR)JRH{UfXD9+eDg^>bBuXX9!OxTmguy|Xdrk82^l~dH>S$54#r&Rqz%0iM@
zv003)4
z^YIE!Q+}vc2uHx>dD)&_<(07=UgxA4iDR9Uv$qxv>0vQ6n@w%;A6t#Ji56#0Q!qv6
zjquCwf#`a;n_+_+y_#mRyxT9tds8p*O2u)P^Ou`V7;=*6exBt4x23_IBT?9&)?tW=
zq!E4NY%-z!fTMXcCntEzS-sxiTW?43eXb|dPFPJ*3rkctj_rlIl7gojOTEs<88n94
zwANup^sBP4YVO^oTZ|ndC~?|G!%iJC!KRF~cg&h4&_8KaK%oO110uaF_%@CqW(^q8
zps=nlR^pdauaC#*fC-=S@Cp0&fxQMeaX7Jm&ce(}ZCdB~#ii{t=ko{a6)SBVY#Y^h
z#t7Unlvr|i-rQnMV(aX(=D|aTS6XLH%bJIU(QQW9ONydg?nbgp2G)HtxqqwvxBU24
z;l^WrDH*EsCi#IT#7~A@ew~_kgagKzydq9z39zGXeU39b=w`~P0wDjR+_KN;KKnKf
z3?28#3K5gbr-`0~EdJ`YZI(N1p0oX*8Xna#F=NWiYlV7DJNVjLWG*OdDEzuenGnvD
zxvUN;4*8bLcZGd16W|2cR_!rZuu|W-K+>*JAYb=BseL?vZGbg9j!*!X!W95GPi^;Rs@7b@ji3@mIMdSvM$aFN9$?*Y-A7
zH(0(J$LOqK$0@hmb6uj%jZcqmcVneStGs}NwXcQBh@4;q8_lchLDk90GS
zQh6f5D0|z$-3a^pFED`sb^hh~9w-_b&)YV>aWw(Q=<>`Kx~@}c)P-^HUR9DZe{Q>;o&nXZ}DIq
z3G$D5CmF8LY*6Es9qX1oPuoojuWx85)CuYIob*1kd2cn>tuI*tg}q}J$&&^*0Zm
zgEAy$Mb`aS3l8R-i>3)YcMLrpKbErniQNT{p5#>TWOiwk0DIX3I9OgD`F=3Ll^
zQOLCPxy4gV6FYNPJ$b~nKNBYspxCU
zbm$ZOE{hy=Z!z4&OCKZ8#$W$ali@SZf|J;>zn$Gr-i7tXx=OE;ow{$?&!l-&KUGDd
zala;B`_e=FMA8_#${hV}0Smq_lh2OebKIj2aZmvqK}Tm>(8U&X4t8*J2OZpac$SyhL^^SMdLU07rX+0_1-t@MC$L!~6(d(tjCer@x0-N?cSZ1JHZ}d>Xu2
Gzx)LY`}5`i
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.svg b/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.svg
new file mode 100644
index 00000000000..163df36aed0
--- /dev/null
+++ b/packages/components/nodes/chatmodels/ChatAIBadgr/aibadgr.svg
@@ -0,0 +1,174 @@
+
\ No newline at end of file
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
index c8130c7d7c8..8f7acb007dd 100644
--- a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
+++ b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
@@ -19,7 +19,7 @@ class AIBadgrEmbedding_Embeddings implements INode {
this.name = 'aiBadgrEmbedding'
this.version = 1.0
this.type = 'AIBadgrEmbedding'
- this.icon = 'aibadgr.png'
+ this.icon = 'aibadgr.svg'
this.category = 'Embeddings'
this.description = 'AI Badgr Embedding models to generate embeddings for a given text'
this.baseClasses = [this.type, ...getBaseClasses(OpenAIEmbeddings)]
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.png b/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.png
deleted file mode 100644
index 371103f6f83cc8a3efe7784ae7e0177ca5f245c7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1598
zcmZ{kc~DbV6vkgL88k?100UUjq5&i8V~@D72*!ZHfJh^V21vqE!lFS)2n>`>l)`|>
zAZT%o0u}*T98^Rck%AjZ-pflOpeQP+KvWD3Tc38OGo4On?!Di9=iJ|%`R*ULkP$%D
z$FITz0H9CX=@W!%1-eU@E@BS0H8%nS#JR#1q6U`7675jlHXk&=6E7%uR1cqU$6qZR9FsxE2V3|y*KooLVIxv91kZfQ;4#^;?R3?!i
z5CqAjDg=?EcjR)JRH{UfXD9+eDg^>bBuXX9!OxTmguy|Xdrk82^l~dH>S$54#r&Rqz%0iM@
zv003)4
z^YIE!Q+}vc2uHx>dD)&_<(07=UgxA4iDR9Uv$qxv>0vQ6n@w%;A6t#Ji56#0Q!qv6
zjquCwf#`a;n_+_+y_#mRyxT9tds8p*O2u)P^Ou`V7;=*6exBt4x23_IBT?9&)?tW=
zq!E4NY%-z!fTMXcCntEzS-sxiTW?43eXb|dPFPJ*3rkctj_rlIl7gojOTEs<88n94
zwANup^sBP4YVO^oTZ|ndC~?|G!%iJC!KRF~cg&h4&_8KaK%oO110uaF_%@CqW(^q8
zps=nlR^pdauaC#*fC-=S@Cp0&fxQMeaX7Jm&ce(}ZCdB~#ii{t=ko{a6)SBVY#Y^h
z#t7Unlvr|i-rQnMV(aX(=D|aTS6XLH%bJIU(QQW9ONydg?nbgp2G)HtxqqwvxBU24
z;l^WrDH*EsCi#IT#7~A@ew~_kgagKzydq9z39zGXeU39b=w`~P0wDjR+_KN;KKnKf
z3?28#3K5gbr-`0~EdJ`YZI(N1p0oX*8Xna#F=NWiYlV7DJNVjLWG*OdDEzuenGnvD
zxvUN;4*8bLcZGd16W|2cR_!rZuu|W-K+>*JAYb=BseL?vZGbg9j!*!X!W95GPi^;Rs@7b@ji3@mIMdSvM$aFN9$?*Y-A7
zH(0(J$LOqK$0@hmb6uj%jZcqmcVneStGs}NwXcQBh@4;q8_lchLDk90GS
zQh6f5D0|z$-3a^pFED`sb^hh~9w-_b&)YV>aWw(Q=<>`Kx~@}c)P-^HUR9DZe{Q>;o&nXZ}DIq
z3G$D5CmF8LY*6Es9qX1oPuoojuWx85)CuYIob*1kd2cn>tuI*tg}q}J$&&^*0Zm
zgEAy$Mb`aS3l8R-i>3)YcMLrpKbErniQNT{p5#>TWOiwk0DIX3I9OgD`F=3Ll^
zQOLCPxy4gV6FYNPJ$b~nKNBYspxCU
zbm$ZOE{hy=Z!z4&OCKZ8#$W$ali@SZf|J;>zn$Gr-i7tXx=OE;ow{$?&!l-&KUGDd
zala;B`_e=FMA8_#${hV}0Smq_lh2OebKIj2aZmvqK}Tm>(8U&X4t8*J2OZpac$SyhL^^SMdLU07rX+0_1-t@MC$L!~6(d(tjCer@x0-N?cSZ1JHZ}d>Xu2
Gzx)LY`}5`i
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.svg b/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.svg
new file mode 100644
index 00000000000..163df36aed0
--- /dev/null
+++ b/packages/components/nodes/embeddings/AIBadgrEmbedding/aibadgr.svg
@@ -0,0 +1,174 @@
+
\ No newline at end of file
From 45219ae6f71b17c4f6eb0d2c8502e0b5607cf2cb Mon Sep 17 00:00:00 2001
From: michaelmanley <55236695+michaelbrinkworth@users.noreply.github.com>
Date: Thu, 18 Dec 2025 16:02:25 +1000
Subject: [PATCH 4/5] update base url
---
.../chatmodels/ChatAIBadgr/ChatAIBadgr.ts | 120 +++++++++++++++---
.../AIBadgrEmbedding/AIBadgrEmbedding.ts | 82 +++++++++---
2 files changed, 169 insertions(+), 33 deletions(-)
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
index b64071d6a90..bddadafd543 100644
--- a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
+++ b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
@@ -1,9 +1,10 @@
import { BaseCache } from '@langchain/core/caches'
-import { ChatOpenAI } from '@langchain/openai'
+import { ChatOpenAI, ChatOpenAIFields } from '@langchain/openai'
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
class ChatAIBadgr_ChatModels implements INode {
+ readonly baseURL: string = 'https://aibadgr.com/api/v1'
label: string
name: string
version: number
@@ -12,8 +13,8 @@ class ChatAIBadgr_ChatModels implements INode {
category: string
description: string
baseClasses: string[]
- inputs: INodeParams[]
credential: INodeParams
+ inputs: INodeParams[]
constructor() {
this.label = 'ChatAIBadgr'
@@ -22,7 +23,7 @@ class ChatAIBadgr_ChatModels implements INode {
this.type = 'ChatAIBadgr'
this.icon = 'aibadgr.svg'
this.category = 'Chat Models'
- this.description = 'Wrapper around AI Badgr large language models'
+ this.description = 'Wrapper around AI Badgr large language models that use the Chat endpoint'
this.baseClasses = [this.type, ...getBaseClasses(ChatOpenAI)]
this.credential = {
label: 'Connect Credential',
@@ -41,7 +42,7 @@ class ChatAIBadgr_ChatModels implements INode {
label: 'Model Name',
name: 'modelName',
type: 'string',
- placeholder: 'gpt-4o',
+ default: 'gpt-4o',
description: 'Refer to models page'
},
{
@@ -49,7 +50,7 @@ class ChatAIBadgr_ChatModels implements INode {
name: 'temperature',
type: 'number',
step: 0.1,
- default: 0.9,
+ default: 0.7,
optional: true
},
{
@@ -57,32 +58,117 @@ class ChatAIBadgr_ChatModels implements INode {
name: 'streaming',
type: 'boolean',
default: true,
- optional: true
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Max Tokens',
+ name: 'maxTokens',
+ type: 'number',
+ step: 1,
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Top Probability',
+ name: 'topP',
+ type: 'number',
+ step: 0.1,
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Frequency Penalty',
+ name: 'frequencyPenalty',
+ type: 'number',
+ step: 0.1,
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Presence Penalty',
+ name: 'presencePenalty',
+ type: 'number',
+ step: 0.1,
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Base Options',
+ name: 'baseOptions',
+ type: 'json',
+ optional: true,
+ additionalParams: true,
+ description: 'Additional options to pass to the AI Badgr client. This should be a JSON object.'
}
]
}
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
- const modelName = nodeData.inputs?.modelName as string
- const cache = nodeData.inputs?.cache as BaseCache
const temperature = nodeData.inputs?.temperature as string
+ const modelName = nodeData.inputs?.modelName as string
+ const maxTokens = nodeData.inputs?.maxTokens as string
+ const topP = nodeData.inputs?.topP as string
+ const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string
+ const presencePenalty = nodeData.inputs?.presencePenalty as string
const streaming = nodeData.inputs?.streaming as boolean
+ const baseOptions = nodeData.inputs?.baseOptions
+ if (nodeData.inputs?.credentialId) {
+ nodeData.credential = nodeData.inputs?.credentialId
+ }
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
- const aiBadgrApiKey = getCredentialParam('aiBadgrApiKey', credentialData, nodeData)
+ const openAIApiKey = getCredentialParam('aiBadgrApiKey', credentialData, nodeData)
+
+ // Custom error handling for missing API key
+ if (!openAIApiKey || openAIApiKey.trim() === '') {
+ throw new Error(
+ 'AI Badgr API Key is missing or empty. Please provide a valid AI Badgr API key in the credential configuration.'
+ )
+ }
+
+ // Custom error handling for missing model name
+ if (!modelName || modelName.trim() === '') {
+ throw new Error('Model Name is required. Please enter a valid model name (e.g., gpt-4o).')
+ }
+
+ const cache = nodeData.inputs?.cache as BaseCache
- const obj: any = {
- model: modelName,
+ const obj: ChatOpenAIFields = {
temperature: parseFloat(temperature),
- openAIApiKey: aiBadgrApiKey,
- streaming: streaming ?? true,
- configuration: {
- baseURL: 'https://aibadgr.com/api/v1'
- }
+ modelName,
+ openAIApiKey,
+ apiKey: openAIApiKey,
+ streaming: streaming ?? true
}
+
+ if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
+ if (topP) obj.topP = parseFloat(topP)
+ if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
+ if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty)
if (cache) obj.cache = cache
- const model = new ChatOpenAI(obj)
+ let parsedBaseOptions: any | undefined = undefined
+
+ if (baseOptions) {
+ try {
+ parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions)
+ if (parsedBaseOptions.baseURL) {
+ console.warn("The 'baseURL' parameter is not allowed when using the ChatAIBadgr node.")
+ parsedBaseOptions.baseURL = undefined
+ }
+ } catch (exception) {
+ throw new Error('Invalid JSON in the BaseOptions: ' + exception)
+ }
+ }
+
+ const model = new ChatOpenAI({
+ ...obj,
+ configuration: {
+ baseURL: this.baseURL,
+ ...parsedBaseOptions
+ }
+ })
return model
}
}
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
index 8f7acb007dd..c5cd946bc7b 100644
--- a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
+++ b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
@@ -1,8 +1,9 @@
-import { OpenAIEmbeddings, OpenAIEmbeddingsParams } from '@langchain/openai'
+import { ClientOptions, OpenAIEmbeddings, OpenAIEmbeddingsParams } from '@langchain/openai'
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
class AIBadgrEmbedding_Embeddings implements INode {
+ readonly baseURL: string = 'https://aibadgr.com/api/v1'
label: string
name: string
version: number
@@ -11,17 +12,17 @@ class AIBadgrEmbedding_Embeddings implements INode {
category: string
description: string
baseClasses: string[]
- inputs: INodeParams[]
credential: INodeParams
+ inputs: INodeParams[]
constructor() {
this.label = 'AIBadgrEmbedding'
this.name = 'aiBadgrEmbedding'
- this.version = 1.0
+ this.version = 3.0
this.type = 'AIBadgrEmbedding'
this.icon = 'aibadgr.svg'
this.category = 'Embeddings'
- this.description = 'AI Badgr Embedding models to generate embeddings for a given text'
+ this.description = 'AI Badgr API to generate embeddings for a given text'
this.baseClasses = [this.type, ...getBaseClasses(OpenAIEmbeddings)]
this.credential = {
label: 'Connect Credential',
@@ -31,35 +32,84 @@ class AIBadgrEmbedding_Embeddings implements INode {
}
this.inputs = [
{
- label: 'Cache',
- name: 'cache',
- type: 'BaseCache',
- optional: true
+ label: 'Strip New Lines',
+ name: 'stripNewLines',
+ type: 'boolean',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Batch Size',
+ name: 'batchSize',
+ type: 'number',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'Timeout',
+ name: 'timeout',
+ type: 'number',
+ optional: true,
+ additionalParams: true
+ },
+ {
+ label: 'BaseOptions',
+ name: 'baseOptions',
+ type: 'json',
+ optional: true,
+ additionalParams: true
},
{
label: 'Model Name',
name: 'modelName',
type: 'string',
- placeholder: 'text-embedding-3-small',
- description: 'Refer to embedding models page'
+ optional: true
+ },
+ {
+ label: 'Dimensions',
+ name: 'dimensions',
+ type: 'number',
+ optional: true,
+ additionalParams: true
}
]
}
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise {
+ const stripNewLines = nodeData.inputs?.stripNewLines as boolean
+ const batchSize = nodeData.inputs?.batchSize as string
+ const timeout = nodeData.inputs?.timeout as string
const modelName = nodeData.inputs?.modelName as string
+ const dimensions = nodeData.inputs?.dimensions as string
+ const baseOptions = nodeData.inputs?.baseOptions
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
- const aiBadgrApiKey = getCredentialParam('aiBadgrApiKey', credentialData, nodeData)
+ const openAIApiKey = getCredentialParam('aiBadgrApiKey', credentialData, nodeData)
+
+ const obj: Partial & { openAIApiKey?: string; configuration?: ClientOptions } = {
+ openAIApiKey
+ }
+
+ if (stripNewLines) obj.stripNewLines = stripNewLines
+ if (batchSize) obj.batchSize = parseInt(batchSize, 10)
+ if (timeout) obj.timeout = parseInt(timeout, 10)
+ if (modelName) obj.modelName = modelName
+ if (dimensions) obj.dimensions = parseInt(dimensions, 10)
- const obj: Partial = {
- modelName: modelName,
- openAIApiKey: aiBadgrApiKey,
- configuration: {
- baseURL: 'https://aibadgr.com/api/v1'
+ let parsedBaseOptions: any | undefined = undefined
+ if (baseOptions) {
+ try {
+ parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions)
+ } catch (exception) {
+ throw new Error("Invalid JSON in the AIBadgrEmbedding's BaseOptions: " + exception)
}
}
+ obj.configuration = {
+ baseURL: this.baseURL,
+ defaultHeaders: parsedBaseOptions
+ }
+
const model = new OpenAIEmbeddings(obj)
return model
}
From f1c3adc7fe7a672deac30ad0750b64b365dc4de7 Mon Sep 17 00:00:00 2001
From: michaelmanley <55236695+michaelbrinkworth@users.noreply.github.com>
Date: Thu, 18 Dec 2025 19:27:41 +1000
Subject: [PATCH 5/5] gemini feedback
---
.../nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts | 2 +-
.../embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts | 9 +++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
index bddadafd543..d4655c02988 100644
--- a/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
+++ b/packages/components/nodes/chatmodels/ChatAIBadgr/ChatAIBadgr.ts
@@ -135,13 +135,13 @@ class ChatAIBadgr_ChatModels implements INode {
const cache = nodeData.inputs?.cache as BaseCache
const obj: ChatOpenAIFields = {
- temperature: parseFloat(temperature),
modelName,
openAIApiKey,
apiKey: openAIApiKey,
streaming: streaming ?? true
}
+ if (temperature) obj.temperature = parseFloat(temperature)
if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10)
if (topP) obj.topP = parseFloat(topP)
if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty)
diff --git a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
index c5cd946bc7b..289538ad868 100644
--- a/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
+++ b/packages/components/nodes/embeddings/AIBadgrEmbedding/AIBadgrEmbedding.ts
@@ -57,7 +57,8 @@ class AIBadgrEmbedding_Embeddings implements INode {
name: 'baseOptions',
type: 'json',
optional: true,
- additionalParams: true
+ additionalParams: true,
+ description: 'Additional options to pass to the AI Badgr client. This should be a JSON object.'
},
{
label: 'Model Name',
@@ -100,6 +101,10 @@ class AIBadgrEmbedding_Embeddings implements INode {
if (baseOptions) {
try {
parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions)
+ if (parsedBaseOptions.baseURL) {
+ console.warn("The 'baseURL' parameter is not allowed when using the AIBadgrEmbedding node.")
+ parsedBaseOptions.baseURL = undefined
+ }
} catch (exception) {
throw new Error("Invalid JSON in the AIBadgrEmbedding's BaseOptions: " + exception)
}
@@ -107,7 +112,7 @@ class AIBadgrEmbedding_Embeddings implements INode {
obj.configuration = {
baseURL: this.baseURL,
- defaultHeaders: parsedBaseOptions
+ ...(parsedBaseOptions ?? {})
}
const model = new OpenAIEmbeddings(obj)