diff --git a/README.md b/README.md index 4e1efd3d..1dc25083 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -> BaseAI is now archived in the favor of [Langbase AI Primitives](https://langbase.com/docs). The more we built BaseAI the more we realized frameworks are a bad idea in AI engineering. This space is moving fast and frameworks become blockers. Instead you should be using AI primitives, like [memory, pipes, agents](https://langbase.com/docs) that work with any language as APIs and with TypeScript and Python SDKs. You can use any coding agent, like [CommandCode](https://commandcode.ai) to make your own AI framework with these AI primitives. BaseAI is a great example how. - -

- + + + +

BaseAI

@@ -15,12 +15,7 @@ ## Getting Started -BaseAI is the AI framework for building serverless and composable AI agents with memory and tools. It allows you to develop AI agent pipes on your local machine with integrated agentic tools and memory (RAG). Visit our [BaseAI.dev/learn](https://baseai.dev/learn) guide to start with BaseAI. - -### Documentation (recommended) - -Please check [BaseAI.dev/docs](https://baseai.dev/docs) and [BaseAI.dev/learn](https://baseai.dev/learn) to get started with full documentation. - +BaseAI is the AI framework for building declarative and composable AI-powered LLM products. It allows you to develop AI agent pipes on your local machine with integrated agentic tools and memory (RAG). Visit our [learn](https://baseai.dev/learn) guide to get started with BaseAI. ### 1. Initialize a new BaseAI project @@ -204,7 +199,11 @@ Key Features: Stream ended. ``` > [!TIP] -> You can also run RAG locally with BaseAI. Check out the memory agent quickstart [guide](https://baseai.dev/docs/memory/quickstart) for more details. +> You can also run RAG locally with BaseAI. Check out memory quickstart [guide](https://baseai.dev/docs/memory/quickstart) for more details. + +## Documentation + +Visit [baseai.dev/docs](https://baseai.dev/docs) for the full documentation. ## Contributing diff --git a/apps/baseai.dev/content/docs/api-reference/pipe-run.mdx b/apps/baseai.dev/content/docs/api-reference/pipe-run.mdx index 29df14f3..f1402e95 100644 --- a/apps/baseai.dev/content/docs/api-reference/pipe-run.mdx +++ b/apps/baseai.dev/content/docs/api-reference/pipe-run.mdx @@ -83,7 +83,6 @@ The BaseAI core package provides a `pipe.run()` function that you can use in you ```ts {{title: 'RunOptions Object'}} interface RunOptions { messages?: Message[]; - runTools?: boolean; variables?: Variable[]; threadId?: string; rawResponse?: boolean; @@ -156,14 +155,6 @@ The BaseAI core package provides a `pipe.run()` function that you can use in you --- - ### runTools - - - - Enable if you want BaseAI to automically run tools**.** - - - ### variables diff --git a/apps/baseai.dev/content/docs/docs/index.mdx b/apps/baseai.dev/content/docs/docs/index.mdx index a0160e34..f565e29e 100644 --- a/apps/baseai.dev/content/docs/docs/index.mdx +++ b/apps/baseai.dev/content/docs/docs/index.mdx @@ -9,13 +9,13 @@ modified: 2024-09-24 --- - BaseAI.dev + BaseAI.dev

BaseAI Docs

- BaseAI is the first web AI framework for building Serverless AI agents with Node.js and TypeScript. + BaseAI is the first web AI framework built for web developers. - **OPEN**: BaseAI is **free and open-source** - **LOCAL**: world-class **local developer experience** @@ -27,7 +27,7 @@ modified: 2024-09-24 - BaseAI is the first web AI framework for building Serverless AI agents with Node.js and TypeScript. + The first Web AI Framework for web developers. - **OPEN**: BaseAI is **free and open-source** - **LOCAL**: world-class **local dev experience** diff --git a/apps/baseai.dev/content/docs/docs/supported-models-and-providers.mdx b/apps/baseai.dev/content/docs/docs/supported-models-and-providers.mdx index 5ffae1a5..41aac660 100644 --- a/apps/baseai.dev/content/docs/docs/supported-models-and-providers.mdx +++ b/apps/baseai.dev/content/docs/docs/supported-models-and-providers.mdx @@ -76,7 +76,6 @@ Learn more about [using Ollama models](/docs/guides/using-ollama-models) in Base | Model | Provider | Owner | Context | Cost* | |---------------------------------------------------------------------------------------------------------------------------|----------|------------|---------|----------------------------------------------| -| Llama-3.3-70B-Instruct-Turbo
ID: | Together | Meta | 131,072 | $0.88 prompt
$0.88 completion | | Llama-3.1-405B-Instruct-Turbo
ID: | Together | Meta | 4,096 | $5 prompt
$5 completion | | Llama-3.1-70B-Instruct-Turbo
ID: | Together | Meta | 8,192 | $0.88 prompt
$0.88 completion | | Llama-3.1-8B-Instruct-Turbo
ID: | Together | Meta | 8,192 | $0.18 prompt
$0.18 completion | @@ -122,7 +121,6 @@ Learn more about [using Ollama models](/docs/guides/using-ollama-models) in Base | Model | Provider | Owner | Context | Cost* | |-----------------------------------------------------------------------------------------|----------|---------|---------|---------------------------------------------| -| Llama-3.3-70b-versatile
ID: | Groq | Meta | 128,000 | $0.59 prompt
$0.79 completion | | Llama-3.1-70b-versatile
ID: | Groq | Meta | 131,072 | $0.59 prompt
$0.79 completion | | Llama-3.1-8b-instant
ID: | Groq | Meta | 131,072 | $0.59 prompt
$0.79 completion | | Llama-3-70b
ID: | Groq | Meta | 8,192 | $0.59 prompt
$0.79 completion | @@ -138,7 +136,6 @@ Learn more about [using Ollama models](/docs/guides/using-ollama-models) in Base | Model | Provider | Owner | Context | Cost* | |------------------------------------------------------------------------------|--------------|-------|---------|--------------------------------------------| | Llama-3.2-3b
ID: | Fireworks AI | Meta | 131,072 | $0.1 prompt
$0.1 completion | -| Llama 3.3 70B Instruct
ID: | Fireworks AI | Meta | 131,072 | $0.9 prompt
$0.9 completion | | Llama-3.2-1b
ID: | Fireworks AI | Meta | 131,072 | $0.1 prompt
$0.1 completion | | Llama-3.1-405b
ID: | Fireworks AI | Meta | 131,072 | $3 prompt
$3 completion | | Llama-3.1-70b
ID: | Fireworks AI | Meta | 131,072 | $0.9 prompt
$0.9 completion | diff --git a/apps/baseai.dev/content/docs/guides/memory-from-git.mdx b/apps/baseai.dev/content/docs/guides/memory-from-git.mdx index 8023709a..4361a838 100644 --- a/apps/baseai.dev/content/docs/guides/memory-from-git.mdx +++ b/apps/baseai.dev/content/docs/guides/memory-from-git.mdx @@ -8,7 +8,7 @@ tags: - langbase section: 'Memory' published: 2024-10-08 -modified: 2024-11-26 +modified: 2024-10-08 --- # Create a Memory from git Repository @@ -34,37 +34,27 @@ It will also prompt you if you want to create a memory from the current project Do you want to create memory from current project git repository? (yes/no) yes ``` -It will create a memory at `baseai/memory/chat-with-repo` and track files in the current git repository. It prints the path of the memory created. +## Step #3 Provide directory -Open that file in your editor, it looks like this: +Next, it will ask you which directory or subdirectory you want to use for the memory. You can select the current directory or any subdirectory. -```ts -import {MemoryI} from '@baseai/core'; +``` +Enter the path to the directory to track (relative to current directory): +``` -const chatWithRepoMemory = (): MemoryI => ({ - name: 'chat-with-repo', - description: "My list of docs as memory for an AI agent pipe", - git: { - enabled: true, - include: ['**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '' - } -}); +Provide the path relative to the root of the project directory that you want to use for the memory. E.g., `src/content/docs`, to use the `docs` directory in the `src/content` directory. -export default chatWithRepoMemory; -``` +## Step #4 Provide file extensions -Below is the explanation of the fields in the memory file: +Next, it will ask you which files extensions you want to track. You can provide a comma-separated list of file extensions. E.g., `.mdx,.md` to track markdown files. Alternatively, you can provide `*` to track all files. -- `enabled`: Set to `true` to enable tracking of git repository. -- `include`: Follows glob pattern to include files from the git repository. You can change the pattern to include only specific files or directories. -- `gitignore`: Set to `true` to include `.gitignore` file in the memory. -- `deployedAt`: Set to the commit hash where the memory was last deployed. It is used to track the changes in the memory for deployment. Try to avoid changing this field manually. -- `embeddedAt`: Set to the commit hash where the memory was last embedded. It is used to track the changes in the memory for local development. Try to avoid changing this field manually. +``` +Enter file extensions to track (use * for all, or comma-separated list, e.g., .md,.mdx) +``` -## Step #3 Deploy the memory +That's it! It creates a memory at `baseai/memory/chat-with-repo` in your current directory that tracks the git repository directory and file extensions you provided. + +## Step #5 Deploy the memory Commit all the changes to git and deploy. @@ -72,13 +62,12 @@ Commit all the changes to git and deploy. npx baseai@latest deploy -m chat-with-repo ``` ---- +Next time you want to update the memory with the latest changes from the git repository, you can run the `deploy` command again. Make sure to commit all the changes before deploying. -## Tracking changes from Git Repository +--- -That's it! Next time you make changes to the git repository, you can run the `deploy` command again to update the memory. Make sure to commit all the changes before deploying. +## Running the memory locally -Similarly, if you are using memory locally, make sure to `embed` the memory again after commit before running the AI agent pipe. As a result, it automatically updates the memory with the latest changes and record the hashes in the memory file. +You can embed the memory locally using the `embed` command. Just like any other memory and use it with a Pipe. Follow the [quickstart guide](/docs/memory/quickstart) to see how to embed and use the memory. --- - diff --git a/apps/baseai.dev/next.config.mjs b/apps/baseai.dev/next.config.mjs index 9564050d..fc785992 100644 --- a/apps/baseai.dev/next.config.mjs +++ b/apps/baseai.dev/next.config.mjs @@ -7,7 +7,6 @@ const nextConfig = { images: { domains: ['raw.githubusercontent.com/'] }, - transpilePackages: ['next-mdx-remote'], async redirects() { return []; } diff --git a/apps/baseai.dev/package.json b/apps/baseai.dev/package.json index c400ce7e..43ce4ecc 100644 --- a/apps/baseai.dev/package.json +++ b/apps/baseai.dev/package.json @@ -16,6 +16,7 @@ "@headlessui/react": "^1.7.15", "@headlessui/tailwindcss": "^0.2.0", "@heroicons/react": "^2.1.3", + "@intercom/messenger-js-sdk": "^0.0.14", "@mdx-js/loader": "^3.0.0", "@mdx-js/react": "^3.0.0", "@next/mdx": "^14.0.4", @@ -46,7 +47,7 @@ "mdast-util-to-string": "^4.0.0", "mdx-annotations": "^0.1.1", "mxcn": "^2.0.0", - "next": "14.2.35", + "next": "^14.0.4", "next-mdx-remote": "^5.0.0", "next-themes": "^0.2.1", "react": "^18.2.0", diff --git a/apps/baseai.dev/public/favicon/2024/android-chrome-192x192.png b/apps/baseai.dev/public/favicon/2024/android-chrome-192x192.png deleted file mode 100644 index ed7c8c99..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/android-chrome-192x192.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/android-chrome-512x512.png b/apps/baseai.dev/public/favicon/2024/android-chrome-512x512.png deleted file mode 100644 index 2de91b20..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/android-chrome-512x512.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/apple-touch-icon.png b/apps/baseai.dev/public/favicon/2024/apple-touch-icon.png deleted file mode 100644 index f3607b30..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/apple-touch-icon.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/browserconfig.xml b/apps/baseai.dev/public/favicon/2024/browserconfig.xml deleted file mode 100644 index b9639caf..00000000 --- a/apps/baseai.dev/public/favicon/2024/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #000000 - - - diff --git a/apps/baseai.dev/public/favicon/2024/favicon-16x16.png b/apps/baseai.dev/public/favicon/2024/favicon-16x16.png deleted file mode 100644 index d96c6e05..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/favicon-16x16.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/favicon-32x32.png b/apps/baseai.dev/public/favicon/2024/favicon-32x32.png deleted file mode 100644 index 2afa3606..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/favicon-32x32.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/favicon.ico b/apps/baseai.dev/public/favicon/2024/favicon.ico deleted file mode 100644 index 26fbba19..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/favicon.ico and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/mstile-144x144.png b/apps/baseai.dev/public/favicon/2024/mstile-144x144.png deleted file mode 100644 index 055941f8..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/mstile-144x144.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/mstile-150x150.png b/apps/baseai.dev/public/favicon/2024/mstile-150x150.png deleted file mode 100644 index 8f748f87..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/mstile-150x150.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/mstile-310x150.png b/apps/baseai.dev/public/favicon/2024/mstile-310x150.png deleted file mode 100644 index 05bd230f..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/mstile-310x150.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/mstile-310x310.png b/apps/baseai.dev/public/favicon/2024/mstile-310x310.png deleted file mode 100644 index f493e2ca..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/mstile-310x310.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/mstile-70x70.png b/apps/baseai.dev/public/favicon/2024/mstile-70x70.png deleted file mode 100644 index 46fab254..00000000 Binary files a/apps/baseai.dev/public/favicon/2024/mstile-70x70.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/2024/safari-pinned-tab.svg b/apps/baseai.dev/public/favicon/2024/safari-pinned-tab.svg deleted file mode 100644 index 8bb66010..00000000 --- a/apps/baseai.dev/public/favicon/2024/safari-pinned-tab.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - - - - - - diff --git a/apps/baseai.dev/public/favicon/2024/site.webmanifest b/apps/baseai.dev/public/favicon/2024/site.webmanifest deleted file mode 100644 index 1b51ab61..00000000 --- a/apps/baseai.dev/public/favicon/2024/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "LANGBASE", - "short_name": "LANGBASE", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#000000", - "background_color": "#000000", - "display": "standalone" -} diff --git a/apps/baseai.dev/public/favicon/old/android-chrome-192x192.png b/apps/baseai.dev/public/favicon/old/android-chrome-192x192.png deleted file mode 100644 index 1131a116..00000000 Binary files a/apps/baseai.dev/public/favicon/old/android-chrome-192x192.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/android-chrome-512x512.png b/apps/baseai.dev/public/favicon/old/android-chrome-512x512.png deleted file mode 100644 index b953c267..00000000 Binary files a/apps/baseai.dev/public/favicon/old/android-chrome-512x512.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/apple-touch-icon.png b/apps/baseai.dev/public/favicon/old/apple-touch-icon.png deleted file mode 100644 index 819ab604..00000000 Binary files a/apps/baseai.dev/public/favicon/old/apple-touch-icon.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/browserconfig.xml b/apps/baseai.dev/public/favicon/old/browserconfig.xml deleted file mode 100644 index b9639caf..00000000 --- a/apps/baseai.dev/public/favicon/old/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #000000 - - - diff --git a/apps/baseai.dev/public/favicon/old/favicon-16x16.png b/apps/baseai.dev/public/favicon/old/favicon-16x16.png deleted file mode 100644 index abd1f229..00000000 Binary files a/apps/baseai.dev/public/favicon/old/favicon-16x16.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/favicon-32x32.png b/apps/baseai.dev/public/favicon/old/favicon-32x32.png deleted file mode 100644 index 3f8fe83c..00000000 Binary files a/apps/baseai.dev/public/favicon/old/favicon-32x32.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/favicon.ico b/apps/baseai.dev/public/favicon/old/favicon.ico deleted file mode 100644 index 7c6d4a8a..00000000 Binary files a/apps/baseai.dev/public/favicon/old/favicon.ico and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/mstile-150x150.png b/apps/baseai.dev/public/favicon/old/mstile-150x150.png deleted file mode 100644 index edd66071..00000000 Binary files a/apps/baseai.dev/public/favicon/old/mstile-150x150.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/old/safari-pinned-tab.svg b/apps/baseai.dev/public/favicon/old/safari-pinned-tab.svg deleted file mode 100644 index 030832dd..00000000 --- a/apps/baseai.dev/public/favicon/old/safari-pinned-tab.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - - - - - - diff --git a/apps/baseai.dev/public/favicon/old/site.webmanifest b/apps/baseai.dev/public/favicon/old/site.webmanifest deleted file mode 100644 index 30ca3c44..00000000 --- a/apps/baseai.dev/public/favicon/old/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Langbase.com", - "short_name": "Langbase.com", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/apps/baseai.dev/public/favicon/svg-black/favicon.png b/apps/baseai.dev/public/favicon/svg-black/favicon.png deleted file mode 100644 index 0bd8dd5f..00000000 Binary files a/apps/baseai.dev/public/favicon/svg-black/favicon.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/svg-black/favicon.svg b/apps/baseai.dev/public/favicon/svg-black/favicon.svg deleted file mode 100644 index c31c3778..00000000 --- a/apps/baseai.dev/public/favicon/svg-black/favicon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/apps/baseai.dev/public/favicon/svg-white/favicon.png b/apps/baseai.dev/public/favicon/svg-white/favicon.png deleted file mode 100644 index 535f661e..00000000 Binary files a/apps/baseai.dev/public/favicon/svg-white/favicon.png and /dev/null differ diff --git a/apps/baseai.dev/public/favicon/svg-white/favicon.svg b/apps/baseai.dev/public/favicon/svg-white/favicon.svg deleted file mode 100644 index e02b9289..00000000 --- a/apps/baseai.dev/public/favicon/svg-white/favicon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/apps/baseai.dev/src/app/layout.tsx b/apps/baseai.dev/src/app/layout.tsx index f2542e5d..9db3326d 100644 --- a/apps/baseai.dev/src/app/layout.tsx +++ b/apps/baseai.dev/src/app/layout.tsx @@ -1,5 +1,5 @@ import { Providers } from '@/app/providers'; -import SupportButton from '@/components/support-button'; +import IntercomClient from '@/components/intercom'; import '@/styles/tailwind.css'; import { Inter } from 'next/font/google'; const inter = Inter({ subsets: ['latin'] }); @@ -53,7 +53,7 @@ export default async function RootLayout({ - + {children} diff --git a/apps/baseai.dev/src/components/intercom.tsx b/apps/baseai.dev/src/components/intercom.tsx new file mode 100644 index 00000000..e1360162 --- /dev/null +++ b/apps/baseai.dev/src/components/intercom.tsx @@ -0,0 +1,28 @@ +'use client'; + +import Intercom from '@intercom/messenger-js-sdk'; +import { useEffect } from 'react'; + +const IntercomClient = () => { + useEffect(() => { + // Initialize Intercom. + initializeIntercom(); + }, []); + + const initializeIntercom = () => { + // Check if app id exists. + if (!process.env.NEXT_PUBLIC_INTERCOM_APP_ID) { + return; + } + + Intercom({ + app_id: process.env.NEXT_PUBLIC_INTERCOM_APP_ID, + source: 'BaseAI', + created_at: new Date().getTime(), + }); + }; + + return <>; +}; + +export default IntercomClient; diff --git a/apps/baseai.dev/src/components/support-button.tsx b/apps/baseai.dev/src/components/support-button.tsx deleted file mode 100644 index 370acac5..00000000 --- a/apps/baseai.dev/src/components/support-button.tsx +++ /dev/null @@ -1,35 +0,0 @@ -'use client'; - -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger -} from '@/components/ui/tooltip'; - -export default function SupportButton() { - return ( - - - - - Contact Support - - - -

Contact Support

-
-
-
- ); -} \ No newline at end of file diff --git a/apps/baseai.dev/src/mdx/languages.mjs b/apps/baseai.dev/src/mdx/languages.mjs index 8074789c..2000aef5 100644 --- a/apps/baseai.dev/src/mdx/languages.mjs +++ b/apps/baseai.dev/src/mdx/languages.mjs @@ -1,23 +1,20 @@ -import { createRequire } from 'module'; - -const require = createRequire(import.meta.url); -const langGraphQL = require('shiki/languages/graphql.tmLanguage.json'); -const langJS = require('shiki/languages/javascript.tmLanguage.json'); -const langJSX = require('shiki/languages/jsx.tmLanguage.json'); -const langJSON = require('shiki/languages/json.tmLanguage.json'); -const langXML = require('shiki/languages/xml.tmLanguage.json'); -const langYAML = require('shiki/languages/yaml.tmLanguage.json'); -const langPHP = require('shiki/languages/php.tmLanguage.json'); -const langHTML = require('shiki/languages/html.tmLanguage.json'); -const langCSS = require('shiki/languages/css.tmLanguage.json'); -const langSCSS = require('shiki/languages/scss.tmLanguage.json'); -const langSASS = require('shiki/languages/sass.tmLanguage.json'); -const langLESS = require('shiki/languages/less.tmLanguage.json'); -const langMarkdown = require('shiki/languages/markdown.tmLanguage.json'); -const langTS = require('shiki/languages/typescript.tmLanguage.json'); -const langTSX = require('shiki/languages/tsx.tmLanguage.json'); -const langShell = require('shiki/languages/shellscript.tmLanguage.json'); -const langPy = require('shiki/languages/python.tmLanguage.json'); +import langGraphQL from 'shiki/languages/graphql.tmLanguage.json' assert { type: 'json' }; +import langJS from 'shiki/languages/javascript.tmLanguage.json' assert { type: 'json' }; +import langJSX from 'shiki/languages/jsx.tmLanguage.json' assert { type: 'json' }; +import langJSON from 'shiki/languages/json.tmLanguage.json' assert { type: 'json' }; +import langXML from 'shiki/languages/xml.tmLanguage.json' assert { type: 'json' }; +import langYAML from 'shiki/languages/yaml.tmLanguage.json' assert { type: 'json' }; +import langPHP from 'shiki/languages/php.tmLanguage.json' assert { type: 'json' }; +import langHTML from 'shiki/languages/html.tmLanguage.json' assert { type: 'json' }; +import langCSS from 'shiki/languages/css.tmLanguage.json' assert { type: 'json' }; +import langSCSS from 'shiki/languages/scss.tmLanguage.json' assert { type: 'json' }; +import langSASS from 'shiki/languages/sass.tmLanguage.json' assert { type: 'json' }; +import langLESS from 'shiki/languages/less.tmLanguage.json' assert { type: 'json' }; +import langMarkdown from 'shiki/languages/markdown.tmLanguage.json' assert { type: 'json' }; +import langTS from 'shiki/languages/typescript.tmLanguage.json' assert { type: 'json' }; +import langTSX from 'shiki/languages/tsx.tmLanguage.json' assert { type: 'json' }; +import langShell from 'shiki/languages/shellscript.tmLanguage.json' assert { type: 'json' }; +import langPy from 'shiki/languages/python.tmLanguage.json' assert { type: 'json' }; const lang = [ { diff --git a/apps/baseai.dev/src/mdx/rehype.mjs b/apps/baseai.dev/src/mdx/rehype.mjs index 34874934..3aa8ea37 100644 --- a/apps/baseai.dev/src/mdx/rehype.mjs +++ b/apps/baseai.dev/src/mdx/rehype.mjs @@ -1,15 +1,12 @@ -import { createRequire } from 'module'; import { slugifyWithCounter } from '@sindresorhus/slugify'; import * as acorn from 'acorn'; import { toString } from 'mdast-util-to-string'; import { mdxAnnotations } from 'mdx-annotations'; import shiki from 'shiki'; import { visit } from 'unist-util-visit'; +import theme from './themes/shades-of-purple.json' assert { type: 'json' }; import lang from './languages.mjs'; -const require = createRequire(import.meta.url); -const theme = require('./themes/shades-of-purple.json'); - export function rehypeParseCodeBlocks() { return tree => { visit(tree, 'element', (node, _nodeIndex, parentNode) => { diff --git a/apps/baseai.dev/src/styles/global.css b/apps/baseai.dev/src/styles/global.css index 7b656b4d..babdfeba 100644 --- a/apps/baseai.dev/src/styles/global.css +++ b/apps/baseai.dev/src/styles/global.css @@ -116,18 +116,3 @@ html { font-weight: normal; font-style: normal; } - -/* Crisp Chat Widget Style Overrides */ -#crisp-chatbox .cc-1d4mk.cc-8mq05 { - background-color: black !important; -} - -/* Additional selector for better specificity */ -#crisp-chatbox [data-id="chat_opened"] .cc-1d4mk { - background-color: black !important; -} - -/* Target the chat bubble background */ -.crisp-client .cc-1d4mk { - background-color: black !important; -} diff --git a/examples/agents/readme-writer-agent/baseai/memory/code-files/index.ts b/examples/agents/readme-writer-agent/baseai/memory/code-files/index.ts index 83215427..256869b0 100644 --- a/examples/agents/readme-writer-agent/baseai/memory/code-files/index.ts +++ b/examples/agents/readme-writer-agent/baseai/memory/code-files/index.ts @@ -1,14 +1,13 @@ import {MemoryI} from '@baseai/core'; +import path from 'path'; const memoryCodeFiles = (): MemoryI => ({ name: 'code-files', description: 'Memory that contains project files', - git: { - enabled: false, - include: ['documents/**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '', + config: { + useGitRepo: false, + dirToTrack: path.posix.join('.'), + extToTrack: ['*'], }, }); diff --git a/examples/agents/readme-writer-agent/package.json b/examples/agents/readme-writer-agent/package.json index e24cad5b..6570b7c3 100644 --- a/examples/agents/readme-writer-agent/package.json +++ b/examples/agents/readme-writer-agent/package.json @@ -32,7 +32,7 @@ "dependencies": { "@baseai/core": "^0.9.20", "@clack/prompts": "^0.7.0", - "chalk": "5.6.0", + "chalk": "^5.3.0", "clear-any-console": "^1.16.2", "figures": "^6.1.0", "picocolors": "^1.1.0", diff --git a/examples/astro/baseai/memory/chat-with-docs/index.ts b/examples/astro/baseai/memory/chat-with-docs/index.ts index 651e715f..3c9c53b3 100644 --- a/examples/astro/baseai/memory/chat-with-docs/index.ts +++ b/examples/astro/baseai/memory/chat-with-docs/index.ts @@ -1,14 +1,13 @@ import type {MemoryI} from '@baseai/core'; +import path from 'path'; const buidMemory = (): MemoryI => ({ name: 'chat-with-docs', description: 'Chat with given docs', - git: { - enabled: false, - include: ['documents/**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '', + config: { + useGitRepo: false, + dirToTrack: path.posix.join(''), + extToTrack: ['*'], }, }); diff --git a/examples/astro/package.json b/examples/astro/package.json index 95c957d2..bca1a46a 100644 --- a/examples/astro/package.json +++ b/examples/astro/package.json @@ -17,7 +17,7 @@ "@astrojs/react": "^3.6.2", "@astrojs/tailwind": "^5.1.1", "@astrojs/vercel": "^7.8.1", - "@baseai/core": "^0.9.43", + "@baseai/core": "^0.9.33", "@radix-ui/react-slot": "^1.1.0", "@types/react": "^18.3.9", "@types/react-dom": "^18.3.0", @@ -33,6 +33,6 @@ "typescript": "^5.6.2" }, "devDependencies": { - "baseai": "^0.9.44" + "baseai": "^0.9.33" } } diff --git a/examples/nextjs/app/api/langbase/pipes/run-tool-stream/route.ts b/examples/nextjs/app/api/langbase/pipes/run-tool-stream/route.ts index 16d72972..210be812 100644 --- a/examples/nextjs/app/api/langbase/pipes/run-tool-stream/route.ts +++ b/examples/nextjs/app/api/langbase/pipes/run-tool-stream/route.ts @@ -9,10 +9,9 @@ export async function POST(req: NextRequest) { const pipe = new Pipe(pipeWithToolsStream()); // 2. Run the pipe with user messages and other run options. - let {stream, threadId} = (await pipe.run({ - ...runOptions, - stream: true, - })) as unknown as RunResponseStream; + let {stream, threadId} = (await pipe.run( + runOptions, + )) as unknown as RunResponseStream; // 3. Stream the response. return new Response(stream, { diff --git a/examples/nextjs/baseai/memory/chat-with-docs/index.ts b/examples/nextjs/baseai/memory/chat-with-docs/index.ts index a2140495..58f08569 100644 --- a/examples/nextjs/baseai/memory/chat-with-docs/index.ts +++ b/examples/nextjs/baseai/memory/chat-with-docs/index.ts @@ -1,14 +1,13 @@ import {MemoryI} from '@baseai/core'; +import path from 'path'; const buidMemory = (): MemoryI => ({ name: 'chat-with-docs', description: 'Chat with given docs', - git: { - enabled: false, - include: ['documents/**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '', + config: { + useGitRepo: false, + dirToTrack: path.posix.join(''), + extToTrack: ['*'], }, }); diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index ca90550b..8bbafef7 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -11,14 +11,14 @@ "baseai": "baseai" }, "dependencies": { - "@baseai/core": "^0.9.43", + "@baseai/core": "^0.9.33", "@radix-ui/react-slot": "^1.1.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lucide-react": "^0.416.0", "mathjs": "^13.1.1", "mxcn": "^2.0.0", - "next": "14.2.35", + "next": "14.2.5", "openai": "^4.53.0", "react": "^18", "react-dom": "^18", @@ -29,7 +29,7 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", - "baseai": "^0.9.44", + "baseai": "^0.9.33", "eslint": "^8", "eslint-config-next": "14.2.5", "mini-css-extract-plugin": "^2.9.0", diff --git a/examples/nodejs/baseai/memory/ai-agent-memory/index.ts b/examples/nodejs/baseai/memory/ai-agent-memory/index.ts deleted file mode 100644 index 312ef85e..00000000 --- a/examples/nodejs/baseai/memory/ai-agent-memory/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {MemoryI} from '@baseai/core'; - -const memoryAiAgentMemory = (): MemoryI => ({ - name: 'ai-agent-memory', - description: 'My list of docs as memory for an AI agent pipe', - git: { - enabled: true, - include: ['**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '', - }, - documents: { - meta: doc => { - // generate a URL for each document - const url = `https://example.com/${doc.path}`; - return { - url, - name: doc.name, - }; - }, - }, -}); - -export default memoryAiAgentMemory; diff --git a/examples/nodejs/baseai/memory/chat-with-docs/index.ts b/examples/nodejs/baseai/memory/chat-with-docs/index.ts index 8f013d10..78711b34 100644 --- a/examples/nodejs/baseai/memory/chat-with-docs/index.ts +++ b/examples/nodejs/baseai/memory/chat-with-docs/index.ts @@ -1,14 +1,13 @@ import {MemoryI} from '@baseai/core'; +import path from 'path'; const buildMemory = (): MemoryI => ({ name: 'chat-with-docs', description: 'Chat with docs', - git: { - enabled: false, - include: ['documents/**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '', + config: { + useGitRepo: false, + dirToTrack: path.posix.join(''), + extToTrack: ['*'], }, }); diff --git a/examples/nodejs/baseai/memory/chat-with-repo/index.ts b/examples/nodejs/baseai/memory/chat-with-repo/index.ts index 60baccc4..c9faa3e7 100644 --- a/examples/nodejs/baseai/memory/chat-with-repo/index.ts +++ b/examples/nodejs/baseai/memory/chat-with-repo/index.ts @@ -1,15 +1,14 @@ -import {MemoryI} from '@baseai/core'; +import { MemoryI } from '@baseai/core'; +import path from 'path'; const memoryChatWithRepo = (): MemoryI => ({ - name: 'chat-with-repo', - description: '', - git: { - enabled: true, - include: ['examples/**/*'], - gitignore: true, - deployedAt: '', - embeddedAt: '', - }, + name: 'chat-with-repo', + description: '', + config: { + useGitRepo: true, + dirToTrack: path.posix.join('examples'), + extToTrack: ["*"] + } }); export default memoryChatWithRepo; diff --git a/examples/nodejs/package.json b/examples/nodejs/package.json index 5be76560..4c48ca12 100644 --- a/examples/nodejs/package.json +++ b/examples/nodejs/package.json @@ -17,11 +17,11 @@ "author": "Ahmad Awais (https://twitter.com/MrAhmadAwais)", "license": "UNLICENSED", "dependencies": { - "@baseai/core": "^0.9.43", + "@baseai/core": "^0.9.33", "dotenv": "^16.4.5" }, "devDependencies": { - "baseai": "^0.9.44", + "baseai": "^0.9.33", "tsx": "^4.19.0" } } diff --git a/examples/remix/baseai/memory/chat-with-docs/index.ts b/examples/remix/baseai/memory/chat-with-docs/index.ts index 925380b1..58f08569 100644 --- a/examples/remix/baseai/memory/chat-with-docs/index.ts +++ b/examples/remix/baseai/memory/chat-with-docs/index.ts @@ -1,10 +1,14 @@ import {MemoryI} from '@baseai/core'; +import path from 'path'; const buidMemory = (): MemoryI => ({ name: 'chat-with-docs', description: 'Chat with given docs', - useGit: false, - include: ['documents/**/*'], + config: { + useGitRepo: false, + dirToTrack: path.posix.join(''), + extToTrack: ['*'], + }, }); export default buidMemory; diff --git a/examples/remix/package.json b/examples/remix/package.json index 494b703c..dbd12357 100644 --- a/examples/remix/package.json +++ b/examples/remix/package.json @@ -13,7 +13,7 @@ "baseai": "baseai" }, "dependencies": { - "@baseai/core": "^0.9.43", + "@baseai/core": "^0.9.33", "@radix-ui/react-slot": "^1.1.0", "@remix-run/node": "2.12.0", "@remix-run/react": "2.12.0", @@ -35,7 +35,7 @@ "@typescript-eslint/parser": "^6.7.4", "@vercel/remix": "2.12.0", "autoprefixer": "^10.4.20", - "baseai": "^0.9.44", + "baseai": "^0.9.33", "eslint": "^8.38.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.28.1", diff --git a/packages/baseai/CHANGELOG.md b/packages/baseai/CHANGELOG.md index d1b20baa..4bbc2087 100644 --- a/packages/baseai/CHANGELOG.md +++ b/packages/baseai/CHANGELOG.md @@ -1,71 +1,5 @@ # baseai -## 0.9.44 - -### Patch Changes - -- 👌 IMPROVE: Pinned chalk version - -## 0.9.43 - -### Patch Changes - -- Fix moderation - -## 0.9.42 - -### Patch Changes - -- 📦 NEW: LB-LLM-Key header support - -## 0.9.41 - -### Patch Changes - -- 🐛 FIX: Google stream - -## 0.9.40 - -### Patch Changes - -- 📦 NEW: meta-llama/Llama-3.3-70B-Instruct-Turbo model - -## 0.9.39 - -### Patch Changes - -- 📦 NEW: tools support in pipe.run() - -## 0.9.38 - -### Patch Changes - -- 📦 NEW: .env file based BaseAI auth - -## 0.9.37 - -### Patch Changes - -- 👌 IMPROVE: Remove unused type - -## 0.9.36 - -### Patch Changes - -- 📦 NEW: Dynamically set document metadata - -## 0.9.35 - -### Patch Changes - -- 📦 NEW: Pipe API key support in pipe.run() - -## 0.9.34 - -### Patch Changes - -- 👌 IMPROVE: Memory config with new features and better UX - ## 0.9.33 ### Patch Changes diff --git a/packages/baseai/package.json b/packages/baseai/package.json index fb30c983..0e1c22c1 100644 --- a/packages/baseai/package.json +++ b/packages/baseai/package.json @@ -1,7 +1,7 @@ { "name": "baseai", "description": "The Web AI Framework Dev - BaseAI.dev", - "version": "0.9.44", + "version": "0.9.33", "license": "UNLICENSED", "type": "module", "main": "./dist/index.js", @@ -52,7 +52,7 @@ "@hono/zod-openapi": "^0.16.0", "@sindresorhus/slugify": "^2.2.1", "camelcase": "^8.0.0", - "chalk": "5.6.0", + "chalk": "^5.3.0", "cli-alerts": "^2.0.0", "cli-handle-error": "^4.4.0", "cli-handle-unhandled": "^1.1.1", @@ -60,11 +60,11 @@ "cli-table3": "^0.6.5", "cli-welcome": "^3.0.0", "compute-cosine-similarity": "^1.1.0", + "conf": "^13.0.1", "cosmiconfig": "^9.0.0", "cosmiconfig-typescript-loader": "^5.0.0", "dotenv": "^16.4.5", "execa": "^9.4.0", - "fast-glob": "^3.3.2", "figures": "^6.1.0", "get-package-json-file": "^2.0.0", "hono": "^4.5.11", diff --git a/packages/baseai/src/add/index.ts b/packages/baseai/src/add/index.ts index 27720abb..46fd3fb3 100644 --- a/packages/baseai/src/add/index.ts +++ b/packages/baseai/src/add/index.ts @@ -1,10 +1,10 @@ +import { getStoredAuth } from '@/auth'; import { dim, dimItalic } from '@/utils/formatting'; import { getAvailablePipes } from '@/utils/get-available-pipes'; import { getAvailableTools } from '@/utils/get-available-tools'; import { heading } from '@/utils/heading'; import icons from '@/utils/icons'; import { isToolPresent } from '@/utils/is-tool-present'; -import { retrieveAuthentication } from '@/utils/retrieve-credentials'; import { formatCode } from '@/utils/ts-format-code'; import * as p from '@clack/prompts'; import slugify from '@sindresorhus/slugify'; @@ -43,6 +43,37 @@ function extractLoginName(loginAndPipe: string) { }; } +/** + * Represents an account with login credentials and an API key. + */ +interface Account { + login: string; + apiKey: string; +} + +/** + * Retrieves the stored authentication account. + * + * This function attempts to retrieve the stored authentication account + * asynchronously. If the account is found, it is returned. If no account + * is found or an error occurs during retrieval, `null` is returned. + * + * @returns {Promise} A promise that resolves to the stored + * authentication account, or `null` if no account is found or an error occurs. + */ +async function retrieveAuthentication(): Promise { + try { + const account = await getStoredAuth(); + if (!account) return null; + + return account; + } catch (error) { + p.log.error( + `Error retrieving stored auth: ${(error as Error).message}` + ); + return null; + } +} /** * Fetches a pipe from Langbase using the provided login and name. @@ -62,17 +93,9 @@ async function getPipe({ name: string; spinner: Spinner; }) { + spinner.start('Fetching pipe from Langbase'); try { - const account = await retrieveAuthentication({ spinner }); - if (!account) { - p.log.error( - 'Authentication failed. Please run "npx baseai auth" to authenticate.' - ); - return; - } - - spinner.start('Fetching pipe from Langbase'); - + const account = await retrieveAuthentication(); const API_URL = `https://api.langbase.com/v1/pipes/${login}/${name}`; const createResponse = await fetch(API_URL, { diff --git a/packages/baseai/src/auth/index.ts b/packages/baseai/src/auth/index.ts index d042df4f..1309548b 100644 --- a/packages/baseai/src/auth/index.ts +++ b/packages/baseai/src/auth/index.ts @@ -9,11 +9,21 @@ import { outro, password } from '@clack/prompts'; -import fs from 'fs/promises'; +import Conf from 'conf'; +import fs from 'fs'; import open from 'open'; import path from 'path'; import color from 'picocolors'; +const config = new Conf({ + projectName: 'baseai' +}); + +interface Account { + login: string; + apiKey: string; +} + export async function auth() { p.intro( heading({ @@ -62,6 +72,17 @@ export async function auth() { process.exit(1); } + // Store in Conf (old functionality) + const newAccount: Account = { login, apiKey }; + const existingAccounts = (config.get('accounts') as Account[]) || []; + const updatedAccounts = [...existingAccounts, newAccount]; + config.set('accounts', updatedAccounts); + + // Store in .env file (new functionality) + // const envKeyName = apiKey.startsWith('user_') + // ? 'LANGBASE_USER_API_KEY' + // : 'LANGBASE_ORG_API_KEY'; + const envKeyName = 'LANGBASE_API_KEY'; const envContent = `\n# Langbase API key for https://langbase.com/${login}\n${envKeyName}=${apiKey}\n\n`; @@ -78,45 +99,37 @@ export async function auth() { const baiConfig = await loadConfig(); let envFile = baiConfig.envFilePath || '.env'; - const envFileContent = await fs.readFile(envFile, 'utf-8'); - - const oldKey = envFileContent - .split('\n') - .reverse() // Reverse to get the latest key if there are multiple - .find(line => line.includes('LANGBASE_API_KEY')) - ?.split('=')[1]; - - if (oldKey) { - const shouldOverwrite = await confirm({ - message: `API key found in ${envFile}. Overwrite?` - }); - - if (isCancel(shouldOverwrite)) { - cancel('Operation cancelled.'); - process.exit(0); - } - - if (!shouldOverwrite) { - outro( - color.yellow('API key is not overwritten.') - ); - process.exit(0); - } - - const newEnvContent = envFileContent.replace( - new RegExp(`LANGBASE_API_KEY=${oldKey}`), - envContent.trim() - ); - - await fs.writeFile(path.join(process.cwd(), envFile), newEnvContent); - } else { - await fs.appendFile(path.join(process.cwd(), envFile), envContent); - } + fs.appendFileSync(path.join(process.cwd(), envFile), envContent); outro( color.green( - `Authentication successful. API key is stored in ${envFile}` + `Authentication successful. Credentials stored in config and ${envFile}` ) ); + console.log(color.dim(`Config file location: ${config.path}`)); process.exit(0); } + +export function getStoredAuth(): Account | undefined { + const accounts = (config.get('accounts') as Account[]) || []; + const currentLogin = config.get('currentAccount') as string | undefined; + + if (currentLogin) { + return accounts.find(account => account.login === currentLogin); + } + + return accounts[0]; // Return the first account if no current account is set +} + +export function getStoredAccounts(): Account[] { + return (config.get('accounts') as Account[]) || []; +} + +export function setCurrentAccount(login: string): boolean { + const accounts = getStoredAccounts(); + if (accounts.some(account => account.login === login)) { + config.set('currentAccount', login); + return true; + } + return false; +} diff --git a/packages/baseai/src/data/models.ts b/packages/baseai/src/data/models.ts index d8c4e055..83f2fa2b 100644 --- a/packages/baseai/src/data/models.ts +++ b/packages/baseai/src/data/models.ts @@ -253,12 +253,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { } ], [TOGETHER_AI]: [ - { - id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', - provider: TOGETHER_AI, - promptCost: 0.88, - completionCost: 0.88, - }, { id: 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo', provider: TOGETHER_AI, @@ -433,12 +427,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { } ], [GROQ]: [ - { - id: 'llama-3.3-70b-versatile', - provider: GROQ, - promptCost: 0.59, - completionCost: 0.79, - }, { id: 'llama-3.1-70b-versatile', provider: GROQ, @@ -539,12 +527,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { } ], [FIREWORKS_AI]: [ - { - id: 'llama-v3p3-70b-instruct', - provider: FIREWORKS_AI, - promptCost: 0.88, - completionCost: 0.88, - }, { id: 'llama-v3p1-405b-instruct', provider: FIREWORKS_AI, diff --git a/packages/baseai/src/deploy/document.ts b/packages/baseai/src/deploy/document.ts index 484adbca..6692d3c9 100644 --- a/packages/baseai/src/deploy/document.ts +++ b/packages/baseai/src/deploy/document.ts @@ -7,7 +7,9 @@ import { handleError, handleInvalidConfig, listMemoryDocuments, + retrieveAuthentication, uploadDocumentsToMemory, + type Account } from '.'; import path from 'path'; import fs from 'fs/promises'; @@ -19,7 +21,6 @@ import { } from '@/utils/memory/load-memory-files'; import type { MemoryI } from 'types/memory'; import { compareDocumentLists } from '@/utils/memory/compare-docs-list'; -import { retrieveAuthentication, type Account } from '@/utils/retrieve-credentials'; type Spinner = ReturnType; diff --git a/packages/baseai/src/deploy/index.ts b/packages/baseai/src/deploy/index.ts index 8e2a64ba..a4263399 100644 --- a/packages/baseai/src/deploy/index.ts +++ b/packages/baseai/src/deploy/index.ts @@ -18,19 +18,17 @@ import path from 'path'; import color from 'picocolors'; import { type MemoryI } from 'types/memory'; import type { Pipe, PipeOld } from 'types/pipe'; +import { getStoredAuth } from './../auth/index'; import { handleGitSyncMemories, updateDeployedCommitHash } from '@/utils/memory/git-sync/handle-git-sync-memories'; import { handleSingleDocDeploy } from './document'; -import { - generateUpgradeInstructions, - isOldMemoryConfigFormat -} from '@/utils/memory/handle-old-memory-config'; -import { - retrieveAuthentication, - type Account -} from '@/utils/retrieve-credentials'; + +export interface Account { + login: string; + apiKey: string; +} interface ErrorResponse { error?: { message: string }; @@ -159,6 +157,26 @@ async function readToolsDirectory({ } } +export async function retrieveAuthentication({ + spinner +}: { + spinner: Spinner; +}): Promise { + spinner.start('Retrieving stored authentication'); + try { + const account = await getStoredAuth(); + if (!account) { + handleNoAccountFound({ spinner }); + return null; + } + spinner.stop(`Deploying as ${color.cyan(account.login)}`); + return account; + } catch (error) { + handleAuthError({ spinner, error }); + return null; + } +} + async function deployPipes({ spinner, pipes, @@ -335,6 +353,23 @@ function handleDirectoryReadError({ } } +function handleNoAccountFound({ spinner }: { spinner: Spinner }): void { + spinner.stop('No account found'); + p.log.warn('No account found. Please authenticate first.'); + p.log.info(`Run: ${color.green('npx baseai auth')}`); +} + +function handleAuthError({ + spinner, + error +}: { + spinner: Spinner; + error: unknown; +}): void { + spinner.stop('Failed to retrieve authentication'); + p.log.error(`Error retrieving stored auth: ${(error as Error).message}`); +} + export function handleInvalidConfig({ spinner, name, @@ -447,27 +482,19 @@ export async function deployMemory({ p.log.step(`Processing documents for memory: ${memoryNameWithoutExt}`); - if (isOldMemoryConfigFormat(memoryObject)) { - p.note(generateUpgradeInstructions(memoryObject)); - p.cancel( - 'Deployment cancelled. Please update your memory config file to the new format.' - ); - process.exit(1); - } - let filesToDeploy: string[] = []; let filesToDelete: string[] = []; let memoryDocs: MemoryDocumentI[] = []; // Git sync memories - if (memoryObject.git.enabled) { + if (memoryObject.config?.useGitRepo) { // Get names of files to deploy, i.e., changed or new files const { filesToDeploy: gitFilesToDeploy, filesToDelete: gitFilesToDelete } = await handleGitSyncMemories({ memoryName: memoryNameWithoutExt, - config: memoryObject, + config: memoryObject.config, account }); @@ -503,7 +530,7 @@ export async function deployMemory({ documents: memoryDocs, account, overwrite, - isGitSync: memoryObject.git.enabled, + isGitSync: memoryObject.config?.useGitRepo, docsToDelete: filesToDelete }); spinner.stop(`Deployment finished memory: ${memoryObject.name}`); @@ -650,8 +677,7 @@ export async function uploadDocumentsToMemory({ const signedUrl = await getSignedUploadUrl({ documentName: doc.name, memoryName: name, - account, - meta: doc.meta + account }); const uploadResponse = await uploadDocument(signedUrl, doc.blob); @@ -881,18 +907,21 @@ export async function listMemoryDocuments({ async function getSignedUploadUrl({ documentName, memoryName, - account, - meta + account }: { documentName: string; memoryName: string; account: Account; - meta: Record; }): Promise { const { uploadDocument } = getMemoryApiUrls({ memoryName }); + const isOrgAccount = account.apiKey.includes(':'); + + const ownerLogin = isOrgAccount + ? account.apiKey.split(':')[0] + : account.login; try { const response = await fetch(uploadDocument, { method: 'POST', @@ -901,8 +930,8 @@ async function getSignedUploadUrl({ Authorization: `Bearer ${account.apiKey}` }, body: JSON.stringify({ - meta, memoryName, + ownerLogin, fileName: documentName }) }); @@ -1139,10 +1168,10 @@ export async function deploySingleMemory({ // Retrieve authentication const account = await retrieveAuthentication({ spinner }); if (!account) { - p.outro( - `No account found. Skipping deployment. \n Run: ${cyan('npx baseai@latest auth')}` + p.log.error( + 'Authentication failed. Please run "npx baseai auth" to authenticate.' ); - process.exit(1); + return; } // Call deployMemory function @@ -1155,7 +1184,7 @@ export async function deploySingleMemory({ }); p.outro(`Successfully deployed memory: ${memoryName}`); - process.exit(0); + process.exit(1); } catch (error) { if (error instanceof Error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') { diff --git a/packages/baseai/src/dev/data/models.ts b/packages/baseai/src/dev/data/models.ts index b82060c5..8480aae7 100644 --- a/packages/baseai/src/dev/data/models.ts +++ b/packages/baseai/src/dev/data/models.ts @@ -173,12 +173,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { } ], [TOGETHER_AI]: [ - { - id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', - provider: TOGETHER_AI, - promptCost: 0.88, - completionCost: 0.88, - }, { id: 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo', provider: TOGETHER_AI, @@ -353,12 +347,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { } ], [GROQ]: [ - { - id: 'llama-3.3-70b-versatile', - provider: GROQ, - promptCost: 0.59, - completionCost: 0.79, - }, { id: 'llama-3.1-70b-versatile', provider: GROQ, @@ -459,12 +447,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { } ], [FIREWORKS_AI]: [ - { - id: 'llama-v3p3-70b-instruct', - provider: FIREWORKS_AI, - promptCost: 0.88, - completionCost: 0.88, - }, { id: 'llama-v3p1-405b-instruct', provider: FIREWORKS_AI, diff --git a/packages/baseai/src/dev/llms/call-anthropic.ts b/packages/baseai/src/dev/llms/call-anthropic.ts index 432b78d9..70586e57 100644 --- a/packages/baseai/src/dev/llms/call-anthropic.ts +++ b/packages/baseai/src/dev/llms/call-anthropic.ts @@ -6,24 +6,21 @@ import { handleLlmError } from './utils'; import type { ModelParams } from 'types/providers'; import type { Message, Pipe } from 'types/pipe'; import { addToolsToParams } from '../utils/add-tools-to-params'; -import type { PipeTool } from 'types/tools'; export async function callAnthropic({ pipe, messages, llmApiKey, - stream, - paramsTools + stream }: { pipe: Pipe; llmApiKey: string; stream: boolean; messages: Message[]; - paramsTools: PipeTool[] | undefined; }) { try { const modelParams = buildModelParams(pipe, stream, messages); - addToolsToParams(modelParams, pipe, paramsTools); + addToolsToParams(modelParams, pipe); // Transform params according to provider's format const transformedRequestParams = transformToProviderRequest({ diff --git a/packages/baseai/src/dev/llms/call-google.ts b/packages/baseai/src/dev/llms/call-google.ts index 19ba6792..ab8fa45e 100644 --- a/packages/baseai/src/dev/llms/call-google.ts +++ b/packages/baseai/src/dev/llms/call-google.ts @@ -6,24 +6,21 @@ import { applyJsonModeIfEnabledForGoogle, handleLlmError } from './utils'; import type { ModelParams } from 'types/providers'; import type { Message, Pipe } from 'types/pipe'; import { addToolsToParams } from '../utils/add-tools-to-params'; -import type { PipeTool } from 'types/tools'; export async function callGoogle({ pipe, messages, llmApiKey, - stream, - paramsTools + stream }: { pipe: Pipe; stream: boolean; llmApiKey: string; messages: Message[]; - paramsTools: PipeTool[] | undefined; }) { try { const modelParams = buildModelParams(pipe, stream, messages); - addToolsToParams(modelParams, pipe, paramsTools); + addToolsToParams(modelParams, pipe); // Transform params according to provider's format const transformedRequestParams = transformToProviderRequest({ diff --git a/packages/baseai/src/dev/llms/call-llm.ts b/packages/baseai/src/dev/llms/call-llm.ts index dcbf9b74..03bef537 100644 --- a/packages/baseai/src/dev/llms/call-llm.ts +++ b/packages/baseai/src/dev/llms/call-llm.ts @@ -27,22 +27,19 @@ import { callPerplexity } from './call-perplexity'; import { callTogether } from './call-together'; import { callXAI } from './call-xai'; import { getProvider } from '../utils/get-provider'; -import type { PipeTool } from 'types/tools'; export async function callLLM({ pipe, stream, messages, llmApiKey, - variables, - paramsTools + variables }: { pipe: Pipe; stream: boolean; llmApiKey: string; messages: Message[]; variables?: VariablesI; - paramsTools: PipeTool[] | undefined; }) { try { // Get the model provider from the pipe. @@ -73,8 +70,7 @@ export async function callLLM({ pipe, stream, messages, - llmApiKey, - paramsTools + llmApiKey }); } @@ -82,10 +78,9 @@ export async function callLLM({ dlog('ANTHROPIC', '✅'); return await callAnthropic({ pipe, - stream, messages, llmApiKey, - paramsTools + stream }); } @@ -93,10 +88,9 @@ export async function callLLM({ dlog('TOGETHER_AI', '✅'); return await callTogether({ pipe, - stream, messages, llmApiKey, - paramsTools, + stream }); } @@ -116,8 +110,7 @@ export async function callLLM({ pipe, messages, llmApiKey, - stream, - paramsTools + stream }); } @@ -127,8 +120,7 @@ export async function callLLM({ pipe, messages, llmApiKey, - stream, - paramsTools + stream }); } diff --git a/packages/baseai/src/dev/llms/call-openai.ts b/packages/baseai/src/dev/llms/call-openai.ts index 00afca25..7eb8dab1 100644 --- a/packages/baseai/src/dev/llms/call-openai.ts +++ b/packages/baseai/src/dev/llms/call-openai.ts @@ -7,20 +7,17 @@ import { applyJsonModeIfEnabled, handleLlmError } from './utils'; import type { Message, Pipe } from 'types/pipe'; import type { ModelParams } from 'types/providers'; import { addToolsToParams } from '../utils/add-tools-to-params'; -import type { PipeTool } from 'types/tools'; export async function callOpenAI({ pipe, stream, llmApiKey, - messages, - paramsTools + messages }: { pipe: Pipe; stream: boolean; llmApiKey: string; messages: Message[]; - paramsTools: PipeTool[] | undefined; }) { try { validateInput(pipe, messages); @@ -28,7 +25,7 @@ export async function callOpenAI({ await moderateContent(openai, messages, pipe.moderate); const modelParams = buildModelParams(pipe, stream, messages); - addToolsToParams(modelParams, pipe, paramsTools); + addToolsToParams(modelParams, pipe); applyJsonModeIfEnabled(modelParams, pipe); dlog('modelParams', modelParams); diff --git a/packages/baseai/src/dev/llms/call-together.ts b/packages/baseai/src/dev/llms/call-together.ts index 76baeb0d..5ab8250a 100644 --- a/packages/baseai/src/dev/llms/call-together.ts +++ b/packages/baseai/src/dev/llms/call-together.ts @@ -5,20 +5,17 @@ import { applyJsonModeIfEnabled, handleLlmError } from './utils'; import type { Message, Pipe } from 'types/pipe'; import type { ModelParams } from 'types/providers'; import { addToolsToParams } from '../utils/add-tools-to-params'; -import type { PipeTool } from 'types/tools'; export async function callTogether({ pipe, messages, llmApiKey, - stream, - paramsTools + stream }: { pipe: Pipe; llmApiKey: string; stream: boolean; messages: Message[]; - paramsTools: PipeTool[] | undefined; }) { try { const modelParams = buildModelParams(pipe, stream, messages); @@ -32,7 +29,7 @@ export async function callTogether({ // Together behaves weirdly with stop value. Omitting it. delete modelParams['stop']; applyJsonModeIfEnabled(modelParams, pipe); - addToolsToParams(modelParams, pipe, paramsTools); + addToolsToParams(modelParams, pipe); dlog('modelParams', modelParams); return await together.chat.completions.create(modelParams as any); diff --git a/packages/baseai/src/dev/llms/call-xai.ts b/packages/baseai/src/dev/llms/call-xai.ts index d10e605d..6d3baad5 100644 --- a/packages/baseai/src/dev/llms/call-xai.ts +++ b/packages/baseai/src/dev/llms/call-xai.ts @@ -5,20 +5,17 @@ import { handleLlmError } from './utils'; import type { Message, Pipe } from 'types/pipe'; import type { ModelParams } from 'types/providers'; import { addToolsToParams } from '../utils/add-tools-to-params'; -import type { PipeTool } from 'types/tools'; export async function callXAI({ pipe, stream, llmApiKey, - messages, - paramsTools + messages }: { pipe: Pipe; stream: boolean; llmApiKey: string; messages: Message[]; - paramsTools: PipeTool[] | undefined; }) { try { const modelParams = buildModelParams(pipe, stream, messages); @@ -30,7 +27,7 @@ export async function callXAI({ }); // Add tools (functions) to modelParams - addToolsToParams(modelParams, pipe, paramsTools); + addToolsToParams(modelParams, pipe); dlog('modelParams', modelParams); return await groq.chat.completions.create(modelParams as any); diff --git a/packages/baseai/src/dev/providers/google/chatComplete.ts b/packages/baseai/src/dev/providers/google/chatComplete.ts index d5b45b34..3b90512e 100644 --- a/packages/baseai/src/dev/providers/google/chatComplete.ts +++ b/packages/baseai/src/dev/providers/google/chatComplete.ts @@ -439,7 +439,7 @@ export const GoogleChatCompleteStreamChunkTransform: ( model: '', provider: 'google', choices: - parsedChunk.candidates?.map((generation, index) => { + parsedChunk.candidates?.map(generation => { let message: ProviderMessage = { role: 'assistant', content: '' @@ -473,7 +473,7 @@ export const GoogleChatCompleteStreamChunkTransform: ( } return { delta: message, - index: generation.index ?? index, + index: generation.index, finish_reason: generation.finishReason }; }) ?? [] diff --git a/packages/baseai/src/dev/routes/beta/pipes/run.ts b/packages/baseai/src/dev/routes/beta/pipes/run.ts index ddb88673..867c07b2 100644 --- a/packages/baseai/src/dev/routes/beta/pipes/run.ts +++ b/packages/baseai/src/dev/routes/beta/pipes/run.ts @@ -4,7 +4,7 @@ import { dlog } from '@/dev/utils/dlog'; import { handleStreamingResponse } from '@/dev/utils/provider-handlers/streaming-response-handler'; import { logger } from '@/utils/logger-utils'; import { Hono } from 'hono'; -import { schemaMessage, VariablesSchema } from 'types/pipe'; +import { schemaMessage, schemaPipeMessage, VariablesSchema } from 'types/pipe'; import { z } from 'zod'; // Schema definitions @@ -31,7 +31,7 @@ const PipeSchema = z.object({ status: z.string(), meta: MetaSchema, model: ModelSchema, - messages: z.array(schemaMessage), + messages: z.array(schemaPipeMessage), functions: z.array(z.unknown()).default([]), memorysets: z.array(z.string().trim().min(1)).default([]), variables: VariablesSchema diff --git a/packages/baseai/src/dev/routes/v1/pipes/run.ts b/packages/baseai/src/dev/routes/v1/pipes/run.ts index c58d0db2..26b538e7 100644 --- a/packages/baseai/src/dev/routes/v1/pipes/run.ts +++ b/packages/baseai/src/dev/routes/v1/pipes/run.ts @@ -44,7 +44,6 @@ const RequestBodySchema = z.object({ stream: z.boolean(), messages: z.array(schemaMessage), llmApiKey: z.string(), - tools: z.array(pipeToolSchema).optional(), variables: VariablesSchema.optional() }); @@ -139,8 +138,7 @@ const handleRun = async (c: any) => { messages, llmApiKey, stream, - variables, - paramsTools: validatedBody.tools + variables }); return processLlmResponse(c, validatedBody, rawLlmResponse); diff --git a/packages/baseai/src/dev/utils/add-tools-to-params.ts b/packages/baseai/src/dev/utils/add-tools-to-params.ts index 83816e61..bf7bfa08 100644 --- a/packages/baseai/src/dev/utils/add-tools-to-params.ts +++ b/packages/baseai/src/dev/utils/add-tools-to-params.ts @@ -1,19 +1,10 @@ -import type { Pipe, ToolCall } from 'types/pipe'; +import type { Pipe } from 'types/pipe'; import { getProvider } from './get-provider'; import { getSupportedToolSettings, hasToolSupport } from './has-tool-support'; -import type { ModelParams } from 'types/providers'; -import type { PipeTool } from 'types/tools'; +import type { ModelParams, Tool } from 'types/providers'; -export function addToolsToParams( - modelParams: ModelParams, - pipe: Pipe, - paramsTools: PipeTool[] | undefined -) { - const pipeTools = pipe.tools as unknown as string[]; - const hasParamsTools = paramsTools && paramsTools.length > 0; - - // 1. If no tools are provided, return the modelParams as is - if (!hasParamsTools && !pipeTools.length) return modelParams; +export function addToolsToParams(modelParams: ModelParams, pipe: Pipe) { + if (!pipe.tools.length) return; const [providerString, modelName] = pipe.model.split(':'); const provider = getProvider(providerString); @@ -24,30 +15,21 @@ export function addToolsToParams( provider }); - // 2. If the model does not support tool calls, return the modelParams as is - if (!hasToolCallSupport) return modelParams; - - // If tools are provided in request param, prioritize and use them - if (hasParamsTools) { - modelParams.tools = paramsTools as ToolCall[]; - } - - // If tools are not provided in request param, use the tools from the pipe config - if (!hasParamsTools && pipeTools.length) { - modelParams.tools = pipe.tools as ToolCall[]; - } + if (hasToolCallSupport) { + const { hasParallelToolCallSupport, hasToolChoiceSupport } = + getSupportedToolSettings({ + modelName, + provider + }); - const { hasParallelToolCallSupport, hasToolChoiceSupport } = - getSupportedToolSettings({ - modelName, - provider - }); + if (hasParallelToolCallSupport) { + modelParams.parallel_tool_calls = pipe.parallel_tool_calls; + } - if (hasParallelToolCallSupport) { - modelParams.parallel_tool_calls = pipe.parallel_tool_calls; - } + if (hasToolChoiceSupport) { + modelParams.tool_choice = pipe.tool_choice; + } - if (hasToolChoiceSupport) { - modelParams.tool_choice = pipe.tool_choice; + modelParams.tools = pipe.tools as Tool[]; } } diff --git a/packages/baseai/src/dev/utils/moderate.ts b/packages/baseai/src/dev/utils/moderate.ts index 739cdde7..36b0dc0d 100644 --- a/packages/baseai/src/dev/utils/moderate.ts +++ b/packages/baseai/src/dev/utils/moderate.ts @@ -29,10 +29,7 @@ export async function moderate({ } // Perform moderation on the constructed prompt text - const moderation = await openai.moderations.create({ - model: 'omni-moderation-latest', - input: promptText - }); + const moderation = await openai.moderations.create({ input: promptText }); const result = moderation?.results[0]; // dlog('moderation:', result); diff --git a/packages/baseai/src/dev/utils/thread/get-message-content.ts b/packages/baseai/src/dev/utils/thread/get-message-content.ts new file mode 100644 index 00000000..011f4879 --- /dev/null +++ b/packages/baseai/src/dev/utils/thread/get-message-content.ts @@ -0,0 +1,36 @@ +import type { Message } from 'types/pipe'; + +export function getMessageContent(message: Message): string | null { + // Tool calls have no content + if (!message?.content) return null; + + // If content is a string, return it + if (typeof message.content === 'string') { + return message.content; + } + + /** + * If content is an array, find the text content part and return its text + * + * 1. Image messages have text and image content objects + * {"type": "text", "text": "What’s in this image?"}, + * { + * "type": "image_url", + * "image_url": { + * "url": "", + * }, + * }, + * + * 2. Audio messages always have text and audio content objects + * content: [ + * {type: 'text', text: 'What is in this recording?'}, + * {type: 'input_audio', input_audio: {data: base64str, format: 'wav'}}, + * ]; + */ + + if (Array.isArray(message.content)) { + return message.content.find(item => item.type === 'text')?.text || null; + } + + return null; +} diff --git a/packages/baseai/src/dev/utils/thread/process-messages.ts b/packages/baseai/src/dev/utils/thread/process-messages.ts index 4bd0fc7b..8b4c4e59 100644 --- a/packages/baseai/src/dev/utils/thread/process-messages.ts +++ b/packages/baseai/src/dev/utils/thread/process-messages.ts @@ -78,21 +78,41 @@ function replaceVarsInMessagesWithVals({ // 1- message.content is empty // 2- message.role is 'assistant' // 3- message.tool_calls is an array of tool calls requested by LLM. + + // 1. If tool call or no content, return msg as is const isAssistantToolCall = !message.content && message.role === 'assistant' && message.tool_calls?.length; + if (isAssistantToolCall || !message.content) return message; + + // 2. If the content is an array, replace variables in each item + if (Array.isArray(message.content)) { + const updatedContent = message.content.map(contentItem => ({ + ...contentItem, - // Since no content to replace variables in, return the message as is. - if (isAssistantToolCall) return message; - if (!message.content) return message; + text: contentItem.text?.replace( + variableRegex, + (match, varName) => { + const trimmedVarName = varName.trim(); // Trim any extra spaces - // Replace variables in the message content + // If the variable exists in the map, replace with its value; otherwise, leave the placeholder intact + return variablesMap.get(trimmedVarName) || match; + } + ) + })); + return { + ...message, + content: updatedContent + }; + } + + // 3. If content is a string, replace variables in it const updatedContent = message.content.replace( variableRegex, (match, varName) => { - const trimmedVarName = varName.trim(); // Trim any extra spaces - // If the variable exists in the map, replace with its value; otherwise, leave the placeholder intact + const trimmedVarName = varName.trim(); + return variablesMap.get(trimmedVarName) || match; } ); diff --git a/packages/baseai/src/memory/create.ts b/packages/baseai/src/memory/create.ts index 68131a6a..7d77171d 100644 --- a/packages/baseai/src/memory/create.ts +++ b/packages/baseai/src/memory/create.ts @@ -20,7 +20,7 @@ const defaultConfig = { }; const MEMORY_CONSTANTS = { - documentsDir: 'documents' + documentsDir: 'documents' // Path to store documents }; export async function createMemory() { @@ -48,7 +48,7 @@ export async function createMemory() { message: 'Description of the memory', placeholder: defaultConfig.description }), - useGit: () => + useGitRepo: () => p.confirm({ message: 'Do you want to create memory from current project git repository?', @@ -63,72 +63,115 @@ export async function createMemory() { } ); - const memoryNameSlugified = slugify(memoryInfo.name); - const memoryNameCamelCase = camelCase('memory-' + memoryNameSlugified); - const baseDir = path.join(process.cwd(), 'baseai', 'memory'); - const memoryDir = path.join(baseDir, memoryNameSlugified); - const filePath = path.join(memoryDir, 'index.ts'); - const dbDir = path.join(process.cwd(), '.baseai', 'db'); + let memoryFilesDir = '.'; + let fileExtensions: string[] = ['*']; - if (memoryInfo.useGit) { + if (memoryInfo.useGitRepo) { + // Check if the current directory is a Git repository try { await execAsync('git rev-parse --is-inside-work-tree'); } catch (error) { p.cancel('The current directory is not a Git repository.'); process.exit(1); } + + memoryFilesDir = (await p.text({ + message: + 'Enter the path to the directory to track (relative to current directory):', + initialValue: '.', + validate: value => { + if (!value.trim()) { + return 'The path cannot be empty.'; + } + const fullPath = path.resolve(process.cwd(), value); + if (!fs.existsSync(fullPath)) { + return 'The specified path does not exist.'; + } + if (!fs.lstatSync(fullPath).isDirectory()) { + return 'The specified path is not a directory.'; + } + return; + } + })) as string; + + const extensionsInput = (await p.text({ + message: + 'Enter file extensions to track (use * for all, or comma-separated list, e.g., .md,.mdx):', + validate: value => { + if (value.trim() === '') { + return 'Please enter at least one file extension or *'; + } + if (value !== '*') { + const extensions = value.split(',').map(ext => ext.trim()); + const invalidExtensions = extensions.filter( + ext => !/^\.\w+$/.test(ext) + ); + if (invalidExtensions.length > 0) { + return `Invalid extension(s): ${invalidExtensions.join(', ')}. Extensions should start with a dot followed by alphanumeric characters.`; + } + } + return; + } + })) as string; + + fileExtensions = + extensionsInput === '*' + ? ['*'] + : extensionsInput.split(',').map(ext => ext.trim()); } - const memoryContent = `import {MemoryI} from '@baseai/core'; + const memoryNameSlugified = slugify(memoryInfo.name); + const memoryNameCamelCase = camelCase('memory-' + memoryNameSlugified); + + const baseDir = path.join(process.cwd(), 'baseai', 'memory'); + const memoryDir = path.join(baseDir, memoryNameSlugified); + const filePath = path.join(memoryDir, 'index.ts'); + const memoryDocumentsPath = path.join( + memoryDir, + MEMORY_CONSTANTS.documentsDir + ); + const dbDir = path.join(process.cwd(), '.baseai', 'db'); + + const memoryContent = `import { MemoryI } from '@baseai/core'; +import path from 'path'; const ${memoryNameCamelCase} = (): MemoryI => ({ - name: '${memoryNameSlugified}', - description: ${JSON.stringify(memoryInfo.description || '')}, - git: { - enabled: ${memoryInfo.useGit},${ - memoryInfo.useGit - ? ` - include: ['**/*'], - gitignore: true,` - : ` - include: ['${MEMORY_CONSTANTS.documentsDir}/**/*'], - gitignore: false,` - } - deployedAt: '', - embeddedAt: '' - } + name: '${memoryNameSlugified}', + description: ${JSON.stringify(memoryInfo.description) || ''}, + config: { + useGitRepo: ${memoryInfo.useGitRepo}, + dirToTrack: path.posix.join(${memoryFilesDir + .split(path.sep) + .map(segment => `'${segment}'`) + .join(', ')}), + extToTrack: ${JSON.stringify(fileExtensions)} + } }); -export default ${memoryNameCamelCase};`; +export default ${memoryNameCamelCase}; +`; try { await fs.promises.mkdir(baseDir, { recursive: true }); await fs.promises.mkdir(memoryDir, { recursive: true }); await fs.promises.writeFile(filePath, memoryContent); await fs.promises.mkdir(dbDir, { recursive: true }); + await createDb(memoryNameSlugified); - if (!memoryInfo.useGit) { - const memoryDocumentsPath = path.join( - memoryDir, - MEMORY_CONSTANTS.documentsDir - ); + if (!memoryInfo.useGitRepo) { await fs.promises.mkdir(memoryDocumentsPath, { recursive: true }); p.note( `Add documents in baseai/memory/${memoryNameSlugified}/${cyan(`documents`)} to use them in the memory.` ); } else { + const extensionsMsg = fileExtensions.includes('*') + ? 'all file types' + : `files with extensions: ${cyan(fileExtensions.join(', '))}`; p.note( - [ - 'All files in this Git repository will be tracked by default.', - '', - `To modify which files are being tracked, update the config at:`, - cyan(filePath) - ].join('\n') + `All ${extensionsMsg} under ${cyan(memoryFilesDir)} will be tracked and used in the memory.` ); } - await createDb(memoryNameSlugified); - p.outro( heading({ text: memoryNameCamelCase, diff --git a/packages/baseai/src/memory/embed.ts b/packages/baseai/src/memory/embed.ts index 7fa4aa6b..73a35bd0 100644 --- a/packages/baseai/src/memory/embed.ts +++ b/packages/baseai/src/memory/embed.ts @@ -58,7 +58,7 @@ export async function embedMemory({ let filesToEmbed: string[] = []; let filesToDelete: string[] = []; - if (memoryConfig.git.enabled) { + if (memoryConfig?.useGitRepo) { const { filesToDeploy, filesToDelete: gitFilesToDelete } = await handleGitSyncMemories({ memoryName: memoryName, @@ -78,7 +78,7 @@ export async function embedMemory({ let embedResult = 'Embeddings updated.'; if (memoryFiles && memoryFiles.length > 0) { s.message('Generating embeddings...'); - const shouldOverwrite = memoryConfig.git.enabled ? true : overwrite; + const shouldOverwrite = memoryConfig?.useGitRepo ? true : overwrite; embedResult = await generateEmbeddings({ memoryFiles, memoryName, @@ -87,7 +87,7 @@ export async function embedMemory({ }); } - if (memoryConfig.git.enabled) { + if (memoryConfig?.useGitRepo) { if (filesToDelete.length > 0) { await deleteDocumentsFromDB({ memoryName, diff --git a/packages/baseai/src/utils/memory/git-sync/get-changed-files-between-commits.ts b/packages/baseai/src/utils/memory/git-sync/get-changed-files-between-commits.ts index a128f386..f8d582bf 100644 --- a/packages/baseai/src/utils/memory/git-sync/get-changed-files-between-commits.ts +++ b/packages/baseai/src/utils/memory/git-sync/get-changed-files-between-commits.ts @@ -1,23 +1,23 @@ import { execSync } from 'child_process'; /** - * Retrieves the list of changed and deleted files between two Git commits matching specified glob patterns. + * Retrieves the list of changed and deleted files between two Git commits within a specified directory. * * @param {Object} params - The parameters for the function. * @param {string} params.oldCommit - The old commit reference to compare from. * @param {string} [params.latestCommit='HEAD'] - The latest commit reference to compare to. Defaults to 'HEAD'. - * @param {string[]} params.include - Array of glob patterns to track for changes. + * @param {string} params.dirToTrack - The directory to track for changes. * @returns {Promise<{ changedFiles: string[]; deletedFiles: string[] }>} - A promise that resolves to an object containing arrays of changed and deleted files. * @throws {Error} - Throws an error if the Git command execution fails or if the commit references are invalid. */ export async function getChangedAndDeletedFilesBetweenCommits({ oldCommit, latestCommit = 'HEAD', - include + dirToTrack }: { oldCommit: string; latestCommit: string; - include: string[]; + dirToTrack: string; }): Promise<{ changedFiles: string[]; deletedFiles: string[] }> { try { // Validate inputs @@ -25,53 +25,30 @@ export async function getChangedAndDeletedFilesBetweenCommits({ throw new Error('Invalid commit references'); } - if (!Array.isArray(include) || include.length === 0) { - throw new Error('Include patterns must be a non-empty array'); - } - const repoPath = process.cwd(); - // Execute the Git commands for changed and deleted files - const changedResult = execSync( - constructGitCommand({ - include, - oldCommit, - diffFilter: 'ACMRT', - latestCommit - }), - { - encoding: 'utf-8', - cwd: repoPath - } - ).trim(); + // Construct the Git commands to get changed and deleted files in the specific directory + const changedCommand = `git diff --diff-filter=ACMRT --name-only ${oldCommit} ${latestCommit} -- ${dirToTrack}`; + const deletedCommand = `git diff --diff-filter=D --name-only ${oldCommit} ${latestCommit} -- ${dirToTrack}`; + + // Execute the Git commands + const changedResult = execSync(changedCommand, { + encoding: 'utf-8', + cwd: repoPath + }).trim(); - const deletedResult = execSync( - constructGitCommand({ - include, - oldCommit, - diffFilter: 'D', - latestCommit - }), - { - encoding: 'utf-8', - cwd: repoPath - } - ).trim(); + const deletedResult = execSync(deletedCommand, { + encoding: 'utf-8', + cwd: repoPath + }).trim(); // Process the results - const changedFiles = changedResult - ? changedResult - .split('\n') - .filter(Boolean) - .map(file => file.replace(/\//g, '-')) - : []; + let changedFiles = changedResult.split('\n').filter(Boolean); + let deletedFiles = deletedResult.split('\n').filter(Boolean); - const deletedFiles = deletedResult - ? deletedResult - .split('\n') - .filter(Boolean) - .map(file => file.replace(/\//g, '-')) - : []; + // Resolve full paths + changedFiles = changedFiles.map(file => file.replace(/\//g, '-')); + deletedFiles = deletedFiles.map(file => file.replace(/\//g, '-')); return { changedFiles, deletedFiles }; } catch (error) { @@ -79,27 +56,3 @@ export async function getChangedAndDeletedFilesBetweenCommits({ throw error; } } - -// Helper function to construct the Git command for changed files -const constructGitCommand = ({ - include, - oldCommit, - diffFilter, - latestCommit -}: { - include: string[]; - oldCommit: string; - diffFilter: 'ACMRT' | 'D'; - latestCommit: string; -}) => { - const baseCommand = `git diff --diff-filter=${diffFilter} --name-only ${oldCommit} ${latestCommit}`; - - // If there's only one pattern, use it directly - if (include.length === 1) { - return `${baseCommand} -- "${include[0]}"`; - } - - // For multiple patterns, use brace expansion - const patterns = include.map(pattern => `"${pattern}"`).join(' '); - return `${baseCommand} -- ${patterns}`; -}; diff --git a/packages/baseai/src/utils/memory/git-sync/handle-git-sync-memories.ts b/packages/baseai/src/utils/memory/git-sync/handle-git-sync-memories.ts index 5bb638ee..207b5bb9 100644 --- a/packages/baseai/src/utils/memory/git-sync/handle-git-sync-memories.ts +++ b/packages/baseai/src/utils/memory/git-sync/handle-git-sync-memories.ts @@ -72,13 +72,13 @@ export async function handleGitSyncMemories({ // If there's no deployedCommitHash, user is deploying for the first time // Deploy all files in the directory const lastHashUsed = isEmbed - ? config.git?.embeddedAt - : config.git?.deployedAt; + ? config.embeddedCommitHash + : config.deployedCommitHash; if (!lastHashUsed) { filesToDeploy = allFiles; p.log.info( - `Found no previous ${isEmbed ? 'deployed' : 'embedded'} commit. ${isEmbed ? 'Deploying' : 'Embedding'} all ${filesToDeploy.length} files in memory "${memoryName}":` + `Found no previous deployed commit. Deploying all ${filesToDeploy.length} files in memory "${memoryName}":` ); } // Step 2.2: Otherwise, get changed files between commits @@ -87,7 +87,7 @@ export async function handleGitSyncMemories({ await getChangedAndDeletedFilesBetweenCommits({ oldCommit: lastHashUsed, latestCommit: 'HEAD', - include: config.git.include + dirToTrack: config.dirToTrack }); filesToDeploy = changedFiles; diff --git a/packages/baseai/src/utils/memory/git-sync/save-deployed-commit-in-config.ts b/packages/baseai/src/utils/memory/git-sync/save-deployed-commit-in-config.ts index 6c344f44..a8ddff82 100644 --- a/packages/baseai/src/utils/memory/git-sync/save-deployed-commit-in-config.ts +++ b/packages/baseai/src/utils/memory/git-sync/save-deployed-commit-in-config.ts @@ -19,108 +19,27 @@ export async function saveDeployedCommitHashInMemoryConfig({ const indexFilePath = path.join(memoryDir, 'index.ts'); let fileContents = await fs.readFile(indexFilePath, 'utf-8'); - // Check if the git block exists - if (fileContents.includes('git:')) { - // Find the git block including its indentation - const gitBlockMatch = fileContents.match(/(\t*)git:\s*{[^}]*?}/); - if (gitBlockMatch) { - const [fullMatch, outerIndent] = gitBlockMatch; - const innerIndent = outerIndent + '\t'; - - // Parse existing content - const contentMatch = fullMatch.match( - /{\s*\n?\s*(.*?)\s*\n?\s*}/s - ); - let existingContent = contentMatch ? contentMatch[1] : ''; - - let contentLines = existingContent - .split('\n') - .map(line => line.trim().replace(/,\s*$/, '')) // Remove trailing commas - .filter(Boolean); - - let newGitContent: string; - - // If deployedAt exists, update it while preserving formatting - if (existingContent.includes('deployedAt:')) { - contentLines = contentLines.map(line => { - if (line.includes('deployedAt:')) { - return `deployedAt: '${deployedCommitHash}'`; - } - return line; - }); - } else { - // Add deployedAt to existing content - contentLines.push(`deployedAt: '${deployedCommitHash}'`); - } - - // Add commas between lines but not after the last line - newGitContent = contentLines - .map((line, index) => { - const isLast = index === contentLines.length - 1; - return `${innerIndent}${line}${isLast ? '' : ','}`; - }) - .join('\n'); - - // Replace the old git block with the new one - fileContents = fileContents.replace( - /(\t*)git:\s*{[^}]*?}/, - `${outerIndent}git: {\n${newGitContent}\n${outerIndent}}` - ); - } + // Check if the deployedCommitHash already exists in the config + if (fileContents.includes('deployedCommitHash:')) { + // Update the existing deployedCommitHash + fileContents = fileContents.replace( + /deployedCommitHash:\s*['"].*['"]/, + `deployedCommitHash: '${deployedCommitHash}'` + ); } else { - // Add new git config block - const match = fileContents.match( - /(?:const\s+\w+\s*=\s*\(\s*\)\s*(?::\s*\w+)?\s*=>\s*\({[\s\S]*?)(}\))/ + // Add the deployedCommitHash to the config + fileContents = fileContents.replace( + /config:\s*{/, + `config: {\n deployedCommitHash: '${deployedCommitHash}',` ); - - if (match) { - // Insert before the closing parenthesis - const insertPosition = - match.index! + match[0].length - match[1].length; - const prefix = fileContents.slice(0, insertPosition); - const suffix = fileContents.slice(insertPosition); - - // Match the indentation of nearby properties - const indentMatch = prefix.match(/\n(\t+)[^\n]+\n\s*$/); - const baseIndent = indentMatch ? indentMatch[1] : '\t'; - const innerIndent = baseIndent + '\t'; - - const lines = [ - 'enabled: false', - "include: ['**/*']", - 'gitignore: false', - `deployedAt: '${deployedCommitHash}'` - ]; - - const gitConfig = lines - .map((line, index) => { - const isLast = index === lines.length - 1; - return `${innerIndent}${line}${isLast ? '' : ','}`; - }) - .join('\n'); - - fileContents = `${prefix},\n${baseIndent}git: {\n${gitConfig}\n${baseIndent}}${suffix}`; - } else { - throw new Error( - 'Could not find appropriate location to insert git config' - ); - } } // Write the updated contents back to the file await fs.writeFile(indexFilePath, fileContents, 'utf-8'); - p.log.success(`Updated deployedAt hash for memory '${memoryName}'.`); + p.log.success(`Updated deployedCommitHash for memory '${memoryName}'.`); } catch (error) { - if (error instanceof Error) { - p.cancel( - `Failed to save deployedAt hash for memory '${memoryName}': ${error.message}` - ); - } else { - p.cancel( - `Failed to save deployedAt hash for memory '${memoryName}': Unknown error` - ); - } + console.error(`Error saving latest commit hash: ${error}`); throw error; } } diff --git a/packages/baseai/src/utils/memory/git-sync/save-embedded-commit-in-config.ts b/packages/baseai/src/utils/memory/git-sync/save-embedded-commit-in-config.ts index 52051b12..edef22d2 100644 --- a/packages/baseai/src/utils/memory/git-sync/save-embedded-commit-in-config.ts +++ b/packages/baseai/src/utils/memory/git-sync/save-embedded-commit-in-config.ts @@ -19,108 +19,27 @@ export async function saveEmbeddedCommitHashInMemoryConfig({ const indexFilePath = path.join(memoryDir, 'index.ts'); let fileContents = await fs.readFile(indexFilePath, 'utf-8'); - // Check if the git block exists - if (fileContents.includes('git:')) { - // Find the git block including its indentation - const gitBlockMatch = fileContents.match(/(\t*)git:\s*{[^}]*?}/); - if (gitBlockMatch) { - const [fullMatch, outerIndent] = gitBlockMatch; - const innerIndent = outerIndent + '\t'; - - // Parse existing content - const contentMatch = fullMatch.match( - /{\s*\n?\s*(.*?)\s*\n?\s*}/s - ); - let existingContent = contentMatch ? contentMatch[1] : ''; - - let contentLines = existingContent - .split('\n') - .map(line => line.trim().replace(/,\s*$/, '')) // Remove trailing commas - .filter(Boolean); - - let newGitContent: string; - - // If embeddedAt exists, update it while preserving formatting - if (existingContent.includes('embeddedAt:')) { - contentLines = contentLines.map(line => { - if (line.includes('embeddedAt:')) { - return `embeddedAt: '${embeddedCommitHash}'`; - } - return line; - }); - } else { - // Add embeddedAt to existing content - contentLines.push(`embeddedAt: '${embeddedCommitHash}'`); - } - - // Add commas between lines but not after the last line - newGitContent = contentLines - .map((line, index) => { - const isLast = index === contentLines.length - 1; - return `${innerIndent}${line}${isLast ? '' : ','}`; - }) - .join('\n'); - - // Replace the old git block with the new one - fileContents = fileContents.replace( - /(\t*)git:\s*{[^}]*?}/, - `${outerIndent}git: {\n${newGitContent}\n${outerIndent}}` - ); - } + // Check if the embeddedCommitHash already exists in the config + if (fileContents.includes('embeddedCommitHash:')) { + // Update the existing embeddedCommitHash + fileContents = fileContents.replace( + /embeddedCommitHash:\s*['"].*['"]/, + `embeddedCommitHash: '${embeddedCommitHash}'` + ); } else { - // Add new git config block - const match = fileContents.match( - /(?:const\s+\w+\s*=\s*\(\s*\)\s*(?::\s*\w+)?\s*=>\s*\({[\s\S]*?)(}\))/ + // Add the embeddedCommitHash to the config + fileContents = fileContents.replace( + /config:\s*{/, + `config: {\n embeddedCommitHash: '${embeddedCommitHash}',` ); - - if (match) { - // Insert before the closing parenthesis - const insertPosition = - match.index! + match[0].length - match[1].length; - const prefix = fileContents.slice(0, insertPosition); - const suffix = fileContents.slice(insertPosition); - - // Match the indentation of nearby properties - const indentMatch = prefix.match(/\n(\t+)[^\n]+\n\s*$/); - const baseIndent = indentMatch ? indentMatch[1] : '\t'; - const innerIndent = baseIndent + '\t'; - - const lines = [ - 'enabled: false', - "include: ['**/*']", - 'gitignore: false', - `embeddedAt: '${embeddedCommitHash}'` - ]; - - const gitConfig = lines - .map((line, index) => { - const isLast = index === lines.length - 1; - return `${innerIndent}${line}${isLast ? '' : ','}`; - }) - .join('\n'); - - fileContents = `${prefix},\n${baseIndent}git: {\n${gitConfig}\n${baseIndent}}${suffix}`; - } else { - throw new Error( - 'Could not find appropriate location to insert git config' - ); - } } // Write the updated contents back to the file await fs.writeFile(indexFilePath, fileContents, 'utf-8'); - p.log.success(`Updated embeddedAt hash for memory '${memoryName}'.`); + p.log.success(`Updated embeddedCommitHash for memory '${memoryName}'.`); } catch (error) { - if (error instanceof Error) { - p.cancel( - `Failed to save embeddedAt hash for memory '${memoryName}': ${error.message}` - ); - } else { - p.cancel( - `Failed to save embeddedAt hash for memory '${memoryName}': Unknown error` - ); - } + console.error(`Error saving latest commit hash: ${error}`); throw error; } } diff --git a/packages/baseai/src/utils/memory/handle-old-memory-config.ts b/packages/baseai/src/utils/memory/handle-old-memory-config.ts deleted file mode 100644 index e9bd9b4d..00000000 --- a/packages/baseai/src/utils/memory/handle-old-memory-config.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Represents the old memory configuration format for backward compatibility. - */ -export interface OldMemoryConfig { - name: string; - description?: string; - config?: OldConfigObject; -} - -interface OldConfigObject { - useGitRepo: boolean; - dirToTrack: string; - extToTrack: string[] | ['*']; - deployedCommitHash?: string; - embeddedCommitHash?: string; -} - -/** - * Type guard to check if an object is of type `OldConfigObject`. - * - * @param obj - The object to check. - * @returns `true` if the object is an `OldConfigObject`, otherwise `false`. - */ -function isOldConfigObject(obj: unknown): obj is OldConfigObject { - return ( - typeof obj === 'object' && - obj !== null && - 'useGitRepo' in obj && - typeof (obj as OldConfigObject).useGitRepo === 'boolean' && - 'dirToTrack' in obj && - typeof (obj as OldConfigObject).dirToTrack === 'string' && - 'extToTrack' in obj && - Array.isArray((obj as OldConfigObject).extToTrack) - ); -} - -/** - * Checks if an object conforms to the old memory configuration format. - * - * @param obj - The object to check. - * @returns `true` if the object is in the old memory configuration format, otherwise `false`. - */ -export function isOldMemoryConfigFormat(obj: unknown): boolean { - if ( - typeof obj !== 'object' || - obj === null || - !('name' in obj) || - !('config' in obj) - ) { - return false; - } - - const typedObj = obj as { name: unknown; config: unknown }; - - return ( - typeof typedObj.name === 'string' && - (typedObj.config === undefined || isOldConfigObject(typedObj.config)) - ); -} - -/** - * Generates upgrade instructions for converting an old memory configuration to the new format. - * - * @param oldConfig - The old memory configuration. - * @returns A string containing the upgrade instructions. - */ -export function generateUpgradeInstructions( - oldConfig: OldMemoryConfig -): string { - if (!oldConfig.config) { - return 'Invalid memory config.'; - } - - const newConfigExample = { - name: oldConfig.name, - description: oldConfig.description || 'Your memory description', - git: { - enabled: oldConfig.config.useGitRepo, - include: - oldConfig.config.extToTrack[0] === '*' - ? [`${oldConfig.config.dirToTrack}/**/*`] - : oldConfig.config.extToTrack.map( - ext => `${oldConfig.config?.dirToTrack}/**/*${ext}` - ), - gitignore: true, - deployedAt: oldConfig.config.deployedCommitHash || '', - embeddedAt: oldConfig.config.embeddedCommitHash || '' - } - }; - - return ` -Your memory config is using an outdated format in baseai/memory/${oldConfig.name}/index.ts. Please update the file to this new format: - -${JSON.stringify(newConfigExample, null, 2)} - -Key changes: -- Removed nested 'config' object structure -- Git-related fields are now grouped under a 'git' object -- 'useGitRepo' is now 'git.enabled' -- 'dirToTrack' and 'extToTrack' are combined into 'git.include' glob patterns -- 'deployedCommitHash' is now 'git.deployedAt' -- 'embeddedCommitHash' is now 'git.embeddedAt' -- Added new 'git.gitignore' field (defaults to true) - -For more information, refer to the documentation: https://baseai.dev/docs/guides/memory-from-git -`; -} diff --git a/packages/baseai/src/utils/memory/lib.ts b/packages/baseai/src/utils/memory/lib.ts index a567ceb0..ad3d77fe 100644 --- a/packages/baseai/src/utils/memory/lib.ts +++ b/packages/baseai/src/utils/memory/lib.ts @@ -20,6 +20,7 @@ import { loadConfig } from '../config/config-handler'; import { logger } from '../logger-utils'; import { generateLocalEmbeddings } from './generate-local-embeddings'; import { getOpenAIEmbeddings } from './generate-openai-embeddings'; +import { getMessageContent } from '@/dev/utils/thread/get-message-content'; export async function checkDirectoryExists(directoryPath: string) { try { @@ -155,7 +156,7 @@ export const addContextFromMemory = async ({ const lastUserMsg = [...messages] .reverse() .find(m => m.role === 'user'); - const userPrompt = lastUserMsg?.content; + const userPrompt = getMessageContent(lastUserMsg!); // If there is no user prompt, return the messages. if (!userPrompt) return; diff --git a/packages/baseai/src/utils/memory/load-memory-config.ts b/packages/baseai/src/utils/memory/load-memory-config.ts index 2022d83c..8c29d07e 100644 --- a/packages/baseai/src/utils/memory/load-memory-config.ts +++ b/packages/baseai/src/utils/memory/load-memory-config.ts @@ -2,60 +2,77 @@ import fs from 'fs/promises'; import path from 'path'; import * as p from '@clack/prompts'; import { memoryConfigSchema, type MemoryConfigI } from 'types/memory'; -import { - generateUpgradeInstructions, - isOldMemoryConfigFormat, - type OldMemoryConfig -} from './handle-old-memory-config'; -function extractConfigObject(fileContents: string): unknown { - try { - // Remove import statements and exports - const cleanedContent = fileContents - .replace(/import\s+.*?['"];?\s*/g, '') - .replace(/export\s+default\s+/, ''); - - // First try to match a function that returns an object directly with parentheses - let match = cleanedContent.match( - /(?:const\s+)?(\w+)\s*=\s*\(\s*\)\s*(?::\s*\w+)?\s*=>\s*\(({[\s\S]*?})\)/ - ); +function parsePathJoin(joinArgs: string): string { + // Remove any quotes, split by comma, and trim each argument + const args = joinArgs + .split(',') + .map(arg => arg.trim().replace(/['"]/g, '')); + // Join all arguments to preserve the complete path + return path.join(...args); +} - // If no direct parentheses match, try to match function with return statement - if (!match) { - match = cleanedContent.match( - /(?:const\s+)?(\w+)\s*=\s*\(\s*\)\s*(?::\s*\w+)?\s*=>\s*\{[\s\S]*?return\s+({[\s\S]*?})\s*;\s*\}/ - ); - } +function parseConfig(configString: string): MemoryConfigI { + // Remove all whitespace that's not inside quotes + const cleanConfig = configString.replace( + /\s+(?=(?:(?:[^"]*"){2})*[^"]*$)/g, + '' + ); - // If still no match, try to match direct object assignment - if (!match) { - match = cleanedContent.match( - /(?:const\s+)?(?:memory|\w+)\s*=\s*({[\s\S]*?});?$/m - ); - } + const useGitRepoMatch = cleanConfig.match(/useGitRepo:(true|false)/); + const dirToTrackMatch = cleanConfig.match( + /dirToTrack:(?:path\.(?:posix\.)?join\((.*?)\)|['"](.+?)['"])/ + ); + const extToTrackMatch = cleanConfig.match(/extToTrack:(\[.*?\])/); + const deployedCommitHashMatch = cleanConfig.match( + /deployedCommitHash:['"](.+?)['"]/ + ); + const embeddedCommitHashMatch = cleanConfig.match( + /embeddedCommitHash:['"](.+?)['"]/ + ); - if (!match) { - throw new Error('Unable to find memory object definition'); - } + if (!useGitRepoMatch || !dirToTrackMatch || !extToTrackMatch) { + throw new Error('Unable to parse config structure'); + } - // The object literal will be in the last capture group - const memoryObjStr = match[match.length - 1]; + const useGitRepo = useGitRepoMatch[1] === 'true'; + const dirToTrack = dirToTrackMatch[2] + ? dirToTrackMatch[2] + : parsePathJoin(dirToTrackMatch[1]); + const extToTrack = JSON.parse(extToTrackMatch[1].replace(/'/g, '"')); + const deployedCommitHash = deployedCommitHashMatch + ? deployedCommitHashMatch[1] + : undefined; + const embeddedCommitHash = embeddedCommitHashMatch + ? embeddedCommitHashMatch[1] + : undefined; - // Create a new Function that returns the object literal - const fn = new Function(`return ${memoryObjStr}`); - return fn(); - } catch (error) { - console.error('Parsing error:', error); - console.error('File contents:', fileContents); - throw new Error( - `Failed to extract config: ${error instanceof Error ? error.message : 'Unknown error'}` - ); + const config: MemoryConfigI = { + useGitRepo, + dirToTrack, + extToTrack + }; + + if (deployedCommitHash) { + config.deployedCommitHash = deployedCommitHash; } + + if (embeddedCommitHash) { + config.embeddedCommitHash = embeddedCommitHash; + } + + // Validate the parsed config against the schema + const result = memoryConfigSchema.safeParse(config); + if (!result.success) { + throw new Error(`Invalid config: ${result.error.message}`); + } + + return config; } export default async function loadMemoryConfig( memoryName: string -): Promise { +): Promise { try { const memoryDir = path.join( process.cwd(), @@ -65,35 +82,46 @@ export default async function loadMemoryConfig( ); const indexFilePath = path.join(memoryDir, 'index.ts'); + // Check if the directory exists + await fs.access(memoryDir); + + // Check if the index.ts file exists await fs.access(indexFilePath); + + // Read the file contents const fileContents = await fs.readFile(indexFilePath, 'utf-8'); - const configObj = extractConfigObject(fileContents); - // Try to parse with new schema first + // Extract the config object, allowing for any amount of whitespace + const configMatch = fileContents.match(/config\s*:\s*({[\s\S]*?})/); + if (!configMatch) { + return null; + } + + // Parse the config try { - return memoryConfigSchema.parse(configObj); - } catch (parseError) { - if (!configObj) throw parseError; - - // If parsing fails, check if it's an old format - if (isOldMemoryConfigFormat(configObj)) { - p.note( - generateUpgradeInstructions(configObj as OldMemoryConfig) + const config = parseConfig(configMatch[1]); + return config; + } catch (error) { + if (error instanceof Error) { + p.cancel( + `Unable to read config in '${memoryName}/index.ts': ${error.message}` ); + } else { p.cancel( - 'Deployment cancelled. Please update your memory config file to the new format.' + `Unable to read config in '${memoryName}/index.ts': Unknown error occurred` ); - process.exit(1); } - - // If it's neither new nor old format, throw the original error - throw parseError; + process.exit(1); } } catch (error) { if (error instanceof Error) { - p.cancel(`Failed to load memory '${memoryName}': ${error.message}`); + p.cancel( + `Memory '${memoryName}' does not exist or could not be loaded: ${error.message}` + ); } else { - p.cancel(`Failed to load memory '${memoryName}': Unknown error`); + p.cancel( + `Memory '${memoryName}' does not exist or could not be loaded: Unknown error occurred` + ); } process.exit(1); } diff --git a/packages/baseai/src/utils/memory/load-memory-files.ts b/packages/baseai/src/utils/memory/load-memory-files.ts index e643309e..ebaafe24 100644 --- a/packages/baseai/src/utils/memory/load-memory-files.ts +++ b/packages/baseai/src/utils/memory/load-memory-files.ts @@ -5,21 +5,14 @@ import { allSupportedExtensions, MEMORYSETS } from './constants'; import { getDocumentContent } from './get-document-content'; import { formatDocSize } from './lib'; import loadMemoryConfig from './load-memory-config'; -import { - memoryConfigSchema, - type DocumentConfigI, - type MemoryConfigI -} from 'types/memory'; +import { memoryConfigSchema, type MemoryConfigI } from 'types/memory'; import { execSync } from 'child_process'; -import fg from 'fast-glob'; export interface MemoryDocumentI { name: string; size: string; content: string; blob: Blob; - path: string; - meta: Record; } export const loadMemoryFiles = async ( @@ -29,12 +22,11 @@ export const loadMemoryFiles = async ( const memoryConfig = await checkMemoryConfig(memoryName); // useDocumentsDir - const useDocumentsDir = !memoryConfig || !memoryConfig.git.enabled; - const documentConfig = memoryConfig?.documents; + const useDocumentsDir = !memoryConfig || !memoryConfig?.useGitRepo; // Load files from documents directory. if (useDocumentsDir) { - return await loadMemoryFilesFromDocsDir({ memoryName, documentConfig }); + return await loadMemoryFilesFromDocsDir(memoryName); } // Load files from the repo. @@ -58,52 +50,46 @@ export const loadMemoryFilesFromCustomDir = async ({ memoryName: string; memoryConfig: MemoryConfigI; }): Promise => { - const includePatterns = memoryConfig.git.include; + const memoryFilesPath = memoryConfig.dirToTrack; - if (!Array.isArray(includePatterns) || includePatterns.length === 0) { - p.cancel(`No include patterns specified for memory '${memoryName}'`); + try { + await fs.access(memoryFilesPath); + } catch (error) { + p.cancel( + `Documents directory for memory '${memoryName}' does not exist.` + ); process.exit(1); } console.log('Reading documents in memory...'); - // Get all files that match the glob patterns and are tracked by git let allFiles: string[]; try { - // First get all git tracked files - const gitFiles = new Set([ - ...execSync('git ls-files', { encoding: 'utf-8' }) - .split('\n') - .filter(Boolean), - ...execSync('git ls-files --others --exclude-standard', { - encoding: 'utf-8' - }) - .split('\n') - .filter(Boolean), - ...execSync('git diff --name-only', { encoding: 'utf-8' }) - .split('\n') - .filter(Boolean) - ]); - - // Then match against glob patterns - const matchedFiles = await fg(includePatterns, { - ignore: ['node_modules/**'], - dot: true, - gitignore: memoryConfig.git.gitignore || true - }); - - // Only keep files that are both tracked by git and match the patterns - allFiles = matchedFiles.filter((file: string) => gitFiles.has(file)); + allFiles = execSync(`git ls-files ${memoryFilesPath}`, { + encoding: 'utf-8' + }) + .split('\n') + .filter(Boolean); } catch (error) { p.cancel(`Failed to read documents in memory '${memoryName}'.`); process.exit(1); } + // Check if all extensions are allowed. + const allExtensionsAllowed = memoryConfig.extToTrack[0] === '*'; + + // Filter files based on allowed extensions. + const extensionsToUse = allExtensionsAllowed + ? allSupportedExtensions + : memoryConfig.extToTrack.filter(ext => + allSupportedExtensions.includes(ext) + ); + const memoryFilesContent = await Promise.all( allFiles.map(async filePath => { - // Check if the file is allowed - const isSupportedExtension = allSupportedExtensions.some( - extension => filePath.endsWith(extension) + // Check if the file is allowed. + const isSupportedExtension = extensionsToUse.some(extension => + filePath.endsWith(extension) ); if (!isSupportedExtension) { @@ -128,21 +114,12 @@ export const loadMemoryFilesFromCustomDir = async ({ return null; } - const memoryFile = { - path: filePath, + return { name: path.basename(filePath.replace(/\//g, '-')), size: formatDocSize(fileContentBlob.size), content: await getDocumentContent(fileContentBlob), blob: fileContentBlob }; - - let meta = {}; - - if (memoryConfig?.documents?.meta) { - meta = memoryConfig.documents.meta(memoryFile) || {}; - } - - return { ...memoryFile, meta }; }) ); @@ -175,13 +152,9 @@ export const loadMemoryFilesFromCustomDir = async ({ * - Have unsupported file extensions. * 5. Returns an array of `MemoryDocumentI` objects representing the valid memory files. */ -export const loadMemoryFilesFromDocsDir = async ({ - memoryName, - documentConfig -}: { - memoryName: string; - documentConfig?: DocumentConfigI; -}): Promise => { +export const loadMemoryFilesFromDocsDir = async ( + memoryName: string +): Promise => { const memoryDir = path.join(process.cwd(), 'baseai', 'memory', memoryName); const memoryFilesPath = path.join(memoryDir, 'documents'); @@ -234,21 +207,12 @@ export const loadMemoryFilesFromDocsDir = async ({ return null; } - const memoryFile = { + return { name: file, - path: filePath, size: formatDocSize(fileContentBlob.size), content: await getDocumentContent(fileContentBlob), blob: fileContentBlob }; - - let meta = {}; - - if (documentConfig?.meta) { - meta = documentConfig.meta(memoryFile) || {}; - } - - return { ...memoryFile, meta }; }) ); @@ -299,6 +263,28 @@ async function checkMemoryConfig( }; } +/** + * Recursively traverses a directory and returns a list of all file paths. + * + * @param dir - The directory to traverse. + * @returns A promise that resolves to an array of file paths. + */ +const traverseDirectory = async (dir: string): Promise => { + const files: string[] = []; + const entries = await fs.readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + files.push(...(await traverseDirectory(fullPath))); + } else { + files.push(fullPath); + } + } + + return files; +}; + export const getMemoryFileNames = async ( memoryName: string ): Promise => { diff --git a/packages/baseai/src/utils/retrieve-credentials.ts b/packages/baseai/src/utils/retrieve-credentials.ts deleted file mode 100644 index accd30c7..00000000 --- a/packages/baseai/src/utils/retrieve-credentials.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { loadConfig } from './config/config-handler'; -import fs from 'fs/promises'; -import * as p from '@clack/prompts'; -import color from 'picocolors'; - -export interface Account { - apiKey: string; -} - -type Spinner = ReturnType; - -function handleNoAccountFound({ spinner }: { spinner: Spinner }): void { - spinner.stop('No account found'); - p.log.warn('No account found. Please authenticate first.'); - p.log.info(`Run: ${color.green('npx baseai auth')}`); -} -function handleAuthError({ - spinner, - error -}: { - spinner: Spinner; - error: unknown; -}): void { - spinner.stop('Failed to retrieve authentication'); - p.log.error(`Error retrieving stored auth: ${(error as Error).message}`); -} - -export async function retrieveAuthentication({ - spinner -}: { - spinner: Spinner; -}): Promise { - spinner.start('Retrieving stored authentication'); - try { - const baiConfig = await loadConfig(); - let envFile = baiConfig.envFilePath || '.env'; - const envFileContent = await fs.readFile(envFile, 'utf-8'); - - const apiKey = envFileContent - .split('\n') - .reverse() - .find(line => line.includes('LANGBASE_API_KEY=')) - ?.split('=')[1]; - - if (!apiKey) { - handleNoAccountFound({ spinner }); - return null; - } - - spinner.stop('Retrieved stored authentication'); - - return { - apiKey - }; - } catch (error) { - handleAuthError({ spinner, error }); - return null; - } -} diff --git a/packages/baseai/types/memory.ts b/packages/baseai/types/memory.ts index 2716493b..cf7936f8 100644 --- a/packages/baseai/types/memory.ts +++ b/packages/baseai/types/memory.ts @@ -1,5 +1,11 @@ import { z } from 'zod'; +export interface MemoryI { + name: string; + description?: string; + config?: MemoryConfigI; +} + export const memoryNameSchema = z .string() .min(3, 'Memory name must be at least 3 characters long') @@ -16,43 +22,28 @@ export const memoryDocSchema = z.object({ documentName: docNameSchema }); -export const gitConfigSchema = z.object({ - enabled: z.boolean(), - include: z - .array(z.string().trim().min(1, 'Include pattern must not be empty')) - .min(1, 'At least one include pattern must be specified') - .describe('Glob patterns to include files in the memory'), - gitignore: z.boolean().optional().default(true), - deployedAt: z.string().trim().optional().default(''), - embeddedAt: z.string().trim().optional().default('') -}); - -export const documentSchema = z.object({ - meta: z - .function() - .args( - z.object({ - name: z.string(), - size: z.string(), - content: z.string(), - blob: z.instanceof(Blob), - path: z.string(), - }) - ) - .returns(z.record(z.string())) - .optional() -}); - export const memoryConfigSchema = z.object({ - name: z.string(), - description: z.string().optional(), - git: gitConfigSchema, - documents: documentSchema.optional() + useGitRepo: z.boolean(), + dirToTrack: z + .string() + .trim() + .min(1, 'Directory to track must not be empty'), + extToTrack: z.union([ + z.tuple([z.literal('*')]), + z + .array( + z + .string() + .trim() + .regex( + /^\.\w+$/, + 'File extension must start with a dot followed by alphanumeric characters' + ) + ) + .min(1, 'At least one file extension must be specified') + ]), + deployedCommitHash: z.string().optional(), + embeddedCommitHash: z.string().optional() }); -export type GitConfigI = z.infer; - export type MemoryConfigI = z.infer; -export type DocumentConfigI = z.infer; - -export type MemoryI = MemoryConfigI; diff --git a/packages/baseai/types/model.ts b/packages/baseai/types/model.ts index 4ec94b0f..82353a72 100644 --- a/packages/baseai/types/model.ts +++ b/packages/baseai/types/model.ts @@ -29,8 +29,7 @@ export type TogetherModels = | 'together:mistralai/Mistral-7B-Instruct-v0.2' | 'together:mistralai/Mixtral-8x7B-Instruct-v0.1' | 'together:mistralai/Mixtral-8x22B-Instruct-v0.1' - | 'together:databricks/dbrx-instruct' - | 'together:meta-llama/Llama-3.3-70B-Instruct-Turbo'; + | 'together:databricks/dbrx-instruct'; export type AnthropicModels = | 'anthropic:claude-3-5-sonnet-latest' @@ -47,8 +46,7 @@ export type GroqModels = | 'groq:llama3-8b-8192' | 'groq:mixtral-8x7b-32768' | 'groq:gemma2-9b-it' - | 'groq:gemma-7b-it' - | 'groq:llama-3.3-70b-versatile'; + | 'groq:gemma-7b-it'; export type GoogleModels = | 'google:gemini-1.5-pro-latest' @@ -63,8 +61,7 @@ export type FireworksAIModels = | 'fireworks:llama-v3p1-8b-instruct' | 'fireworks:llama-v3p1-70b-instruct' | 'fireworks:llama-v3-70b-instruct' - | 'fireworks:yi-large' - | 'fireworks:llama-v3p3-70b-instruct'; + | 'fireworks:yi-large'; export type PerplexityModels = | 'perplexity:llama-3.1-sonar-huge-128k-online' diff --git a/packages/baseai/types/pipe.ts b/packages/baseai/types/pipe.ts index bc18a65a..1c9dd560 100644 --- a/packages/baseai/types/pipe.ts +++ b/packages/baseai/types/pipe.ts @@ -13,7 +13,52 @@ import type { } from './model'; import type { PipeTool } from './tools'; +const contentTypeSchema = z.object({ + type: z.string(), + text: z.string().optional(), + image_url: z + .object({ + url: z.string(), + detail: z.string().optional() + }) + .optional() +}); + export const schemaMessage = z + .object({ + role: z.enum(['system', 'user', 'assistant', 'function', 'tool']), + content: z + .union([z.string(), z.array(contentTypeSchema), z.null()]) + .optional(), + tool_call_id: z.string().optional(), + name: z.string().optional(), + tool_calls: z + .array( + z.object({ + id: z.string(), + type: z.string(), + function: z.record(z.unknown()) + }) + ) + .optional() + }) + .refine( + ({ content, role, tool_calls }) => { + // If content is null, role isn't assistant and tool_calls is not present. + // then the schema is invalid + // because the message content is null and its not an assistant tool call + const isSchemaInvalid = + content === null && role !== 'assistant' && !tool_calls; + + if (isSchemaInvalid) return false; + return true; + }, + { + message: 'Message content cannot be empty.' + } + ); + +export const schemaPipeMessage = z .object({ role: z.enum(['system', 'user', 'assistant', 'function', 'tool']), content: z.string().nullable(), @@ -46,6 +91,7 @@ export const schemaMessage = z ); export type Message = z.infer; +export type PipeMessage = z.infer; export const VariableSchema = z.object({ name: z.string(), @@ -98,7 +144,7 @@ export interface Pipe { stop: string[]; tool_choice: ToolChoice; parallel_tool_calls: boolean; - messages: Message[]; + messages: PipeMessage[]; variables: VariablesI; tools: PipeTool[]; memory: { diff --git a/packages/baseai/types/tools.ts b/packages/baseai/types/tools.ts index 7536bc86..06cf0573 100644 --- a/packages/baseai/types/tools.ts +++ b/packages/baseai/types/tools.ts @@ -10,6 +10,14 @@ export interface Tool { }; } +export interface PipeTool { + type: 'function'; + function: { + name: string; + description?: string; + parameters?: Record; + }; +} export const pipeToolSchema = z.object({ type: z.literal('function'), function: z.object({ @@ -18,5 +26,3 @@ export const pipeToolSchema = z.object({ parameters: z.record(z.any()).optional() }) }); - -export type PipeTool = z.infer; diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 7d6cc9b1..b2b793ec 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,65 +1,5 @@ # `baseai` SDK -## 0.9.43 - -### Patch Changes - -- Fix moderation - -## 0.9.42 - -### Patch Changes - -- 📦 NEW: LB-LLM-Key header support - -## 0.9.41 - -### Patch Changes - -- 🐛 FIX: Google stream - -## 0.9.40 - -### Patch Changes - -- 📦 NEW: meta-llama/Llama-3.3-70B-Instruct-Turbo model - -## 0.9.39 - -### Patch Changes - -- 📦 NEW: tools support in pipe.run() - -## 0.9.38 - -### Patch Changes - -- 📦 NEW: .env file based BaseAI auth - -## 0.9.37 - -### Patch Changes - -- 👌 IMPROVE: Remove unused type - -## 0.9.36 - -### Patch Changes - -- 📦 NEW: Dynamically set document metadata - -## 0.9.35 - -### Patch Changes - -- 📦 NEW: Pipe API key support in pipe.run() - -## 0.9.34 - -### Patch Changes - -- 👌 IMPROVE: Memory config with new features and better UX - ## 0.9.33 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 6d986085..d2b950ff 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@baseai/core", "description": "The Web AI Framework's core - BaseAI.dev", - "version": "0.9.43", + "version": "0.9.33", "license": "Apache-2.0", "sideEffects": false, "main": "./dist/index.js", @@ -119,4 +119,4 @@ "langbase.com", "generative AI" ] -} \ No newline at end of file +} diff --git a/packages/core/src/common/request.ts b/packages/core/src/common/request.ts index 9b0edff5..dcd21482 100644 --- a/packages/core/src/common/request.ts +++ b/packages/core/src/common/request.ts @@ -14,7 +14,6 @@ interface RequestConfig { apiKey?: string; baseUrl: string; timeout?: number; - llmKey?: string; } interface SendOptions extends RequestOptions { @@ -91,7 +90,6 @@ export class Request { return { 'Content-Type': 'application/json', Authorization: `Bearer ${this.config.apiKey}`, - 'LB-LLM-Key': this.config.llmKey ?? '', ...headers, }; } diff --git a/packages/core/src/data/models.ts b/packages/core/src/data/models.ts index be39bcd2..9d64f625 100644 --- a/packages/core/src/data/models.ts +++ b/packages/core/src/data/models.ts @@ -113,12 +113,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { }, ], [TOGETHER_AI]: [ - { - id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', - provider: TOGETHER_AI, - promptCost: 0.88, - completionCost: 0.88, - }, { id: 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo', provider: TOGETHER_AI, @@ -249,12 +243,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { }, ], [GROQ]: [ - { - id: 'llama-3.3-70b-versatile', - provider: GROQ, - promptCost: 0.59, - completionCost: 0.79, - }, { id: 'llama-3.1-70b-versatile', provider: GROQ, @@ -339,12 +327,6 @@ export const modelsByProvider: ModelsByProviderInclCosts = { }, ], [FIREWORKS_AI]: [ - { - id: 'llama-v3p3-70b-instruct', - provider: FIREWORKS_AI, - promptCost: 0.88, - completionCost: 0.88, - }, { id: 'llama-v3p1-405b-instruct', provider: FIREWORKS_AI, diff --git a/packages/core/src/helpers/stream.ts b/packages/core/src/helpers/stream.ts index 64593011..55a7a53f 100644 --- a/packages/core/src/helpers/stream.ts +++ b/packages/core/src/helpers/stream.ts @@ -1,7 +1,7 @@ import {ChatCompletionStream} from 'openai/lib/ChatCompletionStream'; import {ChunkStream} from 'src/pipes'; import {Stream} from 'openai/streaming'; -import {ToolCallResult} from 'types/pipes'; +import {ToolCall} from 'types/pipes'; export interface Runner extends ChatCompletionStream {} @@ -91,7 +91,7 @@ export function handleResponseStream({ */ export async function getToolsFromStream( stream: ReadableStream, -): Promise { +): Promise { let run = getRunner(stream); const {choices} = await run.finalChatCompletion(); return choices[0].message.tool_calls; diff --git a/packages/core/src/pipes/pipes.ts b/packages/core/src/pipes/pipes.ts index 410d74d4..b675ec2c 100644 --- a/packages/core/src/pipes/pipes.ts +++ b/packages/core/src/pipes/pipes.ts @@ -1,11 +1,5 @@ import type {Runner} from 'src/helpers'; -import { - Message, - MessageRole, - Pipe as PipeI, - ToolCallResult, - Tools, -} from '../../types/pipes'; +import {Message, MessageRole, Pipe as PipeI, ToolCall} from '../../types/pipes'; import {Request} from '../common/request'; import {getLLMApiKey} from '../utils/get-llm-api-key'; import {getApiUrl, isProd} from '../utils/is-prod'; @@ -25,10 +19,7 @@ export interface RunOptions { threadId?: string; rawResponse?: boolean; runTools?: boolean; - tools?: Tools[]; - name?: string; // Pipe name for SDK, - apiKey?: string; // pipe level key for SDK - llmKey?: string; // LLM API key + name?: string; // Pipe name for SDK } export interface RunOptionsStream extends RunOptions { @@ -92,19 +83,13 @@ export class Pipe { private maxCalls: number; private hasTools: boolean; private prod: boolean; - private baseUrl: string; - private entityApiKey?: string; constructor(options: PipeOptions) { this.prod = options.prod ?? isProd(); - this.baseUrl = getApiUrl(this.prod); + const baseUrl = getApiUrl(this.prod); - this.request = new Request({ - apiKey: options.apiKey, - baseUrl: this.baseUrl, - }); + this.request = new Request({apiKey: options.apiKey, baseUrl}); this.pipe = options; - this.entityApiKey = options.apiKey; delete this.pipe.prod; delete this.pipe.apiKey; @@ -126,16 +111,14 @@ export class Pipe { return tools; } - private async runTools(toolCalls: ToolCallResult[]): Promise { - const toolPromises = toolCalls.map(async (toolCall: ToolCallResult) => { + private async runTools(toolCalls: ToolCall[]): Promise { + const toolPromises = toolCalls.map(async (toolCall: ToolCall) => { const toolName = toolCall.function.name; const toolParameters = JSON.parse(toolCall.function.arguments); const toolFunction = this.tools[toolName]; if (!toolFunction) { - throw new Error( - `Tool ${toolName} not found. If this is intentional, please set runTools to false to disable tool execution by default.`, - ); + throw new Error(`Tool '${toolName}' not found`); } const toolResponse = await toolFunction(toolParameters); @@ -180,6 +163,7 @@ export class Pipe { private async handleStreamResponse( options: RunOptionsStream, response: RunResponseStream, + pipeName: string, ): Promise { const endpoint = '/v1/pipes/run'; const stream = this.isStreamRequested(options); @@ -234,6 +218,7 @@ export class Pipe { messages, threadId: currentResponse.threadId, }, + pipeName ); callCount++; @@ -262,30 +247,7 @@ export class Pipe { const modelProvider = getProvider(providerString); const isAnthropic = modelProvider === ANTHROPIC; const hasTools = this.pipe.tools.length > 0; - - // For SDK - // Run the given pipe name - if (options.name) { - this.pipe = {...this.pipe, name: options.name}; - } - - // For SDK - // Run the pipe against the given Pipe API key - if (options.apiKey) { - this.request = new Request({ - apiKey: options.apiKey, - baseUrl: this.baseUrl, - ...((options.llmKey && {llmKey: options.llmKey}) || {}), - }); - } - - if (options.llmKey && !options.apiKey) { - this.request = new Request({ - apiKey: this.entityApiKey, - baseUrl: this.baseUrl, - llmKey: options.llmKey, - }); - } + const pipeName = options.name || this.pipe.name; let stream = this.isStreamRequested(options); @@ -295,20 +257,14 @@ export class Pipe { stream = false; } - let runTools = options.runTools ?? true; - - // Do not run tools if they are explicitly provided in the options. - if (options.tools && options.tools?.length) { - runTools = false; - } - + const runTools = options.runTools ?? true; delete options.runTools; const body = {...options, stream}; let response = await this.createRequest< RunResponse | RunResponseStream - >(endpoint, body); + >(endpoint, body, pipeName); if (Object.entries(response).length === 0) { return {} as RunResponse | RunResponseStream; } @@ -325,6 +281,7 @@ export class Pipe { return await this.handleStreamResponse( options as RunOptionsStream, response as RunResponseStream, + pipeName ); } @@ -348,7 +305,7 @@ export class Pipe { // }); const toolResults = await this.runTools( - responseMessage.tool_calls as ToolCallResult[], + responseMessage.tool_calls as ToolCall[], ); // logger('\npipe.run.toolResults'); // logger(toolResults, {depth: null, colors: true}); @@ -367,7 +324,7 @@ export class Pipe { messages, stream: false, threadId: currentResponse.threadId, - }); + }, pipeName); callCount++; @@ -386,13 +343,17 @@ export class Pipe { return currentResponse; } - private async createRequest(endpoint: string, body: any): Promise { + private async createRequest( + endpoint: string, + body: any, + pipeName?: string, + ): Promise { const isProdEnv = this.prod; const prodOptions = { endpoint, body: { ...body, - name: this.pipe.name, + name: pipeName || this.pipe.name, }, }; @@ -449,7 +410,7 @@ interface ContentChunk { interface ToolCallChunk { type: 'toolCall'; - toolCall: ToolCallResult; + toolCall: ToolCall; } interface ChoiceStream { @@ -462,7 +423,7 @@ interface ChoiceStream { interface Delta { role?: MessageRole; content?: string; - tool_calls?: ToolCallResult[]; + tool_calls?: ToolCall[]; } interface UnknownChunk { @@ -481,7 +442,7 @@ export interface ChunkStream { export interface Chunk { type: 'content' | 'toolCall' | 'unknown'; content?: string; - toolCall?: ToolCallResult; + toolCall?: ToolCall; rawChunk?: ChunkStream; } diff --git a/packages/core/types/memory.ts b/packages/core/types/memory.ts index aca7fbb8..e5d8205a 100644 --- a/packages/core/types/memory.ts +++ b/packages/core/types/memory.ts @@ -1,26 +1,13 @@ -export interface GitConfig { - enabled: boolean; - include: string[]; - gitignore?: boolean; - deployedAt?: string; - embeddedAt?: string; -} - -export interface MemoryDocumentI { - name: string; - size: string; - content: string; - blob: Blob; - path: string; -} - -export interface Document { - meta?: (doc: MemoryDocumentI) => Record; -} - export interface Memory { name: string; description?: string; - git: GitConfig; - documents?: Document; + config?: MemoryConfig; +} + +interface MemoryConfig { + useGitRepo: boolean; + dirToTrack: string; + extToTrack: string[]; + deployedCommitHash?: string; + embeddedCommitHash?: string; } diff --git a/packages/core/types/model.ts b/packages/core/types/model.ts index 960cdaad..a8d2bbc9 100644 --- a/packages/core/types/model.ts +++ b/packages/core/types/model.ts @@ -29,8 +29,7 @@ export type TogetherModels = | 'together:mistralai/Mistral-7B-Instruct-v0.2' | 'together:mistralai/Mixtral-8x7B-Instruct-v0.1' | 'together:mistralai/Mixtral-8x22B-Instruct-v0.1' - | 'together:databricks/dbrx-instruct' - | 'together:meta-llama/Llama-3.3-70B-Instruct-Turbo'; + | 'together:databricks/dbrx-instruct'; export type AnthropicModels = | 'anthropic:claude-3-5-sonnet-latest' @@ -47,8 +46,7 @@ export type GroqModels = | 'groq:llama3-8b-8192' | 'groq:mixtral-8x7b-32768' | 'groq:gemma2-9b-it' - | 'groq:gemma-7b-it' - | 'groq:llama-3.3-70b-versatile'; + | 'groq:gemma-7b-it'; export type GoogleModels = | 'google:gemini-1.5-pro-latest' @@ -63,8 +61,7 @@ export type FireworksAIModels = | 'fireworks:llama-v3p1-8b-instruct' | 'fireworks:llama-v3p1-70b-instruct' | 'fireworks:llama-v3-70b-instruct' - | 'fireworks:yi-large' - | 'fireworks:llama-v3p3-70b-instruct'; + | 'fireworks:yi-large'; export type PerplexityModels = | 'perplexity:llama-3.1-sonar-huge-128k-online' diff --git a/packages/core/types/pipes.ts b/packages/core/types/pipes.ts index d4390e86..21acd841 100644 --- a/packages/core/types/pipes.ts +++ b/packages/core/types/pipes.ts @@ -19,7 +19,7 @@ export interface Function { arguments: string; } -export interface ToolCallResult { +export interface ToolCall { id: string; type: 'function'; function: Function; @@ -30,7 +30,7 @@ export interface Message { content: string | null; name?: string; tool_call_id?: string; - tool_calls?: ToolCallResult[]; + tool_calls?: ToolCall[]; } interface ToolFunction { @@ -44,15 +44,6 @@ interface ToolChoiceFunction { type ToolChoice = 'auto' | 'required' | ToolChoiceFunction; -export interface Tools { - type: 'function'; - function: { - name: string; - description?: string; - parameters?: Record; - }; -} - export type Model = | OpenAIModels | TogetherModels diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c662e8e..86fcb11d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,9 @@ importers: '@heroicons/react': specifier: ^2.1.3 version: 2.1.5(react@18.3.1) + '@intercom/messenger-js-sdk': + specifier: ^0.0.14 + version: 0.0.14 '@mdx-js/loader': specifier: ^3.0.0 version: 3.0.1(webpack@5.95.0(esbuild@0.17.19)) @@ -154,14 +157,14 @@ importers: specifier: ^2.0.0 version: 2.0.0 next: - specifier: 14.2.35 - version: 14.2.35(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^14.0.4 + version: 14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-mdx-remote: specifier: ^5.0.0 version: 5.0.0(@types/react@18.3.11)(react@18.3.1) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.35(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.2.1(next@14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 version: 18.3.1 @@ -264,10 +267,10 @@ importers: version: 5.1.1(astro@4.15.10(@types/node@22.7.4)(rollup@4.24.0)(terser@5.34.1)(typescript@5.6.2))(tailwindcss@3.4.13(ts-node@10.9.1(@types/node@22.7.4)(typescript@5.6.2)))(ts-node@10.9.1(@types/node@22.7.4)(typescript@5.6.2)) '@astrojs/vercel': specifier: ^7.8.1 - version: 7.8.1(astro@4.15.10(@types/node@22.7.4)(rollup@4.24.0)(terser@5.34.1)(typescript@5.6.2))(next@14.2.35(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 7.8.1(astro@4.15.10(@types/node@22.7.4)(rollup@4.24.0)(terser@5.34.1)(typescript@5.6.2))(next@14.2.5(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@baseai/core': - specifier: ^0.9.43 - version: 0.9.43(react@18.3.1)(zod@3.23.8) + specifier: ^0.9.33 + version: 0.9.33(react@18.3.1)(zod@3.23.8) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.3.11)(react@18.3.1) @@ -309,14 +312,14 @@ importers: version: 5.6.2 devDependencies: baseai: - specifier: ^0.9.44 - version: 0.9.44(@types/node@22.7.4)(typescript@5.6.2) + specifier: ^0.9.33 + version: 0.9.33(@types/node@22.7.4)(typescript@5.6.2) examples/nextjs: dependencies: '@baseai/core': - specifier: ^0.9.43 - version: 0.9.43(react@18.3.1)(zod@3.23.8) + specifier: ^0.9.33 + version: 0.9.33(react@18.3.1)(zod@3.23.8) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.3.11)(react@18.3.1) @@ -336,8 +339,8 @@ importers: specifier: ^2.0.0 version: 2.0.0 next: - specifier: 14.2.35 - version: 14.2.35(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 14.2.5 + version: 14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) openai: specifier: ^4.53.0 version: 4.67.1(zod@3.23.8) @@ -364,8 +367,8 @@ importers: specifier: ^18 version: 18.3.0 baseai: - specifier: ^0.9.44 - version: 0.9.44(@types/node@20.16.10)(typescript@5.6.2) + specifier: ^0.9.33 + version: 0.9.33(@types/node@20.16.10)(typescript@5.6.2) eslint: specifier: ^8 version: 8.57.1 @@ -388,15 +391,15 @@ importers: examples/nodejs: dependencies: '@baseai/core': - specifier: ^0.9.43 - version: 0.9.43(react@18.3.1)(zod@3.23.8) + specifier: ^0.9.33 + version: 0.9.33(react@18.3.1)(zod@3.23.8) dotenv: specifier: ^16.4.5 version: 16.4.5 devDependencies: baseai: - specifier: ^0.9.44 - version: 0.9.44(@types/node@22.7.4)(typescript@5.6.2) + specifier: ^0.9.33 + version: 0.9.33(@types/node@22.7.4)(typescript@5.6.2) tsx: specifier: ^4.19.0 version: 4.19.1 @@ -404,8 +407,8 @@ importers: examples/remix: dependencies: '@baseai/core': - specifier: ^0.9.43 - version: 0.9.43(react@18.3.1)(zod@3.23.8) + specifier: ^0.9.33 + version: 0.9.33(react@18.3.1)(zod@3.23.8) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.3.11)(react@18.3.1) @@ -465,8 +468,8 @@ importers: specifier: ^10.4.20 version: 10.4.20(postcss@8.4.47) baseai: - specifier: ^0.9.44 - version: 0.9.44(@types/node@22.7.4)(typescript@5.6.2) + specifier: ^0.9.33 + version: 0.9.33(@types/node@22.7.4)(typescript@5.6.2) eslint: specifier: ^8.38.0 version: 8.57.1 @@ -525,8 +528,8 @@ importers: specifier: ^8.0.0 version: 8.0.0 chalk: - specifier: 5.6.0 - version: 5.6.0 + specifier: ^5.3.0 + version: 5.3.0 cli-alerts: specifier: ^2.0.0 version: 2.0.0 @@ -548,6 +551,9 @@ importers: compute-cosine-similarity: specifier: ^1.1.0 version: 1.1.0 + conf: + specifier: ^13.0.1 + version: 13.0.1 cosmiconfig: specifier: ^9.0.0 version: 9.0.0(typescript@5.6.2) @@ -560,9 +566,6 @@ importers: execa: specifier: ^9.4.0 version: 9.4.0 - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 figures: specifier: ^6.1.0 version: 6.1.0 @@ -1033,8 +1036,8 @@ packages: resolution: {integrity: sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==} engines: {node: '>=6.9.0'} - '@baseai/core@0.9.43': - resolution: {integrity: sha512-jb0EUJjWqvvqq6Kh7xKTdCwgez4/hoJH3B8VaoWYLXYquOpCsGmVe7hgtt22bgJ2r6LPucglLShGz5uv9DbbKA==} + '@baseai/core@0.9.33': + resolution: {integrity: sha512-AupqofK69YY0drWpXxGOQNWQ0/JV7OrOd6J9Kytkr0dznn9E0e+s7KuqfYklCWhLkBy8NsjYRTQGk3hbplGUbg==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 @@ -2105,6 +2108,9 @@ packages: cpu: [x64] os: [win32] + '@intercom/messenger-js-sdk@0.0.14': + resolution: {integrity: sha512-2dH4BDAh9EI90K7hUkAdZ76W79LM45Sd1OBX7t6Vzy8twpNiQ5X+7sH9G5hlJlkSGnf+vFWlFcy9TOYAyEs1hA==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -2173,8 +2179,8 @@ packages: '@microsoft/tsdoc@0.14.2': resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} - '@next/env@14.2.35': - resolution: {integrity: sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==} + '@next/env@14.2.5': + resolution: {integrity: sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==} '@next/eslint-plugin-next@14.2.14': resolution: {integrity: sha512-kV+OsZ56xhj0rnTn6HegyTGkoa16Mxjrpk7pjWumyB2P8JVQb8S9qtkjy/ye0GnTr4JWtWG4x/2qN40lKZ3iVQ==} @@ -2193,56 +2199,56 @@ packages: '@mdx-js/react': optional: true - '@next/swc-darwin-arm64@14.2.33': - resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==} + '@next/swc-darwin-arm64@14.2.5': + resolution: {integrity: sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@14.2.33': - resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==} + '@next/swc-darwin-x64@14.2.5': + resolution: {integrity: sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@14.2.33': - resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==} + '@next/swc-linux-arm64-gnu@14.2.5': + resolution: {integrity: sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@14.2.33': - resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==} + '@next/swc-linux-arm64-musl@14.2.5': + resolution: {integrity: sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@14.2.33': - resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==} + '@next/swc-linux-x64-gnu@14.2.5': + resolution: {integrity: sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@14.2.33': - resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==} + '@next/swc-linux-x64-musl@14.2.5': + resolution: {integrity: sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@14.2.33': - resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==} + '@next/swc-win32-arm64-msvc@14.2.5': + resolution: {integrity: sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-ia32-msvc@14.2.33': - resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==} + '@next/swc-win32-ia32-msvc@14.2.5': + resolution: {integrity: sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@next/swc-win32-x64-msvc@14.2.33': - resolution: {integrity: sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==} + '@next/swc-win32-x64-msvc@14.2.5': + resolution: {integrity: sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3466,6 +3472,14 @@ packages: ajv: optional: true + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -3652,6 +3666,9 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + atomically@2.0.3: + resolution: {integrity: sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==} + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -3687,8 +3704,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseai@0.9.44: - resolution: {integrity: sha512-NhRxhWEBW/pmaODcCMFAXNZgM0XVQHrUsEeUkmXuHV4UXSfiJPg/W1r6yDwGq9bCz/pqPNXdHlU9vy0+0GsOTw==} + baseai@0.9.33: + resolution: {integrity: sha512-pOluUwNOA0tH9FrYh7dWA9yYw25ccsvNhvyjHd3Ja1h9dkjHfaGpd87eiS0Vi8Vj92/ooASpvJui6RGBwScE5A==} hasBin: true basic-auth@2.0.1: @@ -3845,10 +3862,6 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - chalk@5.6.0: - resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -4057,6 +4070,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + conf@13.0.1: + resolution: {integrity: sha512-l9Uwc9eOnz39oADzGO2cSBDi7siv8lwO+31ocQ2nOJijnDiW3pxqm9VV10DPYUO28wW83DjABoUqY1nfHRR2hQ==} + engines: {node: '>=18'} + confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} @@ -4226,6 +4243,10 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debounce-fn@6.0.0: + resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==} + engines: {node: '>=18'} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -4407,6 +4428,10 @@ packages: dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} @@ -4482,6 +4507,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -6056,6 +6085,9 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-typed@8.0.1: + resolution: {integrity: sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -6799,8 +6831,8 @@ packages: react: '*' react-dom: '*' - next@14.2.35: - resolution: {integrity: sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==} + next@14.2.5: + resolution: {integrity: sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -8077,7 +8109,6 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} - deprecated: The work that was done in this beta branch won't be included in future versions sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} @@ -8252,6 +8283,9 @@ packages: strip-literal@2.1.0: resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + stubborn-fs@1.2.5: + resolution: {integrity: sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==} + style-to-object@0.4.4: resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} @@ -8650,6 +8684,10 @@ packages: uid-promise@1.0.0: resolution: {integrity: sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==} + uint8array-extras@1.4.0: + resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + engines: {node: '>=18'} + ultrahtml@1.5.3: resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==} @@ -9144,6 +9182,9 @@ packages: whatwg-url@7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + when-exit@2.1.3: + resolution: {integrity: sha512-uVieSTccFIr/SFQdFWN/fFaQYmV37OKtuaGphMAzi4DmmUlrvRBJW5WSLkHyjNQY/ePJMz3LoiX9R3yy1Su6Hw==} + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -9589,10 +9630,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/vercel@7.8.1(astro@4.15.10(@types/node@22.7.4)(rollup@4.24.0)(terser@5.34.1)(typescript@5.6.2))(next@14.2.35(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@astrojs/vercel@7.8.1(astro@4.15.10(@types/node@22.7.4)(rollup@4.24.0)(terser@5.34.1)(typescript@5.6.2))(next@14.2.5(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@astrojs/internal-helpers': 0.4.1 - '@vercel/analytics': 1.3.1(next@14.2.35(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@vercel/analytics': 1.3.1(next@14.2.5(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@vercel/edge': 1.1.2 '@vercel/nft': 0.27.4 astro: 4.15.10(@types/node@22.7.4)(rollup@4.24.0)(terser@5.34.1)(typescript@5.6.2) @@ -9846,7 +9887,7 @@ snapshots: '@babel/helper-validator-identifier': 7.25.7 to-fast-properties: 2.0.0 - '@baseai/core@0.9.43(react@18.3.1)(zod@3.23.8)': + '@baseai/core@0.9.33(react@18.3.1)(zod@3.23.8)': dependencies: openai: 4.67.1(zod@3.23.8) optionalDependencies: @@ -10651,6 +10692,8 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true + '@intercom/messenger-js-sdk@0.0.14': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -10797,7 +10840,7 @@ snapshots: '@microsoft/tsdoc@0.14.2': {} - '@next/env@14.2.35': {} + '@next/env@14.2.5': {} '@next/eslint-plugin-next@14.2.14': dependencies: @@ -10814,31 +10857,31 @@ snapshots: '@mdx-js/loader': 3.0.1(webpack@5.95.0(esbuild@0.17.19)) '@mdx-js/react': 3.0.1(@types/react@18.3.11)(react@18.3.1) - '@next/swc-darwin-arm64@14.2.33': + '@next/swc-darwin-arm64@14.2.5': optional: true - '@next/swc-darwin-x64@14.2.33': + '@next/swc-darwin-x64@14.2.5': optional: true - '@next/swc-linux-arm64-gnu@14.2.33': + '@next/swc-linux-arm64-gnu@14.2.5': optional: true - '@next/swc-linux-arm64-musl@14.2.33': + '@next/swc-linux-arm64-musl@14.2.5': optional: true - '@next/swc-linux-x64-gnu@14.2.33': + '@next/swc-linux-x64-gnu@14.2.5': optional: true - '@next/swc-linux-x64-musl@14.2.33': + '@next/swc-linux-x64-musl@14.2.5': optional: true - '@next/swc-win32-arm64-msvc@14.2.33': + '@next/swc-win32-arm64-msvc@14.2.5': optional: true - '@next/swc-win32-ia32-msvc@14.2.33': + '@next/swc-win32-ia32-msvc@14.2.5': optional: true - '@next/swc-win32-x64-msvc@14.2.33': + '@next/swc-win32-x64-msvc@14.2.5': optional: true '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': @@ -11956,11 +11999,11 @@ snapshots: '@vanilla-extract/private@1.0.6': {} - '@vercel/analytics@1.3.1(next@14.2.35(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@vercel/analytics@1.3.1(next@14.2.5(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: server-only: 0.0.1 optionalDependencies: - next: 14.2.35(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 '@vercel/build-utils@8.4.5': {} @@ -12424,6 +12467,10 @@ snapshots: optionalDependencies: ajv: 8.17.1 + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 @@ -12711,6 +12758,11 @@ snapshots: asynckit@0.4.0: {} + atomically@2.0.3: + dependencies: + stubborn-fs: 1.2.5 + when-exit: 2.1.3 + autoprefixer@10.4.20(postcss@8.4.47): dependencies: browserslist: 4.24.0 @@ -12739,7 +12791,7 @@ snapshots: base64-js@1.5.1: {} - baseai@0.9.44(@types/node@20.16.10)(typescript@5.6.2): + baseai@0.9.33(@types/node@20.16.10)(typescript@5.6.2): dependencies: '@antfu/ni': 0.23.0 '@clack/core': 0.3.4 @@ -12748,7 +12800,7 @@ snapshots: '@hono/zod-openapi': 0.16.2(hono@4.6.3)(zod@3.23.8) '@sindresorhus/slugify': 2.2.1 camelcase: 8.0.0 - chalk: 5.6.0 + chalk: 5.3.0 cli-alerts: 2.0.0 cli-handle-error: 4.4.0 cli-handle-unhandled: 1.1.1 @@ -12756,11 +12808,11 @@ snapshots: cli-table3: 0.6.5 cli-welcome: 3.0.0 compute-cosine-similarity: 1.1.0 + conf: 13.0.1 cosmiconfig: 9.0.0(typescript@5.6.2) cosmiconfig-typescript-loader: 5.0.0(@types/node@20.16.10)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2) dotenv: 16.4.5 execa: 9.4.0 - fast-glob: 3.3.2 figures: 6.1.0 get-package-json-file: 2.0.0 hono: 4.6.3 @@ -12787,7 +12839,7 @@ snapshots: - supports-color - typescript - baseai@0.9.44(@types/node@22.7.4)(typescript@5.6.2): + baseai@0.9.33(@types/node@22.7.4)(typescript@5.6.2): dependencies: '@antfu/ni': 0.23.0 '@clack/core': 0.3.4 @@ -12796,7 +12848,7 @@ snapshots: '@hono/zod-openapi': 0.16.2(hono@4.6.3)(zod@3.23.8) '@sindresorhus/slugify': 2.2.1 camelcase: 8.0.0 - chalk: 5.6.0 + chalk: 5.3.0 cli-alerts: 2.0.0 cli-handle-error: 4.4.0 cli-handle-unhandled: 1.1.1 @@ -12804,11 +12856,11 @@ snapshots: cli-table3: 0.6.5 cli-welcome: 3.0.0 compute-cosine-similarity: 1.1.0 + conf: 13.0.1 cosmiconfig: 9.0.0(typescript@5.6.2) cosmiconfig-typescript-loader: 5.0.0(@types/node@22.7.4)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2) dotenv: 16.4.5 execa: 9.4.0 - fast-glob: 3.3.2 figures: 6.1.0 get-package-json-file: 2.0.0 hono: 4.6.3 @@ -12880,7 +12932,7 @@ snapshots: dependencies: ansi-align: 3.0.1 camelcase: 8.0.0 - chalk: 5.6.0 + chalk: 5.3.0 cli-boxes: 3.0.0 string-width: 7.2.0 type-fest: 4.26.1 @@ -13010,7 +13062,7 @@ snapshots: chalk-template@1.1.0: dependencies: - chalk: 5.6.0 + chalk: 5.3.0 chalk@2.4.2: dependencies: @@ -13030,8 +13082,6 @@ snapshots: chalk@5.3.0: {} - chalk@5.6.0: {} - character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -13122,7 +13172,7 @@ snapshots: cli-meow-help@4.0.0: dependencies: - chalk: 5.6.0 + chalk: 5.3.0 chalk-template: 1.1.0 cli-table3: 0.6.5 @@ -13141,7 +13191,7 @@ snapshots: cli-welcome@3.0.0: dependencies: - chalk: 5.6.0 + chalk: 5.3.0 clear-any-console: 1.16.2 client-only@0.0.1: {} @@ -13243,6 +13293,18 @@ snapshots: concat-map@0.0.1: {} + conf@13.0.1: + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + atomically: 2.0.3 + debounce-fn: 6.0.0 + dot-prop: 9.0.0 + env-paths: 3.0.0 + json-schema-typed: 8.0.1 + semver: 7.6.3 + uint8array-extras: 1.4.0 + confbox@0.1.7: {} consola@3.2.3: {} @@ -13393,6 +13455,10 @@ snapshots: dayjs@1.11.13: {} + debounce-fn@6.0.0: + dependencies: + mimic-function: 5.0.1 + debug@2.6.9: dependencies: ms: 2.0.0 @@ -13538,6 +13604,10 @@ snapshots: dom-accessibility-api@0.5.16: {} + dot-prop@9.0.0: + dependencies: + type-fest: 4.26.1 + dotenv@16.0.3: {} dotenv@16.4.5: {} @@ -13608,6 +13678,8 @@ snapshots: env-paths@2.2.1: {} + env-paths@3.0.0: {} + environment@1.1.0: {} err-code@2.0.3: {} @@ -15568,6 +15640,8 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema-typed@8.0.1: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -15707,7 +15781,7 @@ snapshots: log-symbols@6.0.0: dependencies: - chalk: 5.6.0 + chalk: 5.3.0 is-unicode-supported: 1.3.0 log-symbols@7.0.0: @@ -16773,15 +16847,15 @@ snapshots: - '@types/react' - supports-color - next-themes@0.2.1(next@14.2.35(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.2.1(next@14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 14.2.35(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@14.2.35(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.5(@babel/core@7.25.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.35 + '@next/env': 14.2.5 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001666 @@ -16791,23 +16865,23 @@ snapshots: react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.1(@babel/core@7.25.7)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.33 - '@next/swc-darwin-x64': 14.2.33 - '@next/swc-linux-arm64-gnu': 14.2.33 - '@next/swc-linux-arm64-musl': 14.2.33 - '@next/swc-linux-x64-gnu': 14.2.33 - '@next/swc-linux-x64-musl': 14.2.33 - '@next/swc-win32-arm64-msvc': 14.2.33 - '@next/swc-win32-ia32-msvc': 14.2.33 - '@next/swc-win32-x64-msvc': 14.2.33 + '@next/swc-darwin-arm64': 14.2.5 + '@next/swc-darwin-x64': 14.2.5 + '@next/swc-linux-arm64-gnu': 14.2.5 + '@next/swc-linux-arm64-musl': 14.2.5 + '@next/swc-linux-x64-gnu': 14.2.5 + '@next/swc-linux-x64-musl': 14.2.5 + '@next/swc-win32-arm64-msvc': 14.2.5 + '@next/swc-win32-ia32-msvc': 14.2.5 + '@next/swc-win32-x64-msvc': 14.2.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros optional: true - next@14.2.35(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.5(@playwright/test@1.47.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.35 + '@next/env': 14.2.5 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001666 @@ -16817,15 +16891,15 @@ snapshots: react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.1(@babel/core@7.25.7)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.33 - '@next/swc-darwin-x64': 14.2.33 - '@next/swc-linux-arm64-gnu': 14.2.33 - '@next/swc-linux-arm64-musl': 14.2.33 - '@next/swc-linux-x64-gnu': 14.2.33 - '@next/swc-linux-x64-musl': 14.2.33 - '@next/swc-win32-arm64-msvc': 14.2.33 - '@next/swc-win32-ia32-msvc': 14.2.33 - '@next/swc-win32-x64-msvc': 14.2.33 + '@next/swc-darwin-arm64': 14.2.5 + '@next/swc-darwin-x64': 14.2.5 + '@next/swc-linux-arm64-gnu': 14.2.5 + '@next/swc-linux-arm64-musl': 14.2.5 + '@next/swc-linux-x64-gnu': 14.2.5 + '@next/swc-linux-x64-musl': 14.2.5 + '@next/swc-win32-arm64-msvc': 14.2.5 + '@next/swc-win32-ia32-msvc': 14.2.5 + '@next/swc-win32-x64-msvc': 14.2.5 '@playwright/test': 1.47.2 transitivePeerDependencies: - '@babel/core' @@ -17080,7 +17154,7 @@ snapshots: ora@8.1.0: dependencies: - chalk: 5.6.0 + chalk: 5.3.0 cli-cursor: 5.0.0 cli-spinners: 2.9.2 is-interactive: 2.0.0 @@ -18398,6 +18472,8 @@ snapshots: dependencies: js-tokens: 9.0.0 + stubborn-fs@1.2.5: {} + style-to-object@0.4.4: dependencies: inline-style-parser: 0.1.1 @@ -18884,6 +18960,8 @@ snapshots: uid-promise@1.0.0: {} + uint8array-extras@1.4.0: {} + ultrahtml@1.5.3: {} unbox-primitive@1.0.2: @@ -19493,6 +19571,8 @@ snapshots: tr46: 1.0.1 webidl-conversions: 4.0.2 + when-exit@2.1.3: {} + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4