From 92665b22ee6a7824b49e810783fc13e84faad7c5 Mon Sep 17 00:00:00 2001 From: Joseph McElroy Date: Mon, 12 Feb 2024 17:38:00 +0000 Subject: [PATCH] add server deps --- package.json | 3 +- .../routes/enterprise_search/ai_playground.ts | 86 ++++++++ .../server/routes/enterprise_search/index.ts | 2 + yarn.lock | 183 +++++++++++++++++- 4 files changed, 268 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/server/routes/enterprise_search/ai_playground.ts diff --git a/package.json b/package.json index 333cb86edde48..29b6fea038db8 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "@dnd-kit/core": "^3.1.1", "@dnd-kit/sortable": "^4.0.0", "@dnd-kit/utilities": "^2.0.0", + "@elastic/ai-assist": "0.0.8", "@elastic/apm-rum": "^5.16.0", "@elastic/apm-rum-react": "^2.0.2", "@elastic/charts": "63.0.0", @@ -1694,4 +1695,4 @@ "zod-to-json-schema": "^3.22.3" }, "packageManager": "yarn@1.22.21" -} \ No newline at end of file +} diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/ai_playground.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/ai_playground.ts new file mode 100644 index 0000000000000..b7d27881ae838 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/ai_playground.ts @@ -0,0 +1,86 @@ +import { RouteDependencies } from '../../plugin'; +import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler'; +import Assist, { ConversationalChain } from '@elastic/ai-assist'; +import { ChatOpenAI } from '@elastic/ai-assist/models'; +import { Prompt } from '@elastic/ai-assist'; +import { schema } from '@kbn/config-schema'; +import Stream from 'stream'; + +export function registerAIPlaygroundRoutes({ log, router }: RouteDependencies) { + router.post( + { + path: '/internal/enterprise_search/ai_playground/chat', + validate: { + body: schema.object({ + data: schema.any(), + messages: schema.any(), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + + const aiClient = Assist({ + es_client: client.asCurrentUser, + }); + + const { messages, data } = await request.body; + + const model = new ChatOpenAI({ + openAIApiKey: data.api_key, + }); + + const chain = ConversationalChain({ + model, + rag: { + index: data.indices, + retriever: (question: string) => { + return { + text_expansion: { + 'vector.tokens': { + model_id: '.elser_model_2', + model_text: question, + }, + }, + }; + }, + }, + prompt: Prompt(data.prompt, { + citations: true, + context: true, + type: 'openai', + }), + }); + + const stream = await chain.stream(aiClient, messages); + + const reader = (stream as ReadableStream).getReader(); + + class UIStream extends Stream.Readable { + _read() { + const that = this; + + function read() { + reader.read().then(({ done, value }: { done: boolean; value?: string }) => { + if (done) { + that.push(null); + return; + } + that.push(value); + read(); + }); + } + read(); + } + } + + return response.custom({ + body: new UIStream(), + statusCode: 200, + headers: { + 'Content-Type': 'text/plain; charset=utf-8', + }, + }); + }) + ); +} diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/index.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/index.ts index 36afbe64ff0ee..ae602334ef232 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/index.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/index.ts @@ -7,6 +7,7 @@ import { RouteDependencies } from '../../plugin'; +import { registerAIPlaygroundRoutes } from './ai_playground'; import { registerDocumentRoute } from './documents'; import { registerIndexRoutes } from './indices'; import { registerMappingRoute } from './mapping'; @@ -19,4 +20,5 @@ export const registerEnterpriseSearchRoutes = (dependencies: RouteDependencies) registerSearchRoute(dependencies); registerDocumentRoute(dependencies); registerSearchApplicationsRoutes(dependencies); + registerAIPlaygroundRoutes(dependencies); }; diff --git a/yarn.lock b/yarn.lock index da75092376854..6f25a33fb6ace 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1627,6 +1627,16 @@ dependencies: tslib "^2.0.0" +"@elastic/ai-assist@0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@elastic/ai-assist/-/ai-assist-0.0.7.tgz#a315cb167cc0a5013e119bb916a81694dc5d9154" + integrity sha512-SEzDsjm5/LNJGfZHSnVRVqY4wB/4L5vnwyid5zZNDXMvTGBuMBiH4AgfRTAKU0z0Qqdty1x99xcgEfQ5jx3EAQ== + dependencies: + "@elastic/elasticsearch" "^8.11.0" + "@langchain/community" "^0.0.20" + "@langchain/openai" "^0.0.12" + ai "^2.2.33" + "@elastic/apm-rum-core@^5.21.0": version "5.21.0" resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.21.0.tgz#0dc214b2c829c80a2cd07d37a250c89761fe8386" @@ -1711,6 +1721,14 @@ "@elastic/transport" "^8.3.1" tslib "^2.4.0" +"@elastic/elasticsearch@^8.11.0": + version "8.12.1" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.12.1.tgz#fd80ef7a4cb959832ae01623a428055f65ffa0e4" + integrity sha512-/dJtxtvoN2vRXip6xUrEyzthhzVUOKL8L9YNq25HpMwqiqrJTK70/dOp6GM8oTVQ87UPyJBiiCxQY2+cvg2XWw== + dependencies: + "@elastic/transport" "^8.4.0" + tslib "^2.4.0" + "@elastic/elasticsearch@npm:@elastic/elasticsearch-canary@8.9.1-canary.1": version "8.9.1-canary.1" resolved "https://registry.yarnpkg.com/@elastic/elasticsearch-canary/-/elasticsearch-canary-8.9.1-canary.1.tgz#7c1cdc6cc4129910544b2a3abd6a73b9fcc82ff3" @@ -1904,6 +1922,18 @@ tslib "^2.4.0" undici "^5.22.1" +"@elastic/transport@^8.4.0": + version "8.4.0" + resolved "https://registry.yarnpkg.com/@elastic/transport/-/transport-8.4.0.tgz#e1ec05f7a2857162c161e2c97008f9b21301a673" + integrity sha512-Yb3fDa7yGD0ca3uMbL64M3vM1cE5h5uHmBcTjkdB4VpCasRNKSd09iDpwqX8zX1tbBtxcaKYLceKthWvPeIxTw== + dependencies: + debug "^4.3.4" + hpagent "^1.0.0" + ms "^2.1.3" + secure-json-parse "^2.4.0" + tslib "^2.4.0" + undici "^5.22.1" + "@emotion/babel-plugin-jsx-pragmatic@^0.2.1": version "0.2.1" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin-jsx-pragmatic/-/babel-plugin-jsx-pragmatic-0.2.1.tgz#01d3306fde73b60d683f78f3bd9f6b2c919b63b6" @@ -6584,6 +6614,58 @@ resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== +"@langchain/community@^0.0.20": + version "0.0.20" + resolved "https://registry.yarnpkg.com/@langchain/community/-/community-0.0.20.tgz#a64307e959545fa0b4ed6b67d5aba3437cd76879" + integrity sha512-maPMjvF50Z+4eMs7HKmY3wfT+k6IjULqLUVPtVdN1zSGobRvnUIbQMKUY2IXVTZmaMXKBAIob+49X8vjO2snDQ== + dependencies: + "@langchain/core" "~0.1.16" + "@langchain/openai" "~0.0.10" + flat "^5.0.2" + langsmith "~0.0.48" + uuid "^9.0.0" + zod "^3.22.3" + +"@langchain/core@~0.1.13", "@langchain/core@~0.1.16": + version "0.1.24" + resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.1.24.tgz#e029a5641147ef0d9219750704e9f2c5d9b01aa3" + integrity sha512-MBsBMses4/6zUetPzZaw9FyRqCebvB+jqaZE+VNDK37wzW+W4hssxat6gyfFbqegOw2VUG64yy57velLbe8fCw== + dependencies: + ansi-styles "^5.0.0" + camelcase "6" + decamelize "1.2.0" + js-tiktoken "^1.0.8" + langsmith "~0.0.48" + ml-distance "^4.0.0" + p-queue "^6.6.2" + p-retry "4" + sax "^1.3.0" + uuid "^9.0.0" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + +"@langchain/openai@^0.0.12": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.0.12.tgz#4c6a4dda3ca96f103482f389299e018340aa2b75" + integrity sha512-MR9x1xRXwJpdYlVx9Tga89q/MvxPrSTYyA5vy9tQ8dfQHNWnlgmI4gB/hDIsWUu1ooScagD4wW+aTnohTX+g+g== + dependencies: + "@langchain/core" "~0.1.13" + js-tiktoken "^1.0.7" + openai "^4.24.2" + zod "^3.22.3" + zod-to-json-schema "3.20.3" + +"@langchain/openai@~0.0.10": + version "0.0.14" + resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.0.14.tgz#27a6ba83f6b754391868b22f3b90cd440038acf0" + integrity sha512-co6nRylPrLGY/C3JYxhHt6cxLq07P086O7K3QaZH7SFFErIN9wSzJonpvhZR07DEUq6eK6wKgh2ORxA/NcjSRQ== + dependencies: + "@langchain/core" "~0.1.13" + js-tiktoken "^1.0.7" + openai "^4.26.0" + zod "^3.22.4" + zod-to-json-schema "^3.22.3" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" @@ -11204,6 +11286,19 @@ aggregate-error@^3.0.0, aggregate-error@^3.1.0: clean-stack "^2.0.0" indent-string "^4.0.0" +ai@^2.2.33: + version "2.2.33" + resolved "https://registry.yarnpkg.com/ai/-/ai-2.2.33.tgz#cf81359812885d5583492edc1a622aa85be5dbf5" + integrity sha512-y9iMgt/RjFZCrjx5NuC+tdZqvunM9Bo1ufuC1BpgyjPmmE2RYduM+3Whjez0fu808KkwTQvvhUhhC5NkAy8/9g== + dependencies: + eventsource-parser "1.0.0" + nanoid "3.3.6" + solid-swr-store "0.10.7" + sswr "2.0.0" + swr "2.2.0" + swr-store "0.10.6" + swrv "1.0.4" + airbnb-js-shims@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" @@ -14829,10 +14924,10 @@ decamelize-keys@^1.1.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@1.2.0, decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== decamelize@^4.0.0: version "4.0.0" @@ -16654,6 +16749,11 @@ events@^3.0.0, events@^3.2.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +eventsource-parser@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-1.0.0.tgz#6332e37fd5512e3c8d9df05773b2bf9e152ccc04" + integrity sha512-9jgfSCa3dmEme2ES3mPByGXfgZ87VbP97tng1G2nWwWx6bV2nYxm2AWCrbQjXToSe+yYlqaZNtxffR9IeQr95g== + eventsource-parser@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-1.1.1.tgz#576f8bcf391c5e5ccdea817abd9ead36d1754247" @@ -20736,6 +20836,13 @@ js-tiktoken@^1.0.7: dependencies: base64-js "^1.5.1" +js-tiktoken@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/js-tiktoken/-/js-tiktoken-1.0.10.tgz#2b343ec169399dcee8f9ef9807dbd4fafd3b30dc" + integrity sha512-ZoSxbGjvGyMT13x6ACo9ebhDha/0FHdKA+OsQcMOWcm1Zs7r90Rhk5lhERLzji+3rA7EKpXCgwXcM5fF3DMpdA== + dependencies: + base64-js "^1.5.1" + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -23059,9 +23166,9 @@ nanoid@3.3.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== -nanoid@^3.3.1, nanoid@^3.3.6: +nanoid@3.3.6, nanoid@^3.3.1, nanoid@^3.3.6: version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== nanomatch@^1.2.9: @@ -23831,6 +23938,21 @@ openai@^4.17.0, openai@^4.24.1: node-fetch "^2.6.7" web-streams-polyfill "^3.2.1" +openai@^4.24.2, openai@^4.26.0: + version "4.26.1" + resolved "https://registry.yarnpkg.com/openai/-/openai-4.26.1.tgz#7b7c0225c09922445f68f3c4cdbd5775ed31108c" + integrity sha512-DvWbjhWbappsFRatOWmu4Dp1/Q4RG9oOz6CfOSjy0/Drb8G+5iAiqWAO4PfpGIkhOOKtvvNfQri2SItl+U7LhQ== + dependencies: + "@types/node" "^18.11.18" + "@types/node-fetch" "^2.6.4" + abort-controller "^3.0.0" + agentkeepalive "^4.2.1" + digest-fetch "^1.3.0" + form-data-encoder "1.7.2" + formdata-node "^4.3.2" + node-fetch "^2.6.7" + web-streams-polyfill "^3.2.1" + openapi-sampler@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/openapi-sampler/-/openapi-sampler-1.4.0.tgz#c133cad6250481f2ec7e48b16eb70062adb514c0" @@ -27485,6 +27607,11 @@ sax@>=0.6.0, sax@^1.2.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +sax@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + saxes@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" @@ -28153,6 +28280,11 @@ socks@^2.7.1: ip "^2.0.0" smart-buffer "^4.2.0" +solid-swr-store@0.10.7: + version "0.10.7" + resolved "https://registry.yarnpkg.com/solid-swr-store/-/solid-swr-store-0.10.7.tgz#9511308f01250a1509efbfaad5b481be7517e436" + integrity sha512-A6d68aJmRP471aWqKKPE2tpgOiR5fH4qXQNfKIec+Vap+MGQm3tvXlT8n0I8UgJSlNAsSAUuw2VTviH2h3Vv5g== + sonic-boom@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.3.0.tgz#5c77c846ce6c395dddf2eb8e8e65f9cc576f2e76" @@ -28487,6 +28619,13 @@ ssri@^8.0.1: dependencies: minipass "^3.1.1" +sswr@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sswr/-/sswr-2.0.0.tgz#db5e1f7c44addb8316de8e7efe23b7ea2cba090d" + integrity sha512-mV0kkeBHcjcb0M5NqKtKVg/uTIYNlIIniyDfSGrSfxpEdM9C365jK0z55pl9K0xAkNTJi2OAOVFQpgMPUk+V0w== + dependencies: + swrev "^4.0.0" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -29176,6 +29315,30 @@ swagger2openapi@^7.0.6: yaml "^1.10.0" yargs "^17.0.1" +swr-store@0.10.6: + version "0.10.6" + resolved "https://registry.yarnpkg.com/swr-store/-/swr-store-0.10.6.tgz#1856bda886e87dbed40c8c9874c1b1624d2e502d" + integrity sha512-xPjB1hARSiRaNNlUQvWSVrG5SirCjk2TmaUyzzvk69SZQan9hCJqw/5rG9iL7xElHU784GxRPISClq4488/XVw== + dependencies: + dequal "^2.0.3" + +swr@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.0.tgz#575c6ac1bec087847f4c86a39ccbc0043c834d6a" + integrity sha512-AjqHOv2lAhkuUdIiBu9xbuettzAzWXmCEcLONNKJRba87WAefz8Ca9d6ds/SzrPc235n1IxWYdhJ2zF3MNUaoQ== + dependencies: + use-sync-external-store "^1.2.0" + +swrev@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/swrev/-/swrev-4.0.0.tgz#83da6983c7ef9d71ac984a9b169fc197cbf18ff8" + integrity sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA== + +swrv@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/swrv/-/swrv-1.0.4.tgz#278b4811ed4acbb1ae46654972a482fd1847e480" + integrity sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g== + symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -32107,6 +32270,11 @@ zip-stream@^4.1.0: compress-commons "^4.1.0" readable-stream "^3.6.0" +zod-to-json-schema@3.20.3: + version "3.20.3" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.20.3.tgz#8c95d8c20f20455ffa0b4b526c29703f35f6d787" + integrity sha512-/Q3wnyxAfCt94ZcrGiXXoiAfRqasxl9CX64LZ9fj+4dKH68zulUtU0uk1WMxQPfAxQ0ZI70dKzcoW7hHj+DwSQ== + zod-to-json-schema@^3.20.4, zod-to-json-schema@^3.22.3: version "3.22.3" resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.22.3.tgz#1c71f9fa23f80b2f3b5eed537afa8a13a66a5200" @@ -32117,6 +32285,11 @@ zod@^3.22.3: resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.3.tgz#2fbc96118b174290d94e8896371c95629e87a060" integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug== +zod@^3.22.4: + version "3.22.4" + resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"