From f85c9359839a133e0a56ce8a404401a0fef795e0 Mon Sep 17 00:00:00 2001 From: vinodkiran Date: Wed, 20 Sep 2023 14:31:52 +0530 Subject: [PATCH 1/2] Adding support for LLMonitor --- .../credentials/LLMonitorApi.credential.ts | 33 ++++++++++++++++++ .../nodes/analytic/LLMonitor/LLMonitor.ts | 33 ++++++++++++++++++ .../nodes/analytic/LLMonitor/llmonitor.png | Bin 0 -> 1726 bytes packages/components/package.json | 1 + packages/components/src/handler.ts | 18 +++++++--- packages/ui/src/assets/images/llmonitor.png | Bin 0 -> 1726 bytes .../ui-component/dialog/AnalyseFlowDialog.js | 21 +++++++++++ 7 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 packages/components/credentials/LLMonitorApi.credential.ts create mode 100644 packages/components/nodes/analytic/LLMonitor/LLMonitor.ts create mode 100644 packages/components/nodes/analytic/LLMonitor/llmonitor.png create mode 100644 packages/ui/src/assets/images/llmonitor.png diff --git a/packages/components/credentials/LLMonitorApi.credential.ts b/packages/components/credentials/LLMonitorApi.credential.ts new file mode 100644 index 000000000..97b195ec5 --- /dev/null +++ b/packages/components/credentials/LLMonitorApi.credential.ts @@ -0,0 +1,33 @@ +import { INodeParams, INodeCredential } from '../src/Interface' + +class LLMonitorApi implements INodeCredential { + label: string + name: string + version: number + description: string + inputs: INodeParams[] + + constructor() { + this.label = 'LLMonitor API' + this.name = 'llmonitorApi' + this.version = 1.0 + this.description = + 'Refer to official guide on how to get API key on Langsmith' + this.inputs = [ + { + label: 'APP ID', + name: 'llmonitorAppId', + type: 'password', + placeholder: '' + }, + { + label: 'Endpoint', + name: 'llmonitorEndpoint', + type: 'string', + default: 'https://app.llmonitor.com' + } + ] + } +} + +module.exports = { credClass: LLMonitorApi } diff --git a/packages/components/nodes/analytic/LLMonitor/LLMonitor.ts b/packages/components/nodes/analytic/LLMonitor/LLMonitor.ts new file mode 100644 index 000000000..a1ae317c4 --- /dev/null +++ b/packages/components/nodes/analytic/LLMonitor/LLMonitor.ts @@ -0,0 +1,33 @@ +import { INode, INodeParams } from '../../../src/Interface' + +class LLMonitor_Analytic implements INode { + label: string + name: string + version: number + description: string + type: string + icon: string + category: string + baseClasses: string[] + inputs?: INodeParams[] + credential: INodeParams + + constructor() { + this.label = 'LLMonitor' + this.name = 'llmonitor' + this.version = 1.0 + this.type = 'LLMonitor' + this.icon = 'llmonitor.png' + this.category = 'Analytic' + this.baseClasses = [this.type] + this.inputs = [] + this.credential = { + label: 'Connect Credential', + name: 'credential', + type: 'credential', + credentialNames: ['llmonitorApi'] + } + } +} + +module.exports = { nodeClass: LLMonitor_Analytic } diff --git a/packages/components/nodes/analytic/LLMonitor/llmonitor.png b/packages/components/nodes/analytic/LLMonitor/llmonitor.png new file mode 100644 index 0000000000000000000000000000000000000000..d50a704431d724fa02aae7e24a58f68600e802d8 GIT binary patch literal 1726 zcmV;v20{6WP)$hw(%WbFxUp$fMGFUHU%~`3A7A69(!ggFdoMC__nGxJn%iu z`RAPfd~^PDzW+bN`T9qn0v8F;=S`p#mxOBJl29#NI6|DK9|?h-a!H3ws1Wd*5Dq|5 zNjw`(XI$~5H<6;A86gk=MzyM!jjcnPW*!G-?UTZ@4+GIpU3(jmM8p0Y62>vT`r890 zy+l}Ne|seHrxm9?ivIrzi4e|@uUSU4%KBZ?xWB#ohvlstSyveA3YkvQbZdM_BN8x; z;UjD@5ZR2Pfn+*`XJHT&A>4MU@QO+{s#QvO2;K9wZkdIJ3XTXfj2D1>lPy|E!#2l=FAdKkkv-@UY{zr3b~x$ygJg^EP)to zVrlH%&z2ttWA(5B0Dz)^)o|PyJG`b-ai9}ciY9)ufcG#Etul&T7$;4w$|in^an>91 zBvN&RUX)2w+tt?Qh6!oKP31)H<8eB0Vxg%JBGi(`1XF`CXWn>-l$MxWvJE}fXirHu&;zvuAXbNEUQ`9JKQF}>O( z7Xtubkcmdxl#6@pfn#5xX;%=-=9rcoNq({upqpwT|F>Tmy90+{9TUTI1 zy*FoDDhR=>H?$at{^X1O`R3Pp+Diy+L=tZno;&4YRzeNeL%m9=5INg7)9$^cVp*E= zg%r9R&BztwNbf6Y5DS?4_aE1?4rI63xXdNtki zpPOE$PYI7}R!DJz*o>l85BhLtlkTH^<8_B>$`UEm`>dx6XiKg7&H?GO^FA4 zG;!a#OE+KZ(thWv899x9{5bQ${A#7TmOW%~40jaj^Uh{Tk3!0PixcE8W}kQ~XMRT% zeSgkIXS2Z;`45JBk-}b-3wSrjt&-xLLxa5@IuSjJdR}+7{#r@Xv^&Uro6Zu`t{_g3 z?NSk+kp!Y??4woJhmRZ>L)oXST_qb4f#KM3W-E4BK5s>(p7Vy@>Nn+uq)#P#!>s>! zt4MaUBzb4UbJy-Q$wg|RfI2x-X-}NxMkW&=<^Gid9_zdng^{4BKiiyi^KEOFMI|fm zMpBgXAo;)_Uhs$AY-|7k2qsw$zq>-jt10!oFTAjOmIt^n^wV+cK#ROee^v~r!Eag&KN_|0IOm^@6U2Xa zBfnc%PZ!r)G-_WI6$0LSlh0{H=k==(J^K5)Yr!8OD0X5n2tKb@-LM#$dpVRk{`tR` zLn(}`Fsfccrw0|eH9pjNT7c3(F??|^>Nve9CNP|$C@CM&NrYFF(qXMq$}8H)?s)Q- zvn#RVOwGCKy-Fi6^!+dNyke?YdRD=VJNV(F&Fa^&h6&}-ua-|)JI%#9Sp{3M!`n8e zEflYRipB`#VNuH_jcp@Zr5IsX+a#V{3`A$#!L@J$RPuP5A6Dz(#CkXZ0)SpBG|I$k z5uXR2h;=4MMADcmp7f(f&+dm64eIo`Jw<_09T)B&<0YY5xFl2y7mm>X0ssL2|JvM= Uk^cbmzW@LL07*qoM6N<$f_vUR-2eap literal 0 HcmV?d00001 diff --git a/packages/components/package.json b/packages/components/package.json index a69b8f262..2512104e1 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -46,6 +46,7 @@ "langfuse-langchain": "^1.0.14-alpha.0", "langsmith": "^0.0.32", "linkifyjs": "^4.1.1", + "llmonitor": "^0.5.5", "mammoth": "^1.5.1", "moment": "^2.29.3", "mysql2": "^3.5.1", diff --git a/packages/components/src/handler.ts b/packages/components/src/handler.ts index f13719ce6..10f9a2141 100644 --- a/packages/components/src/handler.ts +++ b/packages/components/src/handler.ts @@ -4,6 +4,7 @@ import { Logger } from 'winston' import { Server } from 'socket.io' import { Client } from 'langsmith' import { LangChainTracer } from 'langchain/callbacks' +import { LLMonitorHandler } from 'langchain/callbacks/handlers/llmonitor' import { getCredentialData, getCredentialParam } from './utils' import { ICommonObject, INodeData } from './Interface' import CallbackHandler from 'langfuse-langchain' @@ -194,11 +195,11 @@ export const additionalCallbacks = async (nodeData: INodeData, options: ICommonO for (const provider in analytic) { const providerStatus = analytic[provider].status as boolean if (providerStatus) { + const credentialId = analytic[provider].credentialId as string + const credentialData = await getCredentialData(credentialId ?? '', options) if (provider === 'langSmith') { - const credentialId = analytic[provider].credentialId as string const langSmithProject = analytic[provider].projectName as string - const credentialData = await getCredentialData(credentialId ?? '', options) const langSmithApiKey = getCredentialParam('langSmithApiKey', credentialData, nodeData) const langSmithEndpoint = getCredentialParam('langSmithEndpoint', credentialData, nodeData) @@ -214,13 +215,11 @@ export const additionalCallbacks = async (nodeData: INodeData, options: ICommonO }) callbacks.push(tracer) } else if (provider === 'langFuse') { - const credentialId = analytic[provider].credentialId as string const flushAt = analytic[provider].flushAt as string const flushInterval = analytic[provider].flushInterval as string const requestTimeout = analytic[provider].requestTimeout as string const release = analytic[provider].release as string - const credentialData = await getCredentialData(credentialId ?? '', options) const langFuseSecretKey = getCredentialParam('langFuseSecretKey', credentialData, nodeData) const langFusePublicKey = getCredentialParam('langFusePublicKey', credentialData, nodeData) const langFuseEndpoint = getCredentialParam('langFuseEndpoint', credentialData, nodeData) @@ -237,6 +236,17 @@ export const additionalCallbacks = async (nodeData: INodeData, options: ICommonO const handler = new CallbackHandler(langFuseOptions) callbacks.push(handler) + } else if (provider === 'llmonitor') { + const llmonitorAppId = getCredentialParam('llmonitorAppId', credentialData, nodeData) + const llmonitorEndpoint = getCredentialParam('llmonitorEndpoint', credentialData, nodeData) + + const llmonitorFields: ICommonObject = { + appId: llmonitorAppId, + apiUrl: llmonitorEndpoint ?? 'https://app.llmonitor.com' + } + + const handler = new LLMonitorHandler(llmonitorFields) + callbacks.push(handler) } } } diff --git a/packages/ui/src/assets/images/llmonitor.png b/packages/ui/src/assets/images/llmonitor.png new file mode 100644 index 0000000000000000000000000000000000000000..d50a704431d724fa02aae7e24a58f68600e802d8 GIT binary patch literal 1726 zcmV;v20{6WP)$hw(%WbFxUp$fMGFUHU%~`3A7A69(!ggFdoMC__nGxJn%iu z`RAPfd~^PDzW+bN`T9qn0v8F;=S`p#mxOBJl29#NI6|DK9|?h-a!H3ws1Wd*5Dq|5 zNjw`(XI$~5H<6;A86gk=MzyM!jjcnPW*!G-?UTZ@4+GIpU3(jmM8p0Y62>vT`r890 zy+l}Ne|seHrxm9?ivIrzi4e|@uUSU4%KBZ?xWB#ohvlstSyveA3YkvQbZdM_BN8x; z;UjD@5ZR2Pfn+*`XJHT&A>4MU@QO+{s#QvO2;K9wZkdIJ3XTXfj2D1>lPy|E!#2l=FAdKkkv-@UY{zr3b~x$ygJg^EP)to zVrlH%&z2ttWA(5B0Dz)^)o|PyJG`b-ai9}ciY9)ufcG#Etul&T7$;4w$|in^an>91 zBvN&RUX)2w+tt?Qh6!oKP31)H<8eB0Vxg%JBGi(`1XF`CXWn>-l$MxWvJE}fXirHu&;zvuAXbNEUQ`9JKQF}>O( z7Xtubkcmdxl#6@pfn#5xX;%=-=9rcoNq({upqpwT|F>Tmy90+{9TUTI1 zy*FoDDhR=>H?$at{^X1O`R3Pp+Diy+L=tZno;&4YRzeNeL%m9=5INg7)9$^cVp*E= zg%r9R&BztwNbf6Y5DS?4_aE1?4rI63xXdNtki zpPOE$PYI7}R!DJz*o>l85BhLtlkTH^<8_B>$`UEm`>dx6XiKg7&H?GO^FA4 zG;!a#OE+KZ(thWv899x9{5bQ${A#7TmOW%~40jaj^Uh{Tk3!0PixcE8W}kQ~XMRT% zeSgkIXS2Z;`45JBk-}b-3wSrjt&-xLLxa5@IuSjJdR}+7{#r@Xv^&Uro6Zu`t{_g3 z?NSk+kp!Y??4woJhmRZ>L)oXST_qb4f#KM3W-E4BK5s>(p7Vy@>Nn+uq)#P#!>s>! zt4MaUBzb4UbJy-Q$wg|RfI2x-X-}NxMkW&=<^Gid9_zdng^{4BKiiyi^KEOFMI|fm zMpBgXAo;)_Uhs$AY-|7k2qsw$zq>-jt10!oFTAjOmIt^n^wV+cK#ROee^v~r!Eag&KN_|0IOm^@6U2Xa zBfnc%PZ!r)G-_WI6$0LSlh0{H=k==(J^K5)Yr!8OD0X5n2tKb@-LM#$dpVRk{`tR` zLn(}`Fsfccrw0|eH9pjNT7c3(F??|^>Nve9CNP|$C@CM&NrYFF(qXMq$}8H)?s)Q- zvn#RVOwGCKy-Fi6^!+dNyke?YdRD=VJNV(F&Fa^&h6&}-ua-|)JI%#9Sp{3M!`n8e zEflYRipB`#VNuH_jcp@Zr5IsX+a#V{3`A$#!L@J$RPuP5A6Dz(#CkXZ0)SpBG|I$k z5uXR2h;=4MMADcmp7f(f&+dm64eIo`Jw<_09T)B&<0YY5xFl2y7mm>X0ssL2|JvM= Uk^cbmzW@LL07*qoM6N<$f_vUR-2eap literal 0 HcmV?d00001 diff --git a/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js b/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js index 1ed68fb58..2d9a7d91f 100644 --- a/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js +++ b/packages/ui/src/ui-component/dialog/AnalyseFlowDialog.js @@ -31,6 +31,7 @@ import { Input } from 'ui-component/input/Input' import { StyledButton } from 'ui-component/button/StyledButton' import langsmithPNG from 'assets/images/langchain.png' import langfusePNG from 'assets/images/langfuse.png' +import llmonitorPNG from 'assets/images/llmonitor.png' // store import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions' @@ -115,6 +116,26 @@ const analyticProviders = [ optional: true } ] + }, + { + label: 'LLMonitor', + name: 'llmonitor', + icon: llmonitorPNG, + url: 'https://llmonitor.com', + inputs: [ + { + label: 'Connect Credential', + name: 'credential', + type: 'credential', + credentialNames: ['llmonitorApi'] + }, + { + label: 'On/Off', + name: 'status', + type: 'boolean', + optional: true + } + ] } ] From e312c6ee2256124f1669fd1a68cd443ecfd77bf4 Mon Sep 17 00:00:00 2001 From: vinodkiran Date: Thu, 21 Sep 2023 08:35:19 +0530 Subject: [PATCH 2/2] Fix: Incorrect documentation link for LLMonitor. --- packages/components/credentials/LLMonitorApi.credential.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/components/credentials/LLMonitorApi.credential.ts b/packages/components/credentials/LLMonitorApi.credential.ts index 97b195ec5..e5ecc8aba 100644 --- a/packages/components/credentials/LLMonitorApi.credential.ts +++ b/packages/components/credentials/LLMonitorApi.credential.ts @@ -11,8 +11,7 @@ class LLMonitorApi implements INodeCredential { this.label = 'LLMonitor API' this.name = 'llmonitorApi' this.version = 1.0 - this.description = - 'Refer to official guide on how to get API key on Langsmith' + this.description = 'Refer to official guide to get APP ID' this.inputs = [ { label: 'APP ID',