From 70d12fbc77617246d81d328b60ff604e2c019239 Mon Sep 17 00:00:00 2001 From: samuelghill Date: Wed, 18 Dec 2024 10:48:22 -0800 Subject: [PATCH] call endpoint via a langchain chatapp --- .../app/chatwxflows-0.1.0.tgz | Bin 0 -> 1892 bytes examples/rag-question-answer/app/package.json | 4 +- examples/rag-question-answer/app/src/App.jsx | 2 +- .../app/src/callWxflows.js | 31 +++++------ .../rag-question-answer/app/src/tools.tsx | 49 ++++++++++++++++++ 5 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 examples/rag-question-answer/app/chatwxflows-0.1.0.tgz create mode 100644 examples/rag-question-answer/app/src/tools.tsx diff --git a/examples/rag-question-answer/app/chatwxflows-0.1.0.tgz b/examples/rag-question-answer/app/chatwxflows-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..69247b6a057af3e7bd56e1debc9382ad1d334d15 GIT binary patch literal 1892 zcmV-q2b=gGiwFP!00002|LqyuZsWK$&;E+DM6r=ug_iG$Qg3GVQecYBOwpNQ3K&^0 zEgjoRDAGexPO@45dqGh*JK63-(*SAB7mMWKx$#`-HH&W85<79CO($ZU(`$Y7%p(Yb z(O>{itp`ES3x*>&>JLXjw>ugI12_u0-NASaN5Rnxj7%G*j)LGBgbacJs^3>KNTw0A zQAuRTdF#Xc8Y4qvTqFYjrsNuxx%cpHEtSzekl76NrHnI<#D@piFrHxuMr8=w_Iaz* zfj35HI^Z(jCpxRl<4adwDCkWU=lT)F#Tb zk!iGIrgP0UOh+nN8)u<8HhQheZ%|7_jCapQEyq?+WBOi1u*gJY5-GsC%B75vdu@1V z0RT7#ES`KFCLr*(!4Um!#mwh_{)Nk1?YSd%h!6&THA4}vWg<)n$17vjI_y}kX{Jw* zX>-D8GEb>Cxc&tN6=*uQcMFT~WQl?$)hxyZ%ed(*6q@Z*{QTPHVoAHuO_X&7=D zF>dkvsT%}A7!J-(NBwv>97cmP91McNcsv@+quwZpqv04&&-!QV?6f}|kMVRqjt22y zFvR|RK92CLd&c5|khO(cC7h?96SMkcuMQ@)hUh#IalYzJYb&7<<59+$k;?8}?VwU< zF|b>f?4qTK*vK37$mbO^kZ9<`AEDbLjl+^7<#OpM)WvG2Q((mn3iHt@WNC%H=2GVy zKUf&;O{Zj)rA!bX$U9&uFabaQcuB6V{K5=69oV4Ki4-A_O_%uP>b54kkg6c#H8=pd zXtL6-5!#U~z{_{31D;GKK%|&)p3YFjWDk5_?7x2e@ZO4&h-I?4cbI$-8RtIq+BIwW z^;ImlwylPtpSO+<<9}?d_w)Z}7eb!14EXo?zdP(b%K!af+&kp|m(TwjreHQpQk(C; zcR2(m;F(pT;p?x#{?fhuHvIZ)off@R#$_Z@XfoxN?BP_#w5}i8aA8*lINSArBuqT#R6%PdvX+JIkDuiB{xBVi)`d|;e zXDRxyVJcyBj(WFJNE=l`#Rx4_(I^lq)O$JnsZ^_@6{f68VmS%AM1hJK^!8J!yWJ+J zV#`9Hn!dwXQ?CT8Rw@B^S+W_+QMsToGwgy+%d=M(RA%Oa=2ZWVdM$;<3+kZtG`PB` zxQ=HA?@Xz>hFv`uYR9b0dB`<3D4CU#xA_JApp;bJ&u;~w{Q?<9nNk>s@P`M7di!&` z#I$X_()eH2yD!@R^#{H2qyBF+9v$NUtLy*DpxfwlU;-PN#1ND*H$|=468Ac^H=K!O zv|@?qL{ed=gt8TU-B`_Xr~aLzcABvz7Qmgx!3MUv(%HpEn?+C#&zaWHlnCz(idgS* zM89PkzpI)*7ej=L2xSC!GZ($xcNw(Ytcs&n-d>uinH`gtSpC7KGDfZL&BZ>yB3hS-&{0(8RGU`^pGpi&Dp*sfkG zz)C?iD}XlMixj6Sww3W#W}AGHlFFFznmkhoLK=Im z))Rk|k6mrjFB$5*pqV_yR*j(Wor2r4bnpUy*PrU5tL^QWi{CT~fA{kJJ*FCb7bd=| zkK%IeZH6#?C>alP71cq8zI}J;Cf-BE`L^wYP5oiLa^>$}=REz8nRRAteVS>EKgk=k zlnT$-*5KQw<<(Cbx%c{TbIa6n$K`Sirg#j=e{FRVXAycHiy}W?Ys2K5J%MxEk&@?y zxU(TUr6Tv7$pns_QvZJc)O`_`vCIke*JV%v?02z-|On^ z=`_`t{U1Gal=WZnORu#QFZ=%A4f@?j_1|#NJ=A|MF|5xJ>+~etbr}1^n4Q{M)ZL_RT+% z={KeJ*C=8XQGyL#_Nriu?5BYCY4@yTq`X+S)1~FpH2Fp5Lj2UHy*@q7*?Lti>|s1t z|6duf(Yb9WVj=(Q@jvKx`}^^K&^z@1FBJcYlG2cHN~mjn^Y~d#ikMNYxzK1dx$^7W eK!$Wodt`fXro%Xl!#IprH2wt(f1rW@CIA4a7Q)5= literal 0 HcmV?d00001 diff --git a/examples/rag-question-answer/app/package.json b/examples/rag-question-answer/app/package.json index c68ee3f..feb2712 100644 --- a/examples/rag-question-answer/app/package.json +++ b/examples/rag-question-answer/app/package.json @@ -10,13 +10,15 @@ "@carbon/react": "^1.37.0", "@graphql-tools/utils": "^10.1.3", "@vitejs/plugin-react": "^4.0.4", + "chatwxflows": "file:./chatwxflows-0.1.0.tgz", "graphql": "^16.8.1", "graphql-request": "^6.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "vite": "^4.4.9", "watzen": "^0.1.10", - "wxflows": "^0.1.0" + "wxflows": "^0.1.1", + "zod": "^3.24.1" }, "devDependencies": { "sass": "^1.66.1" diff --git a/examples/rag-question-answer/app/src/App.jsx b/examples/rag-question-answer/app/src/App.jsx index 4d47e66..334a065 100644 --- a/examples/rag-question-answer/app/src/App.jsx +++ b/examples/rag-question-answer/app/src/App.jsx @@ -22,7 +22,7 @@ function App() { throw new Error('Something went wrong') } } catch (e) { - console.error('Something went wrong') + console.error('Something went wrong', e) } finally { setIsLoading(false) } diff --git a/examples/rag-question-answer/app/src/callWxflows.js b/examples/rag-question-answer/app/src/callWxflows.js index 36ded23..9c227f2 100644 --- a/examples/rag-question-answer/app/src/callWxflows.js +++ b/examples/rag-question-answer/app/src/callWxflows.js @@ -1,34 +1,29 @@ -import wxflows from 'wxflows' +import { ChatWXFlows } from 'chatwxflows' +import { calculatorTool } from './tools'; export async function getAnswer(question) { - const model = new wxflows({ + const chatModel = new ChatWXFlows({ + n: 4, endpoint: import.meta.env.VITE_WXFLOWS_ENDPOINT, apikey: import.meta.env.VITE_WXFLOWS_APIKEY, - }) - - const schema = await model.generate() - - // Make sure these match your values in `wxflows.toml` - const flowName = 'myRag' - const collection = 'watsonxdocs' - - const result = await model.ragAnswer({ - schema, - flowName, + flowName: 'myRag', variables: { n: 5, - question, aiEngine: 'WATSONX', model: 'ibm/granite-13b-chat-v2', - collection, + collection: 'watsonxdocs', parameters: { max_new_tokens: 1000, temperature: 0.7, stop_sequences: ['\n\n'], }, searchEngine: 'GETTINGSTARTED', - }, - }) + } + }); + + const llmWithTools = chatModel.bindTools([calculatorTool]); - return result?.data?.[flowName]?.out?.modelResponse?.results[0]?.generated_text; + const res = await llmWithTools.invoke(question); + + return res.content } \ No newline at end of file diff --git a/examples/rag-question-answer/app/src/tools.tsx b/examples/rag-question-answer/app/src/tools.tsx new file mode 100644 index 0000000..6c6e1e3 --- /dev/null +++ b/examples/rag-question-answer/app/src/tools.tsx @@ -0,0 +1,49 @@ +import { tool } from "@langchain/core/tools"; +import { z } from "zod"; + +export const calculatorSchema = z.object({ + operation: z + .enum(["add", "subtract", "multiply", "divide"]) + .describe("The type of operation to execute."), + number1: z.number().describe("The first number to operate on."), + number2: z.number().describe("The second number to operate on."), +}); + +export const calculatorTool = tool(async ({ operation, number1, number2 }) => { + if (operation === "add") { + return `${number1 + number2}`; + } else if (operation === "subtract") { + return `${number1 - number2}`; + } else if (operation === "multiply") { + return `${number1 * number2}`; + } else if (operation === "divide") { + return `${number1 / number2}`; + } else { + throw new Error("Invalid operation."); + } + }, { + name: "calculator", + description: "Can perform mathematical operations.", + schema: calculatorSchema, + }); + + +export const getCalculatorToolML = async (calculatorTool: any, userMessage: string, operation: string) => { + // Extract operation and numbers using a regex + const match = userMessage.match(/What is (\d+) \* (\d+)/); + if (!match) { + throw new Error("Could not parse the question."); + } + + const number1 = parseFloat(match[1]); + const number2 = parseFloat(match[2]); + + // Invoke the calculator tool + const result = await calculatorTool.invoke({ + operation, + number1, + number2, + }); + + return `The result of ${number1} * ${number2} is ${result}.`; +} \ No newline at end of file