mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-01 22:14:03 -04:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c5ff164ac | |||
| 7edeb1c2d7 | |||
| 8b95abdc85 | |||
| ffe0cd1ef1 | |||
| 5d2111a19f | |||
| 68ac7fd57f | |||
| 7320d96a36 | |||
| ee17fb475b |
+18
-19
@@ -12,6 +12,10 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
POSTGRES_USER: runneradmin
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
strategy:
|
||||
@@ -19,17 +23,20 @@ jobs:
|
||||
matrix:
|
||||
node-version: [18.x, 20.x, 22.x]
|
||||
name: E2E on Node.js ${{ matrix.node-version }}
|
||||
|
||||
env: POSTGRES_DB=vectordb
|
||||
POSTGRES_USER=testuser
|
||||
POSTGRES_PASSWORD=testpwd
|
||||
POSTGRES_HOST_AUTH_METHOD=trust
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: ankane/setup-postgres@v1
|
||||
with:
|
||||
database: llamaindex_node_test
|
||||
dev-files: true
|
||||
- run: |
|
||||
cd /tmp
|
||||
git clone --branch v0.7.0 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
sudo make install
|
||||
- uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -47,19 +54,8 @@ jobs:
|
||||
node-version: [18.x, 20.x, 22.x]
|
||||
name: Test on Node.js ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ankane/setup-postgres@v1
|
||||
with:
|
||||
database: llamaindex_node_test
|
||||
dev-files: true
|
||||
- run: |
|
||||
cd /tmp
|
||||
git clone --branch v0.7.0 https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
sudo make install
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
@@ -107,7 +103,7 @@ jobs:
|
||||
- nextjs-agent
|
||||
- nextjs-edge-runtime
|
||||
- nextjs-node-runtime
|
||||
# - waku-query-engine
|
||||
- waku-query-engine
|
||||
runs-on: ubuntu-latest
|
||||
name: Build LlamaIndex Example (${{ matrix.packages }})
|
||||
steps:
|
||||
@@ -146,6 +142,9 @@ jobs:
|
||||
- name: Pack @llamaindex/cloud
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/cloud
|
||||
- name: Pack @llamaindex/openai
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/llm/openai
|
||||
- name: Pack @llamaindex/core
|
||||
run: pnpm pack --pack-destination ${{ runner.temp }}
|
||||
working-directory: packages/core
|
||||
|
||||
@@ -189,6 +189,21 @@ export async function chatWithAgent(
|
||||
}
|
||||
```
|
||||
|
||||
### Vite
|
||||
|
||||
We have some wasm dependencies for better performance. You can use `vite-plugin-wasm` to load them.
|
||||
|
||||
```ts
|
||||
import wasm from "vite-plugin-wasm";
|
||||
|
||||
export default {
|
||||
plugins: [wasm()],
|
||||
ssr: {
|
||||
external: ["tiktoken"],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Playground
|
||||
|
||||
Check out our NextJS playground at https://llama-playground.vercel.app/. The source is available at https://github.com/run-llama/ts-playground
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# docs
|
||||
|
||||
## 0.0.68
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.67
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.66
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -4,12 +4,19 @@ sidebar_position: 7
|
||||
|
||||
# Storage
|
||||
|
||||
Storage in LlamaIndex.TS works automatically once you've configured a `StorageContext` object. Just configure the `persistDir` and attach it to an index.
|
||||
Storage in LlamaIndex.TS works automatically once you've configured a
|
||||
`StorageContext` object.
|
||||
|
||||
Right now, only saving and loading from disk is supported, with future integrations planned!
|
||||
## Local Storage
|
||||
|
||||
You can configure the `persistDir` and attach it to an index.
|
||||
|
||||
```typescript
|
||||
import { Document, VectorStoreIndex, storageContextFromDefaults } from "./src";
|
||||
import {
|
||||
Document,
|
||||
VectorStoreIndex,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
persistDir: "./storage",
|
||||
@@ -21,6 +28,33 @@ const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
});
|
||||
```
|
||||
|
||||
## PostgreSQL Storage
|
||||
|
||||
You can configure the `schemaName`, `tableName`, `namespace`, and
|
||||
`connectionString`. If a `connectionString` is not
|
||||
provided, it will use the environment variables `PGHOST`, `PGUSER`,
|
||||
`PGPASSWORD`, `PGDATABASE` and `PGPORT`.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
Document,
|
||||
VectorStoreIndex,
|
||||
PostgresDocumentStore,
|
||||
PostgresIndexStore,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
docStore: new PostgresDocumentStore(),
|
||||
indexStore: new PostgresIndexStore(),
|
||||
});
|
||||
|
||||
const document = new Document({ text: "Test Text" });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [StorageContext](../api/interfaces/StorageContext.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.66",
|
||||
"version": "0.0.68",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @llamaindex/autotool-01-node-example
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
"scripts": {
|
||||
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
|
||||
},
|
||||
"version": "0.0.6"
|
||||
"version": "0.0.8"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @llamaindex/autotool-02-next-example
|
||||
|
||||
## 0.1.52
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.1.51
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
- @llamaindex/autotool@2.0.1
|
||||
|
||||
## 0.1.50
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/autotool-02-next-example",
|
||||
"private": true,
|
||||
"version": "0.1.50",
|
||||
"version": "0.1.52",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"unplugin": "^1.12.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"llamaindex": "^0.5.25",
|
||||
"llamaindex": "^0.5.27",
|
||||
"openai": "^4",
|
||||
"typescript": "^4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/experimental
|
||||
|
||||
## 0.0.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.75
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/experimental",
|
||||
"description": "Experimental package for LlamaIndexTS",
|
||||
"version": "0.0.75",
|
||||
"version": "0.0.77",
|
||||
"type": "module",
|
||||
"types": "dist/type/index.d.ts",
|
||||
"main": "dist/cjs/index.js",
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# llamaindex
|
||||
|
||||
## 0.5.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7edeb1c: feat: decouple openai from `llamaindex` module
|
||||
|
||||
This should be a non-breaking change, but just you can now only install `@llamaindex/openai` to reduce the bundle size in the future
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- @llamaindex/openai@0.1.1
|
||||
|
||||
## 0.5.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ffe0cd1: faet: add openai o1 support
|
||||
- ffe0cd1: feat: add PostgreSQL storage
|
||||
|
||||
## 0.5.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/cloudflare-worker-agent-test
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/cloudflare-worker-agent-test",
|
||||
"version": "0.0.59",
|
||||
"version": "0.0.61",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/next-agent-test
|
||||
|
||||
## 0.1.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.1.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.1.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-agent-test",
|
||||
"version": "0.1.59",
|
||||
"version": "0.1.61",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# test-edge-runtime
|
||||
|
||||
## 0.1.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.1.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.1.58
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/nextjs-edge-runtime-test",
|
||||
"version": "0.1.58",
|
||||
"version": "0.1.60",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/next-node-runtime
|
||||
|
||||
## 0.0.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/next-node-runtime-test",
|
||||
"version": "0.0.40",
|
||||
"version": "0.0.42",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @llamaindex/waku-query-engine-test
|
||||
|
||||
## 0.0.61
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7edeb1c]
|
||||
- llamaindex@0.5.27
|
||||
|
||||
## 0.0.60
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- Updated dependencies [ffe0cd1]
|
||||
- llamaindex@0.5.26
|
||||
|
||||
## 0.0.59
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/waku-query-engine-test",
|
||||
"version": "0.0.59",
|
||||
"version": "0.0.61",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -20,6 +20,7 @@
|
||||
"@types/react-dom": "18.3.0",
|
||||
"autoprefixer": "10.4.20",
|
||||
"tailwindcss": "3.4.10",
|
||||
"typescript": "5.5.4"
|
||||
"typescript": "5.5.4",
|
||||
"vite-plugin-wasm": "^3.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,22 @@ export default async function RootLayout({ children }: RootLayoutProps) {
|
||||
const data = await getData();
|
||||
|
||||
return (
|
||||
<div className="font-['Nunito']">
|
||||
<meta property="description" content={data.description} />
|
||||
<link rel="icon" type="image/png" href={data.icon} />
|
||||
<Header />
|
||||
<main className="m-6 flex items-center *:min-h-64 *:min-w-64 lg:m-0 lg:min-h-svh lg:justify-center">
|
||||
{children}
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
<html>
|
||||
<head>
|
||||
<meta property="description" content={data.description} />
|
||||
<link rel="icon" type="image/png" href={data.icon} />
|
||||
<title>LlamaIndex Waku Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<div className="font-['Nunito']">
|
||||
<Header />
|
||||
<main className="m-6 flex items-center *:min-h-64 *:min-w-64 lg:m-0 lg:min-h-svh lg:justify-center">
|
||||
{children}
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,7 +38,6 @@ const getData = async () => {
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getConfig = async () => {
|
||||
return {
|
||||
render: "static",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import wasm from "vite-plugin-wasm";
|
||||
|
||||
export default {
|
||||
plugins: [wasm()],
|
||||
ssr: {
|
||||
external: ["tiktoken"],
|
||||
},
|
||||
};
|
||||
@@ -1,51 +0,0 @@
|
||||
import { TransformComponent } from "@llamaindex/core/schema";
|
||||
import {
|
||||
BaseEmbedding,
|
||||
BaseNode,
|
||||
SimilarityType,
|
||||
type EmbeddingInfo,
|
||||
type MessageContentDetail,
|
||||
} from "llamaindex";
|
||||
|
||||
export class OpenAIEmbedding
|
||||
extends TransformComponent
|
||||
implements BaseEmbedding
|
||||
{
|
||||
embedInfo?: EmbeddingInfo;
|
||||
embedBatchSize = 512;
|
||||
|
||||
constructor() {
|
||||
super(async (nodes: BaseNode[], _options?: any): Promise<BaseNode[]> => {
|
||||
nodes.forEach((node) => (node.embedding = [0]));
|
||||
return nodes;
|
||||
});
|
||||
}
|
||||
|
||||
async getQueryEmbedding(query: MessageContentDetail) {
|
||||
return [0];
|
||||
}
|
||||
|
||||
async getTextEmbedding(text: string) {
|
||||
return [0];
|
||||
}
|
||||
|
||||
async getTextEmbeddings(texts: string[]) {
|
||||
return [[0]];
|
||||
}
|
||||
|
||||
async getTextEmbeddingsBatch(texts: string[]) {
|
||||
return [[0]];
|
||||
}
|
||||
|
||||
similarity(
|
||||
embedding1: number[],
|
||||
embedding2: number[],
|
||||
mode?: SimilarityType,
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
truncateMaxTokens(input: string[]): string[] {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,15 @@ import type {
|
||||
import { deepStrictEqual, strictEqual } from "node:assert";
|
||||
import { llmCompleteMockStorage } from "../../node/utils.js";
|
||||
|
||||
import { TransformComponent } from "@llamaindex/core/schema";
|
||||
import {
|
||||
BaseEmbedding,
|
||||
BaseNode,
|
||||
SimilarityType,
|
||||
type EmbeddingInfo,
|
||||
type MessageContentDetail,
|
||||
} from "llamaindex";
|
||||
|
||||
export function getOpenAISession() {
|
||||
return {};
|
||||
}
|
||||
@@ -22,6 +31,7 @@ export function isFunctionCallingModel() {
|
||||
|
||||
export class OpenAI implements LLM {
|
||||
supportToolCall = true;
|
||||
|
||||
get metadata() {
|
||||
return {
|
||||
model: "mock-model",
|
||||
@@ -32,6 +42,7 @@ export class OpenAI implements LLM {
|
||||
isFunctionCallingModel: true,
|
||||
};
|
||||
}
|
||||
|
||||
chat(
|
||||
params: LLMChatParamsStreaming<Record<string, unknown>>,
|
||||
): Promise<AsyncIterable<ChatResponseChunk>>;
|
||||
@@ -77,6 +88,7 @@ export class OpenAI implements LLM {
|
||||
}
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
complete(
|
||||
params: LLMCompletionParamsStreaming,
|
||||
): Promise<AsyncIterable<CompletionResponse>>;
|
||||
@@ -103,3 +115,46 @@ export class OpenAI implements LLM {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenAIEmbedding
|
||||
extends TransformComponent
|
||||
implements BaseEmbedding
|
||||
{
|
||||
embedInfo?: EmbeddingInfo;
|
||||
embedBatchSize = 512;
|
||||
|
||||
constructor() {
|
||||
super(async (nodes: BaseNode[], _options?: any): Promise<BaseNode[]> => {
|
||||
nodes.forEach((node) => (node.embedding = [0]));
|
||||
return nodes;
|
||||
});
|
||||
}
|
||||
|
||||
async getQueryEmbedding(query: MessageContentDetail) {
|
||||
return [0];
|
||||
}
|
||||
|
||||
async getTextEmbedding(text: string) {
|
||||
return [0];
|
||||
}
|
||||
|
||||
async getTextEmbeddings(texts: string[]) {
|
||||
return [[0]];
|
||||
}
|
||||
|
||||
async getTextEmbeddingsBatch(texts: string[]) {
|
||||
return [[0]];
|
||||
}
|
||||
|
||||
similarity(
|
||||
embedding1: number[],
|
||||
embedding2: number[],
|
||||
mode?: SimilarityType,
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
truncateMaxTokens(input: string[]): string[] {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,14 @@ export async function resolve(specifier, context, nextResolve) {
|
||||
return result;
|
||||
}
|
||||
const targetUrl = fileURLToPath(result.url).replace(/\.js$/, ".ts");
|
||||
const relativePath = relative(packageDistDir, targetUrl);
|
||||
if (relativePath.startsWith(".") || relativePath.startsWith("/")) {
|
||||
let relativePath = relative(packageDistDir, targetUrl);
|
||||
// todo: make it more generic if we have more sub modules fixtures in the future
|
||||
if (relativePath.startsWith("../../llm/openai")) {
|
||||
relativePath = relativePath.replace(
|
||||
"../../llm/openai/dist/index.ts",
|
||||
"llm/openai.ts",
|
||||
);
|
||||
} else if (relativePath.startsWith(".") || relativePath.startsWith("/")) {
|
||||
return result;
|
||||
}
|
||||
const url = pathToFileURL(join(fixturesDir, relativePath)).toString();
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Document, VectorStoreQueryMode } from "llamaindex";
|
||||
import { PGVectorStore } from "llamaindex/vector-store/PGVectorStore";
|
||||
import assert from "node:assert";
|
||||
import { test } from "node:test";
|
||||
import pg from "pg";
|
||||
import { registerTypes } from "pgvector/pg";
|
||||
|
||||
let pgClient: pg.Client | pg.Pool;
|
||||
test.afterEach(async () => {
|
||||
await pgClient.end();
|
||||
});
|
||||
|
||||
await test("init with client", async () => {
|
||||
pgClient = new pg.Client({
|
||||
database: "llamaindex_node_test",
|
||||
});
|
||||
await pgClient.connect();
|
||||
await pgClient.query("CREATE EXTENSION IF NOT EXISTS vector");
|
||||
await registerTypes(pgClient);
|
||||
const vectorStore = new PGVectorStore(pgClient);
|
||||
assert.deepStrictEqual(await vectorStore.client(), pgClient);
|
||||
});
|
||||
|
||||
await test("init with pool", async () => {
|
||||
pgClient = new pg.Pool({
|
||||
database: "llamaindex_node_test",
|
||||
});
|
||||
await pgClient.query("CREATE EXTENSION IF NOT EXISTS vector");
|
||||
const client = await pgClient.connect();
|
||||
await registerTypes(client);
|
||||
const vectorStore = new PGVectorStore(client);
|
||||
assert.deepStrictEqual(await vectorStore.client(), client);
|
||||
client.release();
|
||||
});
|
||||
|
||||
await test("init without client", async () => {
|
||||
const vectorStore = new PGVectorStore({
|
||||
database: "llamaindex_node_test",
|
||||
});
|
||||
pgClient = (await vectorStore.client()) as pg.Client;
|
||||
assert.notDeepStrictEqual(pgClient, undefined);
|
||||
});
|
||||
|
||||
await test("simple node", async () => {
|
||||
const dimensions = 3;
|
||||
const schemaName =
|
||||
"llamaindex_vector_store_test_" + Math.random().toString(36).substring(7);
|
||||
const nodeId = "5bb16627-f6c0-459c-bb18-71642813ef21";
|
||||
const node = new Document({
|
||||
text: "hello world",
|
||||
id_: nodeId,
|
||||
embedding: [0.1, 0.2, 0.3],
|
||||
});
|
||||
const vectorStore = new PGVectorStore({
|
||||
database: "llamaindex_node_test",
|
||||
dimensions,
|
||||
schemaName,
|
||||
});
|
||||
|
||||
await vectorStore.add([node]);
|
||||
|
||||
{
|
||||
const result = await vectorStore.query({
|
||||
mode: VectorStoreQueryMode.DEFAULT,
|
||||
similarityTopK: 1,
|
||||
queryEmbedding: [1, 2, 3],
|
||||
});
|
||||
const actualJSON = result.nodes![0]!.toJSON();
|
||||
assert.deepStrictEqual(actualJSON, {
|
||||
...node.toJSON(),
|
||||
hash: actualJSON.hash,
|
||||
metadata: actualJSON.metadata,
|
||||
});
|
||||
assert.deepStrictEqual(result.ids, [nodeId]);
|
||||
assert.deepStrictEqual(result.similarities, [1]);
|
||||
}
|
||||
|
||||
await vectorStore.delete(nodeId);
|
||||
|
||||
{
|
||||
const result = await vectorStore.query({
|
||||
mode: VectorStoreQueryMode.DEFAULT,
|
||||
similarityTopK: 1,
|
||||
queryEmbedding: [1, 2, 3],
|
||||
});
|
||||
assert.deepStrictEqual(result.nodes, []);
|
||||
}
|
||||
|
||||
pgClient = (await vectorStore.client()) as pg.Client;
|
||||
});
|
||||
@@ -10,7 +10,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@types/node": "^22.5.1",
|
||||
"consola": "^3.2.3",
|
||||
"llamaindex": "workspace:*",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "llamaindex",
|
||||
"version": "0.5.25",
|
||||
"version": "0.5.27",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
@@ -33,6 +33,7 @@
|
||||
"@llamaindex/cloud": "workspace:*",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"@llamaindex/openai": "workspace:*",
|
||||
"@mistralai/mistralai": "^1.0.4",
|
||||
"@mixedbread-ai/sdk": "^2.2.11",
|
||||
"@pinecone-database/pinecone": "^3.0.2",
|
||||
@@ -56,7 +57,7 @@
|
||||
"md-utils-ts": "^2.0.0",
|
||||
"mongodb": "^6.7.0",
|
||||
"notion-md-crawler": "^1.0.0",
|
||||
"openai": "^4.57.0",
|
||||
"openai": "^4.60.0",
|
||||
"papaparse": "^5.4.1",
|
||||
"pathe": "^1.1.2",
|
||||
"portkey-ai": "0.1.16",
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
} from "@llamaindex/core/prompts";
|
||||
import { extractText, messagesToHistory } from "@llamaindex/core/utils";
|
||||
import { tokenizers, type Tokenizer } from "@llamaindex/env";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
/**
|
||||
* A ChatHistory is used to keep the state of back and forth chat messages
|
||||
|
||||
@@ -8,12 +8,12 @@ import {
|
||||
import type { QueryType } from "@llamaindex/core/query-engine";
|
||||
import type { BaseOutputParser } from "@llamaindex/core/schema";
|
||||
import { extractText, toToolDescriptions } from "@llamaindex/core/utils";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { SubQuestionOutputParser } from "./OutputParser.js";
|
||||
import type {
|
||||
BaseQuestionGenerator,
|
||||
SubQuestion,
|
||||
} from "./engines/query/types.js";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import type { StructuredOutput } from "./types.js";
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,7 @@ import {
|
||||
type NodeParser,
|
||||
SentenceSplitter,
|
||||
} from "@llamaindex/core/node-parser";
|
||||
import { OpenAIEmbedding } from "./embeddings/OpenAIEmbedding.js";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import { OpenAI, OpenAIEmbedding } from "@llamaindex/openai";
|
||||
|
||||
/**
|
||||
* The ServiceContext is a collection of components that are used in different parts of the application.
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
type CallbackManager,
|
||||
Settings as CoreSettings,
|
||||
} from "@llamaindex/core/global";
|
||||
import { OpenAI } from "./llm/openai.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
import { PromptHelper } from "@llamaindex/core/indices";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { Settings } from "../Settings.js";
|
||||
import { OpenAI } from "../llm/openai.js";
|
||||
import { LLMAgent, LLMAgentWorker, type LLMAgentParams } from "./llm.js";
|
||||
|
||||
// This is likely not necessary anymore but leaving it here just incase it's in use elsewhere
|
||||
|
||||
@@ -13,8 +13,8 @@ import { getAppBaseUrl, getProjectId, initService } from "./utils.js";
|
||||
import { PipelinesService, ProjectsService } from "@llamaindex/cloud/api";
|
||||
import { SentenceSplitter } from "@llamaindex/core/node-parser";
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import { Settings } from "../Settings.js";
|
||||
import { OpenAIEmbedding } from "../embeddings/OpenAIEmbedding.js";
|
||||
|
||||
export class LlamaCloudIndex {
|
||||
params: CloudConstructorParams;
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {
|
||||
} from "@llamaindex/cloud/api";
|
||||
import { SentenceSplitter } from "@llamaindex/core/node-parser";
|
||||
import { BaseNode, type TransformComponent } from "@llamaindex/core/schema";
|
||||
import { OpenAIEmbedding } from "../embeddings/OpenAIEmbedding.js";
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
|
||||
export type GetPipelineCreateParams = {
|
||||
pipelineName: string;
|
||||
|
||||
@@ -1,152 +1 @@
|
||||
import { BaseEmbedding } from "@llamaindex/core/embeddings";
|
||||
import { Tokenizers } from "@llamaindex/env";
|
||||
import type { ClientOptions as OpenAIClientOptions } from "openai";
|
||||
import type { AzureOpenAIConfig } from "../llm/azure.js";
|
||||
import {
|
||||
getAzureConfigFromEnv,
|
||||
getAzureModel,
|
||||
shouldUseAzure,
|
||||
} from "../llm/azure.js";
|
||||
import type { OpenAISession } from "../llm/openai.js";
|
||||
import { getOpenAISession } from "../llm/openai.js";
|
||||
|
||||
export const ALL_OPENAI_EMBEDDING_MODELS = {
|
||||
"text-embedding-ada-002": {
|
||||
dimensions: 1536,
|
||||
maxTokens: 8192,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
},
|
||||
"text-embedding-3-small": {
|
||||
dimensions: 1536,
|
||||
dimensionOptions: [512, 1536],
|
||||
maxTokens: 8192,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
},
|
||||
"text-embedding-3-large": {
|
||||
dimensions: 3072,
|
||||
dimensionOptions: [256, 1024, 3072],
|
||||
maxTokens: 8192,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
},
|
||||
};
|
||||
|
||||
type ModelKeys = keyof typeof ALL_OPENAI_EMBEDDING_MODELS;
|
||||
|
||||
export class OpenAIEmbedding extends BaseEmbedding {
|
||||
/** embeddding model. defaults to "text-embedding-ada-002" */
|
||||
model: string;
|
||||
/** number of dimensions of the resulting vector, for models that support choosing fewer dimensions. undefined will default to model default */
|
||||
dimensions?: number | undefined;
|
||||
|
||||
// OpenAI session params
|
||||
|
||||
/** api key */
|
||||
apiKey?: string | undefined = undefined;
|
||||
/** maximum number of retries, default 10 */
|
||||
maxRetries: number;
|
||||
/** timeout in ms, default 60 seconds */
|
||||
timeout?: number | undefined;
|
||||
/** other session options for OpenAI */
|
||||
additionalSessionOptions?:
|
||||
| Omit<Partial<OpenAIClientOptions>, "apiKey" | "maxRetries" | "timeout">
|
||||
| undefined;
|
||||
|
||||
/** session object */
|
||||
session: OpenAISession;
|
||||
|
||||
/**
|
||||
* OpenAI Embedding
|
||||
* @param init - initial parameters
|
||||
*/
|
||||
constructor(init?: Partial<OpenAIEmbedding> & { azure?: AzureOpenAIConfig }) {
|
||||
super();
|
||||
|
||||
this.model = init?.model ?? "text-embedding-ada-002";
|
||||
this.dimensions = init?.dimensions; // if no dimensions provided, will be undefined/not sent to OpenAI
|
||||
|
||||
this.embedBatchSize = init?.embedBatchSize ?? 10;
|
||||
this.maxRetries = init?.maxRetries ?? 10;
|
||||
|
||||
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
|
||||
this.additionalSessionOptions = init?.additionalSessionOptions;
|
||||
|
||||
// find metadata for model
|
||||
const key = Object.keys(ALL_OPENAI_EMBEDDING_MODELS).find(
|
||||
(key) => key === this.model,
|
||||
) as ModelKeys | undefined;
|
||||
if (key) {
|
||||
this.embedInfo = ALL_OPENAI_EMBEDDING_MODELS[key];
|
||||
}
|
||||
|
||||
if (init?.azure || shouldUseAzure()) {
|
||||
const azureConfig = {
|
||||
...getAzureConfigFromEnv({
|
||||
model: getAzureModel(this.model),
|
||||
}),
|
||||
...init?.azure,
|
||||
};
|
||||
|
||||
this.apiKey = azureConfig.apiKey;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
azure: true,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
...azureConfig,
|
||||
});
|
||||
} else {
|
||||
this.apiKey = init?.apiKey ?? undefined;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
apiKey: this.apiKey,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
* @param options
|
||||
*/
|
||||
private async getOpenAIEmbedding(input: string[]): Promise<number[][]> {
|
||||
// TODO: ensure this for every sub class by calling it in the base class
|
||||
input = this.truncateMaxTokens(input);
|
||||
|
||||
const { data } = await this.session.openai.embeddings.create(
|
||||
this.dimensions
|
||||
? {
|
||||
model: this.model,
|
||||
dimensions: this.dimensions, // only sent to OpenAI if set by user
|
||||
input,
|
||||
}
|
||||
: {
|
||||
model: this.model,
|
||||
input,
|
||||
},
|
||||
);
|
||||
|
||||
return data.map((d) => d.embedding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
*/
|
||||
getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {
|
||||
return this.getOpenAIEmbedding(texts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get embeddings for a single text
|
||||
* @param texts
|
||||
*/
|
||||
async getTextEmbedding(text: string): Promise<number[]> {
|
||||
return (await this.getOpenAIEmbedding([text]))[0]!;
|
||||
}
|
||||
}
|
||||
export * from "@llamaindex/openai";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAIEmbedding } from "./OpenAIEmbedding.js";
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
|
||||
export class FireworksEmbedding extends OpenAIEmbedding {
|
||||
constructor(init?: Partial<OpenAIEmbedding>) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAIEmbedding } from "./OpenAIEmbedding.js";
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
|
||||
export class TogetherEmbedding extends OpenAIEmbedding {
|
||||
constructor(init?: Partial<OpenAIEmbedding>) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { LLM } from "@llamaindex/core/llms";
|
||||
import type { BaseNode } from "@llamaindex/core/schema";
|
||||
import { MetadataMode, TextNode } from "@llamaindex/core/schema";
|
||||
import { OpenAI } from "../llm/index.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
defaultKeywordExtractorPromptTemplate,
|
||||
defaultQuestionAnswerPromptTemplate,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { BaseEmbedding } from "@llamaindex/core/embeddings";
|
||||
import { AsyncLocalStorage } from "@llamaindex/env";
|
||||
import { OpenAIEmbedding } from "../../embeddings/OpenAIEmbedding.js";
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
|
||||
const embeddedModelAsyncLocalStorage = new AsyncLocalStorage<BaseEmbedding>();
|
||||
let globalEmbeddedModel: BaseEmbedding | null = null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAI } from "./openai.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
const ENV_VARIABLE_NAME = "DEEPINFRA_API_TOKEN";
|
||||
const DEFAULT_MODEL = "mistralai/Mixtral-8x22B-Instruct-v0.1";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAI } from "./openai.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
export const DEEPSEEK_MODELS = {
|
||||
"deepseek-coder": { contextWindow: 128000 },
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAI } from "./openai.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
export class FireworksLLM extends OpenAI {
|
||||
constructor(init?: Partial<OpenAI>) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import GroqSDK, { type ClientOptions } from "groq-sdk";
|
||||
import { OpenAI } from "./openai.js";
|
||||
|
||||
export class Groq extends OpenAI {
|
||||
constructor(
|
||||
|
||||
@@ -11,7 +11,6 @@ export {
|
||||
GEMINI_MODEL,
|
||||
type GoogleGeminiSessionOptions,
|
||||
} from "./gemini/types.js";
|
||||
|
||||
export { Groq } from "./groq.js";
|
||||
export { HuggingFaceInferenceAPI, HuggingFaceLLM } from "./huggingface.js";
|
||||
export {
|
||||
|
||||
@@ -1,482 +1 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import _ from "lodash";
|
||||
import type OpenAILLM from "openai";
|
||||
import type {
|
||||
ClientOptions,
|
||||
ClientOptions as OpenAIClientOptions,
|
||||
} from "openai";
|
||||
import { AzureOpenAI, OpenAI as OrigOpenAI } from "openai";
|
||||
import type { ChatModel } from "openai/resources/chat/chat";
|
||||
|
||||
import {
|
||||
type BaseTool,
|
||||
type ChatMessage,
|
||||
type ChatResponse,
|
||||
type ChatResponseChunk,
|
||||
type LLM,
|
||||
type LLMChatParamsNonStreaming,
|
||||
type LLMChatParamsStreaming,
|
||||
type LLMMetadata,
|
||||
type MessageType,
|
||||
type PartialToolCall,
|
||||
ToolCallLLM,
|
||||
type ToolCallLLMMessageOptions,
|
||||
} from "@llamaindex/core/llms";
|
||||
import {
|
||||
extractText,
|
||||
wrapEventCaller,
|
||||
wrapLLMEvent,
|
||||
} from "@llamaindex/core/utils";
|
||||
import { Tokenizers } from "@llamaindex/env";
|
||||
import type {
|
||||
ChatCompletionAssistantMessageParam,
|
||||
ChatCompletionMessageToolCall,
|
||||
ChatCompletionRole,
|
||||
ChatCompletionSystemMessageParam,
|
||||
ChatCompletionTool,
|
||||
ChatCompletionToolMessageParam,
|
||||
ChatCompletionUserMessageParam,
|
||||
} from "openai/resources/chat/completions";
|
||||
import type { ChatCompletionMessageParam } from "openai/resources/index.js";
|
||||
import type { AzureOpenAIConfig } from "./azure.js";
|
||||
import {
|
||||
getAzureConfigFromEnv,
|
||||
getAzureModel,
|
||||
shouldUseAzure,
|
||||
} from "./azure.js";
|
||||
|
||||
export class OpenAISession {
|
||||
openai: Pick<OrigOpenAI, "chat" | "embeddings">;
|
||||
|
||||
constructor(options: ClientOptions & { azure?: boolean } = {}) {
|
||||
if (options.azure) {
|
||||
this.openai = new AzureOpenAI(options as AzureOpenAIConfig);
|
||||
} else {
|
||||
if (!options.apiKey) {
|
||||
options.apiKey = getEnv("OPENAI_API_KEY");
|
||||
}
|
||||
|
||||
if (!options.apiKey) {
|
||||
throw new Error("Set OpenAI Key in OPENAI_API_KEY env variable"); // Overriding OpenAI package's error message
|
||||
}
|
||||
|
||||
this.openai = new OrigOpenAI({
|
||||
...options,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I'm not 100% sure this is necessary vs. just starting a new session
|
||||
// every time we make a call. They say they try to reuse connections
|
||||
// so in theory this is more efficient, but we should test it in the future.
|
||||
const defaultOpenAISession: {
|
||||
session: OpenAISession;
|
||||
options: ClientOptions;
|
||||
}[] = [];
|
||||
|
||||
/**
|
||||
* Get a session for the OpenAI API. If one already exists with the same options,
|
||||
* it will be returned. Otherwise, a new session will be created.
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
export function getOpenAISession(
|
||||
options: ClientOptions & { azure?: boolean } = {},
|
||||
) {
|
||||
let session = defaultOpenAISession.find((session) => {
|
||||
return _.isEqual(session.options, options);
|
||||
})?.session;
|
||||
|
||||
if (!session) {
|
||||
session = new OpenAISession(options);
|
||||
defaultOpenAISession.push({ session, options });
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
export const GPT4_MODELS = {
|
||||
"gpt-4": { contextWindow: 8192 },
|
||||
"gpt-4-32k": { contextWindow: 32768 },
|
||||
"gpt-4-32k-0613": { contextWindow: 32768 },
|
||||
"gpt-4-turbo": { contextWindow: 128000 },
|
||||
"gpt-4-turbo-preview": { contextWindow: 128000 },
|
||||
"gpt-4-1106-preview": { contextWindow: 128000 },
|
||||
"gpt-4-0125-preview": { contextWindow: 128000 },
|
||||
"gpt-4-vision-preview": { contextWindow: 128000 },
|
||||
"gpt-4o": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-05-13": { contextWindow: 128000 },
|
||||
"gpt-4o-mini": { contextWindow: 128000 },
|
||||
"gpt-4o-mini-2024-07-18": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-08-06": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-09-14": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-10-14": { contextWindow: 128000 },
|
||||
"gpt-4-0613": { contextWindow: 128000 },
|
||||
"gpt-4-turbo-2024-04-09": { contextWindow: 128000 },
|
||||
"gpt-4-0314": { contextWindow: 128000 },
|
||||
"gpt-4-32k-0314": { contextWindow: 32768 },
|
||||
};
|
||||
|
||||
// NOTE we don't currently support gpt-3.5-turbo-instruct and don't plan to in the near future
|
||||
export const GPT35_MODELS = {
|
||||
"gpt-3.5-turbo": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-0613": { contextWindow: 4096 },
|
||||
"gpt-3.5-turbo-16k": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-16k-0613": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-1106": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-0125": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-0301": { contextWindow: 16385 },
|
||||
};
|
||||
|
||||
/**
|
||||
* We currently support GPT-3.5 and GPT-4 models
|
||||
*/
|
||||
export const ALL_AVAILABLE_OPENAI_MODELS = {
|
||||
...GPT4_MODELS,
|
||||
...GPT35_MODELS,
|
||||
} satisfies Record<ChatModel, { contextWindow: number }>;
|
||||
|
||||
export function isFunctionCallingModel(llm: LLM): llm is OpenAI {
|
||||
let model: string;
|
||||
if (llm instanceof OpenAI) {
|
||||
model = llm.model;
|
||||
} else if ("model" in llm && typeof llm.model === "string") {
|
||||
model = llm.model;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
const isChatModel = Object.keys(ALL_AVAILABLE_OPENAI_MODELS).includes(model);
|
||||
const isOld = model.includes("0314") || model.includes("0301");
|
||||
return isChatModel && !isOld;
|
||||
}
|
||||
|
||||
export type OpenAIAdditionalMetadata = {};
|
||||
|
||||
export type OpenAIAdditionalChatOptions = Omit<
|
||||
Partial<OpenAILLM.Chat.ChatCompletionCreateParams>,
|
||||
| "max_tokens"
|
||||
| "messages"
|
||||
| "model"
|
||||
| "temperature"
|
||||
| "top_p"
|
||||
| "stream"
|
||||
| "tools"
|
||||
| "toolChoice"
|
||||
>;
|
||||
|
||||
export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
|
||||
model:
|
||||
| ChatModel
|
||||
// string & {} is a hack to allow any string, but still give autocomplete
|
||||
| (string & {});
|
||||
temperature: number;
|
||||
topP: number;
|
||||
maxTokens?: number | undefined;
|
||||
additionalChatOptions?: OpenAIAdditionalChatOptions | undefined;
|
||||
|
||||
// OpenAI session params
|
||||
apiKey?: string | undefined = undefined;
|
||||
maxRetries: number;
|
||||
timeout?: number;
|
||||
session: OpenAISession;
|
||||
additionalSessionOptions?:
|
||||
| undefined
|
||||
| Omit<Partial<OpenAIClientOptions>, "apiKey" | "maxRetries" | "timeout">;
|
||||
|
||||
constructor(
|
||||
init?: Partial<OpenAI> & {
|
||||
azure?: AzureOpenAIConfig;
|
||||
},
|
||||
) {
|
||||
super();
|
||||
this.model = init?.model ?? "gpt-4o";
|
||||
this.temperature = init?.temperature ?? 0.1;
|
||||
this.topP = init?.topP ?? 1;
|
||||
this.maxTokens = init?.maxTokens ?? undefined;
|
||||
|
||||
this.maxRetries = init?.maxRetries ?? 10;
|
||||
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
|
||||
this.additionalChatOptions = init?.additionalChatOptions;
|
||||
this.additionalSessionOptions = init?.additionalSessionOptions;
|
||||
|
||||
if (init?.azure || shouldUseAzure()) {
|
||||
const azureConfig = {
|
||||
...getAzureConfigFromEnv({
|
||||
model: getAzureModel(this.model),
|
||||
}),
|
||||
...init?.azure,
|
||||
};
|
||||
|
||||
this.apiKey = azureConfig.apiKey;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
azure: true,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
...azureConfig,
|
||||
});
|
||||
} else {
|
||||
this.apiKey = init?.apiKey ?? undefined;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
apiKey: this.apiKey,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get supportToolCall() {
|
||||
return isFunctionCallingModel(this);
|
||||
}
|
||||
|
||||
get metadata(): LLMMetadata & OpenAIAdditionalMetadata {
|
||||
const contextWindow =
|
||||
ALL_AVAILABLE_OPENAI_MODELS[
|
||||
this.model as keyof typeof ALL_AVAILABLE_OPENAI_MODELS
|
||||
]?.contextWindow ?? 1024;
|
||||
return {
|
||||
model: this.model,
|
||||
temperature: this.temperature,
|
||||
topP: this.topP,
|
||||
maxTokens: this.maxTokens,
|
||||
contextWindow,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
};
|
||||
}
|
||||
|
||||
static toOpenAIRole(messageType: MessageType): ChatCompletionRole {
|
||||
switch (messageType) {
|
||||
case "user":
|
||||
return "user";
|
||||
case "assistant":
|
||||
return "assistant";
|
||||
case "system":
|
||||
return "system";
|
||||
default:
|
||||
return "user";
|
||||
}
|
||||
}
|
||||
|
||||
static toOpenAIMessage(
|
||||
messages: ChatMessage<ToolCallLLMMessageOptions>[],
|
||||
): ChatCompletionMessageParam[] {
|
||||
return messages.map((message) => {
|
||||
const options = message.options ?? {};
|
||||
if ("toolResult" in options) {
|
||||
return {
|
||||
tool_call_id: options.toolResult.id,
|
||||
role: "tool",
|
||||
content: extractText(message.content),
|
||||
} satisfies ChatCompletionToolMessageParam;
|
||||
} else if ("toolCall" in options) {
|
||||
return {
|
||||
role: "assistant",
|
||||
content: extractText(message.content),
|
||||
tool_calls: options.toolCall.map((toolCall) => {
|
||||
return {
|
||||
id: toolCall.id,
|
||||
type: "function",
|
||||
function: {
|
||||
name: toolCall.name,
|
||||
arguments:
|
||||
typeof toolCall.input === "string"
|
||||
? toolCall.input
|
||||
: JSON.stringify(toolCall.input),
|
||||
},
|
||||
};
|
||||
}),
|
||||
} satisfies ChatCompletionAssistantMessageParam;
|
||||
} else if (message.role === "user") {
|
||||
return {
|
||||
role: "user",
|
||||
content: message.content,
|
||||
} satisfies ChatCompletionUserMessageParam;
|
||||
}
|
||||
|
||||
const response:
|
||||
| ChatCompletionSystemMessageParam
|
||||
| ChatCompletionUserMessageParam
|
||||
| ChatCompletionMessageToolCall = {
|
||||
// fixme(alex): type assertion
|
||||
role: OpenAI.toOpenAIRole(message.role) as never,
|
||||
// fixme: should not extract text, but assert content is string
|
||||
content: extractText(message.content),
|
||||
};
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
chat(
|
||||
params: LLMChatParamsStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>,
|
||||
): Promise<AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>>>;
|
||||
chat(
|
||||
params: LLMChatParamsNonStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>,
|
||||
): Promise<ChatResponse<ToolCallLLMMessageOptions>>;
|
||||
@wrapEventCaller
|
||||
@wrapLLMEvent
|
||||
async chat(
|
||||
params:
|
||||
| LLMChatParamsNonStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>
|
||||
| LLMChatParamsStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>,
|
||||
): Promise<
|
||||
| ChatResponse<ToolCallLLMMessageOptions>
|
||||
| AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>>
|
||||
> {
|
||||
const { messages, stream, tools, additionalChatOptions } = params;
|
||||
const baseRequestParams = <OpenAILLM.Chat.ChatCompletionCreateParams>{
|
||||
model: this.model,
|
||||
temperature: this.temperature,
|
||||
max_tokens: this.maxTokens,
|
||||
tools: tools?.map(OpenAI.toTool),
|
||||
messages: OpenAI.toOpenAIMessage(messages),
|
||||
top_p: this.topP,
|
||||
...Object.assign({}, this.additionalChatOptions, additionalChatOptions),
|
||||
};
|
||||
|
||||
if (
|
||||
Array.isArray(baseRequestParams.tools) &&
|
||||
baseRequestParams.tools.length === 0
|
||||
) {
|
||||
// remove empty tools array to avoid OpenAI error
|
||||
delete baseRequestParams.tools;
|
||||
}
|
||||
|
||||
// Streaming
|
||||
if (stream) {
|
||||
return this.streamChat(baseRequestParams);
|
||||
}
|
||||
|
||||
// Non-streaming
|
||||
const response = await this.session.openai.chat.completions.create({
|
||||
...baseRequestParams,
|
||||
stream: false,
|
||||
});
|
||||
|
||||
const content = response.choices[0]!.message?.content ?? "";
|
||||
|
||||
return {
|
||||
raw: response,
|
||||
message: {
|
||||
content,
|
||||
role: response.choices[0]!.message.role,
|
||||
options: response.choices[0]!.message?.tool_calls
|
||||
? {
|
||||
toolCall: response.choices[0]!.message.tool_calls.map(
|
||||
(toolCall) => ({
|
||||
id: toolCall.id,
|
||||
name: toolCall.function.name,
|
||||
input: toolCall.function.arguments,
|
||||
}),
|
||||
),
|
||||
}
|
||||
: {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// todo: this wrapper is ugly, refactor it
|
||||
@wrapEventCaller
|
||||
protected async *streamChat(
|
||||
baseRequestParams: OpenAILLM.Chat.ChatCompletionCreateParams,
|
||||
): AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>> {
|
||||
const stream: AsyncIterable<OpenAILLM.Chat.ChatCompletionChunk> =
|
||||
await this.session.openai.chat.completions.create({
|
||||
...baseRequestParams,
|
||||
stream: true,
|
||||
});
|
||||
|
||||
// TODO: add callback to streamConverter and use streamConverter here
|
||||
// this will be used to keep track of the current tool call, make sure input are valid json object.
|
||||
let currentToolCall: PartialToolCall | null = null;
|
||||
const toolCallMap = new Map<string, PartialToolCall>();
|
||||
for await (const part of stream) {
|
||||
if (part.choices.length === 0) continue;
|
||||
const choice = part.choices[0]!;
|
||||
// skip parts that don't have any content
|
||||
if (!(choice.delta.content || choice.delta.tool_calls)) continue;
|
||||
|
||||
let shouldEmitToolCall: PartialToolCall | null = null;
|
||||
if (
|
||||
choice.delta.tool_calls?.[0]!.id &&
|
||||
currentToolCall &&
|
||||
choice.delta.tool_calls?.[0].id !== currentToolCall.id
|
||||
) {
|
||||
shouldEmitToolCall = {
|
||||
...currentToolCall,
|
||||
input: JSON.parse(currentToolCall.input),
|
||||
};
|
||||
}
|
||||
if (choice.delta.tool_calls?.[0]!.id) {
|
||||
currentToolCall = {
|
||||
name: choice.delta.tool_calls[0].function!.name!,
|
||||
id: choice.delta.tool_calls[0].id,
|
||||
input: choice.delta.tool_calls[0].function!.arguments!,
|
||||
};
|
||||
toolCallMap.set(choice.delta.tool_calls[0].id, currentToolCall);
|
||||
} else {
|
||||
if (choice.delta.tool_calls?.[0]!.function?.arguments) {
|
||||
currentToolCall!.input +=
|
||||
choice.delta.tool_calls[0].function.arguments;
|
||||
}
|
||||
}
|
||||
|
||||
const isDone: boolean = choice.finish_reason !== null;
|
||||
|
||||
if (isDone && currentToolCall) {
|
||||
// for the last one, we need to emit the tool call
|
||||
shouldEmitToolCall = {
|
||||
...currentToolCall,
|
||||
input: JSON.parse(currentToolCall.input),
|
||||
};
|
||||
}
|
||||
|
||||
yield {
|
||||
raw: part,
|
||||
options: shouldEmitToolCall
|
||||
? { toolCall: [shouldEmitToolCall] }
|
||||
: currentToolCall
|
||||
? {
|
||||
toolCall: [currentToolCall],
|
||||
}
|
||||
: {},
|
||||
delta: choice.delta.content ?? "",
|
||||
};
|
||||
}
|
||||
toolCallMap.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
static toTool(tool: BaseTool): ChatCompletionTool {
|
||||
return {
|
||||
type: "function",
|
||||
function: tool.metadata.parameters
|
||||
? {
|
||||
name: tool.metadata.name,
|
||||
description: tool.metadata.description,
|
||||
parameters: tool.metadata.parameters,
|
||||
}
|
||||
: {
|
||||
name: tool.metadata.name,
|
||||
description: tool.metadata.description,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
export * from "@llamaindex/openai";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { OpenAI } from "./openai.js";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
export class TogetherLLM extends OpenAI {
|
||||
constructor(init?: Partial<OpenAI>) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { DEFAULT_NAMESPACE } from "@llamaindex/core/global";
|
||||
import { PostgresKVStore } from "../kvStore/PostgresKVStore.js";
|
||||
import { KVDocumentStore } from "./KVDocumentStore.js";
|
||||
|
||||
const DEFAULT_TABLE_NAME = "llamaindex_doc_store";
|
||||
|
||||
export class PostgresDocumentStore extends KVDocumentStore {
|
||||
constructor(config?: {
|
||||
schemaName?: string;
|
||||
tableName?: string;
|
||||
connectionString?: string;
|
||||
namespace?: string;
|
||||
}) {
|
||||
const kvStore = new PostgresKVStore({
|
||||
schemaName: config?.schemaName,
|
||||
tableName: config?.tableName || DEFAULT_TABLE_NAME,
|
||||
});
|
||||
const namespace = config?.namespace || DEFAULT_NAMESPACE;
|
||||
super(kvStore, namespace);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
export { SimpleChatStore } from "./chatStore/SimpleChatStore.js";
|
||||
export * from "./chatStore/types.js";
|
||||
export { PostgresDocumentStore } from "./docStore/PostgresDocumentStore.js";
|
||||
export { SimpleDocumentStore } from "./docStore/SimpleDocumentStore.js";
|
||||
export * from "./docStore/types.js";
|
||||
export * from "./FileSystem.js";
|
||||
export { PostgresIndexStore } from "./indexStore/PostgresIndexStore.js";
|
||||
export { SimpleIndexStore } from "./indexStore/SimpleIndexStore.js";
|
||||
export * from "./indexStore/types.js";
|
||||
export { PostgresKVStore } from "./kvStore/PostgresKVStore.js";
|
||||
export { SimpleKVStore } from "./kvStore/SimpleKVStore.js";
|
||||
export * from "./kvStore/types.js";
|
||||
export * from "./StorageContext.js";
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { DEFAULT_NAMESPACE } from "@llamaindex/core/global";
|
||||
import { PostgresKVStore } from "../kvStore/PostgresKVStore.js";
|
||||
import { KVIndexStore } from "./KVIndexStore.js";
|
||||
|
||||
const DEFAULT_TABLE_NAME = "llamaindex_index_store";
|
||||
|
||||
export class PostgresIndexStore extends KVIndexStore {
|
||||
constructor(config?: {
|
||||
schemaName?: string;
|
||||
tableName?: string;
|
||||
connectionString?: string;
|
||||
namespace?: string;
|
||||
}) {
|
||||
const kvStore = new PostgresKVStore({
|
||||
schemaName: config?.schemaName,
|
||||
tableName: config?.tableName || DEFAULT_TABLE_NAME,
|
||||
});
|
||||
const namespace = config?.namespace || DEFAULT_NAMESPACE;
|
||||
super(kvStore, namespace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import { DEFAULT_COLLECTION } from "@llamaindex/core/global";
|
||||
import type pg from "pg";
|
||||
import { BaseKVStore } from "./types.js";
|
||||
|
||||
export type DataType = Record<string, Record<string, any>>;
|
||||
|
||||
const DEFAULT_SCHEMA_NAME = "public";
|
||||
const DEFAULT_TABLE_NAME = "llamaindex_kv_store";
|
||||
|
||||
export class PostgresKVStore extends BaseKVStore {
|
||||
private schemaName: string;
|
||||
private tableName: string;
|
||||
private connectionString: string | undefined = undefined;
|
||||
private db?: pg.Client;
|
||||
|
||||
constructor(config?: {
|
||||
schemaName?: string | undefined;
|
||||
tableName?: string | undefined;
|
||||
connectionString?: string | undefined;
|
||||
}) {
|
||||
super();
|
||||
this.schemaName = config?.schemaName || DEFAULT_SCHEMA_NAME;
|
||||
this.tableName = config?.tableName || DEFAULT_TABLE_NAME;
|
||||
this.connectionString = config?.connectionString;
|
||||
}
|
||||
|
||||
private async getDb(): Promise<pg.Client> {
|
||||
if (!this.db) {
|
||||
try {
|
||||
const pg = await import("pg");
|
||||
const { Client } = pg.default ? pg.default : pg;
|
||||
const db = new Client({ connectionString: this.connectionString });
|
||||
await db.connect();
|
||||
await this.checkSchema(db);
|
||||
this.db = db;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return Promise.reject(err instanceof Error ? err : new Error(`${err}`));
|
||||
}
|
||||
}
|
||||
return Promise.resolve(this.db);
|
||||
}
|
||||
|
||||
private async checkSchema(db: pg.Client) {
|
||||
await db.query(`CREATE SCHEMA IF NOT EXISTS ${this.schemaName}`);
|
||||
const tbl = `CREATE TABLE IF NOT EXISTS ${this.schemaName}.${this.tableName} (
|
||||
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
|
||||
collection VARCHAR,
|
||||
key VARCHAR,
|
||||
value JSONB DEFAULT '{}'
|
||||
)`;
|
||||
await db.query(tbl);
|
||||
const idxs = `CREATE INDEX IF NOT EXISTS idx_${this.tableName}_collection ON ${this.schemaName}.${this.tableName} (collection);
|
||||
CREATE INDEX IF NOT EXISTS idx_${this.tableName}_key ON ${this.schemaName}.${this.tableName} (key);`;
|
||||
await db.query(idxs);
|
||||
return db;
|
||||
}
|
||||
|
||||
client() {
|
||||
return this.getDb();
|
||||
}
|
||||
|
||||
async put(
|
||||
key: string,
|
||||
val: any,
|
||||
collection: string = DEFAULT_COLLECTION,
|
||||
): Promise<void> {
|
||||
const db = await this.getDb();
|
||||
try {
|
||||
await db.query("BEGIN");
|
||||
const sql = `
|
||||
INSERT INTO ${this.schemaName}.${this.tableName}
|
||||
(collection, key, value)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
collection = EXCLUDED.collection,
|
||||
key = EXCLUDED.key,
|
||||
value = EXCLUDED.value
|
||||
RETURNING id
|
||||
`;
|
||||
const values = [collection, key, val];
|
||||
await db.query(sql, values);
|
||||
await db.query("COMMIT");
|
||||
} catch (error) {
|
||||
await db.query("ROLLBACK");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async get(
|
||||
key: string,
|
||||
collection: string = DEFAULT_COLLECTION,
|
||||
): Promise<any> {
|
||||
const db = await this.getDb();
|
||||
try {
|
||||
await db.query("BEGIN");
|
||||
const sql = `SELECT * FROM ${this.schemaName}.${this.tableName} WHERE key = $1 AND collection = $2`;
|
||||
const result = await db.query(sql, [key, collection]);
|
||||
await db.query("COMMIT");
|
||||
return result.rows[0].value;
|
||||
} catch (error) {
|
||||
await db.query("ROLLBACK");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getAll(collection: string = DEFAULT_COLLECTION): Promise<DataType> {
|
||||
const db = await this.getDb();
|
||||
try {
|
||||
await db.query("BEGIN");
|
||||
const sql = `SELECT * FROM ${this.schemaName}.${this.tableName} WHERE collection = $1`;
|
||||
const result = await db.query(sql, [collection]);
|
||||
await db.query("COMMIT");
|
||||
return result.rows.reduce((acc, row) => {
|
||||
acc[row.key] = row.value;
|
||||
return acc;
|
||||
}, {});
|
||||
} catch (error) {
|
||||
await db.query("ROLLBACK");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async delete(
|
||||
key: string,
|
||||
collection: string = DEFAULT_COLLECTION,
|
||||
): Promise<boolean> {
|
||||
const db = await this.getDb();
|
||||
try {
|
||||
await db.query("BEGIN");
|
||||
const sql = `DELETE FROM ${this.schemaName}.${this.tableName} WHERE key = $1 AND collection = $2`;
|
||||
const result = await db.query(sql, [key, collection]);
|
||||
await db.query("COMMIT");
|
||||
return !!result.rowCount && result.rowCount > 0;
|
||||
} catch (error) {
|
||||
await db.query("ROLLBACK");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
import { Document } from "llamaindex";
|
||||
import { PGVectorStore } from "llamaindex/vector-store/PGVectorStore";
|
||||
import pg from "pg";
|
||||
import { registerTypes } from "pgvector/pg";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { VectorStoreQueryMode } from "../../src/index.js";
|
||||
|
||||
describe("pg - init", () => {
|
||||
test("init with client", async () => {
|
||||
const client = new pg.Client({
|
||||
database: "llamaindex_node_test",
|
||||
});
|
||||
await client.connect();
|
||||
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
||||
await registerTypes(client);
|
||||
const vectorStore = new PGVectorStore(client);
|
||||
expect(await vectorStore.client()).toBe(client);
|
||||
});
|
||||
|
||||
test("init with pool", async () => {
|
||||
const pool = new pg.Pool({
|
||||
database: "llamaindex_node_test",
|
||||
});
|
||||
await pool.query("CREATE EXTENSION IF NOT EXISTS vector");
|
||||
const client = await pool.connect();
|
||||
await registerTypes(client);
|
||||
const vectorStore = new PGVectorStore(client);
|
||||
expect(await vectorStore.client()).toBe(client);
|
||||
});
|
||||
|
||||
test("init without client", async () => {
|
||||
const vectorStore = new PGVectorStore({
|
||||
database: "llamaindex_node_test",
|
||||
});
|
||||
expect(await vectorStore.client()).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("pg - save data", () => {
|
||||
test("simple node", async () => {
|
||||
const dimensions = 3;
|
||||
const schemaName =
|
||||
"llamaindex_vector_store_test_" + Math.random().toString(36).substring(7);
|
||||
const nodeId = "5bb16627-f6c0-459c-bb18-71642813ef21";
|
||||
const node = new Document({
|
||||
text: "hello world",
|
||||
id_: nodeId,
|
||||
embedding: [0.1, 0.2, 0.3],
|
||||
});
|
||||
const vectorStore = new PGVectorStore({
|
||||
database: "llamaindex_node_test",
|
||||
dimensions,
|
||||
schemaName,
|
||||
});
|
||||
|
||||
await vectorStore.add([node]);
|
||||
|
||||
{
|
||||
const result = await vectorStore.query({
|
||||
mode: VectorStoreQueryMode.DEFAULT,
|
||||
similarityTopK: 1,
|
||||
queryEmbedding: [1, 2, 3],
|
||||
});
|
||||
const actualJSON = result.nodes![0]!.toJSON();
|
||||
expect(actualJSON).toEqual({
|
||||
...node.toJSON(),
|
||||
hash: actualJSON.hash,
|
||||
metadata: actualJSON.metadata,
|
||||
});
|
||||
expect(result.ids).toEqual([nodeId]);
|
||||
expect(result.similarities).toEqual([1]);
|
||||
}
|
||||
|
||||
await vectorStore.delete(nodeId);
|
||||
|
||||
{
|
||||
const result = await vectorStore.query({
|
||||
mode: VectorStoreQueryMode.DEFAULT,
|
||||
similarityTopK: 1,
|
||||
queryEmbedding: [1, 2, 3],
|
||||
});
|
||||
expect(result.nodes).toEqual([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
# @llamaindex/openai
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7edeb1c: feat: decouple openai from `llamaindex` module
|
||||
|
||||
This should be a non-breaking change, but just you can now only install `@llamaindex/openai` to reduce the bundle size in the future
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "@llamaindex/openai",
|
||||
"description": "OpenAI Adapter for LlamaIndex",
|
||||
"version": "0.1.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/run-llama/LlamaIndexTS.git",
|
||||
"directory": "packages/llm/openai"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "bunchee",
|
||||
"dev": "bunchee --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bunchee": "5.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"openai": "^4.60.0",
|
||||
"remeda": "^2.12.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
import { BaseEmbedding } from "@llamaindex/core/embeddings";
|
||||
import { Tokenizers } from "@llamaindex/env";
|
||||
import type { ClientOptions as OpenAIClientOptions } from "openai";
|
||||
import type { AzureOpenAIConfig } from "./azure.js";
|
||||
import {
|
||||
getAzureConfigFromEnv,
|
||||
getAzureModel,
|
||||
shouldUseAzure,
|
||||
} from "./azure.js";
|
||||
import type { OpenAISession } from "./llm.js";
|
||||
import { getOpenAISession } from "./llm.js";
|
||||
|
||||
export const ALL_OPENAI_EMBEDDING_MODELS = {
|
||||
"text-embedding-ada-002": {
|
||||
dimensions: 1536,
|
||||
maxTokens: 8192,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
},
|
||||
"text-embedding-3-small": {
|
||||
dimensions: 1536,
|
||||
dimensionOptions: [512, 1536],
|
||||
maxTokens: 8192,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
},
|
||||
"text-embedding-3-large": {
|
||||
dimensions: 3072,
|
||||
dimensionOptions: [256, 1024, 3072],
|
||||
maxTokens: 8192,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
},
|
||||
};
|
||||
|
||||
type ModelKeys = keyof typeof ALL_OPENAI_EMBEDDING_MODELS;
|
||||
|
||||
export class OpenAIEmbedding extends BaseEmbedding {
|
||||
/** embeddding model. defaults to "text-embedding-ada-002" */
|
||||
model: string;
|
||||
/** number of dimensions of the resulting vector, for models that support choosing fewer dimensions. undefined will default to model default */
|
||||
dimensions?: number | undefined;
|
||||
|
||||
// OpenAI session params
|
||||
|
||||
/** api key */
|
||||
apiKey?: string | undefined = undefined;
|
||||
/** maximum number of retries, default 10 */
|
||||
maxRetries: number;
|
||||
/** timeout in ms, default 60 seconds */
|
||||
timeout?: number | undefined;
|
||||
/** other session options for OpenAI */
|
||||
additionalSessionOptions?:
|
||||
| Omit<Partial<OpenAIClientOptions>, "apiKey" | "maxRetries" | "timeout">
|
||||
| undefined;
|
||||
|
||||
/** session object */
|
||||
session: OpenAISession;
|
||||
|
||||
/**
|
||||
* OpenAI Embedding
|
||||
* @param init - initial parameters
|
||||
*/
|
||||
constructor(init?: Partial<OpenAIEmbedding> & { azure?: AzureOpenAIConfig }) {
|
||||
super();
|
||||
|
||||
this.model = init?.model ?? "text-embedding-ada-002";
|
||||
this.dimensions = init?.dimensions; // if no dimensions provided, will be undefined/not sent to OpenAI
|
||||
|
||||
this.embedBatchSize = init?.embedBatchSize ?? 10;
|
||||
this.maxRetries = init?.maxRetries ?? 10;
|
||||
|
||||
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
|
||||
this.additionalSessionOptions = init?.additionalSessionOptions;
|
||||
|
||||
// find metadata for model
|
||||
const key = Object.keys(ALL_OPENAI_EMBEDDING_MODELS).find(
|
||||
(key) => key === this.model,
|
||||
) as ModelKeys | undefined;
|
||||
if (key) {
|
||||
this.embedInfo = ALL_OPENAI_EMBEDDING_MODELS[key];
|
||||
}
|
||||
|
||||
if (init?.azure || shouldUseAzure()) {
|
||||
const azureConfig = {
|
||||
...getAzureConfigFromEnv({
|
||||
model: getAzureModel(this.model),
|
||||
}),
|
||||
...init?.azure,
|
||||
};
|
||||
|
||||
this.apiKey = azureConfig.apiKey;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
azure: true,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
...azureConfig,
|
||||
});
|
||||
} else {
|
||||
this.apiKey = init?.apiKey ?? undefined;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
apiKey: this.apiKey,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
* @param options
|
||||
*/
|
||||
private async getOpenAIEmbedding(input: string[]): Promise<number[][]> {
|
||||
// TODO: ensure this for every sub class by calling it in the base class
|
||||
input = this.truncateMaxTokens(input);
|
||||
|
||||
const { data } = await this.session.openai.embeddings.create(
|
||||
this.dimensions
|
||||
? {
|
||||
model: this.model,
|
||||
dimensions: this.dimensions, // only sent to OpenAI if set by user
|
||||
input,
|
||||
}
|
||||
: {
|
||||
model: this.model,
|
||||
input,
|
||||
},
|
||||
);
|
||||
|
||||
return data.map((d) => d.embedding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embeddings for a batch of texts
|
||||
* @param texts
|
||||
*/
|
||||
getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {
|
||||
return this.getOpenAIEmbedding(texts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get embeddings for a single text
|
||||
* @param texts
|
||||
*/
|
||||
async getTextEmbedding(text: string): Promise<number[]> {
|
||||
return (await this.getOpenAIEmbedding([text]))[0]!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export { ALL_OPENAI_EMBEDDING_MODELS, OpenAIEmbedding } from "./embedding";
|
||||
export {
|
||||
ALL_AVAILABLE_OPENAI_MODELS,
|
||||
GPT35_MODELS,
|
||||
GPT4_MODELS,
|
||||
O1_MODELS,
|
||||
OpenAI,
|
||||
OpenAISession,
|
||||
type OpenAIAdditionalChatOptions,
|
||||
type OpenAIAdditionalMetadata,
|
||||
} from "./llm";
|
||||
|
||||
export { type AzureOpenAIConfig } from "./azure";
|
||||
@@ -0,0 +1,502 @@
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import type OpenAILLM from "openai";
|
||||
import type {
|
||||
ClientOptions,
|
||||
ClientOptions as OpenAIClientOptions,
|
||||
} from "openai";
|
||||
import { AzureOpenAI, OpenAI as OrigOpenAI } from "openai";
|
||||
import type { ChatModel } from "openai/resources/chat/chat";
|
||||
import { isDeepEqual } from "remeda";
|
||||
|
||||
import {
|
||||
type BaseTool,
|
||||
type ChatMessage,
|
||||
type ChatResponse,
|
||||
type ChatResponseChunk,
|
||||
type LLM,
|
||||
type LLMChatParamsNonStreaming,
|
||||
type LLMChatParamsStreaming,
|
||||
type LLMMetadata,
|
||||
type MessageType,
|
||||
type PartialToolCall,
|
||||
ToolCallLLM,
|
||||
type ToolCallLLMMessageOptions,
|
||||
} from "@llamaindex/core/llms";
|
||||
import {
|
||||
extractText,
|
||||
wrapEventCaller,
|
||||
wrapLLMEvent,
|
||||
} from "@llamaindex/core/utils";
|
||||
import { Tokenizers } from "@llamaindex/env";
|
||||
import type {
|
||||
ChatCompletionAssistantMessageParam,
|
||||
ChatCompletionMessageToolCall,
|
||||
ChatCompletionRole,
|
||||
ChatCompletionSystemMessageParam,
|
||||
ChatCompletionTool,
|
||||
ChatCompletionToolMessageParam,
|
||||
ChatCompletionUserMessageParam,
|
||||
} from "openai/resources/chat/completions";
|
||||
import type { ChatCompletionMessageParam } from "openai/resources/index.js";
|
||||
import type { AzureOpenAIConfig } from "./azure.js";
|
||||
import {
|
||||
getAzureConfigFromEnv,
|
||||
getAzureModel,
|
||||
shouldUseAzure,
|
||||
} from "./azure.js";
|
||||
|
||||
export class OpenAISession {
|
||||
openai: Pick<OrigOpenAI, "chat" | "embeddings">;
|
||||
|
||||
constructor(options: ClientOptions & { azure?: boolean } = {}) {
|
||||
if (options.azure) {
|
||||
this.openai = new AzureOpenAI(options as AzureOpenAIConfig);
|
||||
} else {
|
||||
if (!options.apiKey) {
|
||||
options.apiKey = getEnv("OPENAI_API_KEY");
|
||||
}
|
||||
|
||||
if (!options.apiKey) {
|
||||
throw new Error("Set OpenAI Key in OPENAI_API_KEY env variable"); // Overriding OpenAI package's error message
|
||||
}
|
||||
|
||||
this.openai = new OrigOpenAI({
|
||||
...options,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I'm not 100% sure this is necessary vs. just starting a new session
|
||||
// every time we make a call. They say they try to reuse connections
|
||||
// so in theory this is more efficient, but we should test it in the future.
|
||||
const defaultOpenAISession: {
|
||||
session: OpenAISession;
|
||||
options: ClientOptions;
|
||||
}[] = [];
|
||||
|
||||
/**
|
||||
* Get a session for the OpenAI API. If one already exists with the same options,
|
||||
* it will be returned. Otherwise, a new session will be created.
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
export function getOpenAISession(
|
||||
options: ClientOptions & { azure?: boolean } = {},
|
||||
) {
|
||||
let session = defaultOpenAISession.find((session) => {
|
||||
return isDeepEqual(session.options, options);
|
||||
})?.session;
|
||||
|
||||
if (!session) {
|
||||
session = new OpenAISession(options);
|
||||
defaultOpenAISession.push({ session, options });
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
export const GPT4_MODELS = {
|
||||
"chatgpt-4o-latest": {
|
||||
contextWindow: 128000,
|
||||
},
|
||||
"gpt-4": { contextWindow: 8192 },
|
||||
"gpt-4-32k": { contextWindow: 32768 },
|
||||
"gpt-4-32k-0613": { contextWindow: 32768 },
|
||||
"gpt-4-turbo": { contextWindow: 128000 },
|
||||
"gpt-4-turbo-preview": { contextWindow: 128000 },
|
||||
"gpt-4-1106-preview": { contextWindow: 128000 },
|
||||
"gpt-4-0125-preview": { contextWindow: 128000 },
|
||||
"gpt-4-vision-preview": { contextWindow: 128000 },
|
||||
"gpt-4o": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-05-13": { contextWindow: 128000 },
|
||||
"gpt-4o-mini": { contextWindow: 128000 },
|
||||
"gpt-4o-mini-2024-07-18": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-08-06": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-09-14": { contextWindow: 128000 },
|
||||
"gpt-4o-2024-10-14": { contextWindow: 128000 },
|
||||
"gpt-4-0613": { contextWindow: 128000 },
|
||||
"gpt-4-turbo-2024-04-09": { contextWindow: 128000 },
|
||||
"gpt-4-0314": { contextWindow: 128000 },
|
||||
"gpt-4-32k-0314": { contextWindow: 32768 },
|
||||
};
|
||||
|
||||
// NOTE we don't currently support gpt-3.5-turbo-instruct and don't plan to in the near future
|
||||
export const GPT35_MODELS = {
|
||||
"gpt-3.5-turbo": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-0613": { contextWindow: 4096 },
|
||||
"gpt-3.5-turbo-16k": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-16k-0613": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-1106": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-0125": { contextWindow: 16385 },
|
||||
"gpt-3.5-turbo-0301": { contextWindow: 16385 },
|
||||
};
|
||||
|
||||
export const O1_MODELS = {
|
||||
"o1-preview": {
|
||||
contextWindow: 128000,
|
||||
},
|
||||
"o1-preview-2024-09-12": {
|
||||
contextWindow: 128000,
|
||||
},
|
||||
"o1-mini": {
|
||||
contextWindow: 128000,
|
||||
},
|
||||
"o1-mini-2024-09-12": {
|
||||
contextWindow: 128000,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* We currently support GPT-3.5 and GPT-4 models
|
||||
*/
|
||||
export const ALL_AVAILABLE_OPENAI_MODELS = {
|
||||
...GPT4_MODELS,
|
||||
...GPT35_MODELS,
|
||||
...O1_MODELS,
|
||||
} satisfies Record<ChatModel, { contextWindow: number }>;
|
||||
|
||||
export function isFunctionCallingModel(llm: LLM): llm is OpenAI {
|
||||
let model: string;
|
||||
if (llm instanceof OpenAI) {
|
||||
model = llm.model;
|
||||
} else if ("model" in llm && typeof llm.model === "string") {
|
||||
model = llm.model;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
const isChatModel = Object.keys(ALL_AVAILABLE_OPENAI_MODELS).includes(model);
|
||||
const isOld = model.includes("0314") || model.includes("0301");
|
||||
const isO1 = model.startsWith("o1");
|
||||
return isChatModel && !isOld && !isO1;
|
||||
}
|
||||
|
||||
export type OpenAIAdditionalMetadata = {};
|
||||
|
||||
export type OpenAIAdditionalChatOptions = Omit<
|
||||
Partial<OpenAILLM.Chat.ChatCompletionCreateParams>,
|
||||
| "max_tokens"
|
||||
| "messages"
|
||||
| "model"
|
||||
| "temperature"
|
||||
| "top_p"
|
||||
| "stream"
|
||||
| "tools"
|
||||
| "toolChoice"
|
||||
>;
|
||||
|
||||
export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
|
||||
model:
|
||||
| ChatModel
|
||||
// string & {} is a hack to allow any string, but still give autocomplete
|
||||
| (string & {});
|
||||
temperature: number;
|
||||
topP: number;
|
||||
maxTokens?: number | undefined;
|
||||
additionalChatOptions?: OpenAIAdditionalChatOptions | undefined;
|
||||
|
||||
// OpenAI session params
|
||||
apiKey?: string | undefined = undefined;
|
||||
maxRetries: number;
|
||||
timeout?: number;
|
||||
session: OpenAISession;
|
||||
additionalSessionOptions?:
|
||||
| undefined
|
||||
| Omit<Partial<OpenAIClientOptions>, "apiKey" | "maxRetries" | "timeout">;
|
||||
|
||||
constructor(
|
||||
init?: Partial<OpenAI> & {
|
||||
azure?: AzureOpenAIConfig;
|
||||
},
|
||||
) {
|
||||
super();
|
||||
this.model = init?.model ?? "gpt-4o";
|
||||
this.temperature = init?.temperature ?? 0.1;
|
||||
this.topP = init?.topP ?? 1;
|
||||
this.maxTokens = init?.maxTokens ?? undefined;
|
||||
|
||||
this.maxRetries = init?.maxRetries ?? 10;
|
||||
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
|
||||
this.additionalChatOptions = init?.additionalChatOptions;
|
||||
this.additionalSessionOptions = init?.additionalSessionOptions;
|
||||
|
||||
if (init?.azure || shouldUseAzure()) {
|
||||
const azureConfig = {
|
||||
...getAzureConfigFromEnv({
|
||||
model: getAzureModel(this.model),
|
||||
}),
|
||||
...init?.azure,
|
||||
};
|
||||
|
||||
this.apiKey = azureConfig.apiKey;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
azure: true,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
...azureConfig,
|
||||
});
|
||||
} else {
|
||||
this.apiKey = init?.apiKey ?? undefined;
|
||||
this.session =
|
||||
init?.session ??
|
||||
getOpenAISession({
|
||||
apiKey: this.apiKey,
|
||||
maxRetries: this.maxRetries,
|
||||
timeout: this.timeout,
|
||||
...this.additionalSessionOptions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get supportToolCall() {
|
||||
return isFunctionCallingModel(this);
|
||||
}
|
||||
|
||||
get metadata(): LLMMetadata & OpenAIAdditionalMetadata {
|
||||
const contextWindow =
|
||||
ALL_AVAILABLE_OPENAI_MODELS[
|
||||
this.model as keyof typeof ALL_AVAILABLE_OPENAI_MODELS
|
||||
]?.contextWindow ?? 1024;
|
||||
return {
|
||||
model: this.model,
|
||||
temperature: this.temperature,
|
||||
topP: this.topP,
|
||||
maxTokens: this.maxTokens,
|
||||
contextWindow,
|
||||
tokenizer: Tokenizers.CL100K_BASE,
|
||||
};
|
||||
}
|
||||
|
||||
static toOpenAIRole(messageType: MessageType): ChatCompletionRole {
|
||||
switch (messageType) {
|
||||
case "user":
|
||||
return "user";
|
||||
case "assistant":
|
||||
return "assistant";
|
||||
case "system":
|
||||
return "system";
|
||||
default:
|
||||
return "user";
|
||||
}
|
||||
}
|
||||
|
||||
static toOpenAIMessage(
|
||||
messages: ChatMessage<ToolCallLLMMessageOptions>[],
|
||||
): ChatCompletionMessageParam[] {
|
||||
return messages.map((message) => {
|
||||
const options = message.options ?? {};
|
||||
if ("toolResult" in options) {
|
||||
return {
|
||||
tool_call_id: options.toolResult.id,
|
||||
role: "tool",
|
||||
content: extractText(message.content),
|
||||
} satisfies ChatCompletionToolMessageParam;
|
||||
} else if ("toolCall" in options) {
|
||||
return {
|
||||
role: "assistant",
|
||||
content: extractText(message.content),
|
||||
tool_calls: options.toolCall.map((toolCall) => {
|
||||
return {
|
||||
id: toolCall.id,
|
||||
type: "function",
|
||||
function: {
|
||||
name: toolCall.name,
|
||||
arguments:
|
||||
typeof toolCall.input === "string"
|
||||
? toolCall.input
|
||||
: JSON.stringify(toolCall.input),
|
||||
},
|
||||
};
|
||||
}),
|
||||
} satisfies ChatCompletionAssistantMessageParam;
|
||||
} else if (message.role === "user") {
|
||||
return {
|
||||
role: "user",
|
||||
content: message.content,
|
||||
} satisfies ChatCompletionUserMessageParam;
|
||||
}
|
||||
|
||||
const response:
|
||||
| ChatCompletionSystemMessageParam
|
||||
| ChatCompletionUserMessageParam
|
||||
| ChatCompletionMessageToolCall = {
|
||||
// fixme(alex): type assertion
|
||||
role: OpenAI.toOpenAIRole(message.role) as never,
|
||||
// fixme: should not extract text, but assert content is string
|
||||
content: extractText(message.content),
|
||||
};
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
||||
chat(
|
||||
params: LLMChatParamsStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>,
|
||||
): Promise<AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>>>;
|
||||
chat(
|
||||
params: LLMChatParamsNonStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>,
|
||||
): Promise<ChatResponse<ToolCallLLMMessageOptions>>;
|
||||
@wrapEventCaller
|
||||
@wrapLLMEvent
|
||||
async chat(
|
||||
params:
|
||||
| LLMChatParamsNonStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>
|
||||
| LLMChatParamsStreaming<
|
||||
OpenAIAdditionalChatOptions,
|
||||
ToolCallLLMMessageOptions
|
||||
>,
|
||||
): Promise<
|
||||
| ChatResponse<ToolCallLLMMessageOptions>
|
||||
| AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>>
|
||||
> {
|
||||
const { messages, stream, tools, additionalChatOptions } = params;
|
||||
const baseRequestParams = <OpenAILLM.Chat.ChatCompletionCreateParams>{
|
||||
model: this.model,
|
||||
temperature: this.temperature,
|
||||
max_tokens: this.maxTokens,
|
||||
tools: tools?.map(OpenAI.toTool),
|
||||
messages: OpenAI.toOpenAIMessage(messages),
|
||||
top_p: this.topP,
|
||||
...Object.assign({}, this.additionalChatOptions, additionalChatOptions),
|
||||
};
|
||||
|
||||
if (
|
||||
Array.isArray(baseRequestParams.tools) &&
|
||||
baseRequestParams.tools.length === 0
|
||||
) {
|
||||
// remove empty tools array to avoid OpenAI error
|
||||
delete baseRequestParams.tools;
|
||||
}
|
||||
|
||||
// Streaming
|
||||
if (stream) {
|
||||
return this.streamChat(baseRequestParams);
|
||||
}
|
||||
|
||||
// Non-streaming
|
||||
const response = await this.session.openai.chat.completions.create({
|
||||
...baseRequestParams,
|
||||
stream: false,
|
||||
});
|
||||
|
||||
const content = response.choices[0]!.message?.content ?? "";
|
||||
|
||||
return {
|
||||
raw: response,
|
||||
message: {
|
||||
content,
|
||||
role: response.choices[0]!.message.role,
|
||||
options: response.choices[0]!.message?.tool_calls
|
||||
? {
|
||||
toolCall: response.choices[0]!.message.tool_calls.map(
|
||||
(toolCall) => ({
|
||||
id: toolCall.id,
|
||||
name: toolCall.function.name,
|
||||
input: toolCall.function.arguments,
|
||||
}),
|
||||
),
|
||||
}
|
||||
: {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// todo: this wrapper is ugly, refactor it
|
||||
@wrapEventCaller
|
||||
protected async *streamChat(
|
||||
baseRequestParams: OpenAILLM.Chat.ChatCompletionCreateParams,
|
||||
): AsyncIterable<ChatResponseChunk<ToolCallLLMMessageOptions>> {
|
||||
const stream: AsyncIterable<OpenAILLM.Chat.ChatCompletionChunk> =
|
||||
await this.session.openai.chat.completions.create({
|
||||
...baseRequestParams,
|
||||
stream: true,
|
||||
});
|
||||
|
||||
// TODO: add callback to streamConverter and use streamConverter here
|
||||
// this will be used to keep track of the current tool call, make sure input are valid json object.
|
||||
let currentToolCall: PartialToolCall | null = null;
|
||||
const toolCallMap = new Map<string, PartialToolCall>();
|
||||
for await (const part of stream) {
|
||||
if (part.choices.length === 0) continue;
|
||||
const choice = part.choices[0]!;
|
||||
// skip parts that don't have any content
|
||||
if (!(choice.delta.content || choice.delta.tool_calls)) continue;
|
||||
|
||||
let shouldEmitToolCall: PartialToolCall | null = null;
|
||||
if (
|
||||
choice.delta.tool_calls?.[0]!.id &&
|
||||
currentToolCall &&
|
||||
choice.delta.tool_calls?.[0].id !== currentToolCall.id
|
||||
) {
|
||||
shouldEmitToolCall = {
|
||||
...currentToolCall,
|
||||
input: JSON.parse(currentToolCall.input),
|
||||
};
|
||||
}
|
||||
if (choice.delta.tool_calls?.[0]!.id) {
|
||||
currentToolCall = {
|
||||
name: choice.delta.tool_calls[0].function!.name!,
|
||||
id: choice.delta.tool_calls[0].id,
|
||||
input: choice.delta.tool_calls[0].function!.arguments!,
|
||||
};
|
||||
toolCallMap.set(choice.delta.tool_calls[0].id, currentToolCall);
|
||||
} else {
|
||||
if (choice.delta.tool_calls?.[0]!.function?.arguments) {
|
||||
currentToolCall!.input +=
|
||||
choice.delta.tool_calls[0].function.arguments;
|
||||
}
|
||||
}
|
||||
|
||||
const isDone: boolean = choice.finish_reason !== null;
|
||||
|
||||
if (isDone && currentToolCall) {
|
||||
// for the last one, we need to emit the tool call
|
||||
shouldEmitToolCall = {
|
||||
...currentToolCall,
|
||||
input: JSON.parse(currentToolCall.input),
|
||||
};
|
||||
}
|
||||
|
||||
yield {
|
||||
raw: part,
|
||||
options: shouldEmitToolCall
|
||||
? { toolCall: [shouldEmitToolCall] }
|
||||
: currentToolCall
|
||||
? {
|
||||
toolCall: [currentToolCall],
|
||||
}
|
||||
: {},
|
||||
delta: choice.delta.content ?? "",
|
||||
};
|
||||
}
|
||||
toolCallMap.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
static toTool(tool: BaseTool): ChatCompletionTool {
|
||||
return {
|
||||
type: "function",
|
||||
function: tool.metadata.parameters
|
||||
? {
|
||||
name: tool.metadata.name,
|
||||
description: tool.metadata.description,
|
||||
parameters: tool.metadata.parameters,
|
||||
}
|
||||
: {
|
||||
name: tool.metadata.name,
|
||||
description: tool.metadata.description,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"outDir": "./lib"
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../llamaindex/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "../../env/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
Generated
+99
-20
@@ -152,7 +152,7 @@ importers:
|
||||
version: 2.4.6
|
||||
chromadb:
|
||||
specifier: ^1.8.1
|
||||
version: 1.8.1(@google/generative-ai@0.12.0)(cohere-ai@7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13))(encoding@0.1.13)(openai@4.57.0(encoding@0.1.13)(zod@3.23.8))
|
||||
version: 1.8.1(@google/generative-ai@0.12.0)(cohere-ai@7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13))(encoding@0.1.13)(openai@4.60.0(encoding@0.1.13)(zod@3.23.8))
|
||||
commander:
|
||||
specifier: ^12.1.0
|
||||
version: 12.1.0
|
||||
@@ -167,7 +167,7 @@ importers:
|
||||
version: link:../packages/llamaindex
|
||||
mongodb:
|
||||
specifier: ^6.7.0
|
||||
version: 6.8.0(@aws-sdk/credential-providers@3.637.0)
|
||||
version: 6.8.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))
|
||||
pathe:
|
||||
specifier: ^1.1.2
|
||||
version: 1.1.2
|
||||
@@ -276,7 +276,7 @@ importers:
|
||||
version: 1.1.0(@types/react@18.3.5)(react@18.3.1)
|
||||
ai:
|
||||
specifier: ^3.3.21
|
||||
version: 3.3.21(openai@4.57.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.4.38(typescript@5.5.4))(zod@3.23.8)
|
||||
version: 3.3.21(openai@4.60.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.4.38(typescript@5.5.4))(zod@3.23.8)
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0
|
||||
@@ -516,6 +516,9 @@ importers:
|
||||
'@llamaindex/env':
|
||||
specifier: workspace:*
|
||||
version: link:../env
|
||||
'@llamaindex/openai':
|
||||
specifier: workspace:*
|
||||
version: link:../llm/openai
|
||||
'@mistralai/mistralai':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4(zod@3.23.8)
|
||||
@@ -554,7 +557,7 @@ importers:
|
||||
version: 4.7.0
|
||||
chromadb:
|
||||
specifier: 1.8.1
|
||||
version: 1.8.1(@google/generative-ai@0.12.0)(cohere-ai@7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13))(encoding@0.1.13)(openai@4.57.0(encoding@0.1.13)(zod@3.23.8))
|
||||
version: 1.8.1(@google/generative-ai@0.12.0)(cohere-ai@7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13))(encoding@0.1.13)(openai@4.60.0(encoding@0.1.13)(zod@3.23.8))
|
||||
cohere-ai:
|
||||
specifier: 7.13.0
|
||||
version: 7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13)
|
||||
@@ -581,13 +584,13 @@ importers:
|
||||
version: 2.0.0
|
||||
mongodb:
|
||||
specifier: ^6.7.0
|
||||
version: 6.8.0(@aws-sdk/credential-providers@3.637.0)
|
||||
version: 6.8.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0)))
|
||||
notion-md-crawler:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0(encoding@0.1.13)
|
||||
openai:
|
||||
specifier: ^4.57.0
|
||||
version: 4.57.0(encoding@0.1.13)(zod@3.23.8)
|
||||
specifier: ^4.60.0
|
||||
version: 4.60.0(encoding@0.1.13)(zod@3.23.8)
|
||||
papaparse:
|
||||
specifier: ^5.4.1
|
||||
version: 5.4.1
|
||||
@@ -652,9 +655,6 @@ importers:
|
||||
'@faker-js/faker':
|
||||
specifier: ^8.4.1
|
||||
version: 8.4.1
|
||||
'@llamaindex/core':
|
||||
specifier: workspace:*
|
||||
version: link:../../core
|
||||
'@types/node':
|
||||
specifier: ^22.5.1
|
||||
version: 22.5.1
|
||||
@@ -700,7 +700,7 @@ importers:
|
||||
dependencies:
|
||||
ai:
|
||||
specifier: ^3.3.21
|
||||
version: 3.3.21(openai@4.57.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.4.38(typescript@5.5.4))(zod@3.23.8)
|
||||
version: 3.3.21(openai@4.60.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.4.38(typescript@5.5.4))(zod@3.23.8)
|
||||
llamaindex:
|
||||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
@@ -840,6 +840,9 @@ importers:
|
||||
typescript:
|
||||
specifier: 5.5.4
|
||||
version: 5.5.4
|
||||
vite-plugin-wasm:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))
|
||||
|
||||
packages/llamaindex/tests:
|
||||
devDependencies:
|
||||
@@ -850,6 +853,25 @@ importers:
|
||||
specifier: ^2.0.5
|
||||
version: 2.0.5(@types/node@22.5.1)(terser@5.31.6)
|
||||
|
||||
packages/llm/openai:
|
||||
dependencies:
|
||||
'@llamaindex/core':
|
||||
specifier: workspace:*
|
||||
version: link:../../core
|
||||
'@llamaindex/env':
|
||||
specifier: workspace:*
|
||||
version: link:../../env
|
||||
openai:
|
||||
specifier: ^4.60.0
|
||||
version: 4.60.0(encoding@0.1.13)(zod@3.23.8)
|
||||
remeda:
|
||||
specifier: ^2.12.0
|
||||
version: 2.12.0
|
||||
devDependencies:
|
||||
bunchee:
|
||||
specifier: 5.3.2
|
||||
version: 5.3.2(typescript@5.5.4)
|
||||
|
||||
packages/wasm-tools:
|
||||
dependencies:
|
||||
'@assemblyscript/loader':
|
||||
@@ -8385,6 +8407,15 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
openai@4.60.0:
|
||||
resolution: {integrity: sha512-U/wNmrUPdfsvU1GrKRP5mY5YHR3ev6vtdfNID6Sauz+oquWD8r+cXPL1xiUlYniosPKajy33muVHhGS/9/t6KA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
zod: ^3.23.8
|
||||
peerDependenciesMeta:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
opener@1.5.2:
|
||||
resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
|
||||
hasBin: true
|
||||
@@ -9460,6 +9491,9 @@ packages:
|
||||
remark-stringify@11.0.0:
|
||||
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
||||
|
||||
remeda@2.12.0:
|
||||
resolution: {integrity: sha512-VAlyhh1os8boCA9/7yN9sXzo0tfCeOwScGXztwBspS0DXQmbIN8xTBfEABvbAW8rMJMPzqxQ1UymHquuESh/pg==}
|
||||
|
||||
renderkid@3.0.0:
|
||||
resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==}
|
||||
|
||||
@@ -10444,6 +10478,10 @@ packages:
|
||||
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
||||
type-fest@4.26.1:
|
||||
resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
type-is@1.6.18:
|
||||
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -10689,6 +10727,11 @@ packages:
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
|
||||
vite-plugin-wasm@3.3.0:
|
||||
resolution: {integrity: sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==}
|
||||
peerDependencies:
|
||||
vite: ^2 || ^3 || ^4 || ^5
|
||||
|
||||
vite@5.4.2:
|
||||
resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
@@ -14746,7 +14789,7 @@ snapshots:
|
||||
|
||||
'@smithy/is-array-buffer@2.2.0':
|
||||
dependencies:
|
||||
tslib: 2.6.3
|
||||
tslib: 2.7.0
|
||||
|
||||
'@smithy/is-array-buffer@3.0.0':
|
||||
dependencies:
|
||||
@@ -15958,7 +16001,7 @@ snapshots:
|
||||
clean-stack: 2.2.0
|
||||
indent-string: 4.0.0
|
||||
|
||||
ai@3.3.21(openai@4.57.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.4.38(typescript@5.5.4))(zod@3.23.8):
|
||||
ai@3.3.21(openai@4.60.0(zod@3.23.8))(react@18.3.1)(sswr@2.1.0(svelte@4.2.19))(svelte@4.2.19)(vue@3.4.38(typescript@5.5.4))(zod@3.23.8):
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.22
|
||||
'@ai-sdk/provider-utils': 1.0.17(zod@3.23.8)
|
||||
@@ -15975,7 +16018,7 @@ snapshots:
|
||||
secure-json-parse: 2.7.0
|
||||
zod-to-json-schema: 3.23.2(zod@3.23.8)
|
||||
optionalDependencies:
|
||||
openai: 4.57.0(zod@3.23.8)
|
||||
openai: 4.60.0(zod@3.23.8)
|
||||
react: 18.3.1
|
||||
sswr: 2.1.0(svelte@4.2.19)
|
||||
svelte: 4.2.19
|
||||
@@ -16652,14 +16695,14 @@ snapshots:
|
||||
|
||||
chownr@2.0.0: {}
|
||||
|
||||
chromadb@1.8.1(@google/generative-ai@0.12.0)(cohere-ai@7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13))(encoding@0.1.13)(openai@4.57.0(encoding@0.1.13)(zod@3.23.8)):
|
||||
chromadb@1.8.1(@google/generative-ai@0.12.0)(cohere-ai@7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13))(encoding@0.1.13)(openai@4.60.0(encoding@0.1.13)(zod@3.23.8)):
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
isomorphic-fetch: 3.0.0(encoding@0.1.13)
|
||||
optionalDependencies:
|
||||
'@google/generative-ai': 0.12.0
|
||||
cohere-ai: 7.13.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))(encoding@0.1.13)
|
||||
openai: 4.57.0(encoding@0.1.13)(zod@3.23.8)
|
||||
openai: 4.60.0(encoding@0.1.13)(zod@3.23.8)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -17747,6 +17790,16 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.8.2(@typescript-eslint/parser@8.3.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.3.0(eslint@8.57.0)(typescript@5.5.4)
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.3.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0):
|
||||
dependencies:
|
||||
array-includes: 3.1.8
|
||||
@@ -17757,7 +17810,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-module-utils: 2.8.2(@typescript-eslint/parser@8.3.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.15.1
|
||||
is-glob: 4.0.3
|
||||
@@ -20485,7 +20538,7 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@aws-sdk/credential-providers': 3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))
|
||||
|
||||
mongodb@6.8.0(@aws-sdk/credential-providers@3.637.0):
|
||||
mongodb@6.8.0(@aws-sdk/credential-providers@3.637.0(@aws-sdk/client-sso-oidc@3.637.0(@aws-sdk/client-sts@3.637.0))):
|
||||
dependencies:
|
||||
'@mongodb-js/saslprep': 1.1.7
|
||||
bson: 6.8.0
|
||||
@@ -20915,7 +20968,23 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
openai@4.57.0(zod@3.23.8):
|
||||
openai@4.60.0(encoding@0.1.13)(zod@3.23.8):
|
||||
dependencies:
|
||||
'@types/node': 18.19.47
|
||||
'@types/node-fetch': 2.6.11
|
||||
'@types/qs': 6.9.15
|
||||
abort-controller: 3.0.0
|
||||
agentkeepalive: 4.5.0
|
||||
form-data-encoder: 1.7.2
|
||||
formdata-node: 4.4.1
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
qs: 6.13.0
|
||||
optionalDependencies:
|
||||
zod: 3.23.8
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
openai@4.60.0(zod@3.23.8):
|
||||
dependencies:
|
||||
'@types/node': 18.19.47
|
||||
'@types/node-fetch': 2.6.11
|
||||
@@ -22123,6 +22192,10 @@ snapshots:
|
||||
mdast-util-to-markdown: 2.1.0
|
||||
unified: 11.0.5
|
||||
|
||||
remeda@2.12.0:
|
||||
dependencies:
|
||||
type-fest: 4.26.1
|
||||
|
||||
renderkid@3.0.0:
|
||||
dependencies:
|
||||
css-select: 4.3.0
|
||||
@@ -23220,6 +23293,8 @@ snapshots:
|
||||
|
||||
type-fest@2.19.0: {}
|
||||
|
||||
type-fest@4.26.1: {}
|
||||
|
||||
type-is@1.6.18:
|
||||
dependencies:
|
||||
media-typer: 0.3.0
|
||||
@@ -23340,7 +23415,7 @@ snapshots:
|
||||
|
||||
union@0.5.0:
|
||||
dependencies:
|
||||
qs: 6.11.2
|
||||
qs: 6.13.0
|
||||
|
||||
unique-string@3.0.0:
|
||||
dependencies:
|
||||
@@ -23522,6 +23597,10 @@ snapshots:
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
vite-plugin-wasm@3.3.0(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6)):
|
||||
dependencies:
|
||||
vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6)
|
||||
|
||||
vite@5.4.2(@types/node@22.5.1)(terser@5.31.6):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
packages:
|
||||
- "apps/*"
|
||||
- "packages/*"
|
||||
- "packages/llm/*"
|
||||
- "packages/core/tests"
|
||||
- "packages/llamaindex/tests"
|
||||
- "packages/llamaindex/e2e"
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
{
|
||||
"path": "./packages/community/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "./packages/llm/openai/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "./packages/cloud/tsconfig.json"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user