├── .prettierignore ├── pnpm-workspace.yaml ├── packages ├── agent │ ├── src │ │ ├── tasks │ │ │ ├── http │ │ │ │ ├── index.ts │ │ │ │ └── fetch.ts │ │ │ ├── llm │ │ │ │ ├── index.ts │ │ │ │ ├── embedding.ts │ │ │ │ ├── similarity.ts │ │ │ │ ├── generate.ts │ │ │ │ └── evaluate.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── calculate.ts │ │ │ └── task.ts │ │ ├── prompt │ │ │ ├── parsers │ │ │ │ ├── markdown │ │ │ │ │ ├── index.ts │ │ │ │ │ └── code.ts │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ └── parser.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── prompt.ts │ │ ├── agent │ │ │ ├── index.ts │ │ │ ├── agent.ts │ │ │ ├── types.ts │ │ │ └── react.ts │ │ ├── logger │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── dummy.ts │ │ │ ├── logger.ts │ │ │ └── kubernetes.ts │ │ ├── index.ts │ │ ├── tools │ │ │ ├── index.ts │ │ │ ├── http │ │ │ │ └── fetch.ts │ │ │ └── calculate.ts │ │ ├── memory.ts │ │ └── dataset.ts │ ├── turbo.json │ ├── CHANGELOG.md │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── package.json │ ├── examples │ │ ├── http │ │ │ └── fetch │ │ │ │ └── index.ts │ │ └── summarize │ │ │ └── index.ts │ └── README.md └── model │ ├── turbo.json │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── package.json │ ├── src │ ├── providers │ │ ├── index.ts │ │ ├── DeepSeek │ │ │ └── index.ts │ │ ├── provider.ts │ │ ├── AI21 │ │ │ └── index.ts │ │ ├── xAI │ │ │ └── index.ts │ │ ├── Anthropic │ │ │ └── index.ts │ │ ├── Mistral │ │ │ └── index.ts │ │ ├── SambaNova │ │ │ └── index.ts │ │ ├── Groq │ │ │ └── index.ts │ │ └── GoogleGenerativeAI │ │ │ └── index.ts │ ├── index.ts │ └── types.ts │ ├── CHANGELOG.md │ └── README.md ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── question.yml │ ├── feature.yml │ ├── dependency.yml │ ├── documentation.yml │ ├── enhancement.yml │ ├── issue.yml │ └── bug.yml ├── workflows │ ├── assign-pr-author.yml │ └── release.yml ├── dependabot.yml └── pull_request_template.md ├── .gitignore ├── .changeset └── config.json ├── SECURITY.md ├── turbo.json ├── package.json ├── README.md ├── CONTRIBUTING.md ├── CODE_OF_CONDUCT.md └── LICENSE /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' -------------------------------------------------------------------------------- /packages/agent/src/tasks/http/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fetch' 2 | -------------------------------------------------------------------------------- /packages/agent/src/prompt/parsers/markdown/index.ts: -------------------------------------------------------------------------------- 1 | export * from './code' 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: ChikiChat 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .husky 3 | .turbo 4 | .pnpm-store 5 | .vscode 6 | .idea 7 | 8 | dist 9 | node_modules -------------------------------------------------------------------------------- /packages/agent/src/agent/index.ts: -------------------------------------------------------------------------------- 1 | export * from './agent' 2 | export * from './react' 3 | export * from './types' -------------------------------------------------------------------------------- /packages/agent/src/prompt/index.ts: -------------------------------------------------------------------------------- 1 | export * from './parsers' 2 | export * from './prompt' 3 | export * from './types' 4 | -------------------------------------------------------------------------------- /packages/agent/src/prompt/parsers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './markdown'; 2 | export * from './parser'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /packages/agent/src/logger/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dummy'; 2 | export * from './kubernetes'; 3 | export * from './logger'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/llm/index.ts: -------------------------------------------------------------------------------- 1 | export * from './embedding' 2 | export * from './evaluate' 3 | export * from './generate' 4 | export * from './similarity' 5 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './http'; 2 | export * from './llm'; 3 | export * from './calculate'; 4 | export * from './task'; 5 | export * from './types'; 6 | -------------------------------------------------------------------------------- /packages/agent/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "//" 4 | ], 5 | "tasks": { 6 | "build": { 7 | "outputs": [ 8 | "**/dist/**" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /packages/model/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "//" 4 | ], 5 | "tasks": { 6 | "build": { 7 | "outputs": [ 8 | "**/dist/**" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /packages/agent/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './agent'; 2 | export * from './logger'; 3 | export * from './prompt'; 4 | export * from './tasks'; 5 | export * from './tools'; 6 | export * from './dataset'; 7 | export * from './memory'; 8 | -------------------------------------------------------------------------------- /packages/agent/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # AI SDK (agent) 👋 2 | 3 | ## 1.0.2 4 | 5 | ### Patch Changes 6 | 7 | - 020657c: fix issue 8 | 9 | ## 1.0.1 10 | 11 | ### Patch Changes 12 | 13 | - 49aa381: removed extends string 14 | 15 | ## 0.1.0 16 | 17 | ### Minor Changes 18 | 19 | - e78a926: Add package agent 20 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch" 10 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: ChikiChat Authors Support 4 | url: https://github.com/ChikiChat/.github/discussions 5 | about: If you have a question, or are looking for advice, please post on our Discuss forum! The community loves to chime in to help. Happy Coding! -------------------------------------------------------------------------------- /packages/agent/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], // Build for commonJS and ESmodules 6 | dts: true, // Generate declaration file (.d.ts) 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | }); -------------------------------------------------------------------------------- /packages/model/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], // Build for commonJS and ESmodules 6 | dts: true, // Generate declaration file (.d.ts) 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | }); -------------------------------------------------------------------------------- /.github/workflows/assign-pr-author.yml: -------------------------------------------------------------------------------- 1 | name: Assign PR Author 2 | 3 | on: 4 | pull_request: 5 | types: [ opened, reopened ] 6 | 7 | permissions: 8 | pull-requests: write 9 | 10 | jobs: 11 | assign-author: 12 | name: Assign PR Author 13 | runs-on: ubuntu-22.04 14 | steps: 15 | - uses: toshimaru/auto-author-assign@v2.1.1 16 | -------------------------------------------------------------------------------- /packages/agent/src/prompt/parsers/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for a parser that can convert a string input into a specific type OUTPUT. 3 | * 4 | * @template OUTPUT - The type of the parsed output. 5 | * @method parse - A method that takes a string input and returns a value of type OUTPUT. 6 | */ 7 | export interface IParser { 8 | parse(input: string): OUTPUT; 9 | } 10 | -------------------------------------------------------------------------------- /packages/agent/src/tools/index.ts: -------------------------------------------------------------------------------- 1 | import {CoreTool} from "ai"; 2 | import {toolCalculate} from "./calculate"; 3 | import {toolHttpFetch} from "./http/fetch"; 4 | 5 | export * from './calculate'; 6 | export * from './http/fetch'; 7 | 8 | /** 9 | * A registry of tools available for use. 10 | * Each tool is identified by a unique string key. 11 | */ 12 | export const registry: Record = { 13 | 'calculate': toolCalculate, 14 | 'http/fetch': toolHttpFetch, 15 | }; -------------------------------------------------------------------------------- /packages/agent/src/prompt/parsers/parser.ts: -------------------------------------------------------------------------------- 1 | import {IParser} from './types'; 2 | 3 | /** 4 | * Default implementation of the IParser interface. 5 | * This parser simply trims the input string and returns it as a string. 6 | */ 7 | export class Parser implements IParser { 8 | /** 9 | * Parses the input string by trimming it. 10 | * 11 | * @param input - The input string to be parsed. 12 | * @returns The trimmed input string. 13 | */ 14 | parse(input: string): OUTPUT { 15 | return input.trim() as OUTPUT; 16 | } 17 | } -------------------------------------------------------------------------------- /packages/agent/src/prompt/types.ts: -------------------------------------------------------------------------------- 1 | import {IParser} from './parsers'; 2 | 3 | /** 4 | * Interface for a prompt that can parse an input string into a specific type OUTPUT. 5 | * 6 | * @template OUTPUT - The type of the parsed output. 7 | * @method variables - A method that returns an array of variable names used in the prompt. 8 | * @method toString - A method that returns the prompt string with variables replaced by their values. 9 | */ 10 | export interface IPrompt extends IParser { 11 | variables(): string[]; 12 | 13 | toString(variables?: { [key: string]: any }): string; 14 | } -------------------------------------------------------------------------------- /packages/agent/src/tools/http/fetch.ts: -------------------------------------------------------------------------------- 1 | import {tool} from 'ai'; 2 | import {z} from 'zod'; 3 | import {TaskHttpFetch} from '../../tasks'; 4 | 5 | /** 6 | * Defines a tool for fetching content from a given URL using the TaskFetch class. 7 | * This tool retrieves the content of a specified URL and returns it as a string. 8 | */ 9 | export const toolHttpFetch = tool({ 10 | description: 'Fetches the raw content from a specified URL using an HTTP request.', 11 | parameters: z.object({url: z.string().describe('The URL of the website to fetch')}), 12 | execute: async ({url}) => (await (new TaskHttpFetch()).execute({url, maxRetries: 1, timeout: 10000})).output, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/agent/src/tools/calculate.ts: -------------------------------------------------------------------------------- 1 | import {tool} from 'ai'; 2 | import {z} from 'zod'; 3 | import {TaskCalculate} from '../tasks'; 4 | 5 | /** 6 | * Defines a tool for evaluating mathematical expressions using the TaskCalculate class. 7 | * This tool leverages the mathjs library to handle a variety of mathematical expressions. 8 | */ 9 | export const toolCalculate = tool({ 10 | description: 'A tool for evaluating mathematical expressions. Example expressions: ' + "'1.2 * (2 + 4.5)', '12.7 cm to inch', 'sin(45 deg) ^ 2'.", 11 | parameters: z.object({expression: z.string()}).describe('The mathematical expression to evaluate.'), 12 | execute: async ({expression}) => (await (new TaskCalculate()).execute({expression})).output, 13 | }) -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Package | Version | Supported | 9 | |-----------|---------|--------------------| 10 | | agent | 1.x.x | :white_check_mark: | 11 | | backend | planned | | 12 | | knowledge | wip | :white_check_mark: | 13 | | model | 1.x.x | :white_check_mark: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /packages/agent/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2019", 4 | "lib": [ 5 | "ES2019", 6 | "DOM" 7 | ], 8 | "moduleResolution": "node", 9 | "strict": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "esModuleInterop": true, 12 | "noImplicitAny": true, 13 | "noImplicitThis": true, 14 | "noImplicitReturns": true, 15 | "noUnusedLocals": true, 16 | "noUncheckedIndexedAccess": true, 17 | "noUnusedParameters": true, 18 | "alwaysStrict": true, 19 | "strictNullChecks": true, 20 | "strictFunctionTypes": true, 21 | "strictBindCallApply": true, 22 | "strictPropertyInitialization": true, 23 | "resolveJsonModule": false, 24 | "skipLibCheck": true, 25 | "forceConsistentCasingInFileNames": true, 26 | "allowSyntheticDefaultImports": true, 27 | "isolatedModules": true, 28 | "rootDir": "./src" 29 | }, 30 | "include": [ 31 | "./src/**/*.ts" 32 | ], 33 | "exclude": [ 34 | "dist", 35 | "node_modules" 36 | ] 37 | } -------------------------------------------------------------------------------- /packages/model/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2019", 4 | "lib": [ 5 | "ES2019", 6 | "DOM" 7 | ], 8 | "moduleResolution": "node", 9 | "strict": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "esModuleInterop": true, 12 | "noImplicitAny": true, 13 | "noImplicitThis": true, 14 | "noImplicitReturns": true, 15 | "noUnusedLocals": true, 16 | "noUncheckedIndexedAccess": true, 17 | "noUnusedParameters": true, 18 | "alwaysStrict": true, 19 | "strictNullChecks": true, 20 | "strictFunctionTypes": true, 21 | "strictBindCallApply": true, 22 | "strictPropertyInitialization": true, 23 | "resolveJsonModule": false, 24 | "skipLibCheck": true, 25 | "forceConsistentCasingInFileNames": true, 26 | "allowSyntheticDefaultImports": true, 27 | "isolatedModules": true, 28 | "rootDir": "./src" 29 | }, 30 | "include": [ 31 | "./src/**/*.ts" 32 | ], 33 | "exclude": [ 34 | "dist", 35 | "node_modules" 36 | ] 37 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | commit-message: 11 | prefix: "chore: github-actions" 12 | include: "scope" 13 | labels: 14 | - "dependency" 15 | - "status/0-triage" 16 | - "priority/p2" 17 | schedule: 18 | interval: "weekly" 19 | 20 | - package-ecosystem: "npm" 21 | directory: "/" 22 | open-pull-requests-limit: 10 23 | commit-message: 24 | prefix: "chore: npm" 25 | include: "scope" 26 | labels: 27 | - "dependency" 28 | - "status/0-triage" 29 | - "priority/p2" 30 | schedule: 31 | interval: "weekly" 32 | ignore: 33 | - dependency-name: '@types/node' 34 | versions: '>=20.0.0' 35 | -------------------------------------------------------------------------------- /packages/agent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@chikichat/agent", 3 | "description": "", 4 | "version": "1.0.2", 5 | "license": "Apache-2.0", 6 | "author": "Leliuga", 7 | "main": "./dist/index.js", 8 | "module": "./dist/index.mjs", 9 | "types": "./dist/index.d.ts", 10 | "files": [ 11 | "dist/**/*" 12 | ], 13 | "scripts": { 14 | "build": "tsup", 15 | "build:watch": "tsup --watch", 16 | "clean": "rm -rf dist" 17 | }, 18 | "dependencies": { 19 | "@chikichat/model": "^1.2.1", 20 | "csv-parse": "^5.6.0", 21 | "mathjs": "^14.4.0", 22 | "yaml": "^2.7.1" 23 | }, 24 | "devDependencies": { 25 | "@types/node": "^20", 26 | "tsup": "^8.4.0", 27 | "typescript": "^5.8.3" 28 | }, 29 | "peerDependencies": { 30 | "ai": "^4.0.0", 31 | "zod": "^3.0.0" 32 | }, 33 | "engines": { 34 | "node": "^20.0.0 || ^22.0.0" 35 | }, 36 | "publishConfig": { 37 | "access": "public" 38 | }, 39 | "repository": { 40 | "type": "git", 41 | "url": "git+https://github.com/ChikiChat/ai.git" 42 | }, 43 | "bugs": { 44 | "url": "https://github.com/ChikiChat/ai/issues" 45 | }, 46 | "keywords": [ 47 | "ai", 48 | "agent", 49 | "chiki" 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/types.ts: -------------------------------------------------------------------------------- 1 | import {z, ZodSchema} from 'zod'; 2 | 3 | /** 4 | * Represents a task that can be executed with a specific input and produces an output. 5 | * Tasks are designed to be reusable and can have dependencies and versioning. 6 | */ 7 | export interface ITask { 8 | /** 9 | * The unique and descriptive name of the task. 10 | */ 11 | readonly name: string; 12 | 13 | /** 14 | * A detailed description of what the task does, including any assumptions or prerequisites. 15 | */ 16 | readonly description: string; 17 | 18 | /** 19 | * Returns the input and output schema for the task. 20 | * 21 | * @returns An object containing the input and output schema. 22 | */ 23 | schema(): { input: INPUT; output: OUTPUT }; 24 | 25 | /** 26 | * Executes the task with the given input and returns a promise that resolves to the output. 27 | * 28 | * @param input - The input data required for the task, conforming to the input schema. 29 | * @returns A promise that resolves to the output of the task, conforming to the output schema. 30 | */ 31 | execute(input: z.infer): Promise>; 32 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yml: -------------------------------------------------------------------------------- 1 | name: ❓ Question report 2 | description: Create a question report to help us improve 3 | labels: [ "question", "priority/p2" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all questions reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:question) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: textarea 17 | attributes: 18 | label: Our question? 19 | placeholder: How can we help you? 20 | validations: 21 | required: true 22 | - type: checkboxes 23 | attributes: 24 | label: Code of Conduct 25 | description: By submitting this question issue, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 26 | options: 27 | - label: I agree to follow this repository Code of Conduct 28 | required: true -------------------------------------------------------------------------------- /packages/model/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@chikichat/model", 3 | "description": "", 4 | "version": "1.2.6", 5 | "license": "Apache-2.0", 6 | "author": "Leliuga", 7 | "main": "./dist/index.js", 8 | "module": "./dist/index.mjs", 9 | "types": "./dist/index.d.ts", 10 | "files": [ 11 | "dist/**/*" 12 | ], 13 | "scripts": { 14 | "build": "tsup", 15 | "build:watch": "tsup --watch", 16 | "clean": "rm -rf dist" 17 | }, 18 | "dependencies": { 19 | "@ai-sdk/anthropic": "^1.2.11", 20 | "@ai-sdk/cohere": "^1.2.10", 21 | "@ai-sdk/google": "^1.2.10", 22 | "@ai-sdk/groq": "^1.2.9", 23 | "@ai-sdk/mistral": "^1.2.6", 24 | "@ai-sdk/openai": "^1.3.10", 25 | "@ai-sdk/xai": "^1.2.16", 26 | "ai": "^4.3.15" 27 | }, 28 | "devDependencies": { 29 | "@types/node": "^20", 30 | "tsup": "^8.4.0", 31 | "typescript": "^5.8.3" 32 | }, 33 | "engines": { 34 | "node": "^20.0.0 || ^22.0.0" 35 | }, 36 | "publishConfig": { 37 | "access": "public" 38 | }, 39 | "repository": { 40 | "type": "git", 41 | "url": "git+https://github.com/ChikiChat/ai.git" 42 | }, 43 | "bugs": { 44 | "url": "https://github.com/ChikiChat/ai/issues" 45 | }, 46 | "keywords": [ 47 | "ai", 48 | "llm", 49 | "chiki", 50 | "providers" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - '.changeset/**' 9 | - '.github/workflows/release.yml' 10 | workflow_dispatch: 11 | 12 | concurrency: ${{ github.workflow }}-${{ github.ref }} 13 | 14 | jobs: 15 | release: 16 | name: Release 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 10 19 | steps: 20 | - name: Checkout Repo 21 | uses: actions/checkout@v4 22 | with: 23 | fetch-depth: 0 24 | 25 | - name: Setup pnpm 26 | uses: pnpm/action-setup@v4 27 | with: 28 | version: 9.12.3 29 | 30 | - name: Setup Node.js 20.x 31 | uses: actions/setup-node@v4 32 | with: 33 | node-version: 20.x 34 | 35 | - name: Install Dependencies 36 | run: pnpm i 37 | 38 | - name: Create Release Pull Request or Publish to npm 39 | id: changesets 40 | uses: changesets/action@v1 41 | with: 42 | # This expects you to have a script called release which does a build for your packages and calls changeset publish 43 | version: pnpm ci:version 44 | publish: pnpm ci:release 45 | env: 46 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 47 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | **Description** 12 | 13 | 14 | ``` 15 | (describe) 16 | ``` 17 | 18 | **Testing & Reproduction steps** 19 | 20 | * In the case of bugs, describe how to replicate 21 | * If any manual tests were done, document the steps and the conditions to replicate 22 | * Call out any important/ relevant unit tests, e2e tests or integration tests you have added or are adding 23 | 24 | ***Links** 25 | Include any links here that might be helpful for people reviewing your PR (Tickets, GH issues, API docs, external 26 | benchmarks, tools docs, etc). If there are none, feel free to delete this section. 27 | 28 | Please be mindful not to leak any customer or confidential information. ChikiChat community may want to use our 29 | internal URL shortener to obfuscate links. 30 | 31 | **PR Checklist** 32 | 33 | - [ ] Finish implementation of the issue 34 | - [ ] Test all functions 35 | - [ ] Documentation 36 | - [ ] Have enough logs to trace activities 37 | - [ ] Notify developers of necessary actions 38 | 39 | -------------------------------------------------------------------------------- /packages/agent/src/logger/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for a logger that provides methods to log messages at different levels. 3 | * Each method accepts a message and an optional set of key-value pairs to include in the log. 4 | */ 5 | export interface ILogger { 6 | readonly name: string; 7 | 8 | /** 9 | * Logs an informational message. 10 | * @param message - The message to log. 11 | * @param keyValuePairs - Optional key-value pairs to include in the log. 12 | */ 13 | info(message: string, keyValuePairs?: { [key: string]: any }): void; 14 | 15 | /** 16 | * Logs an error message. 17 | * @param error - The error to log. 18 | * @param keyValuePairs - Optional key-value pairs to include in the log. 19 | */ 20 | error(error: Error, keyValuePairs?: { [key: string]: any }): void; 21 | 22 | /** 23 | * Logs a warning message. 24 | * @param message - The message to log. 25 | * @param keyValuePairs - Optional key-value pairs to include in the log. 26 | */ 27 | warn(message: string, keyValuePairs?: { [key: string]: any }): void; 28 | 29 | /** 30 | * Logs a debug message. 31 | * @param message - The message to log. 32 | * @param keyValuePairs - Optional key-value pairs to include in the log. 33 | */ 34 | debug(message: string, keyValuePairs?: { [key: string]: any }): void; 35 | } -------------------------------------------------------------------------------- /packages/agent/examples/http/fetch/index.ts: -------------------------------------------------------------------------------- 1 | import {DEFAULT_LANGUAGE_MODEL_NAME} from "@chikichat/model"; 2 | import {Agent, registry as tools} from "@chikichat/agent"; 3 | 4 | /** 5 | * The Agent class is designed to perform specific tasks based on the provided configuration. 6 | * It can be used to summarize text, answer questions, or perform other language-related tasks. 7 | * The class takes a name, a description, and a configuration object that includes the model and prompt. 8 | */ 9 | const fetch = new Agent({ 10 | name: 'http/fetch', 11 | description: 'An agent that fetches content from a URL.', 12 | init: { 13 | prompt: ` 14 | You are an HTTP fetch expert. Please use the appropriate tools to fetch the content from the provided URL and extract the following information: 15 | - Title 16 | - Description 17 | - Images 18 | - Links 19 | 20 | **Input:** $\{input} 21 | 22 | Please ensure that you handle any potential errors and provide the extracted information in a structured format. 23 | `, 24 | /** 25 | * The language model to be used for summarization. 26 | * This can be overridden by the environment variable LANGUAGE_MODEL_NAME. 27 | */ 28 | model: DEFAULT_LANGUAGE_MODEL_NAME, 29 | 30 | tools: { 31 | fetch: tools['http/fetch'], 32 | }, 33 | }, 34 | }); 35 | 36 | fetch.execute({ 37 | 'input': `Use this URL: https://chiki.chat` 38 | }).then(console.log) 39 | 40 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "globalEnv": [ 4 | "CI", 5 | "PORT" 6 | ], 7 | "tasks": { 8 | "build": { 9 | "dependsOn": [ 10 | "^build" 11 | ], 12 | "env": [ 13 | "AI21_API_KEY", 14 | "ANTHROPIC_API_KEY", 15 | "COHERE_API_KEY", 16 | "DEEPSEEK_API_KEY", 17 | "GOOGLE_GENERATIVE_AI_API_KEY", 18 | "GROQ_API_KEY", 19 | "MISTRAL_API_KEY", 20 | "NODE_ENV", 21 | "NVIDIA_API_KEY", 22 | "OPENAI_API_KEY", 23 | "OPENROUTER_API_KEY", 24 | "SAMBANOVA_API_KEY", 25 | "XAI_API_KEY" 26 | ], 27 | "outputs": [ 28 | "dist/**" 29 | ] 30 | }, 31 | "lint": { 32 | "dependsOn": [ 33 | "^lint" 34 | ] 35 | }, 36 | "type-check": { 37 | "dependsOn": [ 38 | "^build", 39 | "build" 40 | ] 41 | }, 42 | "test": { 43 | "dependsOn": [ 44 | "^build", 45 | "build" 46 | ] 47 | }, 48 | "publint": { 49 | "dependsOn": [ 50 | "^build", 51 | "build" 52 | ] 53 | }, 54 | "clean": { 55 | "dependsOn": [ 56 | "^clean" 57 | ] 58 | }, 59 | "dev": { 60 | "cache": false, 61 | "persistent": true 62 | }, 63 | "prettier-check": {}, 64 | "integration-test": { 65 | "dependsOn": [ 66 | "^build", 67 | "build" 68 | ] 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /packages/agent/src/logger/dummy.ts: -------------------------------------------------------------------------------- 1 | import {Logger} from './logger'; 2 | 3 | /** 4 | * A dummy logger implementation that does not output any log messages. 5 | * This class is useful for testing or scenarios where logging is not required. 6 | */ 7 | export class LoggerDummy extends Logger { 8 | /** 9 | * Logs an informational message (no output). 10 | * @param _message - The message to log. 11 | * @param _keyValuePairs - Optional key-value pairs to include in the log. 12 | */ 13 | info(_message: string, _keyValuePairs?: { [key: string]: any }): void { 14 | // No output 15 | } 16 | 17 | /** 18 | * Logs an error message (no output). 19 | * @param _error - The error to log. 20 | * @param _keyValuePairs - Optional key-value pairs to include in the log. 21 | */ 22 | error(_error: Error, _keyValuePairs?: { [key: string]: any }): void { 23 | // No output 24 | } 25 | 26 | /** 27 | * Logs a warning message (no output). 28 | * @param _message - The message to log. 29 | * @param _keyValuePairs - Optional key-value pairs to include in the log. 30 | */ 31 | warn(_message: string, _keyValuePairs?: { [key: string]: any }): void { 32 | // No output 33 | } 34 | 35 | /** 36 | * Logs a debug message (no output). 37 | * @param _message - The message to log. 38 | * @param _keyValuePairs - Optional key-value pairs to include in the log. 39 | */ 40 | debug(_message: string, _keyValuePairs?: { [key: string]: any }): void { 41 | // No output 42 | } 43 | } -------------------------------------------------------------------------------- /packages/model/src/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './provider' 2 | export * from './AI21' 3 | export * from './Anthropic' 4 | export * from './Cohere' 5 | export * from './DeepSeek' 6 | export * from './GoogleGenerativeAI' 7 | export * from './Groq' 8 | export * from './Mistral' 9 | export * from './Nvidia' 10 | export * from './OpenAI' 11 | export * from './OpenRouter' 12 | export * from './SambaNova' 13 | export * from './Together' 14 | export * from './xAI' 15 | 16 | import {Provider} from "./provider"; 17 | import {AI21} from "./AI21"; 18 | import {Anthropic} from "./Anthropic"; 19 | import {Cohere} from "./Cohere"; 20 | import {DeepSeek} from "./DeepSeek"; 21 | import {GoogleGenerativeAI} from "./GoogleGenerativeAI"; 22 | import {Groq} from "./Groq"; 23 | import {Mistral} from "./Mistral"; 24 | import {Nvidia} from "./Nvidia"; 25 | import {OpenAI} from "./OpenAI"; 26 | import {OpenRouter} from "./OpenRouter"; 27 | import {SambaNova} from "./SambaNova"; 28 | import {Together} from "./Together"; 29 | import {xAI} from "./xAI"; 30 | 31 | /** 32 | * List of all providers. 33 | */ 34 | export const providers: Array = [ 35 | new AI21(), 36 | new Anthropic(), 37 | new Cohere(), 38 | new DeepSeek(), 39 | new GoogleGenerativeAI(), 40 | new Groq(), 41 | new Mistral(), 42 | new Nvidia(), 43 | new OpenAI(), 44 | new OpenRouter(), 45 | new SambaNova(), 46 | new Together(), 47 | new xAI(), 48 | ]; 49 | 50 | /** 51 | * Flatten the list of models from all providers. 52 | */ 53 | export const models = providers.flatMap(provider => provider.models); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mono", 3 | "license": "Apache-2.0", 4 | "author": "Leliuga", 5 | "scripts": { 6 | "build": "turbo build", 7 | "changeset": "changeset", 8 | "clean": "turbo clean", 9 | "dev": "turbo dev --no-cache --concurrency 16 --continue", 10 | "lint": "turbo lint", 11 | "prepare": "husky install", 12 | "prettier-check": "prettier --check \"**/*.{js,ts,tsx,md,mdx}\"", 13 | "type-check": "turbo type-check", 14 | "prettier-fix": "prettier --write \"**/*.{js,ts,tsx,md,mdx}\"", 15 | "publint": "turbo publint", 16 | "test": "turbo test", 17 | "ci:release": "turbo clean && turbo build && changeset publish", 18 | "ci:version": "changeset version && pnpm install --no-frozen-lockfile" 19 | }, 20 | "lint-staged": { 21 | "*": [ 22 | "prettier --ignore-unknown --write" 23 | ] 24 | }, 25 | "devDependencies": { 26 | "@changesets/cli": "^2.29.3", 27 | "eslint": "^9.26.0", 28 | "husky": "^9.1.7", 29 | "lint-staged": "^15.5.1", 30 | "prettier": "^3.5.3", 31 | "publint": "^0.3.12", 32 | "turbo": "^2.5.0", 33 | "typescript": "^5.8.3" 34 | }, 35 | "engines": { 36 | "node": "^20.0.0 || ^22.0.0" 37 | }, 38 | "homepage": "https://chiki.chat", 39 | "repository": { 40 | "type": "git", 41 | "url": "git+https://github.com/ChikiChat/ai.git" 42 | }, 43 | "bugs": { 44 | "url": "https://github.com/ChikiChat/ai/issues" 45 | }, 46 | "keywords": [ 47 | "ai", 48 | "chiki" 49 | ], 50 | "packageManager": "pnpm@9.12.3", 51 | "prettier": { 52 | "tabWidth": 2, 53 | "useTabs": false, 54 | "singleQuote": true, 55 | "arrowParens": "avoid", 56 | "trailingComma": "all" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/agent/src/prompt/parsers/markdown/code.ts: -------------------------------------------------------------------------------- 1 | import {IParser} from '../types'; 2 | 3 | /** 4 | * Represents a code block extracted from a Markdown document. 5 | * Each code block contains a language identifier and the actual code content. 6 | */ 7 | export type CodeBlock = { 8 | /** 9 | * The programming language of the code block. 10 | * This is typically specified after the opening triple backticks (```). 11 | * If no language is specified, this field will be an empty string. 12 | */ 13 | language: string; 14 | 15 | /** 16 | * The actual code content within the code block. 17 | * This is the text between the opening and closing triple backticks (```). 18 | */ 19 | code: string; 20 | }; 21 | 22 | /** 23 | * Parser for extracting Markdown code blocks from a given input string. 24 | * This parser uses a regular expression to identify code blocks and extracts 25 | * both the language and the code content. 26 | */ 27 | export class ParserMarkdownCode implements IParser { 28 | 29 | /** 30 | * Parses the input string to extract Markdown code blocks. 31 | * 32 | * @param input - The input string containing Markdown code blocks. 33 | * @returns An array of CodeBlock objects, each containing the language and code content. 34 | * @throws Will throw an error if the input is not a string. 35 | */ 36 | parse(input: string): OUTPUT { 37 | const blocks: CodeBlock[] = []; 38 | const regex = /```(\w*)\n([\s\S]*?)\n```/g; 39 | let match; 40 | 41 | while ((match = regex.exec(input)) !== null) { 42 | blocks.push({ 43 | language: match[1] ? match[1].trim() : '', 44 | code: match[2] ? match[2].trim() : '' 45 | }); 46 | } 47 | 48 | return blocks as OUTPUT; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/model/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # AI SDK (model) 👋 2 | 3 | ## 1.2.6 4 | 5 | ### Patch Changes 6 | 7 | - 394c357: iteration 8 | 9 | ## 1.2.5 10 | 11 | ### Patch Changes 12 | 13 | - d92a3c4: Iteration 14 | 15 | ## 1.2.4 16 | 17 | ### Patch Changes 18 | 19 | - ab2871a: iteration 20 | 21 | ## 1.2.3 22 | 23 | ### Patch Changes 24 | 25 | - b8ea6d5: model iteration 26 | 27 | ## 1.2.2 28 | 29 | ### Patch Changes 30 | 31 | - a0e2d34: chore: packages update 32 | 33 | ## 1.2.1 34 | 35 | ### Patch Changes 36 | 37 | - 216fab7: Iteration 38 | 39 | ## 1.2.0 40 | 41 | ### Minor Changes 42 | 43 | - bf9c911: Add proxy support 44 | 45 | ## 1.1.2 46 | 47 | ### Patch Changes 48 | 49 | - 5cf6f25: exported Provider class 50 | 51 | ## 1.1.1 52 | 53 | ### Patch Changes 54 | 55 | - 8631556: fixed a bug in the model 56 | 57 | ## 1.1.0 58 | 59 | ### Minor Changes 60 | 61 | - eed9080: fixed "process.env" 62 | 63 | ## 1.0.7 64 | 65 | ### Patch Changes 66 | 67 | - d0ec95e: LanguageModelInit prompt field is required 68 | 69 | ## 1.0.6 70 | 71 | ### Patch Changes 72 | 73 | - a9fbf34: LanguageModelInit remove readonly 74 | 75 | ## 1.0.5 76 | 77 | ### Patch Changes 78 | 79 | - e739205: LanguageModelInit schema to simple type 80 | 81 | ## 1.0.4 82 | 83 | ### Patch Changes 84 | 85 | - a844c9d: refactor 86 | 87 | ## 1.0.3 88 | 89 | ### Patch Changes 90 | 91 | - 6358621: Add types LanguageModelInit and EmbeddingModelInit. Comments 92 | 93 | ## 1.0.2 94 | 95 | ### Patch Changes 96 | 97 | - ce7cd4e: update google models ids 98 | 99 | ## 1.0.1 100 | 101 | ### Patch Changes 102 | 103 | - aa04daf: chore (models): update tool call supporting 104 | 105 | ## 1.0.0 106 | 107 | ### Major Changes 108 | 109 | - 0125972: Add providers ai21, anthropic, cohere, deepseek, google-generative-ai, groq, mistral, nvidia, openai, openrouter, sambanova, xai 110 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/calculate.ts: -------------------------------------------------------------------------------- 1 | import * as mathjs from 'mathjs'; 2 | import {z} from 'zod'; 3 | import {Task} from './task'; 4 | 5 | // Define the input schema for the TaskCalculate task 6 | const InputSchema = z.object({ 7 | expression: z.string().trim(), 8 | scope: z.optional(z.record(z.any()).default({})), 9 | }); 10 | 11 | // Define the output schema for the TaskCalculate task 12 | const OutputSchema = z.object({ 13 | output: z.union([z.number(), z.string()]), 14 | }); 15 | 16 | type Input = z.infer; 17 | type Output = z.infer; 18 | 19 | /** 20 | * TaskCalculate class extends the Task class to perform mathematical expression evaluations. 21 | * It uses the mathjs library to evaluate expressions and can handle both string expressions and matrices. 22 | */ 23 | export class TaskCalculate extends Task { 24 | constructor() { 25 | super('Calculate', 'Calculates the result of a mathematical expression.'); 26 | } 27 | 28 | /** 29 | * Returns the input and output schemas for the TaskCalculate task. 30 | * 31 | * @returns An object containing the input and output schemas. 32 | */ 33 | schema(): { input: typeof InputSchema, output: typeof OutputSchema } { 34 | return {input: InputSchema, output: OutputSchema}; 35 | } 36 | 37 | /** 38 | * Perform the calculation of a mathematical expression. 39 | * 40 | * @param input - The input object containing the expression and optional scope. 41 | * @returns An object containing the result of the expression evaluation. 42 | * @throws Will throw an error if the evaluation process fails. 43 | */ 44 | protected async perform(input: Input): Promise { 45 | const {expression, scope} = this.schema().input.parse(input); 46 | 47 | return { 48 | output: mathjs.evaluate(expression, scope || {}) as string | number, 49 | }; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: 🔧 Feature report 2 | description: Create a feature report to help us improve 3 | labels: [ "feature", "status/0-triage", "priority/p3" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all features reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:feature) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: textarea 17 | attributes: 18 | label: What is your feature request? 19 | description: Also tell us, what did you expect to happen? 20 | placeholder: Tell us what you see! 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: How solve? 26 | description: Also tell us, how we can solve it? 27 | placeholder: Tell us how you see! 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Anything else? 33 | description: | 34 | Links? References? Anything that will give us more context about the feature request you are encountering! 35 | 36 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 37 | validations: 38 | required: false 39 | - type: checkboxes 40 | attributes: 41 | label: Code of Conduct 42 | description: By submitting this feature request, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 43 | options: 44 | - label: I agree to follow this repository Code of Conduct 45 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/dependency.yml: -------------------------------------------------------------------------------- 1 | name: 🔗 Dependency report 2 | description: Create a dependency report to help us improve 3 | labels: [ "dependency", "status/0-triage", "priority/p2" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all dependencies reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:dependency) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: textarea 17 | attributes: 18 | label: What happened? 19 | description: Also tell us, what did you expect to happen? 20 | placeholder: Tell us what you see! 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: How solve? 26 | description: Also tell us, how we can solve it? 27 | placeholder: Tell us how you see! 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Anything else? 33 | description: | 34 | Links? References? Anything that will give us more context about the dependency issue you are encountering! 35 | 36 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 37 | validations: 38 | required: false 39 | - type: checkboxes 40 | attributes: 41 | label: Code of Conduct 42 | description: By submitting this dependency issue, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 43 | options: 44 | - label: I agree to follow this repository Code of Conduct 45 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.yml: -------------------------------------------------------------------------------- 1 | name: 📋 Documentation report 2 | description: Create a documentation report to help us improve 3 | labels: [ "documentation", "status/0-triage", "priority/p3" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all documentations reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:documentation) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: textarea 17 | attributes: 18 | label: What happened? 19 | description: Also tell us, what did you expect to happen? 20 | placeholder: Tell us what you see! 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: How solve? 26 | description: Also tell us, how we can solve it? 27 | placeholder: Tell us how you see! 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Anything else? 33 | description: | 34 | Links? References? Anything that will give us more context about the documentation issue you are encountering! 35 | 36 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 37 | validations: 38 | required: false 39 | - type: checkboxes 40 | attributes: 41 | label: Code of Conduct 42 | description: By submitting this documentation issue, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 43 | options: 44 | - label: I agree to follow this repository Code of Conduct 45 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 Enhancement report 2 | description: Create a enhancement report to help us improve 3 | labels: [ "enhancement", "status/0-triage", "priority/p3" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all enhancements reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:enhancement) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: textarea 17 | attributes: 18 | label: What is your enhancement request? 19 | description: Also tell us, what did you expect to happen? 20 | placeholder: Tell us what you see! 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: How solve? 26 | description: Also tell us, how we can solve it? 27 | placeholder: Tell us how you see! 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Anything else? 33 | description: | 34 | Links? References? Anything that will give us more context about the enhancement request you are encountering! 35 | 36 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 37 | validations: 38 | required: false 39 | - type: checkboxes 40 | attributes: 41 | label: Code of Conduct 42 | description: By submitting this enhancement request, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 43 | options: 44 | - label: I agree to follow this repository Code of Conduct 45 | required: true -------------------------------------------------------------------------------- /packages/agent/src/tasks/task.ts: -------------------------------------------------------------------------------- 1 | import {z, ZodSchema} from 'zod'; 2 | import {ITask} from "./types"; 3 | 4 | /** 5 | * Represents a base class for tasks that can be executed with a specific input and produce an output. 6 | * This abstract class implements the ITask interface and provides a template for task execution. 7 | */ 8 | export abstract class Task implements ITask { 9 | /** 10 | * The unique and descriptive name of the task. 11 | */ 12 | readonly name: string; 13 | 14 | /** 15 | * A detailed description of what the task does, including any assumptions or prerequisites. 16 | */ 17 | readonly description: string; 18 | 19 | /** 20 | * Constructs a new task with a given name, description, and logger. 21 | * 22 | * @param name - The unique and descriptive name of the task. 23 | * @param description - A detailed description of what the task does, including any assumptions or prerequisites. 24 | */ 25 | protected constructor(name: string, description: string) { 26 | this.name = name; 27 | this.description = description; 28 | } 29 | 30 | /** 31 | * Returns the input and output schema for the task. 32 | * 33 | * @returns An object containing the input and output schema. 34 | */ 35 | abstract schema(): { input: INPUT; output: OUTPUT }; 36 | 37 | /** 38 | * Abstract method that must be implemented by subclasses to define the specific task logic. 39 | * 40 | * @param input - The input data required for the task, conforming to the input schema. 41 | * @returns A promise that resolves to the output of the task, conforming to the output schema. 42 | */ 43 | protected abstract perform(input: z.infer): Promise>; 44 | 45 | /** 46 | * Executes the task with the given input and returns a promise that resolves to the output. 47 | * 48 | * @param input - The input data required for the task, conforming to the input schema. 49 | * @returns A promise that resolves to the output of the task, conforming to the output schema. 50 | */ 51 | execute(input: z.infer): Promise> { 52 | return this.perform(input); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/agent/README.md: -------------------------------------------------------------------------------- 1 | # AI SDK (agent) 👋 2 | 3 | The AI SDK is a TypeScript toolkit designed to help you build AI-powered applications 4 | using popular frameworks like Next.js, React, Svelte, Vue and runtimes like Bun or Node.js. 5 | 6 | ## Installation 7 | 8 | You will need Bun or Node.js 18+ and pnpm installed on your local development machine. 9 | 10 | ```shell 11 | pnpm i @chikichat/agent 12 | ``` 13 | 14 | ## Agent 15 | 16 | - [x] [Agent](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/agent/agent.ts) - One-Shot 17 | - [x] [ReAct](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/agent/react.ts) - Reason + Act 18 | - [ ] Flow - Step-By-Step 19 | 20 | ## Tasks 21 | 22 | - [x] [Http Fetch](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tasks/http/fetch.ts) 23 | - [x] [Llm Embedding](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tasks/llm/embedding.ts) 24 | - [x] [Llm Evaluate](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tasks/llm/evaluate.ts) 25 | - [x] [Llm Generate](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tasks/llm/generate.ts) 26 | - [x] [Llm Similarity](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tasks/llm/similarity.ts) 27 | - [ ] Pop3 Stat 28 | - [ ] Pop3 List 29 | - [ ] Pop3 Retrieve 30 | - [ ] Pop3 Delete 31 | - [ ] Smtp Send 32 | - [x] [Calculate](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tasks/calculate.ts) 33 | - [ ] Many More 34 | 35 | ## Tools 36 | 37 | - [x] [Http Fetch](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tools/http/fetch.ts) 38 | - [ ] Pop3 Stat 39 | - [ ] Pop3 List 40 | - [ ] Pop3 Retrieve 41 | - [ ] Pop3 Delete 42 | - [ ] Smtp Send 43 | - [x] [Calculate](https://github.com/ChikiChat/ai/blob/main/packages/agent/src/tools/calculate.ts) 44 | - [ ] Many More 45 | 46 | ## Contributing 47 | 48 | Contributions to the AI SDK are welcome and highly appreciated. However, before you jump right into it, we would like 49 | you to review our [Contribution Guidelines](https://github.com/ChikiChat/ai/blob/main/CONTRIBUTING.md) to make sure you 50 | have smooth experience contributing to AI 51 | SDK. 52 | 53 | ## License 54 | 55 | This project is licensed under the Apache License Version 2.0 License - see 56 | the [LICENSE](https://github.com/ChikiChat/ai/blob/main/LICENSE) file for details. 57 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue.yml: -------------------------------------------------------------------------------- 1 | name: 😲 Issue report 2 | description: Create a issue report to help us improve 3 | labels: [ "issue", "status/0-triage", "priority/p1" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all issues reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:issue) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: textarea 17 | attributes: 18 | label: What happened? 19 | description: Also tell us, what did you expect to happen? 20 | placeholder: Tell us what you see! 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: How solve? 26 | description: Also tell us, how we can solve it? 27 | placeholder: Tell us how you see! 28 | validations: 29 | required: true 30 | - type: textarea 31 | attributes: 32 | label: Checklist 33 | description: Also tell us, what did you? 34 | value: | 35 | [ ] Finish implementation of the issue 36 | [ ] Test all functions 37 | [ ] Documentation 38 | [ ] Have enough logs to trace activities 39 | [ ] Notify developers of necessary actions 40 | render: markdown 41 | validations: 42 | required: true 43 | - type: textarea 44 | attributes: 45 | label: Anything else? 46 | description: | 47 | Links? References? Anything that will give us more context about the issue you are encountering! 48 | 49 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 50 | validations: 51 | required: false 52 | - type: checkboxes 53 | attributes: 54 | label: Code of Conduct 55 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 56 | options: 57 | - label: I agree to follow this repository Code of Conduct 58 | required: true -------------------------------------------------------------------------------- /packages/agent/src/tasks/llm/embedding.ts: -------------------------------------------------------------------------------- 1 | import {embedMany} from 'ai'; 2 | import {z} from 'zod'; 3 | import {DEFAULT_EMBEDDING_MODEL_NAME, embeddingModel, usageModel} from '@chikichat/model'; 4 | import {Task} from '../task'; 5 | 6 | // Define the input schema for the TaskLlmEmbedding task 7 | const InputSchema = z.object({ 8 | model: z.string().default(DEFAULT_EMBEDDING_MODEL_NAME), 9 | values: z.array(z.string().trim()) 10 | }); 11 | 12 | // Define the output schema for the TaskLlmEmbedding task 13 | const OutputSchema = z.object({ 14 | output: z.array(z.array(z.number())), 15 | usage: z.object({ 16 | tokens: z.object({ 17 | input: z.number(), 18 | output: z.number(), 19 | }), 20 | cost: z.object({ 21 | input: z.number(), 22 | output: z.number(), 23 | }) 24 | }) 25 | }); 26 | 27 | type Input = z.infer; 28 | type Output = z.infer; 29 | 30 | /** 31 | * TaskLlmEmbedding class extends Task to compute the embedding of strings. 32 | * It uses an embedding model to convert the strings into vectors. 33 | */ 34 | export class TaskLlmEmbedding extends Task { 35 | constructor() { 36 | super('Embedding', 'Computes the embedding of strings using an embedding model.'); 37 | } 38 | 39 | /** 40 | * Returns the input and output schemas for the TaskLlmEmbedding task. 41 | * 42 | * @returns An object containing the input and output schemas. 43 | */ 44 | schema(): { input: typeof InputSchema, output: typeof OutputSchema } { 45 | return {input: InputSchema, output: OutputSchema}; 46 | } 47 | 48 | /** 49 | * Perform the embedding computation. 50 | * 51 | * @param input - The input object containing the model name and an array of strings to embed. 52 | * @returns An object containing the embeddings and usage details. 53 | */ 54 | protected async perform(input: Input): Promise { 55 | const {model, values} = this.schema().input.parse(input); 56 | const {embeddings, usage} = await embedMany({ 57 | model: embeddingModel(model), 58 | values: values, 59 | }); 60 | 61 | return { 62 | output: embeddings, 63 | usage: usageModel(model, usage), 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/agent/src/logger/logger.ts: -------------------------------------------------------------------------------- 1 | import {ILogger} from "./types"; 2 | 3 | /** 4 | * A logger implementation that outputs log messages to the console. 5 | * It provides methods to log messages at different levels: info, error, warn, and debug. 6 | * The debug method only logs messages in a development environment. 7 | */ 8 | export class Logger implements ILogger { 9 | /** 10 | * The name of the logger. 11 | */ 12 | readonly name: string; 13 | 14 | /** 15 | * Creates a new instance of Logger. 16 | * @param name - The name of the logger. 17 | */ 18 | constructor(name: string) { 19 | this.name = name; 20 | } 21 | 22 | /** 23 | * Logs an informational message to the console. 24 | * @param message - The message to log. 25 | * @param keyValuePairs - Optional key-value pairs to include in the log. 26 | */ 27 | info(message: string, keyValuePairs?: { [key: string]: any }): void { 28 | console.log(`[INFO ${this.name}]`, message, keyValuePairs ? JSON.stringify(keyValuePairs) : ''); 29 | } 30 | 31 | /** 32 | * Logs an error message to the console. 33 | * @param error - The error to log. 34 | * @param keyValuePairs - Optional key-value pairs to include in the log. 35 | */ 36 | error(error: Error, keyValuePairs?: { [key: string]: any }): void { 37 | console.error(`[ERROR ${this.name}]`, error.message, keyValuePairs ? JSON.stringify(keyValuePairs) : ''); 38 | } 39 | 40 | /** 41 | * Logs a warning message to the console. 42 | * @param message - The message to log. 43 | * @param keyValuePairs - Optional key-value pairs to include in the log. 44 | */ 45 | warn(message: string, keyValuePairs?: { [key: string]: any }): void { 46 | console.warn(`[WARN ${this.name}]`, message, keyValuePairs ? JSON.stringify(keyValuePairs) : ''); 47 | } 48 | 49 | /** 50 | * Logs a debug message to the console only in a development environment. 51 | * @param message - The message to log. 52 | * @param keyValuePairs - Optional key-value pairs to include in the log. 53 | */ 54 | debug(message: string, keyValuePairs?: { [key: string]: any }): void { 55 | if (process.env.NODE_ENV === 'development') { 56 | console.log(`[DEBUG ${this.name}]`, message, keyValuePairs ? JSON.stringify(keyValuePairs) : ''); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /packages/agent/src/agent/agent.ts: -------------------------------------------------------------------------------- 1 | import {generateText, LanguageModel} from "ai"; 2 | import {EventEmitter} from 'events'; 3 | import {Config, IAgent, Output} from "./types"; 4 | import {Prompt} from "../prompt"; 5 | import { 6 | DEFAULT_FREQUENCY_PENALTY, 7 | DEFAULT_MAX_TOKENS, 8 | DEFAULT_PRESENCE_PENALTY, 9 | DEFAULT_TEMPERATURE, 10 | DEFAULT_TOP_K, 11 | DEFAULT_TOP_P, 12 | languageModel, 13 | usageModel 14 | } from "@chikichat/model"; 15 | 16 | /** 17 | * An agent is a component that performs a specific task and returns an output. 18 | * 19 | * @template OUTPUT - The type of the output produced by the agent. 20 | */ 21 | export class Agent extends EventEmitter implements IAgent { 22 | readonly config: Config; 23 | 24 | constructor(config: Config) { 25 | super(); 26 | this.config = config; 27 | } 28 | 29 | /** 30 | * Executes the current step of the agent's workflow. 31 | * 32 | * @param args - An object containing the arguments needed for the task. 33 | * @returns A promise that resolves to the output of the task. 34 | */ 35 | async execute(args: { [key: string]: any } = {}): Promise> { 36 | const template = new Prompt(this.config.init.prompt, this.config.init.parser); 37 | const prompt = template.toString(args); 38 | 39 | const {text, finishReason, usage} = await generateText({ 40 | prompt: prompt, 41 | model: languageModel(this.config.init.model) as LanguageModel, 42 | maxTokens: this.config.init.maxTokens || DEFAULT_MAX_TOKENS, 43 | maxSteps: 2, 44 | temperature: this.config.init.temperature || DEFAULT_TEMPERATURE, 45 | topP: this.config.init.topP || DEFAULT_TOP_P, 46 | topK: this.config.init.topK || DEFAULT_TOP_K, 47 | presencePenalty: this.config.init.presencePenalty || DEFAULT_PRESENCE_PENALTY, 48 | frequencyPenalty: this.config.init.frequencyPenalty || DEFAULT_FREQUENCY_PENALTY, 49 | tools: this.config.init.tools || {}, 50 | }); 51 | 52 | return { 53 | input: prompt, 54 | output: { 55 | raw: text, 56 | output: template.parse(text) 57 | }, 58 | finishReason: finishReason, 59 | usage: usageModel(this.config.init.model, usage) 60 | }; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: 🐞 Bug report 2 | description: Create a bug report to help us improve 3 | labels: [ "bug", "status/0-triage", "priority/p0" ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thanks for helping us to improve AI!** 9 | 10 | We welcome all bugs reports. Please fill out each area of the form so we can better help you. 11 | If you are reporting, make sure that we do not have any duplicates already open. 12 | You can ensure this by searching the [issue list](https://github.com/ChikiChat/ai/issues?q=is:issue+label:bug) for this repository. 13 | If there is a duplicate, please close your issue and add a comment to the existing issue instead. 14 | 15 | --- 16 | - type: input 17 | attributes: 18 | label: Package version 19 | validations: 20 | required: true 21 | - type: textarea 22 | attributes: 23 | label: Describe the bug 24 | description: Also tell us more about bug 25 | validations: 26 | required: true 27 | - type: textarea 28 | attributes: 29 | label: Steps To Reproduce 30 | description: Steps to reproduce the behavior. 31 | placeholder: | 32 | 1. In this environment... 33 | 2. With this config... 34 | 3. Run '...' 35 | 4. See error... 36 | validations: 37 | required: true 38 | - type: textarea 39 | attributes: 40 | label: Expected behavior 41 | description: A concise description of what you expected to happen. 42 | validations: 43 | required: true 44 | - type: textarea 45 | attributes: 46 | label: Actual behavior 47 | description: A concise description of what you're experiencing. 48 | validations: 49 | required: true 50 | - type: textarea 51 | attributes: 52 | label: Anything else? 53 | description: | 54 | Links? References? Anything that will give us more context about the bug issue you are encountering! 55 | 56 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 57 | validations: 58 | required: false 59 | - type: checkboxes 60 | attributes: 61 | label: Code of Conduct 62 | description: By submitting this bug issue, you agree to follow our [Code of Conduct](https://github.com/ChikiChat/ai/blob/main/CODE_OF_CONDUCT.md) 63 | options: 64 | - label: I agree to follow this repository Code of Conduct 65 | required: true -------------------------------------------------------------------------------- /packages/agent/src/tasks/llm/similarity.ts: -------------------------------------------------------------------------------- 1 | import {cosineSimilarity} from 'ai'; 2 | import {z} from 'zod'; 3 | import {Task} from '../task'; 4 | import {TaskLlmEmbedding} from './embedding'; 5 | 6 | // Define the input schema for the TaskLlmSimilarity task 7 | const InputSchema = z.object({ 8 | model: z.string(), 9 | a: z.string(), 10 | b: z.string(), 11 | }); 12 | 13 | // Define the output schema for the TaskLlmSimilarity task 14 | const OutputSchema = z.object({ 15 | output: z.number(), 16 | usage: z.object({ 17 | tokens: z.object({ 18 | input: z.number(), 19 | output: z.number(), 20 | }), 21 | cost: z.object({ 22 | input: z.number(), 23 | output: z.number(), 24 | }) 25 | }) 26 | }); 27 | 28 | type Input = z.infer; 29 | type Output = z.infer; 30 | 31 | /** 32 | * TaskLlmSimilarity class extends Task to compute the cosine similarity between two strings. 33 | * It uses an embedding model to convert strings into vectors and then calculates the similarity. 34 | */ 35 | export class TaskLlmSimilarity extends Task { 36 | constructor() { 37 | super('Similarity', 'Computes the cosine similarity between two strings using an embedding model.'); 38 | } 39 | 40 | /** 41 | * Returns the input and output schemas for the TaskLlmSimilarity task. 42 | * 43 | * @returns An object containing the input and output schemas. 44 | */ 45 | schema(): { input: typeof InputSchema, output: typeof OutputSchema } { 46 | return {input: InputSchema, output: OutputSchema}; 47 | } 48 | 49 | /** 50 | * Perform the similarity computation. 51 | * 52 | * @param input - The input object containing the model name and two strings to compare. 53 | * @returns An object containing the cosine similarity score and usage details. 54 | */ 55 | protected async perform(input: Input): Promise { 56 | const {model, a, b} = this.schema().input.parse(input); 57 | const {output, usage} = await (new TaskLlmEmbedding().execute({model, values: [a, b]})); 58 | const [embeddingA, embeddingB] = output; 59 | 60 | if (!embeddingA) { 61 | throw new Error('Failed to compute embedding for string A'); 62 | } 63 | 64 | if (!embeddingB) { 65 | throw new Error('Failed to compute embedding for string B'); 66 | } 67 | 68 | return { 69 | output: cosineSimilarity(embeddingA, embeddingB), 70 | usage: usage 71 | }; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AI SDK 👋 2 | 3 | The AI SDK is a TypeScript toolkit designed to help you build AI-powered applications 4 | using popular frameworks like Next.js, React, Svelte, Vue and runtimes like Bun or Node.js. 5 | 6 | We are based on the [AI SDK](https://sdk.vercel.ai). 7 | 8 | ## Motivation 9 | 10 | The AI SDK is driven by several key motivations: 11 | 12 | * **Simplification of AI Integration**: Many providers offer AI services, but integrating these services into 13 | applications can be complex and time-consuming. The AI SDK aims to simplify this process by providing a unified 14 | interface for interacting with multiple AI providers. 15 | * **Cost Tracking and Optimization**: With the increasing use of AI services, it's essential to track and manage costs 16 | effectively. The AI SDK provides features for tracking usage and costs across different providers, enabling developers 17 | to optimize their AI spend. 18 | * **One-Stop Shop for AI Services**: The AI SDK offers a single platform for accessing a wide range of AI services from 19 | various providers, including AI21 Labs, Anthropic, Cohere, Google Generative AI, and many more. This eliminates the 20 | need for developers to manage multiple APIs and credentials. 21 | * **Seamless Switching between Providers**: The AI SDK allows developers to easily switch between different AI 22 | providers, enabling them to compare services, test new models, and choose the best option for their specific use case. 23 | * **Streamlined Development and Deployment**: By providing a standardized interface for AI services, the AI SDK 24 | accelerates development and deployment of AI-powered applications, enabling businesses to bring their products to 25 | market faster. 26 | 27 | Key benefits of the AI SDK include: 28 | 29 | * **Unified Interface**: A single interface for interacting with multiple AI providers 30 | * **Multi-Provider Support**: Access to a wide range of AI services from various providers 31 | * **Cost Tracking and Optimization**: Features for tracking usage and costs across different providers 32 | * **Simplified Development and Deployment**: Accelerated development and deployment of AI-powered applications 33 | 34 | By addressing these motivations and providing these key benefits, the AI SDK aims to become the go-to platform for 35 | developers building AI-powered applications. 36 | 37 | ## Contributing 38 | 39 | Contributions to the AI SDK are welcome and highly appreciated. However, before you jump right into it, we would like 40 | you to review our [Contribution Guidelines](https://github.com/ChikiChat/ai/blob/main/CONTRIBUTING.md) to make sure you have smooth experience contributing to AI 41 | SDK. 42 | 43 | ## License 44 | 45 | This project is licensed under the Apache License Version 2.0 License - see the [LICENSE](https://github.com/ChikiChat/ai/blob/main/LICENSE) file for details. 46 | -------------------------------------------------------------------------------- /packages/model/src/providers/DeepSeek/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createOpenAI, OpenAIProvider} from "@ai-sdk/openai"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class DeepSeek extends Provider { 7 | id = 'deepseek'; 8 | name = 'DeepSeek'; 9 | description = `DeepSeek, unravel the mystery of AGI with curiosity. Answer the essential question with long-termism.`; 10 | models = [ 11 | { 12 | id: `${this.id}/deepseek-reasoner`, 13 | name: 'DeepSeek R1', 14 | description: ``, 15 | architecture: 'DeepseekV3ForCausalLM', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: true, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 129280, embedding: 7168, input: 65536, output: 8192}, 22 | text: {input: true, output: true}, 23 | image: {input: false, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000005500, output: 0.0000021900}, 28 | }, 29 | { 30 | id: `${this.id}/deepseek-chat`, 31 | name: 'DeepSeek V3', 32 | description: ``, 33 | architecture: 'DeepseekV3ForCausalLM', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: true, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 129280, embedding: 7168, input: 65536, output: 8192}, 40 | text: {input: true, output: true}, 41 | image: {input: false, output: false}, 42 | audio: {input: false, output: false}, 43 | video: {input: false, output: false}, 44 | }, 45 | price: {input: 0.0000002700, output: 0.0000011000}, 46 | }, 47 | ]; 48 | default = { 49 | baseURL: 'https://api.deepseek.com/v1', 50 | pricingURL: 'https://api-docs.deepseek.com/quick_start/pricing', 51 | manageAPIKeysURL: 'https://platform.deepseek.com/apiKeys', 52 | model: 'deepseek-chat', 53 | }; 54 | 55 | create(init: RequestInit = {}): OpenAIProvider { 56 | return createOpenAI({name: this.name, baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}); 57 | } 58 | 59 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 60 | return this.create(init)(model); 61 | } 62 | 63 | embeddingModel(_model: string, _init: RequestInit = {}): EmbeddingModel { 64 | throw new Error(`Provider ${this.name} does not support embeddings`); 65 | } 66 | } -------------------------------------------------------------------------------- /packages/agent/src/prompt/prompt.ts: -------------------------------------------------------------------------------- 1 | import {IParser, Parser} from './parsers'; 2 | import {IPrompt} from './types'; 3 | 4 | /** 5 | * Represents a template-based prompt for generating text. 6 | * This class allows for the creation of dynamic prompts by using placeholders 7 | * that can be replaced with specific values at runtime. 8 | * 9 | * @param template - A string template that may contain placeholders in the format `${variableName}`. 10 | * These placeholders will be replaced with actual values when the `toString` method is called. 11 | * @param parser - An instance of IParser used to parse the input string. 12 | */ 13 | export class Prompt implements IPrompt { 14 | private readonly template: string; 15 | private readonly parser: IParser; 16 | 17 | constructor(template: string, parser: IParser = new Parser() as IParser) { 18 | this.template = template; 19 | this.parser = parser; 20 | } 21 | 22 | /** 23 | * Extracts variable names from the template. 24 | * 25 | * @returns An array of variable names found in the template. 26 | * For example, given the template "Hello, ${name}! Today is ${day}.", 27 | * this method will return `["name", "day"]`. 28 | */ 29 | variables(): string[] { 30 | const regex = /\$\{([^}]+)\}/g; 31 | const matches = this.template.match(regex); 32 | if (!matches) return []; 33 | 34 | return [...new Set(matches.map(match => match.slice(2, -1)))]; 35 | } 36 | 37 | /** 38 | * Replaces variables in the template with their corresponding values. 39 | * 40 | * @param variables An object where keys are variable names and values are the values to replace them with. 41 | * For example, given the template "Hello, ${name}! Today is ${day}.", 42 | * and the variables `{ name: "Alice", day: "Monday" }`, 43 | * this method will return "Hello, Alice! Today is Monday.". 44 | * 45 | * @returns The template string with all variables replaced by their corresponding values. 46 | * If no variables are provided, the original template is returned. 47 | */ 48 | public toString(variables?: { [key: string]: any }): string { 49 | if (!variables) { 50 | return this.template; 51 | } 52 | 53 | return this.template.replace(/\$\{([^}]+)\}/g, (match, key) => variables[key] !== undefined ? variables[key] : match).trim(); 54 | } 55 | 56 | /** 57 | * Parses the input string using the parser provided to the prompt. 58 | * 59 | * @param input - The input string to be parsed. 60 | * 61 | * @returns The parsed result of the input string. 62 | */ 63 | public parse(input: string): OUTPUT { 64 | return this.parser.parse(input); 65 | } 66 | } -------------------------------------------------------------------------------- /packages/agent/src/agent/types.ts: -------------------------------------------------------------------------------- 1 | import {FinishReason} from "ai"; 2 | import type {LanguageModelInit, UsageModel} from '@chikichat/model'; 3 | import {IParser} from "../prompt"; 4 | 5 | /** 6 | * Configuration type for an Agent. 7 | * 8 | * @template OUTPUT - The type of the output that the agent will produce. 9 | */ 10 | export type Config = { 11 | /** 12 | * The name of the configuration. 13 | */ 14 | readonly name: string; 15 | 16 | /** 17 | * A description of the configuration. 18 | */ 19 | readonly description: string; 20 | 21 | /** 22 | * The initial input for the agent. 23 | */ 24 | init: Input; 25 | }; 26 | 27 | export type ConfigStep = Config & { 28 | /** 29 | * The maximum number of steps the agent can execute. 30 | */ 31 | maxSteps: number; 32 | 33 | /** 34 | * Optional callback function to be executed after each step. 35 | * 36 | * @param step - The current step number. 37 | * @param input - The input for the current step. 38 | * @param output - The output from the previous step. 39 | * @returns A promise that resolves to the output for the current step. 40 | */ 41 | onStepFinish?: (step: number, input: Input, output: Output) => Promise>; 42 | } 43 | 44 | /** 45 | * Type for the initialization options of a step. 46 | * This includes the language model initialization options and an optional parser. 47 | */ 48 | export type Input = LanguageModelInit & { 49 | readonly parser?: IParser; 50 | } 51 | 52 | /** 53 | * Type for the output of a step or task. 54 | * This includes the input provided, the raw and parsed output, the finish reason, and usage details. 55 | */ 56 | export type Output = { 57 | input: string, // The input string provided to the task or step. 58 | output: { 59 | raw: string, // The raw output string from the task or step. 60 | output: OUTPUT // The parsed output, which can be of any type specified by the parser. 61 | }, 62 | finishReason: FinishReason, // The reason why the task or step finished. 63 | usage: UsageModel, // Usage details, such as tokens used, etc. 64 | } 65 | 66 | /** 67 | * Interface for an Agent that can execute tasks based on a configuration. 68 | * 69 | * @template OUTPUT - The type of the output that the agent will produce. 70 | */ 71 | export interface IAgent { 72 | /** 73 | * Configuration object for the agent.* 74 | */ 75 | config: Config | ConfigStep; 76 | 77 | /** 78 | * Executes the agent's task with the provided arguments. 79 | * 80 | * @param args - An object containing key-value pairs as arguments for the execution. 81 | * @returns A promise that resolves to the output of the execution. 82 | */ 83 | execute(args: { [key: string]: any }): Promise>; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /packages/model/README.md: -------------------------------------------------------------------------------- 1 | # AI SDK (model) 👋 2 | 3 | The AI SDK is a TypeScript toolkit designed to help you build AI-powered applications 4 | using popular frameworks like Next.js, React, Svelte, Vue and runtimes like Bun or Node.js. 5 | 6 | We are based on the [AI SDK](https://sdk.vercel.ai). 7 | 8 | ## Installation 9 | 10 | You will need Bun or Node.js 18+ and pnpm installed on your local development machine. 11 | 12 | ```shell 13 | pnpm i @chikichat/model 14 | ``` 15 | 16 | ## Providers 17 | 18 | - [x] AI21 Labs 19 | - [x] Anthropic 20 | - [x] Cohere 21 | - [x] DeepSeek 22 | - [x] Google Generative AI 23 | - [x] Groq 24 | - [ ] Hugging Face 25 | - [x] Mistral 26 | - [ ] Novita 27 | - [x] Nvidia 28 | - [x] OpenAI 29 | - [x] OpenRouter AI 30 | - [ ] Perplexity 31 | - [ ] Qwen 32 | - [x] SambaNova 33 | - [x] Together 34 | - [ ] Vertex AI 35 | - [x] xAI 36 | 37 | and SPECIAL 38 | 39 | - [ ] Co:Here 40 | - [ ] llama.cpp 41 | - [ ] TensorRT-LLM 42 | 43 | ## Usage Examples 44 | 45 | **Large language models (LLMs) can generate text in response to a prompt, which can contain instructions and information 46 | to process. For example, you can ask a model to come up with a recipe, draft an email, or summarize a document.** 47 | 48 | ###### @/index.ts (Bun Runtime) 49 | 50 | ```ts 51 | import {generateText} from 'ai'; 52 | import {languageModel, usageModel} from '@chikichat/model'; 53 | 54 | const model = 'anthropic/claude-3-5-sonnet-20241022'; 55 | 56 | /** 57 | * Generate text using a language model. 58 | */ 59 | const {text, usage} = await generateText({ 60 | model: languageModel(model, ''), 61 | system: 'You are a friendly assistant!', 62 | prompt: 'Why is the sky blue?', 63 | }); 64 | 65 | console.log(text); 66 | console.log(usageModel(model, usage)); 67 | 68 | // read more: https://sdk.vercel.ai/docs/ai-sdk-core/generating-text 69 | ``` 70 | 71 | ```shell 72 | bun run index.ts 73 | ``` 74 | 75 | **Embeddings are a way to represent words, phrases, or images as vectors in a high-dimensional space. In this space, 76 | similar words are close to each other, and the distance between words can be used to measure their similarity.** 77 | 78 | ###### @/index.ts (Bun Runtime) 79 | 80 | ```ts 81 | import {embed} from 'ai'; 82 | import {embeddingModel} from '@chikichat/model'; 83 | 84 | /** 85 | * Embed a text using an embedding model. 86 | */ 87 | const {embedding} = await embed({ 88 | model: embeddingModel('mistral/mistral-embed', ''), 89 | value: 'sunny day at the beach', 90 | }); 91 | 92 | console.log(embedding); 93 | 94 | // read more: https://sdk.vercel.ai/docs/ai-sdk-core/embeddings 95 | ``` 96 | 97 | ```shell 98 | bun run index.ts 99 | ``` 100 | 101 | ## Contributing 102 | 103 | Contributions to the AI SDK are welcome and highly appreciated. However, before you jump right into it, we would like 104 | you to review our [Contribution Guidelines](https://github.com/ChikiChat/ai/blob/main/CONTRIBUTING.md) to make sure you have smooth experience contributing to AI 105 | SDK. 106 | 107 | ## License 108 | 109 | This project is licensed under the Apache License Version 2.0 License - see the [LICENSE](https://github.com/ChikiChat/ai/blob/main/LICENSE) file for details. 110 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/llm/generate.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DEFAULT_FREQUENCY_PENALTY, 3 | DEFAULT_LANGUAGE_MODEL_NAME, 4 | DEFAULT_MAX_TOKENS, 5 | DEFAULT_PRESENCE_PENALTY, 6 | DEFAULT_TEMPERATURE, 7 | DEFAULT_TOP_K, 8 | DEFAULT_TOP_P, 9 | languageModel, 10 | usageModel 11 | } from '@chikichat/model'; 12 | import {generateText, LanguageModel} from 'ai'; 13 | import {z} from 'zod'; 14 | import {Task} from '../task'; 15 | 16 | /** 17 | * Input schema for the TaskLlmGenerate task. 18 | */ 19 | const InputSchema = z.object({ 20 | prompt: z.string(), 21 | model: z.string().default(DEFAULT_LANGUAGE_MODEL_NAME), 22 | maxTokens: z.number().default(DEFAULT_MAX_TOKENS), 23 | temperature: z.number().min(0).max(2).default(DEFAULT_TEMPERATURE), 24 | topP: z.number().min(0).max(1).default(DEFAULT_TOP_P), 25 | topK: z.number().min(0).max(100).default(DEFAULT_TOP_K), 26 | presencePenalty: z.number().min(0).max(2).default(DEFAULT_PRESENCE_PENALTY), 27 | frequencyPenalty: z.number().min(0).max(2).default(DEFAULT_FREQUENCY_PENALTY), 28 | }); 29 | 30 | /** 31 | * Output schema for the TaskLlmGenerate task. 32 | */ 33 | const OutputSchema = z.object({ 34 | output: z.string().trim(), 35 | usage: z.object({ 36 | tokens: z.object({ 37 | input: z.number(), 38 | output: z.number(), 39 | }), 40 | cost: z.object({ 41 | input: z.number(), 42 | output: z.number(), 43 | }) 44 | }) 45 | }); 46 | 47 | type Input = z.infer; 48 | type Output = z.infer; 49 | 50 | /** 51 | * A task class that generates text based on a provided prompt. 52 | * Extends the base Task class. 53 | */ 54 | export class TaskLlmGenerate extends Task { 55 | 56 | constructor() { 57 | super('Generate', 'Generates text based on a prompt using a language model.'); 58 | } 59 | 60 | /** 61 | * Returns the input and output schemas for the TaskLlmGenerate task. 62 | * 63 | * @returns An object containing the input and output schemas. 64 | */ 65 | schema(): { input: typeof InputSchema, output: typeof OutputSchema } { 66 | return {input: InputSchema, output: OutputSchema}; 67 | } 68 | 69 | /** 70 | * Perform the text generation task. 71 | * 72 | * @param input - The input object containing the initialization parameters and prompt. 73 | * @returns A promise that resolves to the generated text result. 74 | * @throws Will throw an error if the text generation fails. 75 | */ 76 | protected async perform(input: Input): Promise { 77 | const { 78 | prompt, 79 | model, 80 | maxTokens, 81 | temperature, 82 | topP, 83 | topK, 84 | presencePenalty, 85 | frequencyPenalty 86 | } = this.schema().input.parse(input); 87 | 88 | const {text, usage} = await generateText({ 89 | prompt: prompt, 90 | model: languageModel(model) as LanguageModel, 91 | maxTokens: maxTokens, 92 | temperature: temperature, 93 | topP: topP, 94 | topK: topK, 95 | presencePenalty: presencePenalty, 96 | frequencyPenalty: frequencyPenalty, 97 | }); 98 | 99 | return { 100 | output: text, 101 | usage: usageModel(model, usage), 102 | }; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We are really glad that you are reading this contribution guide. 4 | This means you care about the quality of your contributions. 5 | 6 | ## Submitting patches via Github 7 | 8 | ### Prerequisite for submitting patches/PR's 9 | 10 | Basic knowledge about how to use Github: 11 | 12 | * [Properly](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup) setup your git client. 13 | * Know how to create a commit (for details see below). 14 | * Know how to work with git history (rebasing your commits). 15 | * Know how to create Pull Requests. 16 | 17 | ### Before you start making changes 18 | 19 | 1. Check whether the change you want to introduce is not already present in the base repository. 20 | Main base repository can be cloned from: https://github.com/ChikiChat/ai 21 | 2. Check whether the change you want to introduce has not been already submitted by someone else. 22 | - https://github.com/ChikiChat/ai/pulls 23 | 3. If you've found that someone already did what you wanted to do, then be patient. The change should be applied soon in 24 | the main repository, unless maintainers are busy or the patch needs to be improved. 25 | If it seems that your change won't be duplicating already done work, then please continue. 26 | 27 | ### Creating a Pull Request (PR) 28 | 29 | 1. [Fork](https://help.github.com/articles/fork-a-repo/) our ChikiChat base repository. 30 | 2. Clone your copy of base `git clone git@github.com:ChikiChat/ai.git`. 31 | 3. Create a feature branch `git checkout -b my_new_feature`. 32 | 4. Make your desired changes and commit them with 33 | a [correct commit message](https://git-scm.com/book/ch5-2.html#Commit-Guidelines). 34 | 35 | * If needed provide a proper formatted (line wrapped) description of what your patch will do. You can provide a 36 | description in the PR, but you must include a message for this specific commit in the commit description. If in the 37 | future we would like to distance ourselves from Github the PR information could be lost. 38 | 39 | 5. Open your copy of the base repository at github.com and switch to your feature branch. You should now see an option 40 | to create your PR. [More info](https://help.github.com/articles/creating-a-pull-request/) 41 | 6. Wait for an ChikiChat author to review your changes. 42 | 7. If all is ok your PR will be merged but if a author asks for changes please do as follows: 43 | 44 | * Make the requested changes. 45 | * Add your file(s) to git and commit (we will squash your commits if needed). 46 | * Push your changes `git push origin my_new_feature`. 47 | 48 | 8. Goto #6. 49 | 50 | ### Submitting a package with new dependencies 51 | 52 | When you want to submit a package including its new dependencies to our repository, you should bundle these commits into 53 | a single PR. 54 | This is needed so our [CI](https://en.wikipedia.org/wiki/Continuous_integration) will first build the dependencies after 55 | which it will build the parent package. 56 | Failing to include __new__ dependencies will fail the CI tests. 57 | 58 | ### Clean-up a Pull Request (PR) 59 | 60 | If by some mistake you end up with multiple commits in your PR and one of our authors asks you to squash your commits 61 | please do __NOT__ create a new pull request. 62 | Instead please 63 | follow [this rebase tutorial](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages). 64 | 65 | ### Pull Request (PR) max age 66 | 67 | Pull Requests that have not been updated in the last 180 days will automatically be labeled S-stale. After 7 days of 68 | additional inactivity the PR will automatically be closed except if one of the ChikiChat authors will label it with 69 | S-WIP (Work In Progress). 70 | -------------------------------------------------------------------------------- /packages/agent/src/memory.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a simple in-memory key-value store. 3 | * This class provides methods to store, retrieve, update, and delete key-value pairs. 4 | * It uses a `Map` to efficiently manage the data. 5 | */ 6 | export class Memory { 7 | private memory: Map; 8 | 9 | constructor() { 10 | this.memory = new Map(); 11 | } 12 | 13 | /** 14 | * Stores a value in memory with the given key. 15 | * If the key already exists, its value will be updated. 16 | * 17 | * @param key - The key to store the value under. 18 | * @param value - The value to store. 19 | */ 20 | public set(key: K, value: V): void { 21 | this.memory.set(key, value); 22 | } 23 | 24 | /** 25 | * Retrieves the value associated with the given key. 26 | * 27 | * @param key - The key to look up. 28 | * 29 | * @returns The value associated with the key, or `undefined` if the key does not exist. 30 | */ 31 | public get(key: K): V | undefined { 32 | return this.memory.get(key); 33 | } 34 | 35 | /** 36 | * Deletes the key-value pair associated with the given key. 37 | * 38 | * @param key - The key to delete. 39 | * 40 | * @returns `true` if the key was found and deleted, `false` otherwise. 41 | */ 42 | public delete(key: K): boolean { 43 | return this.memory.delete(key); 44 | } 45 | 46 | /** 47 | * Checks if a key exists in memory. 48 | * 49 | * @param key - The key to check for. 50 | * 51 | * @returns `true` if the key exists, `false` otherwise. 52 | */ 53 | public has(key: K): boolean { 54 | return this.memory.has(key); 55 | } 56 | 57 | /** 58 | * Returns an iterator over the keys in memory. 59 | * 60 | * @returns An iterator over the keys. 61 | */ 62 | public keys(): IterableIterator { 63 | return this.memory.keys(); 64 | } 65 | 66 | /** 67 | * Returns an iterator over the values in memory. 68 | * 69 | * @returns An iterator over the values. 70 | */ 71 | public values(): IterableIterator { 72 | return this.memory.values(); 73 | } 74 | 75 | /** 76 | * Returns an iterator over the key-value pairs in memory. 77 | * 78 | * @returns An iterator over the entries. 79 | */ 80 | public entries(): IterableIterator<[K, V]> { 81 | return this.memory.entries(); 82 | } 83 | 84 | /** 85 | * Returns an array of all key-value pairs in memory. 86 | * 87 | * @returns An array of key-value pairs. 88 | */ 89 | public asArray(): [K, V][] { 90 | return Array.from(this.memory.entries()); 91 | } 92 | 93 | /** 94 | * Returns an object representation of the key-value pairs in memory. 95 | * Note: If the keys are not strings, they will be converted to strings using `toString()`. 96 | * 97 | * @returns An object with keys as strings and values as their corresponding values. 98 | */ 99 | public asObject(): { [key: string]: V } { 100 | return Object.fromEntries( 101 | this.asArray().map(([key, value]) => [String(key), value]) 102 | ); 103 | } 104 | 105 | /** 106 | * Clears all key-value pairs from memory. 107 | */ 108 | public clear(): void { 109 | this.memory.clear(); 110 | } 111 | 112 | /** 113 | * Returns the number of key-value pairs in memory. 114 | * 115 | * @returns The number of key-value pairs. 116 | */ 117 | public size(): number { 118 | return this.memory.size; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /packages/model/src/providers/provider.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, generateText, LanguageModel} from "ai"; 2 | import {languageModel} from "../index"; 3 | import {Model, RequestInit} from "../types"; 4 | 5 | /** 6 | * Abstract class representing a provider of AI models. 7 | */ 8 | export abstract class Provider { 9 | /** 10 | * Unique identifier for the provider. 11 | */ 12 | abstract id: string; 13 | 14 | /** 15 | * Name of the provider. 16 | */ 17 | abstract name: string; 18 | 19 | /** 20 | * Description of the provider. 21 | */ 22 | abstract description: string; 23 | 24 | /** 25 | * List of models provided by this provider. 26 | */ 27 | abstract models: Array; 28 | 29 | /** 30 | * Default configuration for the provider. 31 | */ 32 | abstract default: { 33 | baseURL: string; // URL for the API 34 | pricingURL: string; // URL for pricing information 35 | manageAPIKeysURL: string; // URL to manage API keys 36 | model: string; // Default model to use 37 | }; 38 | 39 | /** 40 | * Method to create a language model instance. 41 | * 42 | * @param model - The model identifier. 43 | * @param init - Configuration options for the fetch API. 44 | * @returns A LanguageModel instance. 45 | */ 46 | abstract languageModel(model: string, init: RequestInit): LanguageModel; 47 | 48 | /** 49 | * Method to create an embedding model instance. 50 | * 51 | * @param model - The model identifier. 52 | * @param init - Configuration options for the fetch API. 53 | * @returns An EmbeddingModel instance. 54 | */ 55 | abstract embeddingModel(model: string, init: RequestInit): EmbeddingModel; 56 | 57 | /** 58 | * Method to create a provider instance. 59 | * 60 | * @param url - The API URL for the provider. 61 | * @returns The API base URL to be used. 62 | */ 63 | baseUrl(url: string = ''): string { 64 | return url !== '' ? url : this.default.baseURL; 65 | } 66 | 67 | /** 68 | * Method to retrieve the API key, either from the provided argument or environment variable. 69 | * 70 | * @param apiKey - The API key provided as an argument. 71 | * @returns The API key to be used. 72 | */ 73 | apiKey(apiKey: string = ''): string { 74 | if (apiKey !== '') { 75 | return apiKey; 76 | } 77 | 78 | // Fallback to environment variable if apiKey is not provided 79 | return typeof process !== 'undefined' && process.env[`${this.id.toUpperCase().replace(/-/g, '_')}_API_KEY`] 80 | ? process.env[`${this.id.toUpperCase().replace(/-/g, '_')}_API_KEY`] ?? '' 81 | : ''; 82 | } 83 | 84 | /** 85 | * Method to probe the API to check if it's working. 86 | * 87 | * @param apiKey - The API key for authentication. 88 | * @returns A promise that resolves to true if the API is working, false otherwise. 89 | */ 90 | async probe(apiKey: string = ''): Promise { 91 | try { 92 | // Attempt to generate text using the default model and provided API key 93 | await generateText({ 94 | prompt: `hi`, 95 | model: languageModel(this.default.model, {apiKey: this.apiKey(apiKey)}), 96 | maxTokens: 1, 97 | maxSteps: 1 98 | }); 99 | 100 | // Return true if the API call is successful 101 | return true; 102 | } catch (e) { 103 | // Return false if there's an error during the API call 104 | return false; 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /packages/agent/src/dataset.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import {parse} from 'csv-parse/sync'; 3 | import yaml from 'yaml'; 4 | 5 | type Sample = { 6 | context: string; 7 | statement: string; 8 | expect: string; 9 | } 10 | 11 | /** 12 | * Represents a collection of samples for testing a model. 13 | * Each sample consists of a statement and its expected response. 14 | * This class ensures no duplicate samples based on content. 15 | */ 16 | export class Dataset { 17 | private samples: Set; 18 | 19 | /** 20 | * Constructs a new Dataset instance. 21 | * If a filename is provided, it loads samples from the specified file. 22 | * 23 | * @param filename - The path to the file containing the samples (optional). 24 | */ 25 | constructor(filename?: string) { 26 | this.samples = new Set(); 27 | if (filename) { 28 | this.fromFile(filename); 29 | } 30 | } 31 | 32 | /** 33 | * Loads samples from a file into the dataset. 34 | * Supported file formats are CSV, JSON, YAML, and YML. 35 | * 36 | * @param filename - The path to the file containing the samples. 37 | * @throws Will throw an error if the file format is unsupported. 38 | * @throws Will throw an error if the file does not exist. 39 | * @throws Will throw an error if the file content is not an array of samples. 40 | */ 41 | public fromFile(filename: string): void { 42 | const ext = filename.split('.').pop()?.toLowerCase(); 43 | if (!ext || !['csv', 'json', 'yaml', 'yml'].includes(ext)) { 44 | throw new Error(`Unsupported file format: ${ext}`); 45 | } 46 | 47 | if (!fs.existsSync(filename)) { 48 | throw new Error(`File not found: ${filename}`); 49 | } 50 | 51 | const content = fs.readFileSync(filename, 'utf8'); 52 | let data: any[] = []; 53 | 54 | switch (ext) { 55 | case 'csv': 56 | data = parse(content, {columns: true}); 57 | break; 58 | case 'json': 59 | data = JSON.parse(content); 60 | break; 61 | case 'yaml': 62 | case 'yml': 63 | data = yaml.parse(content); 64 | break; 65 | } 66 | 67 | if (!Array.isArray(data)) { 68 | throw new Error(`${ext.toUpperCase()} file must contain an array of samples`); 69 | } 70 | 71 | data.forEach((row: any) => { 72 | const context = row.context ?? (Array.isArray(row) ? row[0] : ''); 73 | const statement = row.statement ?? (Array.isArray(row) ? row[1] : ''); 74 | const expect = row.expect ?? (Array.isArray(row) ? row[2] : ''); 75 | 76 | this.set(context, statement, expect) 77 | }); 78 | } 79 | 80 | /** 81 | * Adds a statement and its expected response to the dataset. 82 | * 83 | * @param context - The context for the statement. 84 | * @param statement - The statement to be stored. 85 | * @param expect - The expected response for the statement. 86 | */ 87 | public set(context: string, statement: string, expect: string): void { 88 | this.samples.add({context, statement, expect}); 89 | } 90 | 91 | /** 92 | * Returns an iterator over the samples in the dataset. 93 | * 94 | * @returns An iterator over the samples. 95 | */ 96 | public values(): IterableIterator { 97 | return this.samples.values(); 98 | } 99 | 100 | /** 101 | * Clears all samples from the dataset. 102 | */ 103 | public clear(): void { 104 | this.samples.clear(); 105 | } 106 | 107 | /** 108 | * Returns the number of samples in the dataset. 109 | * 110 | * @returns The number of samples. 111 | */ 112 | public size(): number { 113 | return this.samples.size; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /packages/agent/src/logger/kubernetes.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import {Logger} from './logger'; 3 | 4 | /** 5 | * A logger implementation formatted for Kubernetes environments. 6 | * It outputs log messages to the console with a specific format that includes 7 | * timestamps, log levels, and optional key-value pairs. The debug method only 8 | * logs messages in a development environment. 9 | */ 10 | export class LoggerKubernetes extends Logger { 11 | /** 12 | * Logs an informational message to the console. 13 | * @param message - The message to log. 14 | * @param keyValuePairs - Optional key-value pairs to include in the log. 15 | */ 16 | info(message: string, keyValuePairs?: { [key: string]: any }): void { 17 | console.log(this.format('I', message, keyValuePairs)); 18 | } 19 | 20 | /** 21 | * Logs an error message to the console. 22 | * @param error - The error to log. 23 | * @param keyValuePairs - Optional key-value pairs to include in the log. 24 | */ 25 | error(error: Error, keyValuePairs?: { [key: string]: any }): void { 26 | console.error(this.format('E', error.message, keyValuePairs)); 27 | } 28 | 29 | /** 30 | * Logs a warning message to the console. 31 | * @param message - The message to log. 32 | * @param keyValuePairs - Optional key-value pairs to include in the log. 33 | */ 34 | warn(message: string, keyValuePairs?: { [key: string]: any }): void { 35 | console.warn(this.format('W', message, keyValuePairs)); 36 | } 37 | 38 | /** 39 | * Logs a debug message to the console only in a development environment. 40 | * @param message - The message to log. 41 | * @param keyValuePairs - Optional key-value pairs to include in the log. 42 | */ 43 | debug(message: string, keyValuePairs?: { [key: string]: any }): void { 44 | if (process.env.NODE_ENV === 'development') { 45 | console.log(this.format('D', message, keyValuePairs)); 46 | } 47 | } 48 | 49 | /** 50 | * Formats the log message with a specific format suitable for Kubernetes. 51 | * @param level - The log level (I for Info, E for Error, W for Warn, D for Debug). 52 | * @param message - The message to log. 53 | * @param keyValuePairs - Optional key-value pairs to include in the log. 54 | * @returns The formatted log message. 55 | */ 56 | private format(level: string, message: string, keyValuePairs?: { [key: string]: any }): string { 57 | const timestamp = new Date(); 58 | const month = String(timestamp.getMonth() + 1).padStart(2, '0'); 59 | const day = String(timestamp.getDate()).padStart(2, '0'); 60 | const hours = String(timestamp.getHours()).padStart(2, '0'); 61 | const minutes = String(timestamp.getMinutes()).padStart(2, '0'); 62 | const seconds = String(timestamp.getSeconds()).padStart(2, '0'); 63 | const milliseconds = String(timestamp.getMilliseconds()).padStart(6, '0'); 64 | const formattedTimestamp = `${month}${day} ${hours}:${minutes}:${seconds}.${milliseconds}`; 65 | 66 | let formattedMessage = `'${message}'`; 67 | 68 | if (keyValuePairs) { 69 | for (const key in keyValuePairs) { 70 | const value = keyValuePairs[key]; 71 | formattedMessage += ` ${key}=${JSON.stringify(value)}`; 72 | } 73 | } 74 | 75 | const originalPrepareStackTrace = Error.prepareStackTrace; 76 | Error.prepareStackTrace = (_err, stack) => stack; 77 | const stack = new Error().stack as unknown as NodeJS.CallSite[]; 78 | Error.prepareStackTrace = originalPrepareStackTrace; 79 | 80 | if (stack && stack.length > 2) { 81 | const callSite = stack[2]; 82 | const filename = path.basename(callSite?.getFileName() ?? ''); 83 | const lineNumber = callSite?.getLineNumber(); 84 | return `${level}${formattedTimestamp} ${this.name} ${filename}:${lineNumber}] ${formattedMessage}`; 85 | } 86 | 87 | return `${level}${formattedTimestamp} ${this.name}] ${formattedMessage}`; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/llm/evaluate.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DEFAULT_EMBEDDING_MODEL_NAME, 3 | DEFAULT_FREQUENCY_PENALTY, 4 | DEFAULT_LANGUAGE_MODEL_NAME, 5 | DEFAULT_MAX_TOKENS, 6 | DEFAULT_PRESENCE_PENALTY, 7 | DEFAULT_TEMPERATURE, 8 | DEFAULT_TOP_K, 9 | DEFAULT_TOP_P 10 | } from '@chikichat/model'; 11 | import {z} from 'zod'; 12 | import {Dataset} from '../../dataset'; 13 | import {Task} from '../task'; 14 | import {Prompt} from '../../prompt'; 15 | import {TaskLlmSimilarity} from './similarity'; 16 | import {TaskLlmGenerate} from './generate'; 17 | 18 | /** 19 | * Input schema for the TaskLlmEvaluate task. 20 | * Defines the structure and default values for the input parameters. 21 | */ 22 | const InputSchema = z.object({ 23 | model: z.string().default(DEFAULT_LANGUAGE_MODEL_NAME), 24 | embeddingModel: z.string().default(DEFAULT_EMBEDDING_MODEL_NAME), 25 | datasetPath: z.string(), 26 | prompt: z.optional(z.string()), 27 | maxTokens: z.number().default(DEFAULT_MAX_TOKENS), 28 | temperature: z.number().min(0).max(2).default(DEFAULT_TEMPERATURE), 29 | topP: z.number().min(0).max(1).default(DEFAULT_TOP_P), 30 | topK: z.number().min(0).max(100).default(DEFAULT_TOP_K), 31 | presencePenalty: z.number().min(0).max(2).default(DEFAULT_PRESENCE_PENALTY), 32 | frequencyPenalty: z.number().min(0).max(2).default(DEFAULT_FREQUENCY_PENALTY), 33 | }); 34 | 35 | /** 36 | * Output schema for the TaskLlmEvaluate task. 37 | * Defines the structure of the output data. 38 | */ 39 | const OutputSchema = z.object({ 40 | output: z.array(z.object({ 41 | statement: z.string(), 42 | expect: z.string(), 43 | answer: z.string(), 44 | similarity: z.number() 45 | })) 46 | }); 47 | 48 | type Input = z.infer; 49 | type Output = z.infer; 50 | 51 | /** 52 | * Task to evaluate a language model using a dataset. 53 | * This task generates text responses for each statement in the dataset 54 | * and calculates the similarity between the generated response and the expected response. 55 | */ 56 | export class TaskLlmEvaluate extends Task { 57 | constructor() { 58 | super('Evaluate', 'Evaluates the language model using the dataset.'); 59 | } 60 | 61 | /** 62 | * Returns the input and output schemas for the TaskLlmEvaluate task. 63 | * 64 | * @returns An object containing the input and output schemas. 65 | */ 66 | schema(): { input: typeof InputSchema, output: typeof OutputSchema } { 67 | return {input: InputSchema, output: OutputSchema}; 68 | } 69 | 70 | /** 71 | * Executes the TaskLlmEvaluate task. 72 | * Generates text responses for each statement in the dataset and calculates similarity. 73 | * 74 | * @param input - The input parameters for the task. 75 | * @returns The output results containing statements, expected answers, generated answers, and similarity scores. 76 | */ 77 | protected async perform(input: Input): Promise { 78 | const { 79 | model, 80 | embeddingModel, 81 | datasetPath, 82 | prompt, 83 | maxTokens, 84 | temperature, 85 | topK, 86 | topP, 87 | presencePenalty, 88 | frequencyPenalty 89 | } = this.schema().input.parse(input); 90 | 91 | const dataset = new Dataset(datasetPath); 92 | const p = new Prompt(prompt ?? `Please answer the following question very accurately; a one- to five-word response is ideal:\${statement}`); 93 | const results: Output['output'] = []; 94 | 95 | for (const sample of dataset.values()) { 96 | const {output} = await new TaskLlmGenerate().execute({ 97 | prompt: p.toString({statement: sample.statement}), 98 | model, 99 | maxTokens, 100 | temperature, 101 | topK, 102 | topP, 103 | presencePenalty, 104 | frequencyPenalty 105 | }); 106 | 107 | const answer = p.parse(output); 108 | const {output: similarity} = await new TaskLlmSimilarity().execute({ 109 | model: embeddingModel, 110 | a: sample.expect, 111 | b: answer 112 | }); 113 | 114 | results.push({ 115 | statement: sample.statement, 116 | expect: sample.expect, 117 | answer: answer, 118 | similarity: similarity 119 | }); 120 | } 121 | 122 | return {output: results}; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /packages/agent/src/tasks/http/fetch.ts: -------------------------------------------------------------------------------- 1 | import {z} from 'zod'; 2 | import {Task} from '../task'; 3 | 4 | /** 5 | * Input schema for the TaskHttpFetch task. 6 | */ 7 | const InputSchema = z.object({ 8 | url: z.string().url(), 9 | method: z.enum([ 10 | 'ACL', 'BIND', 'CHECKIN', 'CHECKOUT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LABEL', 'LINK', 'LOCK', 'MERGE', 11 | 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MKREDIRECTREF', 'MKWORKSPACE', 'MOVE', 'OPTIONS', 'ORDERPATCH', 12 | 'PATCH', 'POST', 'PRI', 'PROPFIND', 'PROPPATCH', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'TRACE', 'UNBIND', 13 | 'UNCHECKOUT', 'UNLINK', 'UNLOCK', 'UPDATE', 'UPDATEREDIRECTREF', 'VERSION-CONTROL' 14 | ]).default('GET').optional(), 15 | headers: z.record(z.string(), z.string()).default({ 16 | 'User-Agent': 'ChikiChat-Fetch/0.0.x (+https://chiki.chat)' 17 | }).optional(), 18 | body: z.optional(z.union([z.string(), z.instanceof(Blob), z.instanceof(FormData), z.instanceof(URLSearchParams), z.instanceof(ReadableStream), z.instanceof(ArrayBuffer)])).optional(), 19 | maxRetries: z.number().default(3), 20 | timeout: z.number().default(5000) 21 | }); 22 | 23 | /** 24 | * Output schema for the TaskHttpFetch task. 25 | */ 26 | const OutputSchema = z.object({ 27 | output: z.string().trim(), 28 | status: z.number(), 29 | headers: z.record(z.string(), z.string()), 30 | }); 31 | 32 | type Input = z.infer; 33 | type Output = z.infer; 34 | 35 | /** 36 | * A task class that fetches data from a specified URL with retry logic. 37 | * Extends the base Task class and returns a Response object. 38 | */ 39 | export class TaskHttpFetch extends Task { 40 | /** 41 | * Constructs a new TaskHttpFetch instance. 42 | */ 43 | constructor() { 44 | super('Fetch', 'Fetches data from a specified URL.'); 45 | } 46 | 47 | /** 48 | * Returns the input and output schemas for the TaskHttpFetch task. 49 | * 50 | * @returns An object containing the input and output schemas. 51 | */ 52 | schema(): { input: typeof InputSchema, output: typeof OutputSchema } { 53 | return {input: InputSchema, output: OutputSchema}; 54 | } 55 | 56 | /** 57 | * Perform the fetch operation with retry logic. 58 | * 59 | * @param input - The input object containing the URL, method, headers, body, maxRetries, and timeout. 60 | * @returns A promise that resolves to the Response object from the fetch request. 61 | * @throws Will throw an error if the fetch request fails after the maximum number of retries. 62 | */ 63 | protected async perform(input: Input): Promise { 64 | const {url, method, headers, body, maxRetries, timeout} = this.schema().input.parse(input); 65 | let retries = 0; 66 | 67 | while (retries < maxRetries) { 68 | try { 69 | const controller = new AbortController(); 70 | const id = setTimeout(() => controller.abort(), timeout); 71 | const response = await fetch(url, { 72 | method: method, 73 | headers: headers, 74 | body: body, 75 | signal: controller.signal, 76 | }); 77 | const output = await response.text(); 78 | 79 | clearTimeout(id); 80 | 81 | const h: Record = {}; 82 | response.headers.forEach((value, key) => { 83 | h[key] = value; 84 | }); 85 | 86 | return { 87 | output: output, 88 | status: response.status, 89 | headers: h, 90 | }; 91 | } catch (error: unknown) { 92 | retries++; 93 | if (retries >= maxRetries) { 94 | throw new Error(`Fetch request to ${url} failed after ${maxRetries} retries.`); 95 | } 96 | 97 | if (error instanceof Error) { 98 | if (error.name === 'AbortError') { 99 | console.warn(`Fetch request to ${url} timed out. Retrying...`); 100 | } else { 101 | console.warn(`Fetch request to ${url} failed with error: ${error.message}. Retrying...`); 102 | } 103 | } else { 104 | console.warn(`Fetch request to ${url} failed with an unknown error. Retrying...`); 105 | } 106 | } 107 | } 108 | 109 | throw new Error(`Fetch request to ${url} failed after ${maxRetries} retries.`); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /packages/model/src/providers/AI21/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createOpenAI, OpenAIProvider} from "@ai-sdk/openai"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class AI21 extends Provider { 7 | id = 'ai21'; 8 | name = 'AI21 Labs'; 9 | description = `AI21 Labs builds Foundation Models and AI Systems for the enterprise that accelerate the use of GenAI in production.`; 10 | models = [ 11 | { 12 | id: `${this.id}/jamba-1.6-large`, 13 | name: 'Jamba 1.6 Large', 14 | description: `The most powerful and efficient long context model`, 15 | architecture: 'JambaForCausalLM', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: false, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 65536, embedding: 8192, input: 262144, output: 4096}, 22 | text: {input: true, output: true}, 23 | image: {input: false, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000020000, output: 0.0000080000}, 28 | }, 29 | { 30 | id: `${this.id}/jamba-1.6-mini`, 31 | name: 'Jamba 1.6 Mini', 32 | description: `Efficient & lightweight model for a wide range of tasks`, 33 | architecture: 'JambaForCausalLM', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: false, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 65536, embedding: 8192, input: 262144, output: 4096}, 40 | text: {input: true, output: true}, 41 | image: {input: false, output: false}, 42 | audio: {input: false, output: false}, 43 | video: {input: false, output: false}, 44 | }, 45 | price: {input: 0.0000002000, output: 0.0000004000}, 46 | }, 47 | { 48 | id: `${this.id}/jamba-1.5-large`, 49 | name: 'Jamba 1.5 Large (deprecated)', 50 | description: `The most powerful and efficient long context model`, 51 | architecture: 'JambaForCausalLM', 52 | capabilities: { 53 | embedding: false, 54 | tool_call: false, 55 | rerank: false, 56 | features: [], 57 | size: {vocab: 65536, embedding: 8192, input: 262144, output: 4096}, 58 | text: {input: true, output: true}, 59 | image: {input: false, output: false}, 60 | audio: {input: false, output: false}, 61 | video: {input: false, output: false}, 62 | }, 63 | price: {input: 0.0000020000, output: 0.0000080000}, 64 | }, 65 | { 66 | id: `${this.id}/jamba-1.5-mini`, 67 | name: 'Jamba 1.5 Mini (deprecated)', 68 | description: `Efficient & lightweight model for a wide range of tasks`, 69 | architecture: 'JambaForCausalLM', 70 | capabilities: { 71 | embedding: false, 72 | tool_call: false, 73 | rerank: false, 74 | features: [], 75 | size: {vocab: 65536, embedding: 8192, input: 262144, output: 4096}, 76 | text: {input: true, output: true}, 77 | image: {input: false, output: false}, 78 | audio: {input: false, output: false}, 79 | video: {input: false, output: false}, 80 | }, 81 | price: {input: 0.0000002000, output: 0.0000004000}, 82 | }, 83 | ]; 84 | default = { 85 | baseURL: 'https://api.ai21.com/studio/v1', 86 | pricingURL: 'https://www.ai21.com/pricing', 87 | manageAPIKeysURL: 'https://studio.ai21.com/v2/account/api-key', 88 | model: 'jamba-1.6-mini', 89 | }; 90 | 91 | create(init: RequestInit = {}): OpenAIProvider { 92 | return createOpenAI({ 93 | name: this.name, 94 | baseURL: this.baseUrl(init.baseURL), 95 | apiKey: this.apiKey(init.apiKey), 96 | headers: init.headers 97 | }); 98 | } 99 | 100 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 101 | return this.create(init)(model); 102 | } 103 | 104 | embeddingModel(_model: string, _init: RequestInit = {}): EmbeddingModel { 105 | throw new Error(`Provider ${this.name} does not support embeddings`); 106 | } 107 | } -------------------------------------------------------------------------------- /packages/model/src/providers/xAI/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createXai, XaiProvider} from "@ai-sdk/xai"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class xAI extends Provider { 7 | id = 'xai'; 8 | name = 'xAI'; 9 | description = `xAI is an AI company with the mission of advancing scientific discovery and gaining a deeper understanding of our universe.`; 10 | models = [ 11 | { 12 | id: `${this.id}/grok-beta`, 13 | name: 'Grok 3', 14 | description: ``, 15 | architecture: '', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: true, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 0, embedding: 0, input: 131072, output: 0}, 22 | text: {input: true, output: true}, 23 | image: {input: false, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000050000, output: 0.0000150000}, 28 | }, 29 | { 30 | id: `${this.id}/grok-2-1212`, 31 | name: 'Grok 2', 32 | description: ``, 33 | architecture: '', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: true, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 0, embedding: 0, input: 131072, output: 0}, 40 | text: {input: true, output: true}, 41 | image: {input: false, output: false}, 42 | audio: {input: false, output: false}, 43 | video: {input: false, output: false}, 44 | }, 45 | price: {input: 0.0000020000, output: 0.0000100000}, 46 | }, 47 | { 48 | id: `${this.id}/grok-2-vision-1212`, 49 | name: 'Grok 2 Vision', 50 | description: ``, 51 | architecture: '', 52 | capabilities: { 53 | embedding: false, 54 | tool_call: true, 55 | rerank: false, 56 | features: [], 57 | size: {vocab: 0, embedding: 0, input: 8192, output: 0}, 58 | text: {input: true, output: true}, 59 | image: {input: true, output: false}, 60 | audio: {input: false, output: false}, 61 | video: {input: false, output: false}, 62 | }, 63 | price: {input: 0.0000020000, output: 0.0000100000}, 64 | }, 65 | { 66 | id: `${this.id}/grok-beta`, 67 | name: 'Grok Beta', 68 | description: ``, 69 | architecture: '', 70 | capabilities: { 71 | embedding: false, 72 | tool_call: true, 73 | rerank: false, 74 | features: [], 75 | size: {vocab: 0, embedding: 0, input: 131072, output: 0}, 76 | text: {input: true, output: true}, 77 | image: {input: false, output: false}, 78 | audio: {input: false, output: false}, 79 | video: {input: false, output: false}, 80 | }, 81 | price: {input: 0.0000050000, output: 0.0000150000}, 82 | }, 83 | { 84 | id: `${this.id}/grok-vision-beta`, 85 | name: 'Grok Vision Beta', 86 | description: ``, 87 | architecture: '', 88 | capabilities: { 89 | embedding: false, 90 | tool_call: true, 91 | rerank: false, 92 | features: [], 93 | size: {vocab: 0, embedding: 0, input: 8192, output: 0}, 94 | text: {input: true, output: true}, 95 | image: {input: true, output: false}, 96 | audio: {input: false, output: false}, 97 | video: {input: false, output: false}, 98 | }, 99 | price: {input: 0.0000050000, output: 0.0000150000}, 100 | }, 101 | ]; 102 | default = { 103 | baseURL: 'https://api.x.ai/v1', 104 | pricingURL: 'https://docs.x.ai/docs/models', 105 | manageAPIKeysURL: 'https://console.x.ai/team', 106 | model: `grok-2-1212`, 107 | }; 108 | 109 | create(init: RequestInit = {}): XaiProvider { 110 | return createXai({baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}); 111 | } 112 | 113 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 114 | return this.create(init)(model); 115 | } 116 | 117 | embeddingModel(_model: string, _init: RequestInit = {}): EmbeddingModel { 118 | throw new Error(`Provider ${this.name} does not support embeddings`); 119 | } 120 | } -------------------------------------------------------------------------------- /packages/agent/src/agent/react.ts: -------------------------------------------------------------------------------- 1 | import {CoreMessage, generateText, LanguageModel} from "ai"; 2 | import {EventEmitter} from 'events'; 3 | import {ConfigStep, IAgent, Input, Output} from "./types"; 4 | import {Prompt} from "../prompt"; 5 | import { 6 | DEFAULT_FREQUENCY_PENALTY, 7 | DEFAULT_MAX_TOKENS, 8 | DEFAULT_PRESENCE_PENALTY, 9 | DEFAULT_TEMPERATURE, 10 | DEFAULT_TOP_K, 11 | DEFAULT_TOP_P, 12 | languageModel, 13 | usageModel 14 | } from "@chikichat/model"; 15 | import {Memory} from "../memory"; 16 | 17 | /** 18 | * AgentReAct (Reason + Act) is a class that implements an agent capable of reasoning and acting based on a series of steps. 19 | * It extends the `EventEmitter` class to allow for event-driven communication and implements the `IAgent` interface. 20 | * The agent maintains a history of messages and steps, and it can execute tasks by generating text using a language model. 21 | * The agent can also react to new inputs by adding steps and performing tasks accordingly. 22 | */ 23 | export class AgentReAct extends EventEmitter implements IAgent { 24 | readonly config: ConfigStep; 25 | 26 | /** 27 | * Memory to store key-value pairs for the agent's context. 28 | */ 29 | memory: Memory = new Memory(); 30 | 31 | /** 32 | * Array to store the messages exchanged during the agent's operation. 33 | */ 34 | private messages: CoreMessage[] = []; 35 | 36 | /** 37 | * Map to store the steps performed by the agent, including input and output. 38 | */ 39 | steps: Map; output: Output }> = new Map(); 40 | 41 | /** 42 | * Counter to track the number of steps performed by the agent. 43 | * This counter is incremented each time the `addStep` method is called. 44 | */ 45 | private step: number = 0; 46 | 47 | constructor(config: ConfigStep) { 48 | super(); 49 | 50 | this.config = config; 51 | this.addStep(config.init); 52 | } 53 | 54 | /** 55 | * Adds a step to the agent's workflow with the given input configuration. 56 | * 57 | * @param input - The configuration for the step, including language model initialization and an optional parser. 58 | * @throws Will throw an error if the maximum number of steps is reached. 59 | */ 60 | private addStep(input: Input): void { 61 | this.step++; 62 | this.steps.set(this.step, { 63 | input: input, 64 | output: {} as Output 65 | }); 66 | } 67 | 68 | /** 69 | * Executes the current step of the agent's workflow. 70 | * 71 | * @param args - An object containing the arguments needed for the task. 72 | * @returns A promise that resolves to the output of the task. 73 | */ 74 | async execute(args: { [key: string]: any } = {}): Promise> { 75 | if (this.step > this.config.maxSteps) { 76 | return this.steps.get(this.step - 1)!.output; 77 | } 78 | 79 | const {input} = this.steps.get(this.step)!; 80 | const template = new Prompt(input.prompt, input.parser); 81 | const prompt = template.toString(args); 82 | 83 | this.messages.push({role: 'user', content: prompt}); 84 | const {text, finishReason, usage} = await generateText({ 85 | messages: this.messages, 86 | model: languageModel(input.model) as LanguageModel, 87 | maxTokens: input.maxTokens || DEFAULT_MAX_TOKENS, 88 | maxSteps: 2, 89 | temperature: input.temperature || DEFAULT_TEMPERATURE, 90 | topP: input.topP || DEFAULT_TOP_P, 91 | topK: input.topK || DEFAULT_TOP_K, 92 | presencePenalty: input.presencePenalty || DEFAULT_PRESENCE_PENALTY, 93 | frequencyPenalty: input.frequencyPenalty || DEFAULT_FREQUENCY_PENALTY, 94 | tools: input.tools || {}, 95 | }); 96 | 97 | if (finishReason === "tool-calls") { 98 | /** 99 | * TODO: Handle tool calls and results by adding them to the messages array. ??? 100 | */ 101 | } else { 102 | this.messages.push({role: 'assistant', content: text}); 103 | } 104 | 105 | const output: Output = { 106 | input: prompt, 107 | output: { 108 | raw: text, 109 | output: template.parse(text) 110 | }, 111 | finishReason: finishReason, 112 | usage: usageModel(input.model, usage) 113 | }; 114 | 115 | this.steps.set(this.step, {input: input, output: output}); 116 | 117 | if (this.config.onStepFinish) { 118 | return this.config.onStepFinish(this.step, input, output); 119 | } 120 | 121 | return output; 122 | } 123 | 124 | /** 125 | * Adds a new step to the agent's workflow and executes it. 126 | * 127 | * @param input - The configuration for the new step. 128 | * @param args - An object containing the arguments needed for the task. 129 | * @returns A promise that resolves to the output of the task. 130 | */ 131 | async act(input: Input, args: { [key: string]: any } = {}): Promise> { 132 | this.addStep(input); 133 | 134 | return this.execute(args); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /packages/agent/examples/summarize/index.ts: -------------------------------------------------------------------------------- 1 | import {DEFAULT_LANGUAGE_MODEL_NAME} from "@chikichat/model"; 2 | import {Agent} from "@chikichat/agent"; 3 | 4 | /** 5 | * The Agent class is designed to perform specific tasks based on the provided configuration. 6 | * It can be used to summarize text, answer questions, or perform other language-related tasks. 7 | * The class takes a name, a description, and a configuration object that includes the model and prompt. 8 | */ 9 | const summarize = new Agent({ 10 | name: 'Summarize', 11 | description: 'Summarizes the provided text.', 12 | init: { 13 | prompt: ` 14 | You are a summarization expert. Please summarize the text according to the following instructions: 15 | - Summarize the text up to 100 words. 16 | - Summarize the text up to 5 bullet points. 17 | - Create a summary of the text up to 3 sentences. 18 | - Create a quote. 19 | 20 | **Input:** $\{input} 21 | 22 | Please ensure that the summary is concise, accurate, and captures the key points of the text. 23 | `, 24 | /** 25 | * The language model to be used for summarization. 26 | * This can be overridden by the environment variable LANGUAGE_MODEL_NAME. 27 | */ 28 | model: DEFAULT_LANGUAGE_MODEL_NAME, 29 | }, 30 | }); 31 | 32 | summarize.execute({ 33 | 'input': ` 34 | ### Creating an AI Agent: A Comprehensive Guide 35 | 36 | In the rapidly evolving landscape of artificial intelligence, the creation of an AI agent has become a pivotal step for businesses and organizations looking to enhance their operational efficiency and customer engagement. An AI agent, whether it's a chatbot, virtual assistant, or automated system, is designed to interact with users, perform tasks, and provide information autonomously. Here’s a detailed guide on how to create an effective AI agent. 37 | 38 | #### 1. Define the Purpose and Scope 39 | Before diving into the technical aspects, it's crucial to define the purpose and scope of your AI agent. What specific tasks will it perform? Who is the target audience? What are the key objectives you aim to achieve? Clear objectives will guide the development process and ensure that the AI agent meets the desired outcomes. 40 | 41 | #### 2. Choose the Right Platform and Tools 42 | Selecting the right platform and tools is essential for building an AI agent. Popular platforms offer pre-built templates, natural language processing (NLP) capabilities, and integration options that can significantly streamline the development process. Consider platforms that provide robust NLP features, easy-to-use interfaces, and strong community support. Additionally, evaluate the programming languages and frameworks that best suit your project requirements. Choose tools that are scalable, flexible, and compatible with your existing systems. 43 | 44 | #### 3. Design the Conversation Flow 45 | The conversation flow is the backbone of any AI agent. It dictates how the agent will interact with users, respond to queries, and handle different scenarios. Designing an intuitive and user-friendly conversation flow involves mapping out potential user interactions, creating dialogue trees, and anticipating common user queries. Tools like flowchart software or specialized conversation design tools can be helpful in this process. 46 | 47 | #### 4. Develop and Train the NLP Model 48 | Natural Language Processing (NLP) is the technology that enables AI agents to understand and process human language. Developing and training an NLP model involves several steps: 49 | - **Data Collection**: Gather a diverse set of data that includes various user queries and responses. 50 | - **Data Annotation**: Label the data to help the model understand the context and intent behind the queries. 51 | - **Model Training**: Use machine learning algorithms to train the model on the annotated data. 52 | - **Testing and Iteration**: Continuously test the model and refine it based on user interactions and feedback. 53 | 54 | #### 5. Integrate with Backend Systems 55 | For an AI agent to be truly effective, it needs to be integrated with backend systems such as databases, CRM systems, and other enterprise applications. This integration allows the agent to access and manipulate data, perform tasks, and provide personalized responses. Ensure that the integration is seamless and secure to maintain data integrity and user trust. 56 | 57 | #### 6. Test and Deploy 58 | Testing is a critical phase that involves evaluating the AI agent's performance, usability, and reliability. Conduct thorough testing to identify and fix any issues before deployment. Once the agent is ready, deploy it in a controlled environment to monitor its performance and gather user feedback. Use this feedback to make further improvements. 59 | 60 | #### 7. Monitor and Maintain 61 | After deployment, continuous monitoring and maintenance are essential to ensure the AI agent remains effective and up-to-date. Monitor user interactions, track performance metrics, and update the agent as needed to address new challenges and improve user experience. Regular updates to the NLP model and conversation flow can help the agent adapt to changing user needs and preferences. 62 | 63 | #### Conclusion 64 | Creating an AI agent is a multifaceted process that requires careful planning, technical expertise, and continuous improvement. By following these steps, you can develop an AI agent that not only meets your business objectives but also enhances user satisfaction and engagement. As AI technology continues to advance, the potential for AI agents to transform industries is immense, making it an exciting time to be at the forefront of this innovation. 65 | 66 | --- 67 | 68 | This guide provides a foundational understanding of the process involved in creating an AI agent. Depending on the specific requirements and complexity of your project, additional considerations and steps may be necessary. 69 | `, 70 | }).then(console.log) -------------------------------------------------------------------------------- /packages/model/src/providers/Anthropic/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from 'ai'; 2 | import {AnthropicProvider, createAnthropic} from '@ai-sdk/anthropic'; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class Anthropic extends Provider { 7 | id = 'anthropic'; 8 | name = 'Anthropic'; 9 | description = `Anthropic is an AI safety and research company that's working to build reliable, interpretable, and steerable AI systems.`; 10 | models = [ 11 | { 12 | id: `${this.id}/claude-3-7-sonnet-20250219`, 13 | name: 'Claude 3.7 Sonnet', 14 | description: `Our most intelligent model`, 15 | architecture: '', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: true, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 0, embedding: 0, input: 200000, output: 8192}, 22 | text: {input: true, output: true}, 23 | image: {input: true, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000030000, output: 0.0000150000}, 28 | },{ 29 | id: `${this.id}/claude-3-5-sonnet-20241022`, 30 | name: 'Claude 3.5 Sonnet', 31 | description: `Our previous most intelligent model`, 32 | architecture: '', 33 | capabilities: { 34 | embedding: false, 35 | tool_call: true, 36 | rerank: false, 37 | features: [], 38 | size: {vocab: 0, embedding: 0, input: 200000, output: 8192}, 39 | text: {input: true, output: true}, 40 | image: {input: true, output: false}, 41 | audio: {input: false, output: false}, 42 | video: {input: false, output: false}, 43 | }, 44 | price: {input: 0.0000030000, output: 0.0000150000}, 45 | }, 46 | { 47 | id: `${this.id}/claude-3-5-haiku-20241022`, 48 | name: 'Claude 3.5 Haiku', 49 | description: `Our fastest model`, 50 | architecture: '', 51 | capabilities: { 52 | embedding: false, 53 | tool_call: true, 54 | rerank: false, 55 | features: [], 56 | size: {vocab: 0, embedding: 0, input: 200000, output: 8192}, 57 | text: {input: true, output: true}, 58 | image: {input: false, output: false}, 59 | audio: {input: false, output: false}, 60 | video: {input: false, output: false}, 61 | }, 62 | price: {input: 0.0000008000, output: 0.0000040000}, 63 | }, 64 | { 65 | id: `${this.id}/claude-3-opus-20240229`, 66 | name: 'Claude 3 Opus', 67 | description: `Powerful model for complex tasks`, 68 | architecture: '', 69 | capabilities: { 70 | embedding: false, 71 | tool_call: true, 72 | rerank: false, 73 | features: [], 74 | size: {vocab: 0, embedding: 0, input: 200000, output: 4096}, 75 | text: {input: true, output: true}, 76 | image: {input: true, output: false}, 77 | audio: {input: false, output: false}, 78 | video: {input: false, output: false}, 79 | }, 80 | price: {input: 0.0000150000, output: 0.0000750000}, 81 | }, 82 | { 83 | id: `${this.id}/claude-3-sonnet-20240229`, 84 | name: 'Claude 3 Sonnet', 85 | description: `Balance of intelligence and speed. Strong utility, balanced for scaled deployments.`, 86 | architecture: '', 87 | capabilities: { 88 | embedding: false, 89 | tool_call: true, 90 | rerank: false, 91 | features: [], 92 | size: {vocab: 0, embedding: 0, input: 200000, output: 4096}, 93 | text: {input: true, output: true}, 94 | image: {input: true, output: false}, 95 | audio: {input: false, output: false}, 96 | video: {input: false, output: false}, 97 | }, 98 | price: {input: 0.0000030000, output: 0.0000150000}, 99 | }, 100 | { 101 | id: `${this.id}/claude-3-haiku-20240307`, 102 | name: 'Claude 3 Haiku', 103 | description: `Fastest and most compact model for near-instant responsiveness`, 104 | architecture: '', 105 | capabilities: { 106 | embedding: false, 107 | tool_call: true, 108 | rerank: false, 109 | features: [], 110 | size: {vocab: 0, embedding: 0, input: 200000, output: 4096}, 111 | text: {input: true, output: true}, 112 | image: {input: true, output: false}, 113 | audio: {input: false, output: false}, 114 | video: {input: false, output: false}, 115 | }, 116 | price: {input: 0.0000002500, output: 0.0000012500}, 117 | }, 118 | ]; 119 | default = { 120 | baseURL: 'https://api.anthropic.com/v1', 121 | pricingURL: 'https://www.anthropic.com/pricing', 122 | manageAPIKeysURL: 'https://console.anthropic.com/settings/keys', 123 | model: 'claude-3-haiku-20240307', 124 | }; 125 | 126 | create(init: RequestInit = {}): AnthropicProvider { 127 | return createAnthropic({baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}) 128 | } 129 | 130 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 131 | return this.create(init)(model); 132 | } 133 | 134 | embeddingModel(_model: string, _init: RequestInit = {}): EmbeddingModel { 135 | throw new Error(`Provider ${this.name} does not support embeddings`); 136 | } 137 | } -------------------------------------------------------------------------------- /packages/model/src/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, EmbeddingModelUsage, LanguageModel, LanguageModelUsage} from "ai"; 2 | import { 3 | DEFAULT_FREQUENCY_PENALTY, 4 | DEFAULT_MAX_STEPS, 5 | DEFAULT_MAX_TOKENS, 6 | DEFAULT_PRESENCE_PENALTY, 7 | DEFAULT_TEMPERATURE, 8 | DEFAULT_TOP_K, 9 | DEFAULT_TOP_P, 10 | EmbeddingModelInit, 11 | LanguageModelInit, 12 | Model, RequestInit, 13 | UsageModel 14 | } from "./types"; 15 | import {providers, Provider} from "./providers"; 16 | 17 | export * from "./types"; 18 | export * from "./providers"; 19 | 20 | /** 21 | * Get a language model instance for a given model name and API key. 22 | * 23 | * @param model - The model name in the format "provider/model". 24 | * @param init - Configuration options for the fetch API. 25 | * @returns A LanguageModel instance. 26 | */ 27 | export const languageModel = (model: string, init: RequestInit = {}): LanguageModel => { 28 | return getModel(model, init, (provider: Provider, modelID: string, init: RequestInit = {}) => provider.languageModel(modelID, init)); 29 | }; 30 | 31 | /** 32 | * Get an embedding model instance for a given model name and API key. 33 | * 34 | * @param model - The model name in the format "provider/model". 35 | * @param init - Configuration options for the fetch API. 36 | * @returns An EmbeddingModel instance. 37 | */ 38 | export const embeddingModel = (model: string, init: RequestInit = {}): EmbeddingModel => { 39 | return >getModel(model, init, (provider: Provider, modelID: string, init: RequestInit) => provider.embeddingModel(modelID, init)); 40 | }; 41 | 42 | /** 43 | * Calculate usage statistics for a given model and usage data. 44 | * 45 | * @param model - The model name in the format "provider/model". 46 | * @param usage - Usage data for the model. 47 | * @returns UsageModel containing token and cost information. 48 | */ 49 | export const usageModel = (model: string, usage: LanguageModelUsage | EmbeddingModelUsage): UsageModel => { 50 | const {model: m} = providerAndModel(model); 51 | 52 | if (isEmbeddingModelUsage(usage)) { 53 | const tokens = usage.tokens || 0; 54 | 55 | return { 56 | tokens: { 57 | input: tokens, 58 | output: 0 59 | }, 60 | cost: { 61 | input: m.price.input * tokens, 62 | output: 0 63 | } 64 | }; 65 | } 66 | 67 | const promptTokens = usage.promptTokens || 0; 68 | const completionTokens = usage.completionTokens || 0; 69 | 70 | return { 71 | tokens: { 72 | input: promptTokens, 73 | output: completionTokens 74 | }, 75 | cost: { 76 | input: m.price.input * promptTokens, 77 | output: m.price.output * completionTokens 78 | } 79 | }; 80 | }; 81 | 82 | /** 83 | * Get the provider and model details for a given model name. 84 | * 85 | * @param model - The model name in the format "provider/model". 86 | * @returns An object containing the provider, model, providerID, and modelID. 87 | * @throws Error if the provider or model is not found. 88 | */ 89 | export const providerAndModel = (model: string): { 90 | provider: Provider, 91 | model: Model, 92 | providerID: string, 93 | modelID: string 94 | } => { 95 | const providerID = model.split('/')[0]?.toLowerCase() ?? ''; 96 | const p = providers.find(p => p.id === providerID); 97 | if (!p) { 98 | throw new Error(`Provider ${providerID} not found`); 99 | } 100 | 101 | const modelID = model.split('/').slice(1).join('/'); 102 | const m = p.models.find(m => m.id === model); 103 | if (!m) { 104 | throw new Error(`Provider ${p.name} does not have model ${modelID}`); 105 | } 106 | 107 | return {provider: p, model: m, providerID, modelID}; 108 | }; 109 | 110 | /** 111 | * Initializes a LanguageModelInit object with default settings. 112 | * 113 | * @param model - The name or identifier of the language model to be used. 114 | * @param prompt - The initial prompt to be used by the language model. 115 | * @returns An object of type LanguageModelInit with the provided prompt and model, 116 | * and default values for other properties such as maxTokens, maxSteps, temperature, etc. 117 | */ 118 | export const languageModelInit = (model: string, prompt: string): LanguageModelInit => { 119 | return { 120 | model, 121 | prompt, 122 | maxTokens: DEFAULT_MAX_TOKENS, 123 | maxSteps: DEFAULT_MAX_STEPS, 124 | temperature: DEFAULT_TEMPERATURE, 125 | topP: DEFAULT_TOP_P, 126 | topK: DEFAULT_TOP_K, 127 | presencePenalty: DEFAULT_PRESENCE_PENALTY, 128 | frequencyPenalty: DEFAULT_FREQUENCY_PENALTY, 129 | tools: {} 130 | } 131 | }; 132 | 133 | /** 134 | * Initializes an EmbeddingModelInit object with default settings. 135 | * 136 | * @param model - The name or identifier of the embedding model to be used. 137 | * @returns An object of type EmbeddingModelInit with the provided model and default settings. 138 | */ 139 | export const embeddingModelInit = (model: string): EmbeddingModelInit => { 140 | return { 141 | model, 142 | } 143 | }; 144 | 145 | /** 146 | * Helper function to get a model instance using a provider and model ID. 147 | * 148 | * @param model - The model name in the format "provider/model". 149 | * @param init - Configuration options for the fetch API. 150 | * @param fn - Function to create a model instance. 151 | * @returns A LanguageModel or EmbeddingModel instance. 152 | */ 153 | const getModel = (model: string, init: RequestInit = {}, fn: (provider: Provider, modelID: string, init: RequestInit) => LanguageModel | EmbeddingModel): LanguageModel | EmbeddingModel => { 154 | const {provider, modelID} = providerAndModel(model); 155 | 156 | return fn(provider, modelID, init); 157 | }; 158 | 159 | /** 160 | * Type guard to check if the usage data is for an embedding model. 161 | * 162 | * @param usage - Usage data for the model. 163 | * @returns True if the usage data is for an embedding model, false otherwise. 164 | */ 165 | const isEmbeddingModelUsage = (usage: LanguageModelUsage | EmbeddingModelUsage): usage is EmbeddingModelUsage => { 166 | return (usage as EmbeddingModelUsage).tokens !== undefined; 167 | }; 168 | -------------------------------------------------------------------------------- /packages/model/src/types.ts: -------------------------------------------------------------------------------- 1 | import {Tool} from "ai"; 2 | 3 | /** 4 | * Default language model name. 5 | */ 6 | export const DEFAULT_LANGUAGE_MODEL_NAME: string = typeof process !== 'undefined' && process.env['LANGUAGE_MODEL_NAME'] 7 | ? process.env['LANGUAGE_MODEL_NAME'] 8 | : 'anthropic/claude-3-5-sonnet-20241022'; 9 | 10 | /** 11 | * Default embedding model name. 12 | */ 13 | export const DEFAULT_EMBEDDING_MODEL_NAME: string = typeof process !== 'undefined' && process.env['EMBEDDING_MODEL_NAME'] 14 | ? process.env['EMBEDDING_MODEL_NAME'] 15 | : 'mistral/mistral-embed'; 16 | 17 | /** 18 | * The default maximum number of tokens to generate in the completion. 19 | * This value ensures that the generated text does not exceed a reasonable length. 20 | */ 21 | export const DEFAULT_MAX_TOKENS: number = typeof process !== 'undefined' && process.env['MAX_TOKENS'] 22 | ? parseInt(process.env['MAX_TOKENS']) 23 | : 4096; 24 | 25 | /** 26 | * The default maximum number of steps to generate in the completion. 27 | * This value controls the number of iterations or segments in the text generation process. 28 | */ 29 | export const DEFAULT_MAX_STEPS: number = typeof process !== 'undefined' && process.env['MAX_STEPS'] 30 | ? parseInt(process.env['MAX_STEPS']) 31 | : 2; 32 | 33 | /** 34 | * The default temperature value for controlling the randomness of predictions. 35 | * Lower values make the model more deterministic, while higher values increase randomness. 36 | */ 37 | export const DEFAULT_TEMPERATURE: number = typeof process !== 'undefined' && process.env['TEMPERATURE'] 38 | ? parseFloat(process.env['TEMPERATURE']) 39 | : 0.8; 40 | 41 | /** 42 | * The default value for nucleus sampling (top-p sampling). 43 | * The model considers the smallest set of tokens whose cumulative probability exceeds this value. 44 | */ 45 | export const DEFAULT_TOP_P: number = typeof process !== 'undefined' && process.env['TOP_P'] 46 | ? parseFloat(process.env['TOP_P']) 47 | : 0.9; 48 | 49 | /** 50 | * The default value for limiting the model to the top K most likely next tokens. 51 | * This helps control the diversity of the generated text. 52 | */ 53 | export const DEFAULT_TOP_K: number = typeof process !== 'undefined' && process.env['TOP_K'] 54 | ? parseInt(process.env['TOP_K']) 55 | : 40; 56 | 57 | /** 58 | * The default presence penalty value. 59 | * Penalizes new tokens based on whether they appear in the text so far. 60 | * Increases the model's likelihood to talk about new topics. 61 | */ 62 | export const DEFAULT_PRESENCE_PENALTY: number = typeof process !== 'undefined' && process.env['PRESENCE_PENALTY'] 63 | ? parseFloat(process.env['PRESENCE_PENALTY']) 64 | : 0.0; 65 | 66 | /** 67 | * The default frequency penalty value. 68 | * Penalizes new tokens based on their existing frequency in the text so far. 69 | * Decreases the model's likelihood to repeat the same line verbatim. 70 | */ 71 | export const DEFAULT_FREQUENCY_PENALTY: number = typeof process !== 'undefined' && process.env['FREQUENCY_PENALTY'] 72 | ? parseFloat(process.env['FREQUENCY_PENALTY']) 73 | : 0.0 74 | 75 | 76 | /** 77 | * The default repetition penalty value. 78 | * This value penalizes the model for repeating the same tokens in the generated text. 79 | */ 80 | export const DEFAULT_REPETITION_PENALTY: number = typeof process !== 'undefined' && process.env['REPETITION_PENALTY'] 81 | ? parseFloat(process.env['REPETITION_PENALTY']) 82 | : 1.1 83 | 84 | /** 85 | * Type representing a model provided by a provider. 86 | */ 87 | export type Model = { 88 | id: string; // Unique identifier for the model 89 | name: string; // Name of the model 90 | description: string; // Description of the model 91 | architecture: string; // Architecture of the model 92 | capabilities: Capabilities; // Capabilities of the model 93 | price: Price; // Pricing information for the model 94 | } 95 | 96 | /** 97 | * Type representing the capabilities of a model. 98 | */ 99 | export type Capabilities = { 100 | embedding: boolean; // Whether the model supports embeddings 101 | tool_call: boolean; // Whether the model supports tool calls 102 | rerank: boolean; // Whether the model supports reranking 103 | features: Array; // List of additional features supported by the model 104 | size: { 105 | vocab: number; // Vocabulary size 106 | embedding: number; // Embedding size 107 | input: number; // Maximum input size 108 | output: number; // Maximum output size 109 | } 110 | text: IO; // Input/output capabilities for text 111 | image: IO; // Input/output capabilities for images 112 | audio: IO; // Input/output capabilities for audio 113 | video: IO; // Input/output capabilities for video 114 | } 115 | 116 | /** 117 | * Type representing input/output capabilities. 118 | */ 119 | export type IO = { 120 | input: boolean; // Whether input is supported 121 | output: boolean; // Whether output is supported 122 | } 123 | 124 | /** 125 | * Type representing pricing information for a model. 126 | */ 127 | export type Price = { 128 | input: number; // Cost per input token 129 | output: number; // Cost per output token 130 | } 131 | 132 | /** 133 | * Type representing usage statistics for a model. 134 | */ 135 | export type UsageModel = { 136 | tokens: { 137 | input: number; // Number of input tokens used 138 | output: number; // Number of output tokens used 139 | }, 140 | cost: { 141 | input: number; // Total cost for input tokens 142 | output: number; // Total cost for output tokens 143 | } 144 | } 145 | 146 | /** 147 | * Type representing the initialization configuration for a LanguageModel. 148 | */ 149 | export type LanguageModelInit = { 150 | /** 151 | * The model identifier for text generation. 152 | */ 153 | model: string; 154 | 155 | /** 156 | * The prompt for text generation. 157 | */ 158 | prompt: string; 159 | 160 | /** 161 | * The maximum number of tokens to generate. 162 | * Defaults to {@link DEFAULT_MAX_TOKENS}. 163 | */ 164 | maxTokens?: number; 165 | 166 | /** 167 | * The maximum number of steps to generate. 168 | * Defaults to {@link DEFAULT_MAX_STEPS}. 169 | */ 170 | maxSteps?: number; 171 | 172 | /** 173 | * Controls the randomness of the generated text. 174 | * Lower values make the output more deterministic. 175 | * Defaults to {@link DEFAULT_TEMPERATURE}. 176 | */ 177 | temperature?: number; 178 | 179 | /** 180 | * Implements nucleus sampling to control text diversity. 181 | * The model considers tokens whose cumulative probability exceeds this value. 182 | * Defaults to {@link DEFAULT_TOP_P}. 183 | */ 184 | topP?: number; 185 | 186 | /** 187 | * Limits the model to the top K most likely next tokens. 188 | * Helps control text diversity. 189 | * Defaults to {@link DEFAULT_TOP_K}. 190 | */ 191 | topK?: number; 192 | 193 | /** 194 | * Penalizes tokens that have already appeared in the text. 195 | * Encourages the model to introduce new topics. 196 | * Defaults to {@link DEFAULT_PRESENCE_PENALTY}. 197 | */ 198 | presencePenalty?: number; 199 | 200 | /** 201 | * Penalizes tokens based on their frequency in the text. 202 | * Reduces the likelihood of repeating the same line. 203 | * Defaults to {@link DEFAULT_FREQUENCY_PENALTY}. 204 | */ 205 | frequencyPenalty?: number; 206 | 207 | /** 208 | * The tools available for the model to use. 209 | * The model must support tool invocation. 210 | * Defaults to an empty object. 211 | */ 212 | tools?: Record; 213 | } 214 | 215 | /** 216 | * Type representing the initialization configuration for a EmbeddingModel. 217 | */ 218 | export type EmbeddingModelInit = { 219 | /** 220 | * The model identifier for embeddings. 221 | */ 222 | model: string; 223 | } 224 | 225 | /** 226 | * Configuration options for the request. 227 | */ 228 | export type RequestInit = { 229 | /** 230 | * Base URL for the API requests. 231 | */ 232 | baseURL?: string; 233 | 234 | /** 235 | * Authentication token for API access 236 | */ 237 | apiKey?: string; 238 | 239 | /** 240 | * Organization identifier for scoped API requests 241 | */ 242 | organization?: string; 243 | 244 | /** 245 | * Project identifier for scoped API requests 246 | */ 247 | project?: string; 248 | 249 | /** 250 | * Custom headers to include in the requests. 251 | */ 252 | headers?: Record; 253 | } 254 | -------------------------------------------------------------------------------- /packages/model/src/providers/Mistral/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createMistral, MistralProvider} from "@ai-sdk/mistral"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class Mistral extends Provider { 7 | id = 'mistral'; 8 | name = 'Mistral'; 9 | description = `Mistrals models provide cutting-edge generative capabilities for a variety of use cases.`; 10 | models = [ 11 | { 12 | id: `${this.id}/mistral-saba-latest`, 13 | name: 'Saba', 14 | description: `Custom-trained model to serve specific geographies, markets, and customers.`, 15 | architecture: 'MistralForCausalLM', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: true, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 0, embedding: 0, input: 32768, output: 0}, 22 | text: {input: true, output: true}, 23 | image: {input: false, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000002000, output: 0.0000006000}, 28 | }, 29 | { 30 | id: `${this.id}/mistral-large-latest`, 31 | name: 'Large', 32 | description: `Top-tier reasoning for high-complexity tasks and sophisticated problems.`, 33 | architecture: 'MistralForCausalLM', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: true, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 32768, embedding: 12288, input: 131072, output: 0}, 40 | text: {input: true, output: true}, 41 | image: {input: false, output: false}, 42 | audio: {input: false, output: false}, 43 | video: {input: false, output: false}, 44 | }, 45 | price: {input: 0.0000020000, output: 0.0000060000}, 46 | }, 47 | { 48 | id: `${this.id}/pixtral-large-latest`, 49 | name: 'Pixtral', 50 | description: `Vision-capable large model with frontier reasoning capabilities.`, 51 | architecture: '', 52 | capabilities: { 53 | embedding: false, 54 | tool_call: true, 55 | rerank: false, 56 | features: [], 57 | size: {vocab: 32768, embedding: 28672, input: 131072, output: 0}, 58 | text: {input: true, output: true}, 59 | image: {input: true, output: false}, 60 | audio: {input: false, output: false}, 61 | video: {input: false, output: false}, 62 | }, 63 | price: {input: 0.0000020000, output: 0.0000060000}, 64 | }, 65 | { 66 | id: `${this.id}/ministral-8b-latest`, 67 | name: 'Ministral (8B) 24.10', 68 | description: `Powerful model for on-device use casesl`, 69 | architecture: '', 70 | capabilities: { 71 | embedding: false, 72 | tool_call: true, 73 | rerank: false, 74 | features: [], 75 | size: {vocab: 0, embedding: 0, input: 131072, output: 0}, 76 | text: {input: true, output: true}, 77 | image: {input: false, output: false}, 78 | audio: {input: false, output: false}, 79 | video: {input: false, output: false}, 80 | }, 81 | price: {input: 0.0000001000, output: 0.0000001000}, 82 | }, 83 | { 84 | id: `${this.id}/ministral-3b-latest`, 85 | name: 'Ministral (3B) 24.10', 86 | description: `Most efficient edge model`, 87 | architecture: '', 88 | capabilities: { 89 | embedding: false, 90 | tool_call: true, 91 | rerank: false, 92 | features: [], 93 | size: {vocab: 0, embedding: 0, input: 131072, output: 0}, 94 | text: {input: true, output: true}, 95 | image: {input: false, output: false}, 96 | audio: {input: false, output: false}, 97 | video: {input: false, output: false}, 98 | }, 99 | price: {input: 0.0000000400, output: 0.0000000400}, 100 | }, 101 | { 102 | id: `${this.id}/open-mistral-nemo`, 103 | name: 'Mistral Nemo', 104 | description: `Official open-mistral-nemo Mistral AI model`, 105 | architecture: 'MistralForCausalLM', 106 | capabilities: { 107 | embedding: false, 108 | tool_call: true, 109 | rerank: false, 110 | features: [], 111 | size: {vocab: 131072, embedding: 5120, input: 131072, output: 0}, 112 | text: {input: true, output: true}, 113 | image: {input: false, output: false}, 114 | audio: {input: false, output: false}, 115 | video: {input: false, output: false}, 116 | }, 117 | price: {input: 0.0000001500, output: 0.0000001500}, 118 | }, 119 | { 120 | id: `${this.id}/pixtral-12b`, 121 | name: 'Pixtral (12B)', 122 | description: `Official pixtral-12b-2409 Mistral AI model`, 123 | architecture: '', 124 | capabilities: { 125 | embedding: false, 126 | tool_call: true, 127 | rerank: false, 128 | features: [], 129 | size: {vocab: 131072, embedding: 14336, input: 131072, output: 0}, 130 | text: {input: true, output: true}, 131 | image: {input: true, output: false}, 132 | audio: {input: false, output: false}, 133 | video: {input: false, output: false}, 134 | }, 135 | price: {input: 0.0000001500, output: 0.0000001500}, 136 | }, 137 | { 138 | id: `${this.id}/codestral-latest`, 139 | name: 'Codestral', 140 | description: `State-of-the-art Mistral model trained specifically for code tasks`, 141 | architecture: 'MistralForCausalLM', 142 | capabilities: { 143 | embedding: false, 144 | tool_call: true, 145 | rerank: false, 146 | features: [], 147 | size: {vocab: 32768, embedding: 6144, input: 32768, output: 0}, 148 | text: {input: true, output: true}, 149 | image: {input: false, output: false}, 150 | audio: {input: false, output: false}, 151 | video: {input: false, output: false}, 152 | }, 153 | price: {input: 0.0000003000, output: 0.0000009000}, 154 | }, 155 | { 156 | id: `${this.id}/mistral-small-latest`, 157 | name: 'Mistral Small', 158 | description: `Cost-efficient, fast, and reliable option for use cases such as translation, summarization, and sentiment analysis.`, 159 | architecture: 'MistralForCausalLM', 160 | capabilities: { 161 | embedding: false, 162 | tool_call: true, 163 | rerank: false, 164 | features: [], 165 | size: {vocab: 32768, embedding: 6144, input: 32768, output: 0}, 166 | text: {input: true, output: true}, 167 | image: {input: false, output: false}, 168 | audio: {input: false, output: false}, 169 | video: {input: false, output: false}, 170 | }, 171 | price: {input: 0.0000001000, output: 0.0000003000}, 172 | }, 173 | { 174 | id: `${this.id}/open-mixtral-8x22b`, 175 | name: 'Mixtral (8X22B)', 176 | description: `Official open-mixtral-8x22b Mistral AI model`, 177 | architecture: 'MixtralForCausalLM', 178 | capabilities: { 179 | embedding: false, 180 | tool_call: true, 181 | rerank: false, 182 | features: [], 183 | size: {vocab: 32000, embedding: 6144, input: 65536, output: 0}, 184 | text: {input: true, output: true}, 185 | image: {input: false, output: false}, 186 | audio: {input: false, output: false}, 187 | video: {input: false, output: false}, 188 | }, 189 | price: {input: 0.0000020000, output: 0.0000060000}, 190 | }, 191 | { 192 | id: `${this.id}/open-mixtral-8x7b`, 193 | name: 'Mixtral (8X7B)', 194 | description: `Official open-mixtral-8x7b Mistral AI model`, 195 | architecture: 'MixtralForCausalLM', 196 | capabilities: { 197 | embedding: false, 198 | tool_call: true, 199 | rerank: false, 200 | features: [], 201 | size: {vocab: 32000, embedding: 4096, input: 32768, output: 0}, 202 | text: {input: true, output: true}, 203 | image: {input: false, output: false}, 204 | audio: {input: false, output: false}, 205 | video: {input: false, output: false}, 206 | }, 207 | price: {input: 0.0000007000, output: 0.0000007000}, 208 | }, 209 | { 210 | id: `${this.id}/open-mistral-7b`, 211 | name: 'Mistral (7B)', 212 | description: `Official open-mistral-7b Mistral AI model`, 213 | architecture: 'MistralForCausalLM', 214 | capabilities: { 215 | embedding: false, 216 | tool_call: true, 217 | rerank: false, 218 | features: [], 219 | size: {vocab: 32000, embedding: 4096, input: 32768, output: 0}, 220 | text: {input: true, output: true}, 221 | image: {input: false, output: false}, 222 | audio: {input: false, output: false}, 223 | video: {input: false, output: false}, 224 | }, 225 | price: {input: 0.0000002500, output: 0.0000002500}, 226 | }, 227 | { 228 | id: `${this.id}/mistral-embed`, 229 | name: 'Mistral Embed', 230 | description: `State-of-the-art semantic for extracting representation of text extracts.`, 231 | architecture: '', 232 | capabilities: { 233 | embedding: false, 234 | tool_call: true, 235 | rerank: false, 236 | features: [], 237 | size: {vocab: 0, embedding: 1024, input: 8192, output: 0}, 238 | text: {input: true, output: true}, 239 | image: {input: false, output: false}, 240 | audio: {input: false, output: false}, 241 | video: {input: false, output: false}, 242 | }, 243 | price: {input: 0.0000001000, output: 0.0000000000}, 244 | }, 245 | ]; 246 | default = { 247 | baseURL: 'https://api.mistral.ai/v1', 248 | pricingURL: 'https://mistral.ai/technology', 249 | manageAPIKeysURL: 'https://console.mistral.ai/api-keys/', 250 | model: 'open-mistral-7b', 251 | }; 252 | 253 | create(init: RequestInit = {}): MistralProvider { 254 | return createMistral({baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}); 255 | } 256 | 257 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 258 | return this.create(init)(model); 259 | } 260 | 261 | embeddingModel(model: string, init: RequestInit = {}): EmbeddingModel { 262 | return this.create(init).textEmbeddingModel(model); 263 | } 264 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 - present ChikiChat Authors 2 | 3 | Apache License 4 | Version 2.0, January 2004 5 | http://www.apache.org/licenses/ 6 | 7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | "License" shall mean the terms and conditions for use, reproduction, 12 | and distribution as defined by Sections 1 through 9 of this document. 13 | 14 | "Licensor" shall mean the copyright owner or entity authorized by 15 | the copyright owner that is granting the License. 16 | 17 | "Legal Entity" shall mean the union of the acting entity and all 18 | other entities that control, are controlled by, or are under common 19 | control with that entity. For the purposes of this definition, 20 | "control" means (i) the power, direct or indirect, to cause the 21 | direction or management of such entity, whether by contract or 22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 23 | outstanding shares, or (iii) beneficial ownership of such entity. 24 | 25 | "You" (or "Your") shall mean an individual or Legal Entity 26 | exercising permissions granted by this License. 27 | 28 | "Source" form shall mean the preferred form for making modifications, 29 | including but not limited to software source code, documentation 30 | source, and configuration files. 31 | 32 | "Object" form shall mean any form resulting from mechanical 33 | transformation or translation of a Source form, including but 34 | not limited to compiled object code, generated documentation, 35 | and conversions to other media types. 36 | 37 | "Work" shall mean the work of authorship, whether in Source or 38 | Object form, made available under the License, as indicated by a 39 | copyright notice that is included in or attached to the work 40 | (an example is provided in the Appendix below). 41 | 42 | "Derivative Works" shall mean any work, whether in Source or Object 43 | form, that is based on (or derived from) the Work and for which the 44 | editorial revisions, annotations, elaborations, or other modifications 45 | represent, as a whole, an original work of authorship. For the purposes 46 | of this License, Derivative Works shall not include works that remain 47 | separable from, or merely link (or bind by name) to the interfaces of, 48 | the Work and Derivative Works thereof. 49 | 50 | "Contribution" shall mean any work of authorship, including 51 | the original version of the Work and any modifications or additions 52 | to that Work or Derivative Works thereof, that is intentionally 53 | submitted to Licensor for inclusion in the Work by the copyright owner 54 | or by an individual or Legal Entity authorized to submit on behalf of 55 | the copyright owner. For the purposes of this definition, "submitted" 56 | means any form of electronic, verbal, or written communication sent 57 | to the Licensor or its representatives, including but not limited to 58 | communication on electronic mailing lists, source code control systems, 59 | and issue tracking systems that are managed by, or on behalf of, the 60 | Licensor for the purpose of discussing and improving the Work, but 61 | excluding communication that is conspicuously marked or otherwise 62 | designated in writing by the copyright owner as "Not a Contribution." 63 | 64 | "Contributor" shall mean Licensor and any individual or Legal Entity 65 | on behalf of whom a Contribution has been received by Licensor and 66 | subsequently incorporated within the Work. 67 | 68 | 2. Grant of Copyright License. Subject to the terms and conditions of 69 | this License, each Contributor hereby grants to You a perpetual, 70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 71 | copyright license to reproduce, prepare Derivative Works of, 72 | publicly display, publicly perform, sublicense, and distribute the 73 | Work and such Derivative Works in Source or Object form. 74 | 75 | 3. Grant of Patent License. Subject to the terms and conditions of 76 | this License, each Contributor hereby grants to You a perpetual, 77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 78 | (except as stated in this section) patent license to make, have made, 79 | use, offer to sell, sell, import, and otherwise transfer the Work, 80 | where such license applies only to those patent claims licensable 81 | by such Contributor that are necessarily infringed by their 82 | Contribution(s) alone or by combination of their Contribution(s) 83 | with the Work to which such Contribution(s) was submitted. If You 84 | institute patent litigation against any entity (including a 85 | cross-claim or counterclaim in a lawsuit) alleging that the Work 86 | or a Contribution incorporated within the Work constitutes direct 87 | or contributory patent infringement, then any patent licenses 88 | granted to You under this License for that Work shall terminate 89 | as of the date such litigation is filed. 90 | 91 | 4. Redistribution. You may reproduce and distribute copies of the 92 | Work or Derivative Works thereof in any medium, with or without 93 | modifications, and in Source or Object form, provided that You 94 | meet the following conditions: 95 | 96 | (a) You must give any other recipients of the Work or 97 | Derivative Works a copy of this License; and 98 | 99 | (b) You must cause any modified files to carry prominent notices 100 | stating that You changed the files; and 101 | 102 | (c) You must retain, in the Source form of any Derivative Works 103 | that You distribute, all copyright, patent, trademark, and 104 | attribution notices from the Source form of the Work, 105 | excluding those notices that do not pertain to any part of 106 | the Derivative Works; and 107 | 108 | (d) If the Work includes a "NOTICE" text file as part of its 109 | distribution, then any Derivative Works that You distribute must 110 | include a readable copy of the attribution notices contained 111 | within such NOTICE file, excluding those notices that do not 112 | pertain to any part of the Derivative Works, in at least one 113 | of the following places: within a NOTICE text file distributed 114 | as part of the Derivative Works; within the Source form or 115 | documentation, if provided along with the Derivative Works; or, 116 | within a display generated by the Derivative Works, if and 117 | wherever such third-party notices normally appear. The contents 118 | of the NOTICE file are for informational purposes only and 119 | do not modify the License. You may add Your own attribution 120 | notices within Derivative Works that You distribute, alongside 121 | or as an addendum to the NOTICE text from the Work, provided 122 | that such additional attribution notices cannot be construed 123 | as modifying the License. 124 | 125 | You may add Your own copyright statement to Your modifications and 126 | may provide additional or different license terms and conditions 127 | for use, reproduction, or distribution of Your modifications, or 128 | for any such Derivative Works as a whole, provided Your use, 129 | reproduction, and distribution of the Work otherwise complies with 130 | the conditions stated in this License. 131 | 132 | 5. Submission of Contributions. Unless You explicitly state otherwise, 133 | any Contribution intentionally submitted for inclusion in the Work 134 | by You to the Licensor shall be under the terms and conditions of 135 | this License, without any additional terms or conditions. 136 | Notwithstanding the above, nothing herein shall supersede or modify 137 | the terms of any separate license agreement you may have executed 138 | with Licensor regarding such Contributions. 139 | 140 | 6. Trademarks. This License does not grant permission to use the trade 141 | names, trademarks, service marks, or product names of the Licensor, 142 | except as required for reasonable and customary use in describing the 143 | origin of the Work and reproducing the content of the NOTICE file. 144 | 145 | 7. Disclaimer of Warranty. Unless required by applicable law or 146 | agreed to in writing, Licensor provides the Work (and each 147 | Contributor provides its Contributions) on an "AS IS" BASIS, 148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 149 | implied, including, without limitation, any warranties or conditions 150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 151 | PARTICULAR PURPOSE. You are solely responsible for determining the 152 | appropriateness of using or redistributing the Work and assume any 153 | risks associated with Your exercise of permissions under this License. 154 | 155 | 8. Limitation of Liability. In no event and under no legal theory, 156 | whether in tort (including negligence), contract, or otherwise, 157 | unless required by applicable law (such as deliberate and grossly 158 | negligent acts) or agreed to in writing, shall any Contributor be 159 | liable to You for damages, including any direct, indirect, special, 160 | incidental, or consequential damages of any character arising as a 161 | result of this License or out of the use or inability to use the 162 | Work (including but not limited to damages for loss of goodwill, 163 | work stoppage, computer failure or malfunction, or any and all 164 | other commercial damages or losses), even if such Contributor 165 | has been advised of the possibility of such damages. 166 | 167 | 9. Accepting Warranty or Additional Liability. While redistributing 168 | the Work or Derivative Works thereof, You may choose to offer, 169 | and charge a fee for, acceptance of support, warranty, indemnity, 170 | or other liability obligations and/or rights consistent with this 171 | License. However, in accepting such obligations, You may act only 172 | on Your own behalf and on Your sole responsibility, not on behalf 173 | of any other Contributor, and only if You agree to indemnify, 174 | defend, and hold each Contributor harmless for any liability 175 | incurred by, or claims asserted against, such Contributor by reason 176 | of your accepting any such warranty or additional liability. 177 | 178 | END OF TERMS AND CONDITIONS 179 | 180 | APPENDIX: How to apply the Apache License to your work. 181 | 182 | To apply the Apache License to your work, attach the following 183 | boilerplate notice, with the fields enclosed by brackets "[]" 184 | replaced with your own identifying information. (Don't include 185 | the brackets!) The text should be enclosed in the appropriate 186 | comment syntax for the file format. We also recommend that a 187 | file or class name and description of purpose be included on the 188 | same "printed page" as the copyright notice for easier 189 | identification within third-party archives. 190 | 191 | Copyright [yyyy] [name of copyright owner] 192 | 193 | Licensed under the Apache License, Version 2.0 (the "License"); 194 | you may not use this file except in compliance with the License. 195 | You may obtain a copy of the License at 196 | 197 | http://www.apache.org/licenses/LICENSE-2.0 198 | 199 | Unless required by applicable law or agreed to in writing, software 200 | distributed under the License is distributed on an "AS IS" BASIS, 201 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 202 | See the License for the specific language governing permissions and 203 | limitations under the License. 204 | -------------------------------------------------------------------------------- /packages/model/src/providers/SambaNova/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createOpenAI, OpenAIProvider} from "@ai-sdk/openai"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class SambaNova extends Provider { 7 | id = 'sambanova'; 8 | name = 'SambaNova'; 9 | description = `SambaNova is a leading enterprise AI company specializing in advanced AI platforms.`; 10 | models = [ 11 | { 12 | id: `${this.id}/DeepSeek-R1`, 13 | name: 'DeepSeek R1', 14 | description: '', 15 | architecture: 'DeepseekV3ForCausalLM', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: false, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 129280, embedding: 7168, input: 16384, output: 4096}, 22 | text: {input: true, output: true}, 23 | image: {input: true, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000050000, output: 0.0000070000}, 28 | }, 29 | { 30 | id: `${this.id}/DeepSeek-R1-Distill-Llama-70B`, 31 | name: 'DeepSeek (70B) R1 Distill Llama', 32 | description: '', 33 | architecture: 'LlamaForCausalLM', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: false, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 128256, embedding: 8192, input: 131072, output: 4096}, 40 | text: {input: true, output: true}, 41 | image: {input: true, output: false}, 42 | audio: {input: false, output: false}, 43 | video: {input: false, output: false}, 44 | }, 45 | price: {input: 0.0000007000, output: 0.0000014000}, 46 | }, 47 | { 48 | id: `${this.id}/Qwen3-32B`, 49 | name: 'Qwen 3 (32B)', 50 | description: '', 51 | architecture: 'Qwen3ForCausalLM', 52 | capabilities: { 53 | embedding: false, 54 | tool_call: true, 55 | rerank: false, 56 | features: [], 57 | size: {vocab: 151936, embedding: 5120, input: 40960, output: 4096}, 58 | text: {input: true, output: true}, 59 | image: {input: false, output: false}, 60 | audio: {input: false, output: false}, 61 | video: {input: false, output: false}, 62 | }, 63 | price: {input: 0.0000004000, output: 0.0000008000}, 64 | }, 65 | { 66 | id: `${this.id}/QwQ-32B`, 67 | name: 'QwQ (32B) ', 68 | description: '', 69 | architecture: 'Qwen2ForCausalLM', 70 | capabilities: { 71 | embedding: false, 72 | tool_call: false, 73 | rerank: false, 74 | features: [], 75 | size: {vocab: 152064, embedding: 5120, input: 16384, output: 4096}, 76 | text: {input: true, output: true}, 77 | image: {input: true, output: false}, 78 | audio: {input: false, output: false}, 79 | video: {input: false, output: false}, 80 | }, 81 | price: {input: 0.0000005000, output: 0.0000010000}, 82 | }, 83 | { 84 | id: `${this.id}/DeepSeek-V3-0324`, 85 | name: 'DeepSeek V3', 86 | description: '', 87 | architecture: 'DeepseekV3ForCausalLM', 88 | capabilities: { 89 | embedding: false, 90 | tool_call: false, 91 | rerank: false, 92 | features: [], 93 | size: {vocab: 129280, embedding: 7168, input: 16384, output: 4096}, 94 | text: {input: true, output: true}, 95 | image: {input: true, output: false}, 96 | audio: {input: false, output: false}, 97 | video: {input: false, output: false}, 98 | }, 99 | price: {input: 0.0000010000, output: 0.0000015000}, 100 | }, 101 | { 102 | id: `${this.id}/Llama-4-Maverick-17B-128E-Instruct`, 103 | name: 'LLaMA 4 (128x17B) Maverick', 104 | description: '', 105 | architecture: 'Llama4ForConditionalGeneration', 106 | capabilities: { 107 | embedding: false, 108 | tool_call: false, 109 | rerank: false, 110 | features: [], 111 | size: {vocab: 202048, embedding: 5120, input: 8192, output: 4096}, 112 | text: {input: true, output: true}, 113 | image: {input: true, output: false}, 114 | audio: {input: false, output: false}, 115 | video: {input: false, output: false}, 116 | }, 117 | price: {input: 0.0000006300, output: 0.0000018000}, 118 | }, 119 | { 120 | id: `${this.id}/Llama-4-Scout-17B-16E-Instruct`, 121 | name: 'LLaMA 4 (16x17B) Scout', 122 | description: '', 123 | architecture: 'Llama4ForConditionalGeneration', 124 | capabilities: { 125 | embedding: false, 126 | tool_call: false, 127 | rerank: false, 128 | features: [], 129 | size: {vocab: 202048, embedding: 5120, input: 8192, output: 4096}, 130 | text: {input: true, output: true}, 131 | image: {input: true, output: false}, 132 | audio: {input: false, output: false}, 133 | video: {input: false, output: false}, 134 | }, 135 | price: {input: 0.0000004000, output: 0.0000007000}, 136 | }, 137 | { 138 | id: `${this.id}/Meta-Llama-3.3-70B-Instruct`, 139 | name: 'LLaMa 3.3 (70B)', 140 | description: '', 141 | architecture: 'LlamaForCausalLM', 142 | capabilities: { 143 | embedding: false, 144 | tool_call: true, 145 | rerank: false, 146 | features: [], 147 | size: {vocab: 128256, embedding: 8192, input: 131072, output: 3072}, 148 | text: {input: true, output: true}, 149 | image: {input: true, output: false}, 150 | audio: {input: false, output: false}, 151 | video: {input: false, output: false}, 152 | }, 153 | price: {input: 0.0000006000, output: 0.0000012000}, 154 | }, 155 | { 156 | id: `${this.id}/Meta-Llama-3.2-3B-Instruct`, 157 | name: 'LLaMa 3.2 (3B)', 158 | description: '', 159 | architecture: 'LlamaForCausalLM', 160 | capabilities: { 161 | embedding: false, 162 | tool_call: false, 163 | rerank: false, 164 | features: [], 165 | size: {vocab: 128256, embedding: 3072, input: 8192, output: 4096}, 166 | text: {input: true, output: true}, 167 | image: {input: false, output: false}, 168 | audio: {input: false, output: false}, 169 | video: {input: false, output: false}, 170 | }, 171 | price: {input: 0.0000000800, output: 0.0000001600}, 172 | }, 173 | { 174 | id: `${this.id}/Meta-Llama-3.2-1B-Instruct`, 175 | name: 'LLaMa 3.2 (1B)', 176 | description: '', 177 | architecture: 'LlamaForCausalLM', 178 | capabilities: { 179 | embedding: false, 180 | tool_call: false, 181 | rerank: false, 182 | features: [], 183 | size: {vocab: 128256, embedding: 2048, input: 16384, output: 4096}, 184 | text: {input: true, output: true}, 185 | image: {input: false, output: false}, 186 | audio: {input: false, output: false}, 187 | video: {input: false, output: false}, 188 | }, 189 | price: {input: 0.0000000400, output: 0.0000000800}, 190 | }, 191 | { 192 | id: `${this.id}/Meta-Llama-3.1-405B-Instruct`, 193 | name: 'LLaMa 3.1 (405B) Instruct', 194 | description: '', 195 | architecture: 'LlamaForCausalLM', 196 | capabilities: { 197 | embedding: false, 198 | tool_call: true, 199 | rerank: false, 200 | features: [], 201 | size: {vocab: 128256, embedding: 16384, input: 16384, output: 4096}, 202 | text: {input: true, output: true}, 203 | image: {input: false, output: false}, 204 | audio: {input: false, output: false}, 205 | video: {input: false, output: false}, 206 | }, 207 | price: {input: 0.0000050000, output: 0.0000100000}, 208 | }, 209 | { 210 | id: `${this.id}/Meta-Llama-3.1-8B-Instruct`, 211 | name: 'LLaMa 3.1 (8B) Instruct', 212 | description: '', 213 | architecture: 'LlamaForCausalLM', 214 | capabilities: { 215 | embedding: false, 216 | tool_call: true, 217 | rerank: false, 218 | features: [], 219 | size: {vocab: 128256, embedding: 4096, input: 16384, output: 4096}, 220 | text: {input: true, output: true}, 221 | image: {input: false, output: false}, 222 | audio: {input: false, output: false}, 223 | video: {input: false, output: false}, 224 | }, 225 | price: {input: 0.0000001000, output: 0.0000002000}, 226 | }, 227 | { 228 | id: `${this.id}/Meta-Llama-Guard-3-8B`, 229 | name: 'LLaMa (8B) Guard', 230 | description: '', 231 | architecture: 'LlamaForCausalLM', 232 | capabilities: { 233 | embedding: false, 234 | tool_call: false, 235 | rerank: false, 236 | features: [], 237 | size: {vocab: 128256, embedding: 4096, input: 16384, output: 4096}, 238 | text: {input: true, output: true}, 239 | image: {input: false, output: false}, 240 | audio: {input: false, output: false}, 241 | video: {input: false, output: false}, 242 | }, 243 | price: {input: 0.0000003000, output: 0.0000003000}, 244 | }, 245 | { 246 | id: `${this.id}/E5-Mistral-7B-Instruct`, 247 | name: 'E5 Mistral (7B) Instruct', 248 | description: '', 249 | architecture: 'MistralModel', 250 | capabilities: { 251 | embedding: true, 252 | tool_call: false, 253 | rerank: false, 254 | features: [], 255 | size: {vocab: 32000, embedding: 4096, input: 4096, output: 0}, 256 | text: {input: true, output: false}, 257 | image: {input: false, output: false}, 258 | audio: {input: false, output: false}, 259 | video: {input: false, output: false}, 260 | }, 261 | price: {input: 0.0000001300, output: 0.0000000000}, 262 | }, 263 | ]; 264 | default = { 265 | baseURL: 'https://api.sambanova.ai/v1', 266 | pricingURL: 'https://cloud.sambanova.ai/pricing', 267 | manageAPIKeysURL: 'https://cloud.sambanova.ai/apis', 268 | model: `Llama-3.2-1B-Instruct`, 269 | }; 270 | 271 | create(init: RequestInit = {}): OpenAIProvider { 272 | return createOpenAI({name: this.name, baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}); 273 | } 274 | 275 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 276 | return this.create(init)(model); 277 | } 278 | 279 | embeddingModel(model: string, init: RequestInit = {}): EmbeddingModel { 280 | return this.create(init).embedding(model) 281 | } 282 | } -------------------------------------------------------------------------------- /packages/model/src/providers/Groq/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createGroq, GroqProvider} from "@ai-sdk/groq"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class Groq extends Provider { 7 | id = 'groq'; 8 | name = 'Groq'; 9 | description = `The LPU™ Inference Engine by Groq is a hardware and software platform that delivers exceptional compute speed, quality, and energy efficiency.`; 10 | models = [ 11 | { 12 | id: `${this.id}/deepseek-r1-distill-llama-70b`, 13 | name: 'DeepSeek R1 (70B) Distill LLaMA', 14 | description: '', 15 | architecture: 'LlamaForCausalLM', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: true, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 128256, embedding: 8192, input: 131072, output: 131072}, 22 | text: {input: true, output: true}, 23 | image: {input: false, output: false}, 24 | audio: {input: false, output: false}, 25 | video: {input: false, output: false}, 26 | }, 27 | price: {input: 0.0000007500, output: 0.0000009900}, 28 | }, 29 | { 30 | id: `${this.id}/qwen-qwq-32b`, 31 | name: 'Qwen (32B) QwQ', 32 | description: '', 33 | architecture: 'Qwen2ForCausalLM', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: true, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 152064, embedding: 5120, input: 131072, output: 131072}, 40 | text: {input: true, output: true}, 41 | image: {input: false, output: false}, 42 | audio: {input: false, output: false}, 43 | video: {input: false, output: false}, 44 | }, 45 | price: {input: 0.0000002900, output: 0.0000003900}, 46 | }, 47 | { 48 | id: `${this.id}/gemma2-9b-it`, 49 | name: 'Gemma 2 (9B) Instruct', 50 | description: ``, 51 | architecture: 'Gemma2ForCausalLM', 52 | capabilities: { 53 | embedding: false, 54 | tool_call: true, 55 | rerank: false, 56 | features: [], 57 | size: {vocab: 256000, embedding: 3584, input: 8192, output: 8192}, 58 | text: {input: true, output: true}, 59 | image: {input: false, output: false}, 60 | audio: {input: false, output: false}, 61 | video: {input: false, output: false}, 62 | }, 63 | price: {input: 0.0000002000, output: 0.0000002000}, 64 | }, 65 | { 66 | id: `${this.id}/meta-llama/llama-4-maverick-17b-128e-instruct`, 67 | name: 'LLaMA 4 (128x17B) Maverick', 68 | description: ``, 69 | architecture: 'Llama4ForConditionalGeneration', 70 | capabilities: { 71 | embedding: false, 72 | tool_call: true, 73 | rerank: false, 74 | features: [], 75 | size: {vocab: 202048, embedding: 5120, input: 131072, output: 8192}, 76 | text: {input: true, output: true}, 77 | image: {input: false, output: false}, 78 | audio: {input: false, output: false}, 79 | video: {input: false, output: false}, 80 | }, 81 | price: {input: 0.0000002000, output: 0.0000006000}, 82 | }, 83 | { 84 | id: `${this.id}/meta-llama/llama-4-scout-17b-16e-instruct`, 85 | name: 'LLaMA 4 (16x17B) Scout', 86 | description: ``, 87 | architecture: 'Llama4ForConditionalGeneration', 88 | capabilities: { 89 | embedding: false, 90 | tool_call: true, 91 | rerank: false, 92 | features: [], 93 | size: {vocab: 202048, embedding: 5120, input: 131072, output: 8192}, 94 | text: {input: true, output: true}, 95 | image: {input: false, output: false}, 96 | audio: {input: false, output: false}, 97 | video: {input: false, output: false}, 98 | }, 99 | price: {input: 0.0000001100, output: 0.0000003400}, 100 | }, 101 | { 102 | id: `${this.id}/llama-3.3-70b-versatile`, 103 | name: 'LLaMA 3.3 (70B) Versatile', 104 | description: ``, 105 | architecture: 'LlamaForCausalLM', 106 | capabilities: { 107 | embedding: false, 108 | tool_call: true, 109 | rerank: false, 110 | features: [], 111 | size: {vocab: 128256, embedding: 8192, input: 131072, output: 32768}, 112 | text: {input: true, output: true}, 113 | image: {input: false, output: false}, 114 | audio: {input: false, output: false}, 115 | video: {input: false, output: false}, 116 | }, 117 | price: {input: 0.0000005900, output: 0.0000007900}, 118 | }, 119 | { 120 | id: `${this.id}/llama-3.1-8b-instant`, 121 | name: 'LLaMA 3.1 (8B) Instant', 122 | description: '', 123 | architecture: 'LlamaForCausalLM', 124 | capabilities: { 125 | embedding: false, 126 | tool_call: true, 127 | rerank: false, 128 | features: [], 129 | size: {vocab: 128256, embedding: 4096, input: 131072, output: 131072}, 130 | text: {input: true, output: true}, 131 | image: {input: false, output: false}, 132 | audio: {input: false, output: false}, 133 | video: {input: false, output: false}, 134 | }, 135 | price: {input: 0.0000000500, output: 0.0000000800}, 136 | }, 137 | { 138 | id: `${this.id}/llama3-70b-8192`, 139 | name: 'LLaMA 3 (70B)', 140 | description: '', 141 | architecture: 'LlamaForCausalLM', 142 | capabilities: { 143 | embedding: false, 144 | tool_call: false, 145 | rerank: false, 146 | features: [], 147 | size: {vocab: 128256, embedding: 8192, input: 8192, output: 8192}, 148 | text: {input: true, output: true}, 149 | image: {input: false, output: false}, 150 | audio: {input: false, output: false}, 151 | video: {input: false, output: false}, 152 | }, 153 | price: {input: 0.0000005900, output: 0.0000007900}, 154 | }, 155 | { 156 | id: `${this.id}/llama3-8b-8192`, 157 | name: 'LLaMA 3 (8B)', 158 | description: '', 159 | architecture: 'LlamaForCausalLM', 160 | capabilities: { 161 | embedding: false, 162 | tool_call: false, 163 | rerank: false, 164 | features: [], 165 | size: {vocab: 128256, embedding: 4096, input: 8192, output: 8192}, 166 | text: {input: true, output: true}, 167 | image: {input: false, output: false}, 168 | audio: {input: false, output: false}, 169 | video: {input: false, output: false}, 170 | }, 171 | price: {input: 0.0000000500, output: 0.0000000800}, 172 | }, 173 | { 174 | id: `${this.id}/llama-guard-3-8b`, 175 | name: 'LLaMA Guard 3 (8B)', 176 | description: '', 177 | architecture: 'LlamaForCausalLM', 178 | capabilities: { 179 | embedding: false, 180 | tool_call: false, 181 | rerank: false, 182 | features: [], 183 | size: {vocab: 128256, embedding: 4096, input: 8192, output: 8192}, 184 | text: {input: true, output: true}, 185 | image: {input: false, output: false}, 186 | audio: {input: false, output: false}, 187 | video: {input: false, output: false}, 188 | }, 189 | price: {input: 0.0000002000, output: 0.0000002000}, 190 | }, 191 | { 192 | id: `${this.id}/mistral-saba-24b`, 193 | name: 'Mistral (24B) Saba', 194 | description: '', 195 | architecture: '', 196 | capabilities: { 197 | embedding: false, 198 | tool_call: false, 199 | rerank: false, 200 | features: [], 201 | size: {vocab: 32000, embedding: 4096, input: 32768, output: 32768}, 202 | text: {input: true, output: true}, 203 | image: {input: false, output: false}, 204 | audio: {input: false, output: false}, 205 | video: {input: false, output: false}, 206 | }, 207 | price: {input: 0.0000007900, output: 0.0000007900}, 208 | }, 209 | { 210 | id: `${this.id}/whisper-large-v3-turbo`, 211 | name: 'Whisper Large V3 Turbo', 212 | description: '', 213 | architecture: 'WhisperForConditionalGeneration', 214 | capabilities: { 215 | embedding: false, 216 | tool_call: false, 217 | rerank: false, 218 | features: [], 219 | size: {vocab: 51866, embedding: 0, input: 0, output: 448}, 220 | text: {input: false, output: true}, 221 | image: {input: false, output: false}, 222 | audio: {input: true, output: false}, 223 | video: {input: false, output: false}, 224 | }, 225 | price: {input: 0.0000000000, output: 0.0400000000}, 226 | }, 227 | { 228 | id: `${this.id}/whisper-large-v3`, 229 | name: 'Whisper Large V3', 230 | description: '', 231 | architecture: 'WhisperForConditionalGeneration', 232 | capabilities: { 233 | embedding: false, 234 | tool_call: false, 235 | rerank: false, 236 | features: [], 237 | size: {vocab: 51866, embedding: 0, input: 0, output: 448}, 238 | text: {input: false, output: true}, 239 | image: {input: false, output: false}, 240 | audio: {input: true, output: false}, 241 | video: {input: false, output: false}, 242 | }, 243 | price: {input: 0.0000000000, output: 0.1110000000}, 244 | }, 245 | { 246 | id: `${this.id}/distil-whisper-large-v3-en`, 247 | name: 'Distil Whisper Large V3 En', 248 | description: '', 249 | architecture: 'WhisperForConditionalGeneration', 250 | capabilities: { 251 | embedding: false, 252 | tool_call: false, 253 | rerank: false, 254 | features: [], 255 | size: {vocab: 51866, embedding: 0, input: 0, output: 448}, 256 | text: {input: false, output: true}, 257 | image: {input: false, output: false}, 258 | audio: {input: true, output: false}, 259 | video: {input: false, output: false}, 260 | }, 261 | price: {input: 0.0000000000, output: 0.0200000000}, 262 | }, 263 | ]; 264 | default = { 265 | baseURL: 'https://api.groq.com/openai/v1', 266 | pricingURL: 'https://groq.com/pricing', 267 | manageAPIKeysURL: 'https://console.groq.com/keys', 268 | model: 'llama-3.1-8b-instant', 269 | }; 270 | 271 | create(init: RequestInit = {}): GroqProvider { 272 | return createGroq({baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}); 273 | } 274 | 275 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 276 | return this.create(init)(model); 277 | } 278 | 279 | embeddingModel(_model: string, _init: RequestInit = {}): EmbeddingModel { 280 | throw new Error(`Provider ${this.name} does not support embeddings`); 281 | } 282 | } -------------------------------------------------------------------------------- /packages/model/src/providers/GoogleGenerativeAI/index.ts: -------------------------------------------------------------------------------- 1 | import {EmbeddingModel, LanguageModel} from "ai"; 2 | import {createGoogleGenerativeAI, GoogleGenerativeAIProvider} from "@ai-sdk/google"; 3 | import {Provider} from '../provider'; 4 | import {RequestInit} from "../../types"; 5 | 6 | export class GoogleGenerativeAI extends Provider { 7 | id = 'google-generative-ai'; 8 | name = 'Google Generative AI'; 9 | description = `Create, discover, summarize and automate with Google Cloud's generative AI products and services`; 10 | models = [ 11 | { 12 | id: `${this.id}/gemini-2.5-pro-preview-05-06`, 13 | name: 'Gemini 2.5 Pro Preview 05-06', 14 | description: `State-of-the-art multipurpose model, which excels at coding and complex reasoning tasks`, 15 | architecture: '', 16 | capabilities: { 17 | embedding: false, 18 | tool_call: true, 19 | rerank: false, 20 | features: [], 21 | size: {vocab: 0, embedding: 0, input: 1048576, output: 65536}, 22 | text: {input: true, output: true}, 23 | image: {input: true, output: false}, 24 | audio: {input: true, output: false}, 25 | video: {input: true, output: false}, 26 | }, 27 | price: {input: 0.0000012500, output: 0.0000100000}, 28 | }, 29 | { 30 | id: `${this.id}/gemini-2.5-flash-preview-04-17`, 31 | name: 'Gemini 2.5 Flash Preview 04-17', 32 | description: `State-of-the-art multipurpose model, which excels at coding and complex reasoning tasks`, 33 | architecture: '', 34 | capabilities: { 35 | embedding: false, 36 | tool_call: true, 37 | rerank: false, 38 | features: [], 39 | size: {vocab: 0, embedding: 0, input: 1048576, output: 65536}, 40 | text: {input: true, output: true}, 41 | image: {input: true, output: false}, 42 | audio: {input: true, output: false}, 43 | video: {input: true, output: false}, 44 | }, 45 | price: {input: 0.0000001500, output: 0.0000035000}, 46 | }, 47 | { 48 | id: `${this.id}/gemini-2.0-flash`, 49 | name: 'Gemini 2.0 Flash', 50 | description: `Most capable multi-modal model with great performance across all tasks, with a 1 million token context window, and built for the era of Agents`, 51 | architecture: '', 52 | capabilities: { 53 | embedding: false, 54 | tool_call: true, 55 | rerank: false, 56 | features: [], 57 | size: {vocab: 0, embedding: 0, input: 1048576, output: 8192}, 58 | text: {input: true, output: true}, 59 | image: {input: true, output: false}, 60 | audio: {input: true, output: false}, 61 | video: {input: true, output: false}, 62 | }, 63 | price: {input: 0.0000001000, output: 0.0000004000}, 64 | }, 65 | { 66 | id: `${this.id}/gemini-2.0-flash-lite`, 67 | name: 'Gemini 2.0 Flash-Lite', 68 | description: `Smallest and most cost effective model, built for at scale usage`, 69 | architecture: '', 70 | capabilities: { 71 | embedding: false, 72 | tool_call: true, 73 | rerank: false, 74 | features: [], 75 | size: {vocab: 0, embedding: 0, input: 1048576, output: 8192}, 76 | text: {input: true, output: true}, 77 | image: {input: true, output: false}, 78 | audio: {input: true, output: false}, 79 | video: {input: true, output: false}, 80 | }, 81 | price: {input: 0.0000000750, output: 0.0000003000}, 82 | }, 83 | { 84 | id: `${this.id}/gemini-2.0-flash-thinking-exp-01-21`, 85 | name: 'Gemini 2.0 Flash Thinking Experimental 01-21', 86 | description: `Gemini 2.0 Flash Thinking Mode is an experimental model that's trained to generate the "thinking process" the model goes through as part of its response`, 87 | architecture: '', 88 | capabilities: { 89 | embedding: false, 90 | tool_call: false, 91 | rerank: false, 92 | features: [], 93 | size: {vocab: 0, embedding: 0, input: 1048576, output: 65536}, 94 | text: {input: true, output: true}, 95 | image: {input: true, output: false}, 96 | audio: {input: true, output: false}, 97 | video: {input: true, output: false}, 98 | }, 99 | price: {input: 0.0000000000, output: 0.0000000000}, 100 | }, 101 | { 102 | id: `${this.id}/gemini-1.5-flash`, 103 | name: 'Gemini 1.5 Flash', 104 | description: `Fastest multimodal model with great performance for diverse, repetitive tasks and a 1 million token context window`, 105 | architecture: '', 106 | capabilities: { 107 | embedding: false, 108 | tool_call: true, 109 | rerank: false, 110 | features: [], 111 | size: {vocab: 0, embedding: 0, input: 1000000, output: 8192}, 112 | text: {input: true, output: true}, 113 | image: {input: true, output: false}, 114 | audio: {input: true, output: false}, 115 | video: {input: true, output: false}, 116 | }, 117 | price: {input: 0.0000000750, output: 0.0000003000}, 118 | }, 119 | { 120 | id: `${this.id}/gemini-1.5-flash-8b`, 121 | name: 'Gemini 1.5 Flash-8B', 122 | description: `Smallest model for lower intelligence use cases, with a 1 million token context window`, 123 | architecture: '', 124 | capabilities: { 125 | embedding: false, 126 | tool_call: true, 127 | rerank: false, 128 | features: [], 129 | size: {vocab: 0, embedding: 0, input: 1000000, output: 8192}, 130 | text: {input: true, output: true}, 131 | image: {input: true, output: false}, 132 | audio: {input: true, output: false}, 133 | video: {input: true, output: false}, 134 | }, 135 | price: {input: 0.0000000375, output: 0.0000001500}, 136 | }, 137 | { 138 | id: `${this.id}/gemini-1.5-pro`, 139 | name: 'Gemini 1.5 Pro', 140 | description: `Highest intelligence Gemini 1.5 series model, with a breakthrough 2 million token context window`, 141 | architecture: '', 142 | capabilities: { 143 | embedding: false, 144 | tool_call: true, 145 | rerank: false, 146 | features: [], 147 | size: {vocab: 0, embedding: 0, input: 2000000, output: 8192}, 148 | text: {input: true, output: true}, 149 | image: {input: true, output: false}, 150 | audio: {input: true, output: false}, 151 | video: {input: true, output: false}, 152 | }, 153 | price: {input: 0.0000012500, output: 0.0000050000}, 154 | }, 155 | { 156 | id: `${this.id}/gemma-3-27b-it`, 157 | name: 'Gemma 3 (27B)', 158 | description: `Lightweight, state-of the art, open model built from the same technology that powers Gemini models`, 159 | architecture: 'Gemma3ForConditionalGeneration', 160 | capabilities: { 161 | embedding: false, 162 | tool_call: true, 163 | rerank: false, 164 | features: [], 165 | size: {vocab: 262144, embedding: 5376, input: 131072, output: 8192}, 166 | text: {input: true, output: true}, 167 | image: {input: false, output: false}, 168 | audio: {input: false, output: false}, 169 | video: {input: false, output: false}, 170 | }, 171 | price: {input: 0.0000000000, output: 0.0000000000}, 172 | }, 173 | { 174 | id: `${this.id}/gemma-3-12b-it`, 175 | name: 'Gemma 3 (12B)', 176 | description: `Lightweight, state-of the art, open model built from the same technology that powers Gemini models`, 177 | architecture: 'Gemma3ForConditionalGeneration', 178 | capabilities: { 179 | embedding: false, 180 | tool_call: true, 181 | rerank: false, 182 | features: [], 183 | size: {vocab: 262144, embedding: 3840, input: 32768, output: 8192}, 184 | text: {input: true, output: true}, 185 | image: {input: false, output: false}, 186 | audio: {input: false, output: false}, 187 | video: {input: false, output: false}, 188 | }, 189 | price: {input: 0.0000000000, output: 0.0000000000}, 190 | }, 191 | { 192 | id: `${this.id}/gemma-3-4b-it`, 193 | name: 'Gemma 3 (4B)', 194 | description: `Lightweight, state-of the art, open model built from the same technology that powers Gemini models`, 195 | architecture: 'Gemma3ForConditionalGeneration', 196 | capabilities: { 197 | embedding: false, 198 | tool_call: true, 199 | rerank: false, 200 | features: [], 201 | size: {vocab: 262144, embedding: 2560, input: 32768, output: 8192}, 202 | text: {input: true, output: true}, 203 | image: {input: false, output: false}, 204 | audio: {input: false, output: false}, 205 | video: {input: false, output: false}, 206 | }, 207 | price: {input: 0.0000000000, output: 0.0000000000}, 208 | }, 209 | { 210 | id: `${this.id}/gemma-3-1b-it`, 211 | name: 'Gemma 3 (1B)', 212 | description: `Lightweight, state-of the art, open model built from the same technology that powers Gemini models`, 213 | architecture: 'Gemma3ForCausalLM', 214 | capabilities: { 215 | embedding: false, 216 | tool_call: true, 217 | rerank: false, 218 | features: [], 219 | size: {vocab: 262144, embedding: 1152, input: 32768, output: 8192}, 220 | text: {input: true, output: true}, 221 | image: {input: false, output: false}, 222 | audio: {input: false, output: false}, 223 | video: {input: false, output: false}, 224 | }, 225 | price: {input: 0.0000000000, output: 0.0000000000}, 226 | }, 227 | { 228 | id: `${this.id}/gemini-embedding-exp`, 229 | name: 'Gemini Embedding Experimental', 230 | description: `Obtain a distributed representation of a text`, 231 | architecture: '', 232 | capabilities: { 233 | embedding: true, 234 | tool_call: false, 235 | rerank: false, 236 | features: [], 237 | size: {vocab: 0, embedding: 3072, input: 8192, output: 0}, 238 | text: {input: true, output: false}, 239 | image: {input: false, output: false}, 240 | audio: {input: false, output: false}, 241 | video: {input: false, output: false}, 242 | }, 243 | price: {input: 0.0000000000, output: 0.0000000000}, 244 | }, 245 | { 246 | id: `${this.id}/text-embedding-004`, 247 | name: 'Text Embedding 004', 248 | description: `Obtain a distributed representation of a text`, 249 | architecture: '', 250 | capabilities: { 251 | embedding: true, 252 | tool_call: false, 253 | rerank: false, 254 | features: [], 255 | size: {vocab: 0, embedding: 768, input: 2048, output: 0}, 256 | text: {input: true, output: false}, 257 | image: {input: false, output: false}, 258 | audio: {input: false, output: false}, 259 | video: {input: false, output: false}, 260 | }, 261 | price: {input: 0.0000000000, output: 0.0000000000}, 262 | }, 263 | { 264 | id: `${this.id}/embedding-001`, 265 | name: 'Embedding 001', 266 | description: `Obtain a distributed representation of a text`, 267 | architecture: '', 268 | capabilities: { 269 | embedding: true, 270 | tool_call: false, 271 | rerank: false, 272 | features: [], 273 | size: {vocab: 0, embedding: 768, input: 2048, output: 0}, 274 | text: {input: true, output: false}, 275 | image: {input: false, output: false}, 276 | audio: {input: false, output: false}, 277 | video: {input: false, output: false}, 278 | }, 279 | price: {input: 0.0000000000, output: 0.0000000000}, 280 | }, 281 | ]; 282 | default = { 283 | baseURL: 'https://generativelanguage.googleapis.com/v1beta', 284 | pricingURL: 'https://ai.google.dev/pricing', 285 | manageAPIKeysURL: 'https://aistudio.google.com/app/apikey', 286 | model: 'gemini-1.5-flash-8b-latest', 287 | }; 288 | 289 | create(init: RequestInit = {}): GoogleGenerativeAIProvider { 290 | return createGoogleGenerativeAI({baseURL: this.baseUrl(init.baseURL), apiKey: this.apiKey(init.apiKey), headers: init.headers}); 291 | } 292 | 293 | languageModel(model: string, init: RequestInit = {}): LanguageModel { 294 | return this.create(init)(model); 295 | } 296 | 297 | embeddingModel(model: string, init: RequestInit = {}): EmbeddingModel { 298 | return this.create(init).textEmbeddingModel(model); 299 | } 300 | } --------------------------------------------------------------------------------