diff --git a/.github/scripts/release-snapshot.js b/.github/scripts/release-snapshot.js new file mode 100644 index 00000000..e825d839 --- /dev/null +++ b/.github/scripts/release-snapshot.js @@ -0,0 +1,78 @@ +/** + * This script creates a snapshot release by performing the following steps: + * 1. Ensures the script is running from the project root directory. + * 2. Defines a function to execute shell commands and log their output. + * 3. Defines a function to update the version in a given package.json file. + * - If the current version is already a snapshot, it increments the snapshot number. + * - If the current version is not a snapshot, it increments the patch version and sets the snapshot number to 0. + * 4. Retrieves the current commit short SHA. + * 5. Bumps the version in the specified package.json files. + * 6. Runs a series of commands to version, build, and publish the packages as a snapshot release. + * + * @file /Users/ahmadawais/Documents/Sandbox/baseai/.github/scripts/create-snapshot.js + * @requires child_process + * @requires path + * @requires fs + */ +const {execSync} = require('child_process'); +const path = require('path'); +const fs = require('fs'); + +// Ensure we're in the project root +process.chdir(path.resolve(__dirname, '../..')); + +// Function to execute commands and log output +function run(command) { + console.log(`Running: ${command}`); + try { + execSync(command, {stdio: 'inherit'}); + } catch (error) { + console.error(`Error executing command: ${command}`); + console.error(error); + process.exit(1); + } +} + +// Function to update version in package.json +function bumpVersion(packagePath) { + const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8')); + const currentVersion = pkg.version; + let [major, minor, patch, snapshot] = currentVersion + .split(/[-.]/) + .map(v => (isNaN(parseInt(v)) ? v : parseInt(v))); + + if (snapshot === 'snapshot') { + // If already a snapshot, increment the snapshot number + snapshot = parseInt(pkg.version.split('-snapshot.')[1]) + 1; + } else { + // If not a snapshot, increment patch and set snapshot to 0 + patch += 1; + snapshot = 0; + } + + pkg.version = `${major}.${minor}.${patch}-snapshot.${snapshot}`; + fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2)); + console.log(`Updated ${packagePath} to version ${pkg.version}`); +} + +// Get the current commit short SHA +const SHORT_SHA = execSync('git rev-parse --short HEAD').toString().trim(); + +console.log('Creating snapshot release...'); + +// Bump versions +bumpVersion('./packages/baseai/package.json'); +bumpVersion('./packages/core/package.json'); + +// Version and tag the snapshot release +run(`pnpm changeset version --snapshot ${SHORT_SHA}`); + +// Build and publish the snapshot release +run('pnpm build:pkgs'); +run('pnpm changeset publish --no-git-tag --tag snapshot'); + +// Reset Git changes +console.log('Git commit and push changes...'); +run('git add . && git commit -m "📦 NEW: snapshot release" && git push'); + +console.log('All changes have been reset. Snapshot release process complete!'); diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 77c1d05b..691d40e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,15 @@ We welcome contributions to this project. --- +## Releasing a test snapshot + +Run the following command to create a snapshot of the current changes, this must be done in a custom branch. If the current version is `1.0.0`, the snapshot will be `1.0.1-snapshot.0` and if done again `1.0.1-snapshot.1` and so on. This version will also be committed to the package.json file. And in the next normal release, the version will be `1.0.1` and the snapshot will be reset. + +```bash +pnpm snapshot +``` + + ``` ## Releasing a new version ```bash diff --git a/examples/nodejs/baseai/pipes/summary.ts b/examples/nodejs/baseai/pipes/summary.ts index cb6a3c50..781bab9d 100644 --- a/examples/nodejs/baseai/pipes/summary.ts +++ b/examples/nodejs/baseai/pipes/summary.ts @@ -1,8 +1,9 @@ import {PipeI} from '@baseai/core'; +import {config} from '../baseai.config'; const buildPipe = (): PipeI => ({ - apiKey: process.env.LANGBASE_API_KEY!, // Replace with your API key https://langbase.com/docs/api-reference/api-keys - name: 'summary', + apiKey: config.env.langbase, + name: 'summary-nodejs', description: '', status: 'private', model: 'openai:gpt-4o-mini', @@ -18,7 +19,12 @@ const buildPipe = (): PipeI => ({ stop: [], tool_choice: 'auto', parallel_tool_calls: false, - messages: [{role: 'system', content: `You are a helpful AI assistant.`}], + messages: [ + { + role: 'system', + content: `You are a helpful AI assistant. Make everything less wordy.`, + }, + ], variables: [], memory: [], tools: [], diff --git a/examples/nodejs/examples/pipe.run.ts b/examples/nodejs/examples/pipe.run.ts index 94115bdb..0531f7ba 100644 --- a/examples/nodejs/examples/pipe.run.ts +++ b/examples/nodejs/examples/pipe.run.ts @@ -1,8 +1,12 @@ import 'dotenv/config'; -import {Pipe} from '@baseai/core'; +import {config} from '../baseai/baseai.config'; import pipeSummary from '../baseai/pipes/summary'; +import {Pipe} from './../../../packages/core/src/pipes/pipes'; -const pipe = new Pipe(pipeSummary()); +const pipe = new Pipe({ + ...pipeSummary(), + config, +}); async function main() { const userMsg = 'Who is an AI Engineer?'; diff --git a/package.json b/package.json index c7d2895f..2ad46878 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "changeset": "changeset", "publint": "turbo publint", "type-check": "turbo type-check", - "version-packages": "changeset version && pnpm clean-examples && pnpm install --no-frozen-lockfile --filter=./packages/* --filter=./tools/* ", + "version-packages": "changeset version && pnpm clean-examples && pnpm install --no-frozen-lockfile --filter=./packages/* --filter=./tools/*", "clean": "turbo clean", "clean-all": "turbo clean && rm -rf node_modules", "format": "prettier --write \"**/*.{ts,tsx,md}\"", @@ -29,7 +29,7 @@ "clean-examples": "node .github/scripts/cleanup-examples-changesets.mjs", "update-examples": "npx tsx .github/scripts/update-examples.ts", "ci:version": "changeset version && node .github/scripts/cleanup-examples-changesets.mjs && pnpm install --no-frozen-lockfile", - "snapshot": "changeset --empty && changeset version --snapshot && changeset publish --no-git-tag --snapshot" + "snapshot": "node .github/scripts/release-snapshot.js" }, "devDependencies": { "@baseai/eslint-config": "workspace:*", diff --git a/packages/baseai/package.json b/packages/baseai/package.json index c880d461..8b139f05 100644 --- a/packages/baseai/package.json +++ b/packages/baseai/package.json @@ -1,116 +1,117 @@ { - "name": "baseai", - "description": "The Web AI Framework Dev - BaseAI.dev", - "version": "0.9.7", - "license": "UNLICENSED", - "type": "module", - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "bin": { - "baseai": "bin/baseai.js" - }, - "author": { - "name": "Langbase", - "url": "https://BaseAI.dev" - }, - "repository": { - "type": "git", - "url": "https://github.com/LangbaseInc/baseai.git", - "directory": "packages/cli" - }, - "bugs": { - "url": "https://github.com/LangbaseInc/baseai/issues" - }, - "homepage": "https://BaseAI.dev", - "files": [ - "dist/**" - ], - "scripts": { - "build": "tsup", - "dev": "tsup --watch", - "lint": "eslint \"src/**/*.ts*\"", - "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", - "type-check": "tsc --noEmit", - "prettier-check": "prettier --check \"./**/*.ts*\"", - "test": "pnpm test:node && pnpm test:edge", - "#test": "pnpm test:node && pnpm test:edge && pnpm test:ui && pnpm test:e2e", - "test:edge": "vitest --config vitest.edge.config.js --run", - "test:node": "vitest --config vitest.node.config.js --run", - "test:ui": "pnpm test:ui:react", - "test:ui:react": "vitest --config vitest.ui.react.config.js --run", - "test:e2e": "playwright test", - "test:edge:watch": "vitest --config vitest.edge.config.js", - "test:node:watch": "vitest --config vitest.node.config.js", - "test:ui:react:watch": "vitest --config vitest.ui.react.config.js" - }, - "dependencies": { - "@antfu/ni": "^0.23.0", - "@clack/core": "^0.3.4", - "@clack/prompts": "^0.7.0", - "@hono/node-server": "^1.13.1", - "@hono/zod-openapi": "^0.16.0", - "@sindresorhus/slugify": "^2.2.1", - "camelcase": "^8.0.0", - "chalk": "^5.3.0", - "cli-alerts": "^2.0.0", - "cli-handle-error": "^4.4.0", - "cli-handle-unhandled": "^1.1.1", - "cli-meow-help": "^4.0.0", - "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", - "figures": "^6.1.0", - "get-package-json-file": "^2.0.0", - "hono": "^4.5.11", - "js-tiktoken": "^1.0.14", - "log-symbols": "^7.0.0", - "lowdb": "^7.0.1", - "meow": "^13.2.0", - "node-fetch": "^3.3.2", - "open": "^10.1.0", - "openai": "^4.63.0", - "p-map": "^7.0.2", - "picocolors": "^1.1.0", - "prettier": "^3.3.3", - "source-map-support": "^0.5.21", - "unpdf": "^0.11.0", - "uuid": "^10.0.0", - "xlsx": "^0.18.5", - "zod": "^3.23.8", - "zod-error": "^1.5.0", - "zod-validation-error": "^3.4.0" - }, - "devDependencies": { - "@baseai/eslint-config": "workspace:*", - "@baseai/tsconfig": "workspace:*", - "@types/node": "^22.6.1", - "tsup": "^8.3.0", - "tsx": "^4.19.1", - "typescript": "^5.6.2", - "vitest": "1.6.0" - }, - "keywords": [ - "baseai", - "base", - "base AI framework", - "BaseAI.dev", - "composable AI", - "AI agents", - "AI multi agents", - "ai", - "llm", - "langbase core", - "langbase sdk", - "baseai", - "base ai", - "langbase", - "langbase.com", - "generative AI" - ] -} + "name": "baseai", + "description": "The Web AI Framework Dev - BaseAI.dev", + "version": "0.9.8-snapshot.3", + "license": "UNLICENSED", + "type": "module", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "bin": { + "baseai": "bin/baseai.js" + }, + "author": { + "name": "Langbase", + "url": "https://BaseAI.dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/LangbaseInc/baseai.git", + "directory": "packages/cli" + }, + "bugs": { + "url": "https://github.com/LangbaseInc/baseai/issues" + }, + "homepage": "https://BaseAI.dev", + "files": [ + "dist/**", + "bin/**" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "lint": "eslint \"src/**/*.ts*\"", + "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", + "type-check": "tsc --noEmit", + "prettier-check": "prettier --check \"./**/*.ts*\"", + "test": "pnpm test:node && pnpm test:edge", + "#test": "pnpm test:node && pnpm test:edge && pnpm test:ui && pnpm test:e2e", + "test:edge": "vitest --config vitest.edge.config.js --run", + "test:node": "vitest --config vitest.node.config.js --run", + "test:ui": "pnpm test:ui:react", + "test:ui:react": "vitest --config vitest.ui.react.config.js --run", + "test:e2e": "playwright test", + "test:edge:watch": "vitest --config vitest.edge.config.js", + "test:node:watch": "vitest --config vitest.node.config.js", + "test:ui:react:watch": "vitest --config vitest.ui.react.config.js" + }, + "dependencies": { + "@antfu/ni": "^0.23.0", + "@clack/core": "^0.3.4", + "@clack/prompts": "^0.7.0", + "@hono/node-server": "^1.13.1", + "@hono/zod-openapi": "^0.16.0", + "@sindresorhus/slugify": "^2.2.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-alerts": "^2.0.0", + "cli-handle-error": "^4.4.0", + "cli-handle-unhandled": "^1.1.1", + "cli-meow-help": "^4.0.0", + "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", + "figures": "^6.1.0", + "get-package-json-file": "^2.0.0", + "hono": "^4.5.11", + "js-tiktoken": "^1.0.14", + "log-symbols": "^7.0.0", + "lowdb": "^7.0.1", + "meow": "^13.2.0", + "node-fetch": "^3.3.2", + "open": "^10.1.0", + "openai": "^4.63.0", + "p-map": "^7.0.2", + "picocolors": "^1.1.0", + "prettier": "^3.3.3", + "source-map-support": "^0.5.21", + "unpdf": "^0.11.0", + "uuid": "^10.0.0", + "xlsx": "^0.18.5", + "zod": "^3.23.8", + "zod-error": "^1.5.0", + "zod-validation-error": "^3.4.0" + }, + "devDependencies": { + "@baseai/eslint-config": "workspace:*", + "@baseai/tsconfig": "workspace:*", + "@types/node": "^22.6.1", + "tsup": "^8.3.0", + "tsx": "^4.19.1", + "typescript": "^5.6.2", + "vitest": "1.6.0" + }, + "keywords": [ + "baseai", + "base", + "base AI framework", + "BaseAI.dev", + "composable AI", + "AI agents", + "AI multi agents", + "ai", + "llm", + "langbase core", + "langbase sdk", + "baseai", + "base ai", + "langbase", + "langbase.com", + "generative AI" + ] +} \ No newline at end of file diff --git a/packages/baseai/src/add/index.ts b/packages/baseai/src/add/index.ts index 46fd3fb3..b6ed1207 100644 --- a/packages/baseai/src/add/index.ts +++ b/packages/baseai/src/add/index.ts @@ -302,8 +302,9 @@ async function createLocalPipe(pipe: Pipe) { ${toolData.map(tool => tool.importPath).join('\n')} const ${pipeNameCamelCase} = (): PipeI => ({ - // Replace with your API key https://langbase.com/docs/api-reference/api-keys - apiKey: process.env.LANGBASE_API_KEY!, + // Prod only: Replace with your Langbase API key + // https://langbase.com/docs/api-reference/api-keys + apiKey: process.env.LANGBASE_API_KEY, name: \`${pipe.name}\`, description: \`${pipe.description}\`, status: \`${pipe.status}\`, diff --git a/packages/baseai/src/dev/utils/get-llm-api-key.ts b/packages/baseai/src/dev/utils/get-llm-api-key.ts deleted file mode 100644 index 523a84a0..00000000 --- a/packages/baseai/src/dev/utils/get-llm-api-key.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - ANTHROPIC, - COHERE, - FIREWORKS_AI, - GOOGLE, - GROQ, - OPEN_AI, - PERPLEXITY, - TOGETHER_AI -} from '@/dev/data/models'; - -export function getLLMApiKey(modelProvider: string): string { - switch (true) { - case modelProvider.includes(OPEN_AI): - return process.env.OPENAI_API_KEY || ''; - case modelProvider === ANTHROPIC: - return process.env.ANTHROPIC_API_KEY || ''; - case modelProvider === TOGETHER_AI: - return process.env.TOGETHER_API_KEY || ''; - case modelProvider === GROQ: - return process.env.GROQ_API_KEY || ''; - case modelProvider === GOOGLE: - return process.env.GOOGLE_API_KEY || ''; - case modelProvider.includes(COHERE): - return process.env.COHERE_API_KEY || ''; - case modelProvider.includes(FIREWORKS_AI): - return process.env.FIREWORKS_API_KEY || ''; - case modelProvider.includes(PERPLEXITY): - return process.env.PERPLEXITY_API_KEY || ''; - default: - throw new Error(`Unsupported model provider: ${modelProvider}`); - } -} diff --git a/packages/baseai/src/pipe/index.ts b/packages/baseai/src/pipe/index.ts index 0ba6cb93..c383260d 100644 --- a/packages/baseai/src/pipe/index.ts +++ b/packages/baseai/src/pipe/index.ts @@ -132,8 +132,9 @@ export async function createPipe() { const pipeContent = `import { PipeI } from '@baseai/core';${selectedTools}${selectedMemories} const ${pipeNameCamelCase} = (): PipeI => ({ - // Replace with your API key https://langbase.com/docs/api-reference/api-keys - apiKey: process.env.LANGBASE_API_KEY!, + // Prod only: Replace with your Langbase API key + // https://langbase.com/docs/api-reference/api-keys + apiKey: process.env.LANGBASE_API_KEY, name: '${pipeNameSlugified}', description: '${pipeInfo.description || ''}', status: '${pipeInfo.status}', diff --git a/packages/baseai/src/utils/config/config-handler.ts b/packages/baseai/src/utils/config/config-handler.ts index 467d399f..b8caf0af 100644 --- a/packages/baseai/src/utils/config/config-handler.ts +++ b/packages/baseai/src/utils/config/config-handler.ts @@ -1,27 +1,34 @@ import * as p from '@clack/prompts'; import { cosmiconfig } from 'cosmiconfig'; import { TypeScriptLoader } from 'cosmiconfig-typescript-loader'; -import type { BaseAIConfig } from 'types/config'; +import type { BaseAIConfig, EnvConfig } from 'types/config'; +/** + * Default configuration for BaseAI. + */ export const defaultConfig: BaseAIConfig = { log: { // Enable or disable logging isEnabled: true, - // Log sensitive data + // Enable logging in production when NODE_ENV is set to production + isEnabledInProd: false, logSensitiveData: false, - // Toggle specific log categories pipe: true, 'pipe.completion': true, 'pipe.request': true, 'pipe.response': true, + 'pipe.request.prodOptions': false, + 'pipe.request.localOptions': false, tool: true, memory: true }, memory: { useLocalEmbeddings: false }, - envFilePath: '.env' + // Path to the .env file starting from the root of the project + envFilePath: '.env', // Other default configuration options can be added here + env: {} as EnvConfig }; export async function loadConfig(): Promise { diff --git a/packages/baseai/src/utils/memory/generate-openai-embeddings.ts b/packages/baseai/src/utils/memory/generate-openai-embeddings.ts index 46f0324b..0b58389c 100644 --- a/packages/baseai/src/utils/memory/generate-openai-embeddings.ts +++ b/packages/baseai/src/utils/memory/generate-openai-embeddings.ts @@ -1,16 +1,32 @@ import * as p from '@clack/prompts'; import { getEncoding } from 'js-tiktoken'; import OpenAI from 'openai'; +import { loadConfig } from '../config/config-handler'; +import { cyan } from '../formatting'; import { MEMORYSETS } from './constants'; export const getOpenAIEmbeddings = async ( chunks: string[] ): Promise => { - const openAiKey = process.env.OPENAI_API_KEY; + const config = await loadConfig(); + const configEnv = config?.env; + + const getEnv = (key: string): string | undefined => { + let value: string | undefined; + if (configEnv && key in configEnv) { + value = configEnv[key as keyof typeof configEnv]; + } else { + value = process.env[key]; + } + + return value; + }; + + const openAiKey = getEnv('OPENAI_API_KEY'); if (!openAiKey) { p.cancel( - 'OpenAI key not found. Please set the OPENAI_API_KEY environment variable. Only required locally, in production, add it to your keysets https://langbase.com/docs/features/keysets' + `Environment variable ${cyan(`OPENAI_API_KEY`)} is not set or empty. Only needed in local dev environment. \nNote: In production, add it to your keysets https://langbase.com/docs/features/keysets\n` ); process.exit(1); } diff --git a/packages/baseai/types/config.ts b/packages/baseai/types/config.ts index f4a5bba2..d4860c5c 100644 --- a/packages/baseai/types/config.ts +++ b/packages/baseai/types/config.ts @@ -1,32 +1,123 @@ -// Define the specific log categories as a type +/** + * Represents the various categories of logs that can be generated within the system. + * + * @typedef {LogCategories} LogCategories + * + * @property {'pipe'} pipe - General pipe-related logs. + * @property {'pipe.completion'} pipe.completion - Logs related to the completion of a pipe. + * @property {'pipe.request'} pipe.request - Logs for pipe requests. + * @property {'pipe.response'} pipe.response - Logs for pipe responses. + * @property {'pipe.request.prodOptions'} pipe.request.prodOptions - Logs for production options in pipe requests. + * @property {'pipe.request.localOptions'} pipe.request.localOptions - Logs for local options in pipe requests. + * @property {'tool'} tool - General tool-related logs. + * @property {'tool.calls'} tool.calls - Logs for tool calls. + * @property {'memory'} memory - General memory-related logs. + * @property {'memory.similarChunks'} memory.similarChunks - Logs for similar memory chunks. + * @property {'memory.augmentedContext'} memory.augmentedContext - Logs for augmented memory context. + */ export type LogCategories = | 'pipe' | 'pipe.completion' | 'pipe.request' | 'pipe.response' + | 'pipe.request.prodOptions' + | 'pipe.request.localOptions' | 'tool' | 'tool.calls' | 'memory' | 'memory.similarChunks' | 'memory.augmentedContext'; -// Define a recursive type for nested categories +/** + * Define a recursive type for nested categories + * + * Represents a type for nested categories where each key is a `LogCategories` type. + * The value can either be a boolean or another nested structure of the same type. + * This allows for creating a hierarchical structure of categories with optional boolean flags. + */ type NestedCategories = { [key in LogCategories]?: boolean | NestedCategories; }; -// Logger config +/** + * Configuration settings for the logger. + * + * @typedef {LoggerConfig} + * + * @property {boolean} isEnabled - Indicates if logging is enabled. + * @property {boolean} [isEnabledInProd] - Optional flag to enable logging in production. + * @property {boolean} logSensitiveData - Determines if sensitive data should be logged. + * @property {NestedCategories} - Inherits properties from NestedCategories. + */ export type LoggerConfig = { isEnabled: boolean; + isEnabledInProd?: boolean; logSensitiveData: boolean; } & NestedCategories; +/** + * Configuration interface for memory settings. + * + * @interface MemoryConfig + * + * @property {boolean} useLocalEmbeddings - Indicates whether to use local embeddings. + */ export interface MemoryConfig { useLocalEmbeddings: boolean; } +/** + * Interface representing the environment configuration for the application. + * + * @property {string} [NODE_ENV] - The environment in which the application is running (e.g., 'development', 'production'). + * @property {string} [LANGBASE_API_KEY] - API key for Langbase // Replace with your API key https://langbase.com/docs/api-reference/api-keys + * @property {string} [OPENAI_API_KEY] - API key for OpenAI service. + * @property {string} [ANTHROPIC_API_KEY] - API key for Anthropic service. + * @property {string} [COHERE_API_KEY] - API key for Cohere service. + * @property {string} [FIREWORKS_API_KEY] - API key for Fireworks service. + * @property {string} [GOOGLE_API_KEY] - API key for Google services. + * @property {string} [GROQ_API_KEY] - API key for GROQ service. + * @property {string} [MISTRAL_API_KEY] - API key for Mistral service. + * @property {string} [PERPLEXITY_API_KEY] - API key for Perplexity service. + * @property {string} [TOGETHER_API_KEY] - API key for Together service. + */ +export interface EnvConfig { + NODE_ENV?: string; + LANGBASE_API_KEY?: string; + OPENAI_API_KEY?: string; + ANTHROPIC_API_KEY?: string; + COHERE_API_KEY?: string; + FIREWORKS_API_KEY?: string; + GOOGLE_API_KEY?: string; + GROQ_API_KEY?: string; + MISTRAL_API_KEY?: string; + PERPLEXITY_API_KEY?: string; + TOGETHER_API_KEY?: string; +} + +/** + * Configuration interface for BaseAI. + * + * @interface BaseAIConfig + * + * @property {Object} log - Logging configuration. + * @property {boolean} log.isEnabled - Enable or disable logging. + * @property {boolean} log.isEnabledInProd - Enable logging in production when NODE_ENV is set to production. + * @property {boolean} log.logSensitiveData - Enable or disable logging of sensitive data. + * @property {boolean} log.pipe - Enable or disable logging for pipe operations. + * @property {boolean} log['pipe.completion'] - Enable or disable logging for pipe completion. + * @property {boolean} log['pipe.request'] - Enable or disable logging for pipe requests. + * @property {boolean} log['pipe.response'] - Enable or disable logging for pipe responses. + * @property {boolean} log.tool - Enable or disable logging for tool operations. + * @property {boolean} log.memory - Enable or disable logging for memory operations. + * @property {Object} memory - Memory configuration. + * @property {boolean} memory.useLocalEmbeddings - Use local embeddings for memory operations. + * @property {string} envFilePath - Path to the .env file starting from the root of the project. + * @property {EnvConfig} env - Environment configuration. + */ export interface BaseAIConfig { log: LoggerConfig; memory: MemoryConfig; envFilePath: string; + env?: EnvConfig; } diff --git a/packages/core/package.json b/packages/core/package.json index e58d2ca8..24767227 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,119 +1,119 @@ { - "name": "@baseai/core", - "description": "The Web AI Framework's core - BaseAI.dev", - "version": "0.9.7", - "license": "Apache-2.0", - "sideEffects": false, - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "files": [ - "dist/**", - "CHANGELOG.md" - ], - "scripts": { - "xbuild": "tsup src/index.ts --format esm,cjs --dts --external react", - "build": "tsup", - "dev": "tsup src/index.ts --format esm,cjs --watch --dts --external react", - "xdev": "tsup --watch", - "lint": "eslint \"src/**/*.ts*\"", - "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", - "type-check": "tsc --noEmit", - "prettier-check": "prettier --check \"./**/*.ts*\"", - "test": "pnpm test:node && pnpm test:edge", - "#test": "pnpm test:node && pnpm test:edge && pnpm test:ui && pnpm test:e2e", - "test:edge": "vitest --config vitest.edge.config.js --run", - "test:node": "vitest --config vitest.node.config.js --run", - "test:ui": "pnpm test:ui:react", - "test:ui:react": "vitest --config vitest.ui.react.config.js --run", - "test:e2e": "playwright test", - "test:edge:watch": "vitest --config vitest.edge.config.js", - "test:node:watch": "vitest --config vitest.node.config.js", - "test:ui:react:watch": "vitest --config vitest.ui.react.config.js" - }, - "dependencies": { - "openai": "^4.63.0", - "zod": "^3.23.8" - }, - "devDependencies": { - "@baseai/eslint-config": "workspace:*", - "@baseai/tsconfig": "workspace:*", - "@edge-runtime/vm": "^4.0.3", - "@playwright/test": "^1.47.2", - "@testing-library/react": "^16.0.1", - "@types/node": "^22.6.1", - "@types/react": "^18.3.9", - "@vitejs/plugin-react": "^4.3.1", - "eslint": "^8.57.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.2.1", - "jsdom": "^25.0.1", - "react": "^18", - "tsup": "^8.3.0", - "typescript": "^5.6.2", - "vitest": "1.6.0" - }, - "publishConfig": { - "access": "public" - }, - "exports": { - ".": { - "types": "./dist/index.d.ts", - "require": "./dist/index.js", - "import": "./dist/index.mjs" - }, - "./react": { - "types": "./dist/react/index.d.ts", - "require": "./dist/react/index.js", - "import": "./dist/react/index.mjs" - }, - "./pipes": { - "types": "./dist/pipes/index.d.ts", - "require": "./dist/pipes/index.js", - "import": "./dist/pipes/index.mjs" - }, - "./helpers": { - "types": "./dist/helpers/index.d.ts", - "require": "./dist/helpers/index.js", - "import": "./dist/helpers/index.mjs" - } - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "react": "^18 || ^19", - "zod": "^3.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "zod": { - "optional": true - } - }, - "homepage": "https://BaseAI.dev", - "repository": { - "type": "git", - "url": "git+https://github.com/LangbaseInc/baseai.git" - }, - "bugs": { - "url": "https://github.com/LangbaseInc/baseai/issues" - }, - "author": { - "name": "Langbase", - "url": "https://BaseAI.dev" - }, - "keywords": [ - "ai", - "llm", - "langbase core", - "langbase sdk", - "baseai", - "base ai", - "langbase", - "langbase.com", - "generative AI" - ] -} + "name": "@baseai/core", + "description": "The Web AI Framework's core - BaseAI.dev", + "version": "0.9.8-snapshot.3", + "license": "Apache-2.0", + "sideEffects": false, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist/**", + "CHANGELOG.md" + ], + "scripts": { + "xbuild": "tsup src/index.ts --format esm,cjs --dts --external react", + "build": "tsup", + "dev": "tsup src/index.ts --format esm,cjs --watch --dts --external react", + "xdev": "tsup --watch", + "lint": "eslint \"src/**/*.ts*\"", + "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", + "type-check": "tsc --noEmit", + "prettier-check": "prettier --check \"./**/*.ts*\"", + "test": "pnpm test:node && pnpm test:edge", + "#test": "pnpm test:node && pnpm test:edge && pnpm test:ui && pnpm test:e2e", + "test:edge": "vitest --config vitest.edge.config.js --run", + "test:node": "vitest --config vitest.node.config.js --run", + "test:ui": "pnpm test:ui:react", + "test:ui:react": "vitest --config vitest.ui.react.config.js --run", + "test:e2e": "playwright test", + "test:edge:watch": "vitest --config vitest.edge.config.js", + "test:node:watch": "vitest --config vitest.node.config.js", + "test:ui:react:watch": "vitest --config vitest.ui.react.config.js" + }, + "dependencies": { + "openai": "^4.63.0", + "zod": "^3.23.8" + }, + "devDependencies": { + "@baseai/eslint-config": "workspace:*", + "@baseai/tsconfig": "workspace:*", + "@edge-runtime/vm": "^4.0.3", + "@playwright/test": "^1.47.2", + "@testing-library/react": "^16.0.1", + "@types/node": "^22.6.1", + "@types/react": "^18.3.9", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "jsdom": "^25.0.1", + "react": "^18", + "tsup": "^8.3.0", + "typescript": "^5.6.2", + "vitest": "1.6.0" + }, + "publishConfig": { + "access": "public" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.js", + "import": "./dist/index.mjs" + }, + "./react": { + "types": "./dist/react/index.d.ts", + "require": "./dist/react/index.js", + "import": "./dist/react/index.mjs" + }, + "./pipes": { + "types": "./dist/pipes/index.d.ts", + "require": "./dist/pipes/index.js", + "import": "./dist/pipes/index.mjs" + }, + "./helpers": { + "types": "./dist/helpers/index.d.ts", + "require": "./dist/helpers/index.js", + "import": "./dist/helpers/index.mjs" + } + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18 || ^19", + "zod": "^3.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "zod": { + "optional": true + } + }, + "homepage": "https://BaseAI.dev", + "repository": { + "type": "git", + "url": "git+https://github.com/LangbaseInc/baseai.git" + }, + "bugs": { + "url": "https://github.com/LangbaseInc/baseai/issues" + }, + "author": { + "name": "Langbase", + "url": "https://BaseAI.dev" + }, + "keywords": [ + "ai", + "llm", + "langbase core", + "langbase sdk", + "baseai", + "base ai", + "langbase", + "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 26ee2e99..333d6db1 100644 --- a/packages/core/src/common/request.ts +++ b/packages/core/src/common/request.ts @@ -1,4 +1,5 @@ import {Stream} from 'openai/streaming'; +import {Logger} from 'src/helpers/logger'; import {APIConnectionError, APIError} from './errors'; interface RequestOptions { @@ -10,10 +11,11 @@ interface RequestOptions { rawResponse?: boolean; } -interface RequestConfig { +interface RequestProps { apiKey?: string; baseUrl: string; timeout?: number; + config?: any; // TODO: BaseAIConfig } interface SendOptions extends RequestOptions { @@ -34,10 +36,12 @@ interface HandleGenerateResponseParams { } export class Request { - private config: RequestConfig; + private console: any; + private props: RequestProps; - constructor(config: RequestConfig) { - this.config = config; + constructor(props: RequestProps) { + this.props = props; + this.console = new Logger(this.props.config); } private async send({endpoint, ...options}: SendOptions): Promise { @@ -79,7 +83,7 @@ export class Request { } private buildUrl({endpoint}: {endpoint: string}): string { - return `${this.config.baseUrl}${endpoint}`; + return `${this.props.baseUrl}${endpoint}`; } private buildHeaders({ @@ -89,7 +93,7 @@ export class Request { }): Record { return { 'Content-Type': 'application/json', - Authorization: `Bearer ${this.config.apiKey}`, + Authorization: `Bearer ${this.props.apiKey}`, ...headers, }; } @@ -99,12 +103,17 @@ export class Request { options, headers, }: MakeRequestParams): Promise { - // console.log(' =================== REQUEST ==================='); + this.console.log('pipe.request', { + url, + method: options.method, + headers, + body: options.body, + }); const resp = await fetch(url, { method: options.method, headers, body: JSON.stringify(options.body), - signal: AbortSignal.timeout(this.config.timeout || 30000), + signal: AbortSignal.timeout(this.props.timeout || 30000), }); return resp; } @@ -194,9 +203,6 @@ export class Request { } async post(options: Omit): Promise { - console.log('Request.post.options'); - console.dir(options, {depth: null, colors: true}); - return this.send({...options, method: 'POST'}); } diff --git a/packages/core/src/helpers/logger.ts b/packages/core/src/helpers/logger.ts index c19d0229..50d443e8 100644 --- a/packages/core/src/helpers/logger.ts +++ b/packages/core/src/helpers/logger.ts @@ -1,17 +1,45 @@ import {isProd} from '../utils/is-prod'; -export const logger = (category: any, value?: unknown, logHeader?: string) => { - if (isProd()) return; +export class Logger { + private config: any; - console.log(''); - if (logHeader) { - console.log(`======= ${logHeader} =======`); + constructor(config: any) { + this.config = config; } - console.log(`❯❯ ${category}`); - if (typeof value === 'object' && value !== null) { - console.dir(value, {depth: null, colors: true}); - } else if (value !== undefined) { - console.log(value); + log(category: string, value?: unknown, logHeader?: string): void { + if (isProd(this.config?.env) && !this.config?.log?.isEnabledInProd) + return; + if (!this.config?.log?.isEnabled) return; + if (!this.shouldLog(category)) return; + + console.log(''); + if (logHeader) { + console.log(`======= ${logHeader} =======`); + } + console.log(`=❯ ${category}`); + + if (typeof value === 'object' && value !== null) { + console.dir(value, {depth: null, colors: true}); + } else if (value !== undefined) { + console.log(value); + } + } + + private shouldLog(category: string): boolean { + const logConfig = this.config?.log; + if (!logConfig) return false; + + // Check if the category or its parent category is enabled + const categoryParts = category.split('.'); + while (categoryParts.length > 0) { + const currentCategory = categoryParts.join('.'); + if (logConfig[currentCategory] === true) return true; + if (logConfig[currentCategory] === false) return false; + categoryParts.pop(); + } + + // If no specific setting found, default to true + return true; } -}; +} diff --git a/packages/core/src/pipes/pipes.ts b/packages/core/src/pipes/pipes.ts index 2b057161..f6d423aa 100644 --- a/packages/core/src/pipes/pipes.ts +++ b/packages/core/src/pipes/pipes.ts @@ -1,10 +1,11 @@ import type {Runner} from 'src/helpers'; +import {Logger} from 'src/helpers/logger'; +import {isLocalServerRunning} from 'src/utils/local-server-running'; import {Pipe as PipeI} from '../../types/pipes'; import {Request} from '../common/request'; import {getLLMApiKey} from '../utils/get-llm-api-key'; import {getApiUrl, isProd} from '../utils/is-prod'; import {toOldPipeFormat} from '../utils/to-old-pipe-format'; -import {isLocalServerRunning} from 'src/utils/local-server-running'; // Type Definitions export type Role = 'user' | 'assistant' | 'system' | 'tool'; @@ -75,6 +76,7 @@ export interface RunResponseStream { export interface PipeOptions extends PipeI { maxCalls?: number; + config?: any; } interface ChoiceGenerate { @@ -94,6 +96,9 @@ interface Tool { } export class Pipe { + private console: any; + private config: any; + private configEnv: any; private request: Request; private pipe: any; private tools: Record Promise>; @@ -101,11 +106,16 @@ export class Pipe { private hasTools: boolean; constructor(options: PipeOptions) { - const baseUrl = getApiUrl(); - this.request = new Request({apiKey: options.apiKey, baseUrl}); + this.config = options?.config; + this.console = new Logger(this.config); + this.configEnv = options?.config?.env; + this.request = new Request({ + baseUrl: getApiUrl(this.configEnv), + apiKey: options.apiKey, + config: this.config, + }); this.pipe = toOldPipeFormat(options); delete this.pipe.apiKey; - this.tools = this.getToolsFromPipe(this.pipe); this.maxCalls = options.maxCalls || 100; // TODO: Find a sane default. this.hasTools = Object.keys(this.tools).length > 0; @@ -177,12 +187,14 @@ export class Pipe { public async run( options: RunOptions | RunOptionsStream, ): Promise { - console.log('pipe.run', this.pipe.name, 'RUN'); + this.console.log('pipe', this.pipe.name, 'PIPE RUN'); const endpoint = '/beta/pipes/run'; - console.log('pipe.run.baseUrl.endpoint', getApiUrl() + endpoint); - console.log('pipe.run.options'); - console.dir(options, {depth: null, colors: true}); + this.console.log( + 'pipe.run.baseUrl.endpoint', + getApiUrl(this.configEnv) + endpoint, + ); + this.console.log('pipe.runOptions', options); const requestedStream = this.isStreamRequested(options); const stream = this.hasTools ? false : requestedStream; @@ -197,8 +209,7 @@ export class Pipe { return {} as RunResponse | RunResponseStream; } - console.log('pipe.run.response'); - console.dir(response, {depth: null, colors: true}); + this.console.log('pipe.response', response); if (stream) { return response as RunResponseStream; @@ -212,21 +223,22 @@ export class Pipe { const responseMessage = currentResponse.choices[0].message; if (this.hasNoToolCalls(responseMessage)) { - console.log('No more tool calls. Returning final response.'); + this.console.log( + 'pipe.hasNoToolCalls', + 'No more tool calls. Returning final response.', + ); return currentResponse; } - console.log('\npipe.run.response.toolCalls'); - console.dir(responseMessage.tool_calls, { - depth: null, - colors: true, - }); + this.console.log( + 'pipe.run.response.toolCalls', + responseMessage.tool_calls, + ); const toolResults = await this.runTools( responseMessage.tool_calls as ToolCall[], ); - console.log('\npipe.run.toolResults'); - console.dir(toolResults, {depth: null, colors: true}); + this.console.log('pipe.run.toolResults', toolResults); messages = this.getMessagesToSend( messages, @@ -262,29 +274,38 @@ export class Pipe { } private async createRequest(endpoint: string, body: any): Promise { - const prodOptions = { - endpoint, - body: { - ...body, - name: this.pipe.name, - }, - }; + const isProdEnv = isProd(this.configEnv); + + // PROD. + if (isProdEnv) { + const prodOptions = { + endpoint, + body: { + ...body, + name: this.pipe.name, + }, + }; + this.console.log('pipe.request.prodOptions', prodOptions); + return this.request.post(prodOptions); + } + + // LOCAL. + const isServerRunning = await isLocalServerRunning(); + if (!isServerRunning) return {} as T; + const localOptions = { endpoint, body: { ...body, pipe: this.pipe, - llmApiKey: getLLMApiKey(this.pipe.model.provider), + llmApiKey: getLLMApiKey({ + modelProvider: this.pipe.model.provider, + configEnv: this.configEnv, + }), }, }; - - const isProdEnv = isProd(); - if (!isProdEnv) { - const isServerRunning = await isLocalServerRunning(); - if (!isServerRunning) return {} as T; - } - - return this.request.post(isProdEnv ? prodOptions : localOptions); + this.console.log('pipe.request.localOptions', localOptions); + return this.request.post(localOptions); } } diff --git a/packages/core/src/utils/get-llm-api-key.ts b/packages/core/src/utils/get-llm-api-key.ts index 936cf70f..7275e929 100644 --- a/packages/core/src/utils/get-llm-api-key.ts +++ b/packages/core/src/utils/get-llm-api-key.ts @@ -10,27 +10,47 @@ import { TOGETHER_AI, } from '../data/models'; -export function getLLMApiKey(modelProvider: string): string { +export function getLLMApiKey({ + modelProvider, + configEnv, +}: { + modelProvider: string; + configEnv?: Record; +}): string { + const getEnv = (key: string) => { + let value; + if (configEnv && key in configEnv) { + value = configEnv[key]; + } else { + value = process.env[key]; + } + if (!value) { + throw new Error( + `Environment variable ${key} is not set or empty. Only needed in local dev environment. \nNote: In production, add it to your keysets https://langbase.com/docs/features/keysets\n`, + ); + } + return value; + }; + switch (true) { case modelProvider.includes(OPEN_AI): - return process.env.OPENAI_API_KEY || ''; + return getEnv('OPENAI_API_KEY'); case modelProvider === ANTHROPIC: - return process.env.ANTHROPIC_API_KEY || ''; + return getEnv('ANTHROPIC_API_KEY'); case modelProvider === TOGETHER_AI: - return process.env.TOGETHER_API_KEY || ''; + return getEnv('TOGETHER_API_KEY'); case modelProvider === GROQ: - return process.env.GROQ_API_KEY || ''; + return getEnv('GROQ_API_KEY'); case modelProvider === GOOGLE: - return process.env.GOOGLE_API_KEY || ''; + return getEnv('GOOGLE_API_KEY'); case modelProvider.includes(COHERE): - return process.env.COHERE_API_KEY || ''; + return getEnv('COHERE_API_KEY'); case modelProvider.includes(FIREWORKS_AI): - return process.env.FIREWORKS_API_KEY || ''; + return getEnv('FIREWORKS_API_KEY'); case modelProvider.includes(PERPLEXITY): - return process.env.PERPLEXITY_API_KEY || ''; + return getEnv('PERPLEXITY_API_KEY'); case modelProvider.includes(OLLAMA): - return process.env.OLLAMA_API_KEY || ''; - + return getEnv('OLLAMA_API_KEY'); default: throw new Error(`Unsupported model provider: ${modelProvider}`); } diff --git a/packages/core/src/utils/is-prod.ts b/packages/core/src/utils/is-prod.ts index 226bd5bd..b470ed5d 100644 --- a/packages/core/src/utils/is-prod.ts +++ b/packages/core/src/utils/is-prod.ts @@ -1,17 +1,24 @@ const FORCE_PROD = false; const TEST_PROD_LOCALLY = FORCE_PROD; -export function isProd() { +type ConfigEnv = { + NODE_ENV?: string; + [key: string]: any; +}; + +export function isProd(configEnv?: ConfigEnv): boolean { if (TEST_PROD_LOCALLY) return true; - return process.env.NODE_ENV === 'production'; + + const env = configEnv?.NODE_ENV ?? process.env.NODE_ENV; + return env === 'production'; } -export function isLocal() { - return process.env.NODE_ENV !== 'production'; +export function isLocal(configEnv?: ConfigEnv): boolean { + return !isProd(configEnv); } -export function getApiUrl() { - // TODO: Make local port configurable. - return isProd() ? 'https://api.langbase.com' : 'http://localhost:9000'; - // return isProd() ? 'http://localhost:8787' : 'http://localhost:9000'; +export function getApiUrl(configEnv?: ConfigEnv): string { + return isProd(configEnv) + ? 'https://api.langbase.com' + : 'http://localhost:9000'; } diff --git a/packages/core/src/utils/local-server-running.ts b/packages/core/src/utils/local-server-running.ts index 1dfcf960..cf8a14da 100644 --- a/packages/core/src/utils/local-server-running.ts +++ b/packages/core/src/utils/local-server-running.ts @@ -29,7 +29,7 @@ export async function isLocalServerRunning(): Promise { } catch (error) { // Port is not in use and BaseAI dev server is not running console.error( - `\nBaseAI dev server is not running. \nPlease run "npx baseai@latest dev" in a new teriminal to start dev server.\n`, + `\nBaseAI dev server is not running. \nPlease run "npx baseai dev" in a new teriminal, in the root of this project.\n`, ); return false; } diff --git a/packages/testing/.env.baseai.example b/packages/testing/.env.baseai.example new file mode 100644 index 00000000..8c643651 --- /dev/null +++ b/packages/testing/.env.baseai.example @@ -0,0 +1,21 @@ +# !! SERVER SIDE ONLY !! +# Keep all your API keys secret — use only on the server side. + +# TODO: ADD: Both in your production and local env files. +# Langbase API key for your User or Org account. +# How to get this API key https://langbase.com/docs/api-reference/api-keys +LANGBASE_API_KEY= + +# TODO: ADD: LOCAL ONLY. Add only to local env files. +# Following keys are needed for local pipe runs. For providers you are using. +# For Langbase, please add the key to your LLM keysets. +# Read more: Langbase LLM Keysets https://langbase.com/docs/features/keysets +OPENAI_API_KEY= +ANTHROPIC_API_KEY= +COHERE_API_KEY= +FIREWORKS_API_KEY= +GOOGLE_API_KEY= +GROQ_API_KEY= +MISTRAL_API_KEY= +PERPLEXITY_API_KEY= +TOGETHER_API_KEY= diff --git a/packages/testing/.gitignore b/packages/testing/.gitignore new file mode 100644 index 00000000..7e883297 --- /dev/null +++ b/packages/testing/.gitignore @@ -0,0 +1,4 @@ +# baseai +**/.baseai/ +# env file +.env diff --git a/packages/testing/baseai/baseai.config.ts b/packages/testing/baseai/baseai.config.ts new file mode 100644 index 00000000..34477b0c --- /dev/null +++ b/packages/testing/baseai/baseai.config.ts @@ -0,0 +1,21 @@ +import type {BaseAIConfig} from 'baseai'; + +export const config: BaseAIConfig = { + log: { + isEnabled: true, + isEnabledInProd: true, + logSensitiveData: false, + pipe: true, + tool: true, + memory: true, + 'pipe.completion': true, + 'pipe.request': true, + 'pipe.response': true, + 'pipe.request.prodOptions': false, + 'pipe.request.localOptions': false, + }, + memory: { + useLocalEmbeddings: false, + }, + envFilePath: '.env', +}; diff --git a/packages/testing/baseai/pipes/summary.ts b/packages/testing/baseai/pipes/summary.ts new file mode 100644 index 00000000..9947cdfa --- /dev/null +++ b/packages/testing/baseai/pipes/summary.ts @@ -0,0 +1,32 @@ +import {PipeI} from '@baseai/core'; + +const buildPipe = (): PipeI => ({ + apiKey: process.env.LANGBASE_API_KEY, + name: 'summary-testing', + description: '', + status: 'private', + model: 'openai:gpt-4o-mini', + stream: true, + json: false, + store: true, + moderate: true, + top_p: 1, + max_tokens: 1000, + temperature: 0.7, + presence_penalty: 1, + frequency_penalty: 1, + stop: [], + tool_choice: 'auto', + parallel_tool_calls: false, + messages: [ + { + role: 'system', + content: `You are a helpful AI assistant. Make everything less wordy.`, + }, + ], + variables: [], + memory: [], + tools: [], +}); + +export default buildPipe; diff --git a/packages/testing/index.ts b/packages/testing/index.ts index 25ec8c70..8dd5d63a 100644 --- a/packages/testing/index.ts +++ b/packages/testing/index.ts @@ -1,20 +1,24 @@ -// import {Pipe} from '@baseai/core'; -// import pipeSummary from '../baseai/pipes/summary'; +import {Pipe} from '@baseai/core'; +import 'dotenv/config'; +import {config} from './baseai/baseai.config'; +import pipeSummary from './baseai/pipes/summary'; -// const pipe = new Pipe(pipeSummary()); +const pipe = new Pipe({ + ...pipeSummary(), + config, +}); -// async function main() { -// const userMsg = 'Who is an AI Engineer?'; +async function main() { + const userMsg = 'Who is an AI Engineer?'; -// const response = await pipe.run({ -// messages: [ -// { -// role: 'user', -// content: userMsg, -// }, -// ], -// }); -// console.log('response: ', response); -// } + const response = await pipe.run({ + messages: [ + { + role: 'user', + content: userMsg, + }, + ], + }); +} -// main(); +main(); diff --git a/packages/testing/package.json b/packages/testing/package.json index 1ae66a2c..46c5127a 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -7,7 +7,8 @@ }, "license": "UNLICENSED", "dependencies": { - "@baseai/core": "workspace:*" + "@baseai/core": "workspace:*", + "dotenv": "^16.4.5" }, "devDependencies": { "baseai": "workspace:*" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d8f5ffc..fad2dbc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -706,6 +706,9 @@ importers: '@baseai/core': specifier: workspace:* version: link:../core + dotenv: + specifier: ^16.4.5 + version: 16.4.5 devDependencies: baseai: specifier: workspace:* @@ -12173,7 +12176,7 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2) '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2) eslint-config-prettier: 9.1.0(eslint@8.57.1) - eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.30.0) eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1) @@ -14089,7 +14092,7 @@ snapshots: eslint: 8.57.1 eslint-plugin-turbo: 2.1.3(eslint@8.57.1) - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.30.0): dependencies: eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1) @@ -14107,7 +14110,7 @@ snapshots: debug: 4.3.7(supports-color@5.5.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -14126,7 +14129,7 @@ snapshots: debug: 4.3.7(supports-color@5.5.0) enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -14139,7 +14142,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -14160,7 +14163,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -14188,7 +14191,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -14244,7 +14247,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3