From 15cf921616bed2b0f711a39d2c4b9dcc1b8f59d3 Mon Sep 17 00:00:00 2001 From: Timothy Carambat <rambat1010@gmail.com> Date: Thu, 16 May 2024 10:38:21 -0700 Subject: [PATCH] Support SQL Agent skill (#1411) * Support SQL Agent skill * add MSSQL agent connector * Add frontend to agent skills remove FAKE_DB mock reset skills to pickup child-skill dynamically * add prompt examples for tools on untooled * add better logging on SQL agents * Wipe toolruns on each chat relay so tools can be used within the same session * update comments --- .../SQLConnectorSelection/DBConnection.jsx | 47 ++ .../NewConnectionModal.jsx | 271 +++++++++++ .../SQLConnectorSelection/icons/mssql.png | Bin 0 -> 38612 bytes .../SQLConnectorSelection/icons/mysql.png | Bin 0 -> 12971 bytes .../icons/postgresql.png | Bin 0 -> 47152 bytes .../SQLConnectorSelection/index.jsx | 109 +++++ .../WorkspaceSettings/AgentConfig/index.jsx | 7 + server/endpoints/admin.js | 2 + server/models/systemSettings.js | 112 ++++- server/package.json | 4 + server/utils/agents/aibitat/index.js | 13 +- server/utils/agents/aibitat/plugins/index.js | 3 + .../plugins/sql-agent/SQLConnectors/MSSQL.js | 89 ++++ .../plugins/sql-agent/SQLConnectors/MySQL.js | 59 +++ .../sql-agent/SQLConnectors/Postgresql.js | 52 +++ .../plugins/sql-agent/SQLConnectors/index.js | 60 +++ .../plugins/sql-agent/get-table-schema.js | 98 ++++ .../agents/aibitat/plugins/sql-agent/index.js | 21 + .../plugins/sql-agent/list-database.js | 49 ++ .../aibitat/plugins/sql-agent/list-table.js | 85 ++++ .../agents/aibitat/plugins/sql-agent/query.js | 101 ++++ .../utils/agents/aibitat/plugins/websocket.js | 2 +- .../agents/aibitat/providers/anthropic.js | 2 +- .../utils/agents/aibitat/providers/azure.js | 7 +- .../agents/aibitat/providers/genericOpenAi.js | 6 +- server/utils/agents/aibitat/providers/groq.js | 2 +- .../agents/aibitat/providers/koboldcpp.js | 6 +- .../agents/aibitat/providers/lmstudio.js | 6 +- .../utils/agents/aibitat/providers/localai.js | 6 +- .../utils/agents/aibitat/providers/mistral.js | 6 +- .../utils/agents/aibitat/providers/ollama.js | 6 +- .../utils/agents/aibitat/providers/openai.js | 2 +- .../agents/aibitat/providers/openrouter.js | 6 +- .../agents/aibitat/providers/perplexity.js | 6 +- .../agents/aibitat/providers/textgenwebui.js | 6 +- .../agents/aibitat/providers/togetherai.js | 6 +- server/utils/agents/aibitat/utils/dedupe.js | 19 + server/utils/agents/defaults.js | 14 + server/utils/agents/index.js | 72 ++- server/yarn.lock | 442 +++++++++++++++++- 40 files changed, 1745 insertions(+), 59 deletions(-) create mode 100644 frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/DBConnection.jsx create mode 100644 frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/NewConnectionModal.jsx create mode 100644 frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/mssql.png create mode 100644 frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/mysql.png create mode 100644 frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/postgresql.png create mode 100644 frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/index.jsx create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MSSQL.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MySQL.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/Postgresql.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/get-table-schema.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/index.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/list-database.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/list-table.js create mode 100644 server/utils/agents/aibitat/plugins/sql-agent/query.js diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/DBConnection.jsx b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/DBConnection.jsx new file mode 100644 index 000000000..7a58da454 --- /dev/null +++ b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/DBConnection.jsx @@ -0,0 +1,47 @@ +import PostgreSQLLogo from "./icons/postgresql.png"; +import MySQLLogo from "./icons/mysql.png"; +import MSSQLLogo from "./icons/mssql.png"; +import { X } from "@phosphor-icons/react"; + +export const DB_LOGOS = { + postgresql: PostgreSQLLogo, + mysql: MySQLLogo, + "sql-server": MSSQLLogo, +}; + +export default function DBConnection({ connection, onRemove }) { + const { database_id, engine } = connection; + function removeConfirmation() { + if ( + !window.confirm( + `Delete ${database_id} from the list of available SQL connections? This cannot be undone.` + ) + ) { + return false; + } + onRemove(database_id); + } + + return ( + <div className="flex gap-x-4 items-center"> + <img + src={DB_LOGOS?.[engine] ?? null} + alt={`${engine} logo`} + className="w-10 h-10 rounded-md" + /> + <div className="flex w-full items-center justify-between"> + <div className="flex flex-col"> + <div className="text-sm font-semibold text-white">{database_id}</div> + <div className="mt-1 text-xs text-[#D2D5DB]">{engine}</div> + </div> + <button + type="button" + onClick={removeConfirmation} + className="border-none text-white/40 hover:text-red-500" + > + <X size={24} /> + </button> + </div> + </div> + ); +} diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/NewConnectionModal.jsx b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/NewConnectionModal.jsx new file mode 100644 index 000000000..e76b27cce --- /dev/null +++ b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/NewConnectionModal.jsx @@ -0,0 +1,271 @@ +import { useState } from "react"; +import { createPortal } from "react-dom"; +import ModalWrapper from "@/components/ModalWrapper"; +import { WarningOctagon, X } from "@phosphor-icons/react"; +import { DB_LOGOS } from "./DBConnection"; + +function assembleConnectionString({ + engine, + username = "", + password = "", + host = "", + port = "", + database = "", +}) { + if ([username, password, host, database].every((i) => !!i) === false) + return `Please fill out all the fields above.`; + switch (engine) { + case "postgresql": + return `postgres://${username}:${password}@${host}:${port}/${database}`; + case "mysql": + return `mysql://${username}:${password}@${host}:${port}/${database}`; + case "sql-server": + return `mssql://${username}:${password}@${host}:${port}/${database}`; + default: + return null; + } +} + +const DEFAULT_ENGINE = "postgresql"; +const DEFAULT_CONFIG = { + username: null, + password: null, + host: null, + port: null, + database: null, +}; + +export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { + const [engine, setEngine] = useState(DEFAULT_ENGINE); + const [config, setConfig] = useState(DEFAULT_CONFIG); + if (!isOpen) return null; + + function handleClose() { + setEngine(DEFAULT_ENGINE); + setConfig(DEFAULT_CONFIG); + closeModal(); + } + + function onFormChange() { + const form = new FormData(document.getElementById("sql-connection-form")); + setConfig({ + username: form.get("username").trim(), + password: form.get("password"), + host: form.get("host").trim(), + port: form.get("port").trim(), + database: form.get("database").trim(), + }); + } + + async function handleUpdate(e) { + e.preventDefault(); + e.stopPropagation(); + const form = new FormData(e.target); + onSubmit({ + engine, + database_id: form.get("name"), + connectionString: assembleConnectionString({ engine, ...config }), + }); + handleClose(); + return false; + } + + // Cannot do nested forms, it will cause all sorts of issues, so we portal this out + // to the parent container form so we don't have nested forms. + return createPortal( + <ModalWrapper isOpen={isOpen}> + <div className="relative w-1/3 max-h-full "> + <div className="relative bg-main-gradient rounded-xl shadow-[0_4px_14px_rgba(0,0,0,0.25)] max-h-[90vh] overflow-y-scroll no-scroll"> + <div className="flex items-start justify-between p-4 border-b rounded-t border-gray-500/50"> + <h3 className="text-xl font-semibold text-white"> + New SQL Connection + </h3> + <button + onClick={handleClose} + type="button" + className="border-none transition-all duration-300 text-gray-400 bg-transparent hover:border-white/60 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border" + data-modal-hide="staticModal" + > + <X className="text-gray-300 text-lg" /> + </button> + </div> + + <form + id="sql-connection-form" + onSubmit={handleUpdate} + onChange={onFormChange} + > + <div className="py-[17px] px-[20px] flex flex-col gap-y-6"> + <p className="text-sm text-white"> + Add the connection information for your database below and it + will be available for future SQL agent calls. + </p> + <div className="flex flex-col w-full"> + <div className="border border-red-800 bg-zinc-800 p-4 rounded-lg flex items-center gap-x-2 text-sm text-red-400"> + <WarningOctagon size={28} className="shrink-0" /> + <p> + <b>WARNING:</b> The SQL agent has been <i>instructed</i> to + only perform non-modifying queries. This <b>does not</b>{" "} + prevent a hallucination from still deleting data. Only + connect with a user who has <b>READ_ONLY</b> permissions. + </p> + </div> + + <label className="text-white text-sm font-semibold block my-4"> + Select your SQL engine + </label> + <div className="flex w-full flex-wrap gap-x-4"> + <DBEngine + provider="postgresql" + active={engine === "postgresql"} + onClick={() => setEngine("postgresql")} + /> + <DBEngine + provider="mysql" + active={engine === "mysql"} + onClick={() => setEngine("mysql")} + /> + <DBEngine + provider="sql-server" + active={engine === "sql-server"} + onClick={() => setEngine("sql-server")} + /> + </div> + </div> + + <div className="flex flex-col w-full"> + <label className="text-white text-sm font-semibold block mb-4"> + Connection name + </label> + <input + type="text" + name="name" + className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5" + placeholder="a unique name to identify this SQL connection" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + + <div className="flex gap-x-2"> + <div className="flex flex-col w-60"> + <label className="text-white text-sm font-semibold block mb-4"> + Database user + </label> + <input + type="text" + name="username" + className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5" + placeholder="root" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + <div className="flex flex-col w-60"> + <label className="text-white text-sm font-semibold block mb-4"> + Database user password + </label> + <input + type="text" + name="password" + className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5" + placeholder="password123" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + </div> + + <div className="flex gap-x-2"> + <div className="flex flex-col w-full"> + <label className="text-white text-sm font-semibold block mb-4"> + Server endpoint + </label> + <input + type="text" + name="host" + className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5" + placeholder="the hostname or endpoint for your database" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + <div className="flex flex-col w-30"> + <label className="text-white text-sm font-semibold block mb-4"> + Port + </label> + <input + type="text" + name="port" + className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5" + placeholder="3306" + required={false} + autoComplete="off" + spellCheck={false} + /> + </div> + </div> + + <div className="flex flex-col w-60"> + <label className="text-white text-sm font-semibold block mb-4"> + Database + </label> + <input + type="text" + name="database" + className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5" + placeholder="the database the agent will interact with" + required={true} + autoComplete="off" + spellCheck={false} + /> + </div> + <p className="text-white/40 text-sm"> + {assembleConnectionString({ engine, ...config })} + </p> + </div> + <div className="flex w-full justify-between items-center p-3 space-x-2 border-t rounded-b border-gray-500/50"> + <button + type="button" + onClick={handleClose} + className="border-none text-xs px-2 py-1 font-semibold rounded-lg bg-white hover:bg-transparent border-2 border-transparent hover:border-white hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]" + > + Cancel + </button> + <button + type="submit" + form="sql-connection-form" + className="border-none text-xs px-2 py-1 font-semibold rounded-lg bg-[#46C8FF] hover:bg-[#2C2F36] border-2 border-transparent hover:border-[#46C8FF] hover:text-white h-[32px] w-fit -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]" + > + Save connection + </button> + </div> + </form> + </div> + </div> + </ModalWrapper>, + document.getElementById("workspace-agent-settings-container") + ); +} + +function DBEngine({ provider, active, onClick }) { + return ( + <button + type="button" + onClick={onClick} + className={`flex flex-col p-4 border border-white/40 bg-zinc-800 rounded-lg w-fit hover:bg-zinc-700 ${ + active ? "!bg-blue-500/50" : "" + }`} + > + <img + src={DB_LOGOS[provider]} + className="h-[100px] rounded-md" + alt="PostgreSQL" + /> + </button> + ); +} diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/mssql.png b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/mssql.png new file mode 100644 index 0000000000000000000000000000000000000000..7bd58a9a3eac3327f9f9703a081b79274fc8ee62 GIT binary patch literal 38612 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 literal 0 HcmV?d00001 diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/mysql.png b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/mysql.png new file mode 100644 index 0000000000000000000000000000000000000000..5a440811548774bb7554a38ccfd82a300d1037fd GIT binary patch literal 12971 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 K;$@=x{{Id8SL%WQ literal 0 HcmV?d00001 diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/postgresql.png b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/icons/postgresql.png new file mode 100644 index 0000000000000000000000000000000000000000..67918df7a77905a065d286802efe3055969ec266 GIT binary patch literal 47152 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 E11Pf9Pyhe` literal 0 HcmV?d00001 diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/index.jsx b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/index.jsx new file mode 100644 index 000000000..9feb4b8bb --- /dev/null +++ b/frontend/src/pages/WorkspaceSettings/AgentConfig/SQLConnectorSelection/index.jsx @@ -0,0 +1,109 @@ +import React, { useState } from "react"; +import DBConnection from "./DBConnection"; +import { Plus } from "@phosphor-icons/react"; +import NewSQLConnection from "./NewConnectionModal"; +import { useModal } from "@/hooks/useModal"; + +export default function AgentSQLConnectorSelection({ + skill, + settings, + toggleSkill, + enabled = false, +}) { + const { isOpen, openModal, closeModal } = useModal(); + const [connections, setConnections] = useState( + settings?.preferences?.agent_sql_connections || [] + ); + + return ( + <> + <div className="border-b border-white/40 pb-4"> + <div className="flex flex-col"> + <div className="flex w-full justify-between items-center"> + <label htmlFor="name" className="block input-label"> + SQL Agent + </label> + <label className="border-none relative inline-flex cursor-pointer items-center mt-2"> + <input + type="checkbox" + className="peer sr-only" + checked={enabled} + onClick={() => toggleSkill(skill)} + /> + <div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-lime-300 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div> + <span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300"></span> + </label> + </div> + <p className="text-white text-opacity-60 text-xs font-medium py-1.5"> + Enable your agent to be able to leverage SQL to answer you questions + by connecting to various SQL database providers. + </p> + </div> + {enabled && ( + <> + <input + name="system::agent_sql_connections" + type="hidden" + value={JSON.stringify(connections)} + /> + <input + type="hidden" + value={JSON.stringify( + connections.filter((conn) => conn.action !== "remove") + )} + /> + <div className="flex flex-col mt-2 gap-y-2"> + <p className="text-white font-semibold text-sm"> + Your database connections + </p> + <div className="flex flex-col gap-y-3"> + {connections + .filter((connection) => connection.action !== "remove") + .map((connection) => ( + <DBConnection + key={connection.database_id} + connection={connection} + onRemove={(databaseId) => { + setConnections((prev) => + prev.map((conn) => { + if (conn.database_id === databaseId) + return { ...conn, action: "remove" }; + return conn; + }) + ); + }} + /> + ))} + <button + type="button" + onClick={openModal} + className="w-fit relative flex h-[40px] items-center border-none hover:bg-slate-600/20 rounded-lg" + > + <div className="flex w-full gap-x-2 items-center p-4"> + <div className="bg-zinc-600 p-2 rounded-lg h-[24px] w-[24px] flex items-center justify-center"> + <Plus + weight="bold" + size={14} + className="shrink-0 text-slate-100" + /> + </div> + <p className="text-left text-slate-100 text-sm"> + New SQL connection + </p> + </div> + </button> + </div> + </div> + </> + )} + </div> + <NewSQLConnection + isOpen={isOpen} + closeModal={closeModal} + onSubmit={(newDb) => + setConnections((prev) => [...prev, { action: "add", ...newDb }]) + } + /> + </> + ); +} diff --git a/frontend/src/pages/WorkspaceSettings/AgentConfig/index.jsx b/frontend/src/pages/WorkspaceSettings/AgentConfig/index.jsx index c96cc1246..02065251a 100644 --- a/frontend/src/pages/WorkspaceSettings/AgentConfig/index.jsx +++ b/frontend/src/pages/WorkspaceSettings/AgentConfig/index.jsx @@ -5,6 +5,7 @@ import { castToType } from "@/utils/types"; import { useEffect, useRef, useState } from "react"; import AgentLLMSelection from "./AgentLLMSelection"; import AgentWebSearchSelection from "./WebSearchSelection"; +import AgentSQLConnectorSelection from "./SQLConnectorSelection"; import GenericSkill from "./GenericSkill"; import Admin from "@/models/admin"; import * as Skeleton from "react-loading-skeleton"; @@ -205,6 +206,12 @@ function AvailableAgentSkills({ skills, settings, toggleAgentSkill }) { toggleSkill={toggleAgentSkill} enabled={skills.includes("web-browsing")} /> + <AgentSQLConnectorSelection + skill="sql-agent" + settings={settings} + toggleSkill={toggleAgentSkill} + enabled={skills.includes("sql-agent")} + /> </div> </div> ); diff --git a/server/endpoints/admin.js b/server/endpoints/admin.js index 2ef611f6a..959e023ff 100644 --- a/server/endpoints/admin.js +++ b/server/endpoints/admin.js @@ -350,6 +350,8 @@ function adminEndpoints(app) { agent_search_provider: (await SystemSettings.get({ label: "agent_search_provider" })) ?.value || null, + agent_sql_connections: + await SystemSettings.brief.agent_sql_connections(), default_agent_skills: safeJsonParse( (await SystemSettings.get({ label: "default_agent_skills" })) diff --git a/server/models/systemSettings.js b/server/models/systemSettings.js index 248ca8cd7..7b4f21eeb 100644 --- a/server/models/systemSettings.js +++ b/server/models/systemSettings.js @@ -2,8 +2,10 @@ process.env.NODE_ENV === "development" ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }) : require("dotenv").config(); -const { isValidUrl } = require("../utils/http"); +const { default: slugify } = require("slugify"); +const { isValidUrl, safeJsonParse } = require("../utils/http"); const prisma = require("../utils/prisma"); +const { v4 } = require("uuid"); function isNullOrNaN(value) { if (value === null) return true; @@ -24,6 +26,7 @@ const SystemSettings = { "text_splitter_chunk_overlap", "agent_search_provider", "default_agent_skills", + "agent_sql_connections", ], validations: { footer_data: (updates) => { @@ -65,6 +68,7 @@ const SystemSettings = { }, agent_search_provider: (update) => { try { + if (update === "none") return null; if (!["google-search-engine", "serper-dot-dev"].includes(update)) throw new Error("Invalid SERP provider."); return String(update); @@ -85,6 +89,22 @@ const SystemSettings = { return JSON.stringify([]); } }, + agent_sql_connections: async (updates) => { + const existingConnections = safeJsonParse( + (await SystemSettings.get({ label: "agent_sql_connections" }))?.value, + [] + ); + try { + const updatedConnections = mergeConnections( + existingConnections, + safeJsonParse(updates, []) + ); + return JSON.stringify(updatedConnections); + } catch (e) { + console.error(`Failed to merge connections`); + return JSON.stringify(existingConnections ?? []); + } + }, }, currentSettings: async function () { const { hasVectorCachedFiles } = require("../utils/files"); @@ -204,22 +224,30 @@ const SystemSettings = { // that takes no user input for the keys being modified. _updateSettings: async function (updates = {}) { try { - const updatePromises = Object.keys(updates).map((key) => { - const validatedValue = this.validations.hasOwnProperty(key) - ? this.validations[key](updates[key]) - : updates[key]; + const updatePromises = []; + for (const key of Object.keys(updates)) { + let validatedValue = updates[key]; + if (this.validations.hasOwnProperty(key)) { + if (this.validations[key].constructor.name === "AsyncFunction") { + validatedValue = await this.validations[key](updates[key]); + } else { + validatedValue = this.validations[key](updates[key]); + } + } - return prisma.system_settings.upsert({ - where: { label: key }, - update: { - value: validatedValue === null ? null : String(validatedValue), - }, - create: { - label: key, - value: validatedValue === null ? null : String(validatedValue), - }, - }); - }); + updatePromises.push( + prisma.system_settings.upsert({ + where: { label: key }, + update: { + value: validatedValue === null ? null : String(validatedValue), + }, + create: { + label: key, + value: validatedValue === null ? null : String(validatedValue), + }, + }) + ); + } await Promise.all(updatePromises); return { success: true, error: null }; @@ -392,6 +420,58 @@ const SystemSettings = { CohereModelPref: process.env.COHERE_MODEL_PREF, }; }, + + // For special retrieval of a key setting that does not expose any credential information + brief: { + agent_sql_connections: async function () { + const setting = await SystemSettings.get({ + label: "agent_sql_connections", + }); + if (!setting) return []; + return safeJsonParse(setting.value, []).map((dbConfig) => { + const { connectionString, ...rest } = dbConfig; + return rest; + }); + }, + }, }; +function mergeConnections(existingConnections = [], updates = []) { + let updatedConnections = [...existingConnections]; + const existingDbIds = existingConnections.map((conn) => conn.database_id); + + // First remove all 'action:remove' candidates from existing connections. + const toRemove = updates + .filter((conn) => conn.action === "remove") + .map((conn) => conn.database_id); + updatedConnections = updatedConnections.filter( + (conn) => !toRemove.includes(conn.database_id) + ); + + // Next add all 'action:add' candidates into the updatedConnections; We DO NOT validate the connection strings. + // but we do validate their database_id is unique. + updates + .filter((conn) => conn.action === "add") + .forEach((update) => { + if (!update.connectionString) return; // invalid connection string + + // Remap name to be unique to entire set. + if (existingDbIds.includes(update.database_id)) { + update.database_id = slugify( + `${update.database_id}-${v4().slice(0, 4)}` + ); + } else { + update.database_id = slugify(update.database_id); + } + + updatedConnections.push({ + engine: update.engine, + database_id: update.database_id, + connectionString: update.connectionString, + }); + }); + + return updatedConnections; +} + module.exports.SystemSettings = SystemSettings; diff --git a/server/package.json b/server/package.json index 73b947c46..4f9954700 100644 --- a/server/package.json +++ b/server/package.json @@ -58,11 +58,14 @@ "langchain": "0.1.36", "mime": "^3.0.0", "moment": "^2.29.4", + "mssql": "^10.0.2", "multer": "^1.4.5-lts.1", + "mysql2": "^3.9.7", "node-html-markdown": "^1.3.0", "node-llama-cpp": "^2.8.0", "ollama": "^0.5.0", "openai": "4.38.5", + "pg": "^8.11.5", "pinecone-client": "^1.1.0", "pluralize": "^8.0.0", "posthog-node": "^3.1.1", @@ -72,6 +75,7 @@ "sqlite3": "^5.1.6", "swagger-autogen": "^2.23.5", "swagger-ui-express": "^5.0.0", + "url-pattern": "^1.0.3", "uuid": "^9.0.0", "uuid-apikey": "^1.5.3", "vectordb": "0.4.11", diff --git a/server/utils/agents/aibitat/index.js b/server/utils/agents/aibitat/index.js index f21c4aa45..fa490edb2 100644 --- a/server/utils/agents/aibitat/index.js +++ b/server/utils/agents/aibitat/index.js @@ -498,6 +498,17 @@ Only return the role. return availableNodes[Math.floor(Math.random() * availableNodes.length)]; } + /** + * + * @param {string} pluginName this name of the plugin being called + * @returns string of the plugin to be called compensating for children denoted by # in the string. + * eg: sql-agent:list-database-connections + */ + #parseFunctionName(pluginName = "") { + if (!pluginName.includes("#")) return pluginName; + return pluginName.split("#")[1]; + } + /** * Check if the chat has reached the maximum number of rounds. */ @@ -550,7 +561,7 @@ ${this.getHistory({ to: route.to }) // get the functions that the node can call const functions = fromConfig.functions - ?.map((name) => this.functions.get(name)) + ?.map((name) => this.functions.get(this.#parseFunctionName(name))) .filter((a) => !!a); const provider = this.getProviderForConfig({ diff --git a/server/utils/agents/aibitat/plugins/index.js b/server/utils/agents/aibitat/plugins/index.js index d9ff544e2..9a7ee7a05 100644 --- a/server/utils/agents/aibitat/plugins/index.js +++ b/server/utils/agents/aibitat/plugins/index.js @@ -6,6 +6,7 @@ const { saveFileInBrowser } = require("./save-file-browser.js"); const { chatHistory } = require("./chat-history.js"); const { memory } = require("./memory.js"); const { rechart } = require("./rechart.js"); +const { sqlAgent } = require("./sql-agent/index.js"); module.exports = { webScraping, @@ -16,6 +17,7 @@ module.exports = { chatHistory, memory, rechart, + sqlAgent, // Plugin name aliases so they can be pulled by slug as well. [webScraping.name]: webScraping, @@ -26,4 +28,5 @@ module.exports = { [chatHistory.name]: chatHistory, [memory.name]: memory, [rechart.name]: rechart, + [sqlAgent.name]: sqlAgent, }; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MSSQL.js b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MSSQL.js new file mode 100644 index 000000000..ed75aa7aa --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MSSQL.js @@ -0,0 +1,89 @@ +const mssql = require("mssql"); +const UrlPattern = require("url-pattern"); + +class MSSQLConnector { + #connected = false; + database_id = ""; + connectionConfig = { + user: null, + password: null, + database: null, + server: null, + port: null, + pool: { + max: 10, + min: 0, + idleTimeoutMillis: 30000, + }, + options: { + encrypt: false, + trustServerCertificate: true, + }, + }; + + constructor( + config = { + // we will force into RFC-3986 from DB + // eg: mssql://user:password@server:port/database?{...opts} + connectionString: null, // we will force into RFC-3986 + } + ) { + this.connectionString = config.connectionString; + this._client = null; + this.#parseDatabase(); + } + + #parseDatabase() { + const connectionPattern = new UrlPattern( + "mssql\\://:username\\::password@*\\::port/:database*" + ); + const match = connectionPattern.match(this.connectionString); + this.database_id = match?.database; + this.connectionConfig = { + ...this.connectionConfig, + user: match?.username, + password: match?.password, + database: match?.database, + server: match?._[0], + port: match?.port ? Number(match.port) : null, + }; + } + + async connect() { + this._client = await mssql.connect(this.connectionConfig); + this.#connected = true; + return this._client; + } + + /** + * + * @param {string} queryString the SQL query to be run + * @returns {import(".").QueryResult} + */ + async runQuery(queryString = "") { + const result = { rows: [], count: 0, error: null }; + try { + if (!this.#connected) await this.connect(); + + const query = await this._client.query(queryString); + result.rows = query.recordset; + result.count = query.rowsAffected.reduce((sum, a) => sum + a, 0); + } catch (err) { + console.log(this.constructor.name, err); + result.error = err.message; + } finally { + await this._client.close(); + this.#connected = false; + } + return result; + } + + getTablesSql() { + return `SELECT name FROM sysobjects WHERE xtype='U';`; + } + getTableSchemaSql(table_name) { + return `SELECT COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='${table_name}'`; + } +} + +module.exports.MSSQLConnector = MSSQLConnector; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MySQL.js b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MySQL.js new file mode 100644 index 000000000..d9982ab31 --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/MySQL.js @@ -0,0 +1,59 @@ +const mysql = require("mysql2/promise"); +const UrlPattern = require("url-pattern"); + +class MySQLConnector { + #connected = false; + database_id = ""; + constructor( + config = { + connectionString: null, + } + ) { + this.connectionString = config.connectionString; + this._client = null; + this.database_id = this.#parseDatabase(); + } + + #parseDatabase() { + const connectionPattern = new UrlPattern("mysql\\://*@*/:database*"); + const match = connectionPattern.match(this.connectionString); + return match?.database; + } + + async connect() { + this._client = await mysql.createConnection({ uri: this.connectionString }); + this.#connected = true; + return this._client; + } + + /** + * + * @param {string} queryString the SQL query to be run + * @returns {import(".").QueryResult} + */ + async runQuery(queryString = "") { + const result = { rows: [], count: 0, error: null }; + try { + if (!this.#connected) await this.connect(); + const [query] = await this._client.query(queryString); + result.rows = query; + result.count = query?.length; + } catch (err) { + console.log(this.constructor.name, err); + result.error = err.message; + } finally { + await this._client.end(); + this.#connected = false; + } + return result; + } + + getTablesSql() { + return `SELECT table_name FROM information_schema.tables WHERE table_schema = '${this.database_id}'`; + } + getTableSchemaSql(table_name) { + return `SHOW COLUMNS FROM ${this.database_id}.${table_name};`; + } +} + +module.exports.MySQLConnector = MySQLConnector; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/Postgresql.js b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/Postgresql.js new file mode 100644 index 000000000..463fea510 --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/Postgresql.js @@ -0,0 +1,52 @@ +const pgSql = require("pg"); + +class PostgresSQLConnector { + #connected = false; + constructor( + config = { + connectionString: null, + } + ) { + this.connectionString = config.connectionString; + this._client = new pgSql.Client({ + connectionString: this.connectionString, + }); + } + + async connect() { + await this._client.connect(); + this.#connected = true; + return this._client; + } + + /** + * + * @param {string} queryString the SQL query to be run + * @returns {import(".").QueryResult} + */ + async runQuery(queryString = "") { + const result = { rows: [], count: 0, error: null }; + try { + if (!this.#connected) await this.connect(); + const query = await this._client.query(queryString); + result.rows = query.rows; + result.count = query.rowCount; + } catch (err) { + console.log(this.constructor.name, err); + result.error = err.message; + } finally { + await this._client.end(); + this.#connected = false; + } + return result; + } + + getTablesSql() { + return `SELECT * FROM pg_catalog.pg_tables WHERE schemaname = 'public'`; + } + getTableSchemaSql(table_name) { + return ` select column_name, data_type, character_maximum_length, column_default, is_nullable from INFORMATION_SCHEMA.COLUMNS where table_name = '${table_name}'`; + } +} + +module.exports.PostgresSQLConnector = PostgresSQLConnector; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js new file mode 100644 index 000000000..9cf1e1ff4 --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/SQLConnectors/index.js @@ -0,0 +1,60 @@ +const { SystemSettings } = require("../../../../../../models/systemSettings"); +const { safeJsonParse } = require("../../../../../http"); + +/** + * @typedef {('postgresql'|'mysql'|'sql-server')} SQLEngine + */ + +/** + * @typedef {Object} QueryResult + * @property {[number]} rows - The query result rows + * @property {number} count - Number of rows the query returned/changed + * @property {string|null} error - Error string if there was an issue + */ + +/** + * A valid database SQL connection object + * @typedef {Object} SQLConnection + * @property {string} database_id - Unique identifier of the database connection + * @property {SQLEngine} engine - Engine used by connection + * @property {string} connectionString - RFC connection string for db + */ + +/** + * @param {SQLEngine} identifier + * @param {object} connectionConfig + * @returns Database Connection Engine Class for SQLAgent or throws error + */ +function getDBClient(identifier = "", connectionConfig = {}) { + switch (identifier) { + case "mysql": + const { MySQLConnector } = require("./MySQL"); + return new MySQLConnector(connectionConfig); + case "postgresql": + const { PostgresSQLConnector } = require("./Postgresql"); + return new PostgresSQLConnector(connectionConfig); + case "sql-server": + const { MSSQLConnector } = require("./MSSQL"); + return new MSSQLConnector(connectionConfig); + default: + throw new Error( + `There is no supported database connector for ${identifier}` + ); + } +} + +/** + * Lists all of the known database connection that can be used by the agent. + * @returns {Promise<[SQLConnection]>} + */ +async function listSQLConnections() { + return safeJsonParse( + (await SystemSettings.get({ label: "agent_sql_connections" }))?.value, + [] + ); +} + +module.exports = { + getDBClient, + listSQLConnections, +}; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/get-table-schema.js b/server/utils/agents/aibitat/plugins/sql-agent/get-table-schema.js new file mode 100644 index 000000000..2f66d119d --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/get-table-schema.js @@ -0,0 +1,98 @@ +module.exports.SqlAgentGetTableSchema = { + name: "sql-get-table-schema", + plugin: function () { + const { + listSQLConnections, + getDBClient, + } = require("./SQLConnectors/index.js"); + + return { + name: "sql-get-table-schema", + setup(aibitat) { + aibitat.function({ + super: aibitat, + name: this.name, + description: + "Gets the table schema in SQL for a given `table` and `database_id`", + examples: [ + { + prompt: "What does the customers table in access-logs look like?", + call: JSON.stringify({ + database_id: "access-logs", + table_name: "customers", + }), + }, + { + prompt: + "Get me the full name of a company in records-main, the table should be call comps", + call: JSON.stringify({ + database_id: "records-main", + table_name: "comps", + }), + }, + ], + parameters: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + database_id: { + type: "string", + description: + "The database identifier for which we will connect to to query the table schema. This is a required field.", + }, + table_name: { + type: "string", + description: + "The database identifier for the table name we want the schema for. This is a required field.", + }, + }, + additionalProperties: false, + }, + required: ["database_id", "table_name"], + handler: async function ({ database_id = "", table_name = "" }) { + this.super.handlerProps.log(`Using the sql-get-table-schema tool.`); + try { + const databaseConfig = (await listSQLConnections()).find( + (db) => db.database_id === database_id + ); + if (!databaseConfig) { + this.super.handlerProps.log( + `sql-get-table-schema to find config!.`, + database_id + ); + return `No database connection for ${database_id} was found!`; + } + + const db = getDBClient(databaseConfig.engine, databaseConfig); + this.super.introspect( + `${this.caller}: Querying the table schema for ${table_name} in the ${databaseConfig.database_id} database.` + ); + this.super.introspect( + `Running SQL: ${db.getTableSchemaSql(table_name)}` + ); + const result = await db.runQuery( + db.getTableSchemaSql(table_name) + ); + + if (result.error) { + this.super.handlerProps.log( + `sql-get-table-schema tool reported error`, + result.error + ); + this.super.introspect(`Error: ${result.error}`); + return `There was an error running the query: ${result.error}`; + } + + return JSON.stringify(result); + } catch (e) { + this.super.handlerProps.log( + `sql-get-table-schema raised an error. ${e.message}` + ); + return e.message; + } + }, + }); + }, + }; + }, +}; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/index.js b/server/utils/agents/aibitat/plugins/sql-agent/index.js new file mode 100644 index 000000000..b7c1ed7d3 --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/index.js @@ -0,0 +1,21 @@ +const { SqlAgentGetTableSchema } = require("./get-table-schema"); +const { SqlAgentListDatabase } = require("./list-database"); +const { SqlAgentListTables } = require("./list-table"); +const { SqlAgentQuery } = require("./query"); + +const sqlAgent = { + name: "sql-agent", + startupConfig: { + params: {}, + }, + plugin: [ + SqlAgentListDatabase, + SqlAgentListTables, + SqlAgentGetTableSchema, + SqlAgentQuery, + ], +}; + +module.exports = { + sqlAgent, +}; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/list-database.js b/server/utils/agents/aibitat/plugins/sql-agent/list-database.js new file mode 100644 index 000000000..20e67c281 --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/list-database.js @@ -0,0 +1,49 @@ +module.exports.SqlAgentListDatabase = { + name: "sql-list-databases", + plugin: function () { + const { listSQLConnections } = require("./SQLConnectors"); + return { + name: "sql-list-databases", + setup(aibitat) { + aibitat.function({ + super: aibitat, + name: this.name, + description: + "List all available databases via `list_databases` you currently have access to. Returns a unique string identifier `database_id` that can be used for future calls.", + examples: [ + { + prompt: "What databases can you access?", + call: JSON.stringify({}), + }, + { + prompt: "What databases can you tell me about?", + call: JSON.stringify({}), + }, + { + prompt: "Is there a database named erp-logs you can access?", + call: JSON.stringify({}), + }, + ], + parameters: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: {}, + additionalProperties: false, + }, + handler: async function () { + this.super.handlerProps.log(`Using the sql-list-databases tool.`); + this.super.introspect( + `${this.caller}: Checking what are the available databases.` + ); + + const connections = (await listSQLConnections()).map((conn) => { + const { connectionString, ...rest } = conn; + return rest; + }); + return JSON.stringify(connections); + }, + }); + }, + }; + }, +}; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/list-table.js b/server/utils/agents/aibitat/plugins/sql-agent/list-table.js new file mode 100644 index 000000000..d186bf01e --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/list-table.js @@ -0,0 +1,85 @@ +module.exports.SqlAgentListTables = { + name: "sql-list-tables", + plugin: function () { + const { + listSQLConnections, + getDBClient, + } = require("./SQLConnectors/index.js"); + + return { + name: "sql-list-tables", + setup(aibitat) { + aibitat.function({ + super: aibitat, + name: this.name, + description: + "List all available tables in a database via its `database_id`.", + examples: [ + { + prompt: "What tables are there in the `access-logs` database?", + call: JSON.stringify({ database_id: "access-logs" }), + }, + { + prompt: + "What information can you access in the customer_accts postgres db?", + call: JSON.stringify({ database_id: "customer_accts" }), + }, + { + prompt: "Can you tell me what is in the primary-logs db?", + call: JSON.stringify({ database_id: "primary-logs" }), + }, + ], + parameters: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + database_id: { + type: "string", + description: + "The database identifier for which we will list all tables for. This is a required parameter", + }, + }, + additionalProperties: false, + }, + required: ["database_id"], + handler: async function ({ database_id = "" }) { + try { + this.super.handlerProps.log(`Using the sql-list-tables tool.`); + const databaseConfig = (await listSQLConnections()).find( + (db) => db.database_id === database_id + ); + if (!databaseConfig) { + this.super.handlerProps.log( + `sql-list-tables failed to find config!.`, + database_id + ); + return `No database connection for ${database_id} was found!`; + } + + const db = getDBClient(databaseConfig.engine, databaseConfig); + this.super.introspect( + `${this.caller}: Checking what are the available tables in the ${databaseConfig.database_id} database.` + ); + + this.super.introspect(`Running SQL: ${db.getTablesSql()}`); + const result = await db.runQuery(db.getTablesSql(database_id)); + if (result.error) { + this.super.handlerProps.log( + `sql-list-tables tool reported error`, + result.error + ); + this.super.introspect(`Error: ${result.error}`); + return `There was an error running the query: ${result.error}`; + } + + return JSON.stringify(result); + } catch (e) { + console.error(e); + return e.message; + } + }, + }); + }, + }; + }, +}; diff --git a/server/utils/agents/aibitat/plugins/sql-agent/query.js b/server/utils/agents/aibitat/plugins/sql-agent/query.js new file mode 100644 index 000000000..fca1aeb03 --- /dev/null +++ b/server/utils/agents/aibitat/plugins/sql-agent/query.js @@ -0,0 +1,101 @@ +module.exports.SqlAgentQuery = { + name: "sql-query", + plugin: function () { + const { + getDBClient, + listSQLConnections, + } = require("./SQLConnectors/index.js"); + + return { + name: "sql-query", + setup(aibitat) { + aibitat.function({ + super: aibitat, + name: this.name, + description: + "Run a read-only SQL query on a `database_id` which will return up rows of data related to the query. The query must only be SELECT statements which do not modify the table data. There should be a reasonable LIMIT on the return quantity to prevent long-running or queries which crash the db.", + examples: [ + { + prompt: "How many customers are in dvd-rentals?", + call: JSON.stringify({ + database_id: "dvd-rentals", + sql_query: "SELECT * FROM customers", + }), + }, + { + prompt: "Can you tell me the total volume of sales last month?", + call: JSON.stringify({ + database_id: "sales-db", + sql_query: + "SELECT SUM(sale_amount) AS total_sales FROM sales WHERE sale_date >= DATEADD(month, -1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)) AND sale_date < DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)", + }), + }, + { + prompt: + "Do we have anyone in the staff table for our production db named 'sam'? ", + call: JSON.stringify({ + database_id: "production", + sql_query: + "SElECT * FROM staff WHERE first_name='sam%' OR last_name='sam%'", + }), + }, + ], + parameters: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + database_id: { + type: "string", + description: + "The database identifier for which we will connect to to query the table schema. This is required to run the SQL query.", + }, + sql_query: { + type: "string", + description: + "The raw SQL query to run. Should be a query which does not modify the table and will return results.", + }, + }, + additionalProperties: false, + }, + required: ["database_id", "table_name"], + handler: async function ({ database_id = "", sql_query = "" }) { + this.super.handlerProps.log(`Using the sql-query tool.`); + try { + const databaseConfig = (await listSQLConnections()).find( + (db) => db.database_id === database_id + ); + if (!databaseConfig) { + this.super.handlerProps.log( + `sql-query failed to find config!.`, + database_id + ); + return `No database connection for ${database_id} was found!`; + } + + this.super.introspect( + `${this.caller}: Im going to run a query on the ${database_id} to get an answer.` + ); + const db = getDBClient(databaseConfig.engine, databaseConfig); + + this.super.introspect(`Running SQL: ${sql_query}`); + const result = await db.runQuery(sql_query); + if (result.error) { + this.super.handlerProps.log( + `sql-query tool reported error`, + result.error + ); + this.super.introspect(`Error: ${result.error}`); + return `There was an error running the query: ${result.error}`; + } + + return JSON.stringify(result); + } catch (e) { + console.error(e); + return e.message; + } + }, + }); + }, + }; + }, +}; diff --git a/server/utils/agents/aibitat/plugins/websocket.js b/server/utils/agents/aibitat/plugins/websocket.js index b6154984d..f5c73b33b 100644 --- a/server/utils/agents/aibitat/plugins/websocket.js +++ b/server/utils/agents/aibitat/plugins/websocket.js @@ -49,7 +49,7 @@ const websocket = { setup(aibitat) { aibitat.onError(async (error) => { if (!!error?.message) { - console.error(chalk.red(` error: ${error.message}`)); + console.error(chalk.red(` error: ${error.message}`), error); aibitat.introspect( `Error encountered while running: ${error.message}` ); diff --git a/server/utils/agents/aibitat/providers/anthropic.js b/server/utils/agents/aibitat/providers/anthropic.js index 307731ba7..b69b14d6c 100644 --- a/server/utils/agents/aibitat/providers/anthropic.js +++ b/server/utils/agents/aibitat/providers/anthropic.js @@ -3,7 +3,7 @@ const { RetryError } = require("../error.js"); const Provider = require("./ai-provider.js"); /** - * The provider for the Anthropic API. + * The agent provider for the Anthropic API. * By default, the model is set to 'claude-2'. */ class AnthropicProvider extends Provider { diff --git a/server/utils/agents/aibitat/providers/azure.js b/server/utils/agents/aibitat/providers/azure.js index cdcf7618b..0ecc398f1 100644 --- a/server/utils/agents/aibitat/providers/azure.js +++ b/server/utils/agents/aibitat/providers/azure.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the Azure OpenAI API. + * The agent provider for the Azure OpenAI API. */ class AzureOpenAiProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -84,6 +84,11 @@ class AzureOpenAiProvider extends InheritMultiple([Provider, UnTooled]) { ); completion = response.choices[0].message; } + + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0 }; } catch (error) { throw error; diff --git a/server/utils/agents/aibitat/providers/genericOpenAi.js b/server/utils/agents/aibitat/providers/genericOpenAi.js index e41476d2a..a1b2db3ea 100644 --- a/server/utils/agents/aibitat/providers/genericOpenAi.js +++ b/server/utils/agents/aibitat/providers/genericOpenAi.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the Generic OpenAI provider. + * The agent provider for the Generic OpenAI provider. * Since we cannot promise the generic provider even supports tool calling * which is nearly 100% likely it does not, we can just wrap it in untooled * which often is far better anyway. @@ -94,6 +94,10 @@ class GenericOpenAiProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/groq.js b/server/utils/agents/aibitat/providers/groq.js index 720d87437..01f69f7c1 100644 --- a/server/utils/agents/aibitat/providers/groq.js +++ b/server/utils/agents/aibitat/providers/groq.js @@ -3,7 +3,7 @@ const Provider = require("./ai-provider.js"); const { RetryError } = require("../error.js"); /** - * The provider for the Groq provider. + * The agent provider for the Groq provider. * Using OpenAI tool calling with groq really sucks right now * its just fast and bad. We should probably migrate this to Untooled to improve * coherence. diff --git a/server/utils/agents/aibitat/providers/koboldcpp.js b/server/utils/agents/aibitat/providers/koboldcpp.js index 77088263c..2dd127845 100644 --- a/server/utils/agents/aibitat/providers/koboldcpp.js +++ b/server/utils/agents/aibitat/providers/koboldcpp.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the KoboldCPP provider. + * The agent provider for the KoboldCPP provider. */ class KoboldCPPProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -89,6 +89,10 @@ class KoboldCPPProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/lmstudio.js b/server/utils/agents/aibitat/providers/lmstudio.js index f5c4a2e82..258f2e291 100644 --- a/server/utils/agents/aibitat/providers/lmstudio.js +++ b/server/utils/agents/aibitat/providers/lmstudio.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the LMStudio provider. + * The agent provider for the LMStudio. */ class LMStudioProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -89,6 +89,10 @@ class LMStudioProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/localai.js b/server/utils/agents/aibitat/providers/localai.js index 161172c21..bd0c3b524 100644 --- a/server/utils/agents/aibitat/providers/localai.js +++ b/server/utils/agents/aibitat/providers/localai.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the LocalAI provider. + * The agent provider for the LocalAI provider. */ class LocalAiProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -93,6 +93,10 @@ class LocalAiProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0 }; } catch (error) { throw error; diff --git a/server/utils/agents/aibitat/providers/mistral.js b/server/utils/agents/aibitat/providers/mistral.js index cdc2a5e75..aa2c1c6ec 100644 --- a/server/utils/agents/aibitat/providers/mistral.js +++ b/server/utils/agents/aibitat/providers/mistral.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the Mistral provider. + * The agent provider for the Mistral provider. * Mistral limits what models can call tools and even when using those * the model names change and dont match docs. When you do have the right model * it still fails and is not truly OpenAI compatible so its easier to just wrap @@ -93,6 +93,10 @@ class MistralProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/ollama.js b/server/utils/agents/aibitat/providers/ollama.js index d52d80caa..5cb529e51 100644 --- a/server/utils/agents/aibitat/providers/ollama.js +++ b/server/utils/agents/aibitat/providers/ollama.js @@ -4,7 +4,7 @@ const UnTooled = require("./helpers/untooled.js"); const { Ollama } = require("ollama"); /** - * The provider for the Ollama provider. + * The agent provider for the Ollama provider. */ class OllamaProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -83,6 +83,10 @@ class OllamaProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/openai.js b/server/utils/agents/aibitat/providers/openai.js index 3fcc46ca5..2866a7592 100644 --- a/server/utils/agents/aibitat/providers/openai.js +++ b/server/utils/agents/aibitat/providers/openai.js @@ -3,7 +3,7 @@ const Provider = require("./ai-provider.js"); const { RetryError } = require("../error.js"); /** - * The provider for the OpenAI API. + * The agent provider for the OpenAI API. * By default, the model is set to 'gpt-3.5-turbo'. */ class OpenAIProvider extends Provider { diff --git a/server/utils/agents/aibitat/providers/openrouter.js b/server/utils/agents/aibitat/providers/openrouter.js index 81297ae28..50c0868dd 100644 --- a/server/utils/agents/aibitat/providers/openrouter.js +++ b/server/utils/agents/aibitat/providers/openrouter.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the OpenRouter provider. + * The agent provider for the OpenRouter provider. */ class OpenRouterProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -93,6 +93,10 @@ class OpenRouterProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/perplexity.js b/server/utils/agents/aibitat/providers/perplexity.js index 29970fd06..072206950 100644 --- a/server/utils/agents/aibitat/providers/perplexity.js +++ b/server/utils/agents/aibitat/providers/perplexity.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the Perplexity provider. + * The agent provider for the Perplexity provider. */ class PerplexityProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -89,6 +89,10 @@ class PerplexityProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/textgenwebui.js b/server/utils/agents/aibitat/providers/textgenwebui.js index d1e424255..7ef1cf4c6 100644 --- a/server/utils/agents/aibitat/providers/textgenwebui.js +++ b/server/utils/agents/aibitat/providers/textgenwebui.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the Oobabooga provider. + * The agent provider for the Oobabooga provider. */ class TextWebGenUiProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -88,6 +88,10 @@ class TextWebGenUiProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/providers/togetherai.js b/server/utils/agents/aibitat/providers/togetherai.js index 4ea5e11c2..78cbb512c 100644 --- a/server/utils/agents/aibitat/providers/togetherai.js +++ b/server/utils/agents/aibitat/providers/togetherai.js @@ -4,7 +4,7 @@ const InheritMultiple = require("./helpers/classes.js"); const UnTooled = require("./helpers/untooled.js"); /** - * The provider for the TogetherAI provider. + * The agent provider for the TogetherAI provider. */ class TogetherAIProvider extends InheritMultiple([Provider, UnTooled]) { model; @@ -89,6 +89,10 @@ class TogetherAIProvider extends InheritMultiple([Provider, UnTooled]) { completion = response.choices[0].message; } + // The UnTooled class inherited Deduplicator is mostly useful to prevent the agent + // from calling the exact same function over and over in a loop within a single chat exchange + // _but_ we should enable it to call previously used tools in a new chat interaction. + this.deduplicator.reset("runs"); return { result: completion.content, cost: 0, diff --git a/server/utils/agents/aibitat/utils/dedupe.js b/server/utils/agents/aibitat/utils/dedupe.js index 8c4d582d0..321f69299 100644 --- a/server/utils/agents/aibitat/utils/dedupe.js +++ b/server/utils/agents/aibitat/utils/dedupe.js @@ -38,6 +38,25 @@ class Deduplicator { return this.#hashes.hasOwnProperty(newSig); } + /** + * Resets the object property for this instance of the Deduplicator class + * @param {('runs'|'cooldowns'|'uniques')} type - The type of prop to reset + */ + reset(type = "runs") { + switch (type) { + case "runs": + this.#hashes = {}; + break; + case "cooldowns": + this.#cooldowns = {}; + break; + case "uniques": + this.#uniques = {}; + break; + } + return; + } + startCooldown( key, parameters = { diff --git a/server/utils/agents/defaults.js b/server/utils/agents/defaults.js index 4e12b9062..796a7bbcb 100644 --- a/server/utils/agents/defaults.js +++ b/server/utils/agents/defaults.js @@ -25,8 +25,22 @@ const WORKSPACE_AGENT = { const _setting = ( await SystemSettings.get({ label: "default_agent_skills" }) )?.value; + safeJsonParse(_setting, []).forEach((skillName) => { if (!AgentPlugins.hasOwnProperty(skillName)) return; + + // This is a plugin module with many sub-children plugins who + // need to be named via `${parent}#${child}` naming convention + if (Array.isArray(AgentPlugins[skillName].plugin)) { + for (const subPlugin of AgentPlugins[skillName].plugin) { + defaultFunctions.push( + `${AgentPlugins[skillName].name}#${subPlugin.name}` + ); + } + return; + } + + // This is normal single-stage plugin defaultFunctions.push(AgentPlugins[skillName].name); }); diff --git a/server/utils/agents/index.js b/server/utils/agents/index.js index 08ce5558e..cf6f312d0 100644 --- a/server/utils/agents/index.js +++ b/server/utils/agents/index.js @@ -197,8 +197,60 @@ class AgentHandler { this.invocation = invocation ?? null; } + #parseCallOptions(args, config = {}, pluginName) { + const callOpts = {}; + for (const [param, definition] of Object.entries(config)) { + if ( + definition.required && + (!args.hasOwnProperty(param) || args[param] === null) + ) { + this.log( + `'${param}' required parameter for '${pluginName}' plugin is missing. Plugin may not function or crash agent.` + ); + continue; + } + callOpts[param] = args.hasOwnProperty(param) + ? args[param] + : definition.default || null; + } + return callOpts; + } + #attachPlugins(args) { for (const name of this.#funcsToLoad) { + // Load child plugin + if (name.includes("#")) { + const [parent, childPluginName] = name.split("#"); + if (!AgentPlugins.hasOwnProperty(parent)) { + this.log( + `${parent} is not a valid plugin. Skipping inclusion to agent cluster.` + ); + continue; + } + + const childPlugin = AgentPlugins[parent].plugin.find( + (child) => child.name === childPluginName + ); + if (!childPlugin) { + this.log( + `${parent} does not have child plugin named ${childPluginName}. Skipping inclusion to agent cluster.` + ); + continue; + } + + const callOpts = this.#parseCallOptions( + args, + childPlugin?.startupConfig?.params, + name + ); + this.aibitat.use(childPlugin.plugin(callOpts)); + this.log( + `Attached ${parent}:${childPluginName} plugin to Agent cluster` + ); + continue; + } + + // Load single-stage plugin. if (!AgentPlugins.hasOwnProperty(name)) { this.log( `${name} is not a valid plugin. Skipping inclusion to agent cluster.` @@ -206,24 +258,10 @@ class AgentHandler { continue; } - const callOpts = {}; - for (const [param, definition] of Object.entries( + const callOpts = this.#parseCallOptions( + args, AgentPlugins[name].startupConfig.params - )) { - if ( - definition.required && - (!args.hasOwnProperty(param) || args[param] === null) - ) { - this.log( - `'${param}' required parameter for '${name}' plugin is missing. Plugin may not function or crash agent.` - ); - continue; - } - callOpts[param] = args.hasOwnProperty(param) - ? args[param] - : definition.default || null; - } - + ); const AIbitatPlugin = AgentPlugins[name]; this.aibitat.use(AIbitatPlugin.plugin(callOpts)); this.log(`Attached ${name} plugin to Agent cluster`); diff --git a/server/yarn.lock b/server/yarn.lock index 9e4f184d5..d274e574f 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -82,6 +82,13 @@ "@azure/core-util" "^1.0.0" tslib "^2.6.2" +"@azure/abort-controller@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.1.0.tgz#788ee78457a55af8a1ad342acb182383d2119249" + integrity sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw== + dependencies: + tslib "^2.2.0" + "@azure/abort-controller@^2.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-2.1.2.tgz#42fe0ccab23841d9905812c58f1082d27784566d" @@ -89,7 +96,7 @@ dependencies: tslib "^2.6.2" -"@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0": +"@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0", "@azure/core-auth@^1.5.0": version "1.7.2" resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.7.2.tgz#558b7cb7dd12b00beec07ae5df5907d74df1ebd9" integrity sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g== @@ -98,6 +105,59 @@ "@azure/core-util" "^1.1.0" tslib "^2.6.2" +"@azure/core-client@^1.3.0", "@azure/core-client@^1.4.0", "@azure/core-client@^1.5.0": + version "1.9.2" + resolved "https://registry.yarnpkg.com/@azure/core-client/-/core-client-1.9.2.tgz#6fc69cee2816883ab6c5cdd653ee4f2ff9774f74" + integrity sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w== + dependencies: + "@azure/abort-controller" "^2.0.0" + "@azure/core-auth" "^1.4.0" + "@azure/core-rest-pipeline" "^1.9.1" + "@azure/core-tracing" "^1.0.0" + "@azure/core-util" "^1.6.1" + "@azure/logger" "^1.0.0" + tslib "^2.6.2" + +"@azure/core-http-compat@^2.0.1": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@azure/core-http-compat/-/core-http-compat-2.1.2.tgz#d1585ada24ba750dc161d816169b33b35f762f0d" + integrity sha512-5MnV1yqzZwgNLLjlizsU3QqOeQChkIXw781Fwh1xdAqJR5AA32IUaq6xv1BICJvfbHoa+JYcaij2HFkhLbNTJQ== + dependencies: + "@azure/abort-controller" "^2.0.0" + "@azure/core-client" "^1.3.0" + "@azure/core-rest-pipeline" "^1.3.0" + +"@azure/core-lro@^2.2.0": + version "2.7.2" + resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-2.7.2.tgz#787105027a20e45c77651a98b01a4d3b01b75a08" + integrity sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw== + dependencies: + "@azure/abort-controller" "^2.0.0" + "@azure/core-util" "^1.2.0" + "@azure/logger" "^1.0.0" + tslib "^2.6.2" + +"@azure/core-paging@^1.1.1": + version "1.6.2" + resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.6.2.tgz#40d3860dc2df7f291d66350b2cfd9171526433e7" + integrity sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA== + dependencies: + tslib "^2.6.2" + +"@azure/core-rest-pipeline@^1.1.0", "@azure/core-rest-pipeline@^1.3.0", "@azure/core-rest-pipeline@^1.8.1", "@azure/core-rest-pipeline@^1.9.1": + version "1.16.0" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.0.tgz#631172e2fe0346cf4410d1c8e01ad98d849738e2" + integrity sha512-CeuTvsXxCUmEuxH5g/aceuSl6w2EugvNHKAtKKVdiX915EjJJxAwfzNNWZreNnbxHZ2fi0zaM6wwS23x2JVqSQ== + dependencies: + "@azure/abort-controller" "^2.0.0" + "@azure/core-auth" "^1.4.0" + "@azure/core-tracing" "^1.0.1" + "@azure/core-util" "^1.9.0" + "@azure/logger" "^1.0.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" + tslib "^2.6.2" + "@azure/core-rest-pipeline@^1.13.0", "@azure/core-rest-pipeline@^1.5.0": version "1.15.2" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.15.2.tgz#421729bbd8cd5f9f50b403e79941f27ac1bdc302" @@ -119,14 +179,14 @@ dependencies: tslib "^2.6.2" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.1.2.tgz#065dab4e093fb61899988a1cdbc827d9ad90b4ee" integrity sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA== dependencies: tslib "^2.6.2" -"@azure/core-util@^1.0.0", "@azure/core-util@^1.1.0", "@azure/core-util@^1.3.0", "@azure/core-util@^1.4.0": +"@azure/core-util@^1.0.0", "@azure/core-util@^1.1.0", "@azure/core-util@^1.2.0", "@azure/core-util@^1.3.0", "@azure/core-util@^1.4.0", "@azure/core-util@^1.6.1", "@azure/core-util@^1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.9.0.tgz#469afd7e6452d5388b189f90d33f7756b0b210d1" integrity sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw== @@ -134,6 +194,43 @@ "@azure/abort-controller" "^2.0.0" tslib "^2.6.2" +"@azure/identity@^3.4.1": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-3.4.2.tgz#6b01724c9caac7cadab6b63c76584345bda8e2de" + integrity sha512-0q5DL4uyR0EZ4RXQKD8MadGH6zTIcloUoS/RVbCpNpej4pwte0xpqYxk8K97Py2RiuUvI7F4GXpoT4046VfufA== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-client" "^1.4.0" + "@azure/core-rest-pipeline" "^1.1.0" + "@azure/core-tracing" "^1.0.0" + "@azure/core-util" "^1.6.1" + "@azure/logger" "^1.0.0" + "@azure/msal-browser" "^3.5.0" + "@azure/msal-node" "^2.5.1" + events "^3.0.0" + jws "^4.0.0" + open "^8.0.0" + stoppable "^1.1.0" + tslib "^2.2.0" + +"@azure/keyvault-keys@^4.4.0": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@azure/keyvault-keys/-/keyvault-keys-4.8.0.tgz#1513b3a187bb3a9a372b5980c593962fb793b2ad" + integrity sha512-jkuYxgkw0aaRfk40OQhFqDIupqblIOIlYESWB6DKCVDxQet1pyv86Tfk9M+5uFM0+mCs6+MUHU+Hxh3joiUn4Q== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-auth" "^1.3.0" + "@azure/core-client" "^1.5.0" + "@azure/core-http-compat" "^2.0.1" + "@azure/core-lro" "^2.2.0" + "@azure/core-paging" "^1.1.1" + "@azure/core-rest-pipeline" "^1.8.1" + "@azure/core-tracing" "^1.0.0" + "@azure/core-util" "^1.0.0" + "@azure/logger" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0", "@azure/logger@^1.0.3": version "1.1.2" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.1.2.tgz#3f4b876cefad328dc14aff8b850d63b611e249dc" @@ -141,6 +238,27 @@ dependencies: tslib "^2.6.2" +"@azure/msal-browser@^3.5.0": + version "3.14.0" + resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-3.14.0.tgz#1cb5cab438a9943212aa50c403d11f775c787b21" + integrity sha512-Un85LhOoecJ3HDTS3Uv3UWnXC9/43ZSO+Kc+anSqpZvcEt58SiO/3DuVCAe1A3I5UIBYJNMgTmZPGXQ0MVYrwA== + dependencies: + "@azure/msal-common" "14.10.0" + +"@azure/msal-common@14.10.0": + version "14.10.0" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.10.0.tgz#215449726717b53d549953db77562cad6cb8421c" + integrity sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA== + +"@azure/msal-node@^2.5.1": + version "2.8.1" + resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-2.8.1.tgz#aded28d37eea2e7278c9bd44f2016647390f239c" + integrity sha512-VcZZM+5VvCWRBTOF7SxMKaxrz+EXjntx2u5AQe7QE06e6FuPJElGBrImgNgCh5QmFaNCfVFO+3qNR7UoFD/Gfw== + dependencies: + "@azure/msal-common" "14.10.0" + jsonwebtoken "^9.0.0" + uuid "^8.3.0" + "@azure/openai@1.0.0-beta.10": version "1.0.0-beta.10" resolved "https://registry.yarnpkg.com/@azure/openai/-/openai-1.0.0-beta.10.tgz#13bcf5c5bc34dd27e33dc6aab5db3dc97dd4545b" @@ -427,6 +545,11 @@ resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.3.1.tgz#afb95ff78f44fff7e8a00e17d5820db6add2a076" integrity sha512-Pe3PFccjPVJV1vtlfVvm9OnlbxqdnP5QcscFEFEnK5quChf1ufZtM0r8mR5ToWHMxZOh0s8o/qp9ANGRTo/DAw== +"@js-joda/core@^5.5.3": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-5.6.2.tgz#1885d10daa404cea2bd55575f910ab3bbe6c33d7" + integrity sha512-ow4R+7C24xeTjiMTTZ4k6lvxj7MRBqvqLCQjThQff3RjOmIMokMP20LNYVFhGafJtUx/Xo2Qp4qU8eNoTVH0SA== + "@js-sdsl/ordered-map@^4.4.2": version "4.4.2" resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" @@ -954,6 +1077,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.29.6.tgz#4cd8372f9247372edd5fc5af44f67e2032c46e2f" integrity sha512-aX5IFYWlMa7tQ8xZr3b2gtVReCvg7f3LEhjir/JAjX2bJCMVJA5tIPv30wTD4KDfcwMd7DDYY3hFDeGmOgtrZQ== +"@tediousjs/connection-string@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@tediousjs/connection-string/-/connection-string-0.5.0.tgz#9b3d858c040aac6bdf5584bf45370cef5b6522b4" + integrity sha512-7qSgZbincDDDFyRweCIEvZULFAw5iz/DeunhvuxpL31nfntX3P4Yd4HkHBRg9H8CdqY1e5WFN1PZIz/REL9MVQ== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -1030,6 +1158,14 @@ resolved "https://registry.yarnpkg.com/@types/pad-left/-/pad-left-2.1.1.tgz#17d906fc75804e1cc722da73623f1d978f16a137" integrity sha512-Xd22WCRBydkGSApl5Bw0PhAOHKSVjNL3E3AwzKaps96IMraPqy5BvZIsBVK6JLwdybUzjHnuWVwpDd0JjTfHXA== +"@types/readable-stream@^4.0.0": + version "4.0.14" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-4.0.14.tgz#5a76a00e1e3dd6ff921ea2b3fac7485c5a492c19" + integrity sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + "@types/retry@0.12.0": version "0.12.0" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" @@ -1539,6 +1675,16 @@ bl@^5.0.0: inherits "^2.0.4" readable-stream "^3.4.0" +bl@^6.0.3: + version "6.0.12" + resolved "https://registry.yarnpkg.com/bl/-/bl-6.0.12.tgz#77c35b96e13aeff028496c798b75389ddee9c7f8" + integrity sha512-EnEYHilP93oaOa2MnmNEjAcovPS3JlQZOyzGXi3EyEpPhm9qWvdDp7BmAVEVusGzp8LlwQK56Av+OkDoRjzE0w== + dependencies: + "@types/readable-stream" "^4.0.0" + buffer "^6.0.3" + inherits "^2.0.4" + readable-stream "^4.2.0" + body-parser@1.20.2, body-parser@^1.20.2: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" @@ -1931,6 +2077,11 @@ commander@^10.0.1: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== +commander@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" + integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + commander@^8.0.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -2147,6 +2298,11 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" @@ -2166,6 +2322,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -2383,6 +2544,20 @@ es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23 unbox-primitive "^1.0.2" which-typed-array "^1.1.15" +es-aggregate-error@^1.0.9: + version "1.0.13" + resolved "https://registry.yarnpkg.com/es-aggregate-error/-/es-aggregate-error-1.0.13.tgz#7f28b77c9d8d09bbcd3a466e4be9fe02fa985201" + integrity sha512-KkzhUUuD2CUMqEc8JEqsXEMDHzDPE8RCjZeUBitsnB1eNcAJWQPiciKsMXe3Yytj4Flw1XLl46Qcf9OxvZha7A== + dependencies: + define-data-property "^1.1.4" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + globalthis "^1.0.3" + has-property-descriptors "^1.0.2" + set-function-name "^2.0.2" + es-define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" @@ -2622,6 +2797,11 @@ eventemitter3@^4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +events@^3.0.0, events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -3028,6 +3208,13 @@ gcp-metadata@^5.3.0: gaxios "^5.0.0" json-bigint "^1.0.0" +generate-function@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + generic-pool@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4" @@ -3353,7 +3540,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: +iconv-lite@^0.6.2, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -3516,6 +3703,11 @@ is-date-object@^1.0.1, is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -3584,6 +3776,11 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -3655,6 +3852,13 @@ is-weakset@^2.0.3: call-bind "^1.0.7" get-intrinsic "^1.2.4" +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -3715,6 +3919,11 @@ js-base64@3.7.2: resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.2.tgz#816d11d81a8aff241603d19ce5761e13e41d7745" integrity sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ== +js-md4@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/js-md4/-/js-md4-0.3.2.tgz#cd3b3dc045b0c404556c81ddb5756c23e59d7cf5" + integrity sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA== + js-tiktoken@^1.0.11, js-tiktoken@^1.0.7, js-tiktoken@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/js-tiktoken/-/js-tiktoken-1.0.11.tgz#d7d707b849f703841112660d9d55169424a35344" @@ -3734,6 +3943,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsbi@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-4.3.0.tgz#b54ee074fb6fcbc00619559305c8f7e912b04741" + integrity sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g== + jsbn@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" @@ -3811,7 +4025,7 @@ jsonwebtoken@^8.5.1: ms "^2.1.1" semver "^5.6.0" -jsonwebtoken@^9.0.2: +jsonwebtoken@^9.0.0, jsonwebtoken@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== @@ -4050,7 +4264,7 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== -long@^5.0.0: +long@^5.0.0, long@^5.2.1: version "5.2.3" resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== @@ -4074,6 +4288,16 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^8.0.0: + version "8.0.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-8.0.5.tgz#983fe337f3e176667f8e567cfcce7cb064ea214e" + integrity sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA== + lru-cache@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.2.tgz#255fdbc14b75589d6d0e73644ca167a8db506835" @@ -4327,6 +4551,18 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mssql@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/mssql/-/mssql-10.0.2.tgz#99f9113a05b8ee32c84704fddc3780554cd89a60" + integrity sha512-GrQ6gzv2xA7ndOvONyZ++4RZsNkr8qDiIpvuFn2pR3TPiSk/cKdmvOrDU3jWgon7EPj7CPgmDiMh7Hgtft2xLg== + dependencies: + "@tediousjs/connection-string" "^0.5.0" + commander "^11.0.0" + debug "^4.3.3" + rfdc "^1.3.0" + tarn "^3.0.2" + tedious "^16.4.0" + multer@^1.4.5-lts.1: version "1.4.5-lts.1" resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.5-lts.1.tgz#803e24ad1984f58edffbc79f56e305aec5cfd1ac" @@ -4350,11 +4586,37 @@ mute-stream@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== +mysql2@^3.9.7: + version "3.9.7" + resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.9.7.tgz#843755daf65b5ef08afe545fe14b8fb62824741a" + integrity sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw== + dependencies: + denque "^2.1.0" + generate-function "^2.3.1" + iconv-lite "^0.6.3" + long "^5.2.1" + lru-cache "^8.0.0" + named-placeholders "^1.1.3" + seq-queue "^0.0.5" + sqlstring "^2.3.2" + +named-placeholders@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351" + integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w== + dependencies: + lru-cache "^7.14.1" + napi-build-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== +native-duplexpair@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/native-duplexpair/-/native-duplexpair-1.0.0.tgz#7899078e64bf3c8a3d732601b3d40ff05db58fa0" + integrity sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4372,6 +4634,11 @@ node-abi@^3.3.0: dependencies: semver "^7.3.5" +node-abort-controller@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== + node-addon-api@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" @@ -4685,6 +4952,15 @@ onnxruntime-web@1.14.0: onnxruntime-common "~1.14.0" platform "^1.3.6" +open@^8.0.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + openai@4.38.5: version "4.38.5" resolved "https://registry.yarnpkg.com/openai/-/openai-4.38.5.tgz#87de78eed9f7e63331fb6b1307d8c9dd986b39d0" @@ -4848,6 +5124,62 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + +pg-connection-string@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.4.tgz#f543862adfa49fa4e14bc8a8892d2a84d754246d" + integrity sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.2.tgz#3a592370b8ae3f02a7c8130d245bc02fa2c5f3f2" + integrity sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg== + +pg-protocol@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.1.tgz#21333e6d83b01faaebfe7a33a7ad6bfd9ed38cb3" + integrity sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.11.5: + version "8.11.5" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.5.tgz#e722b0a5f1ed92931c31758ebec3ddf878dd4128" + integrity sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw== + dependencies: + pg-connection-string "^2.6.4" + pg-pool "^3.6.2" + pg-protocol "^1.6.1" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -4882,6 +5214,28 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + posthog-node@^3.1.1: version "3.6.3" resolved "https://registry.yarnpkg.com/posthog-node/-/posthog-node-3.6.3.tgz#4d3a2a4385e01c4d9e91d01dbde104e60285853d" @@ -4937,6 +5291,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -5110,6 +5469,17 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.2.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + readdir-glob@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584" @@ -5199,6 +5569,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" + integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -5298,6 +5673,11 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +seq-queue@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" + integrity sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q== + serve-static@1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" @@ -5450,7 +5830,12 @@ socks@^2.6.2: ip-address "^9.0.5" smart-buffer "^4.2.0" -sprintf-js@^1.1.3: +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + +sprintf-js@^1.1.2, sprintf-js@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== @@ -5472,6 +5857,11 @@ sqlite@^4.2.1: resolved "https://registry.yarnpkg.com/sqlite/-/sqlite-4.2.1.tgz#d4eedfd1ad702f79110792375f4241a90c75c828" integrity sha512-Tll0Ndvnwkuv5Hn6WIbh26rZiYQORuH1t5m/or9LUpSmDmmyFG89G9fKrSeugMPxwmEIXoVxqTun4LbizTs4uw== +sqlstring@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" + integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== + ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" @@ -5496,6 +5886,11 @@ stdin-discarder@^0.1.0: dependencies: bl "^5.0.0" +stoppable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" + integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== + stream-read-all@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/stream-read-all/-/stream-read-all-3.0.1.tgz#60762ae45e61d93ba0978cda7f3913790052ad96" @@ -5585,7 +5980,7 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1: +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -5748,6 +6143,28 @@ tar@^6.0.2, tar@^6.1.11, tar@^6.1.2, tar@^6.2.0: mkdirp "^1.0.3" yallist "^4.0.0" +tarn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" + integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== + +tedious@^16.4.0: + version "16.7.1" + resolved "https://registry.yarnpkg.com/tedious/-/tedious-16.7.1.tgz#1190f30fd99a413f1dc9250dee4835cf0788b650" + integrity sha512-NmedZS0NJiTv3CoYnf1FtjxIDUgVYzEmavrc8q2WHRb+lP4deI9BpQfmNnBZZaWusDbP5FVFZCcvzb3xOlNVlQ== + dependencies: + "@azure/identity" "^3.4.1" + "@azure/keyvault-keys" "^4.4.0" + "@js-joda/core" "^5.5.3" + bl "^6.0.3" + es-aggregate-error "^1.0.9" + iconv-lite "^0.6.3" + js-md4 "^0.3.2" + jsbi "^4.3.0" + native-duplexpair "^1.0.0" + node-abort-controller "^3.1.1" + sprintf-js "^1.1.2" + text-hex@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" @@ -5794,7 +6211,7 @@ triple-beam@^1.3.0: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== -tslib@^2.4.0, tslib@^2.5.3, tslib@^2.6.2: +tslib@^2.2.0, tslib@^2.4.0, tslib@^2.5.3, tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -5966,6 +6383,11 @@ url-join@4.0.1, url-join@^4.0.1: resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== +url-pattern@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/url-pattern/-/url-pattern-1.0.3.tgz#0409292471b24f23c50d65a47931793d2b5acfc1" + integrity sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA== + url-template@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" @@ -5991,7 +6413,7 @@ uuid-apikey@^1.5.3: encode32 "^1.1.0" uuid "^8.3.1" -uuid@^8.3.1: +uuid@^8.3.0, uuid@^8.3.1: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==