Compare commits

...

5 Commits

Author SHA1 Message Date
github-actions[bot] b7382b0d24 Release 0.6.15 (#1295)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-03 19:44:55 -07:00
Alex Yang 2a8241328d fix: lazy load openai (#1294) 2024-10-03 17:12:33 -07:00
Alex Yang 0b20ff9f17 fix(cloud): package.json format (#1291) 2024-10-03 17:07:50 -07:00
github-actions[bot] 1fc26046e3 Release 0.6.14 (#1290)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-03 16:35:54 -07:00
LAWG b17d439d6d fix: ensure id_ is correctly passed during creation (#1282)
Co-authored-by: lawrencegb <lawrence@3api.com>
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-10-03 11:52:26 -07:00
54 changed files with 386 additions and 238 deletions
+13
View File
@@ -1,5 +1,18 @@
# docs
## 0.0.84
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.0.83
### Patch Changes
- llamaindex@0.6.14
## 0.0.82
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.82",
"version": "0.0.84",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
+1 -1
View File
@@ -13,7 +13,7 @@ import { FunctionTool, OpenAI, ToolCallOptions } from "llamaindex";
}
})();
async function callLLM(init: Partial<OpenAI>) {
async function callLLM(init: { model: string }) {
const csvData =
"Country,Average Height (cm)\nNetherlands,156\nDenmark,158\nNorway,160";
+13
View File
@@ -1,5 +1,18 @@
# @llamaindex/autotool
## 3.0.15
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 3.0.14
### Patch Changes
- llamaindex@0.6.14
## 3.0.13
### Patch Changes
@@ -1,5 +1,20 @@
# @llamaindex/autotool-01-node-example
## 0.0.24
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
- @llamaindex/autotool@3.0.15
## 0.0.23
### Patch Changes
- llamaindex@0.6.14
- @llamaindex/autotool@3.0.14
## 0.0.22
### Patch Changes
@@ -13,5 +13,5 @@
"scripts": {
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
},
"version": "0.0.22"
"version": "0.0.24"
}
@@ -1,5 +1,20 @@
# @llamaindex/autotool-02-next-example
## 0.1.68
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
- @llamaindex/autotool@3.0.15
## 0.1.67
### Patch Changes
- llamaindex@0.6.14
- @llamaindex/autotool@3.0.14
## 0.1.66
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool-02-next-example",
"private": true,
"version": "0.1.66",
"version": "0.1.68",
"scripts": {
"dev": "next dev",
"build": "next build",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool",
"type": "module",
"version": "3.0.13",
"version": "3.0.15",
"description": "auto transpile your JS function to LLM Agent compatible",
"files": [
"dist",
+6
View File
@@ -1,5 +1,11 @@
# @llamaindex/cloud
## 0.2.11
### Patch Changes
- 0b20ff9: fix: package.json format
## 0.2.10
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloud",
"version": "0.2.10",
"version": "0.2.11",
"type": "module",
"license": "MIT",
"scripts": {
@@ -51,13 +51,13 @@
"devDependencies": {
"@hey-api/client-fetch": "^0.2.4",
"@hey-api/openapi-ts": "^0.53.0",
"@llamaindex/core": "workspace:^0.2.8",
"@llamaindex/env": "workspace:^0.1.13",
"@llamaindex/core": "workspace:*",
"@llamaindex/env": "workspace:*",
"bunchee": "5.3.2"
},
"peerDependencies": {
"@llamaindex/core": "workspace:^0.2.8",
"@llamaindex/env": "workspace:^0.1.13"
"@llamaindex/core": "workspace:*",
"@llamaindex/env": "workspace:*"
},
"dependencies": {
"magic-bytes.js": "^1.10.0"
+7
View File
@@ -1,5 +1,12 @@
# @llamaindex/community
## 0.0.44
### Patch Changes
- Updated dependencies [b17d439]
- @llamaindex/core@0.2.9
## 0.0.43
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/community",
"description": "Community package for LlamaIndexTS",
"version": "0.0.43",
"version": "0.0.44",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
+6
View File
@@ -1,5 +1,11 @@
# @llamaindex/core
## 0.2.9
### Patch Changes
- b17d439: Fix #1278: resolved issue where the id\_ was not correctly passed as the id when creating a TextNode. As a result, the upsert operation to the vector database was using a generated ID instead of the provided document ID, if available.
## 0.2.8
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/core",
"type": "module",
"version": "0.2.8",
"version": "0.2.9",
"description": "LlamaIndex Core Module",
"exports": {
"./agent": {
+2 -2
View File
@@ -479,7 +479,7 @@ export function buildNodeFromSplits(
) {
const imageDoc = doc as ImageNode;
const imageNode = new ImageNode({
id_: idGenerator(i, imageDoc),
id_: imageDoc.id_ ?? idGenerator(i, imageDoc),
text: textChunk,
image: imageDoc.image,
embedding: imageDoc.embedding,
@@ -496,7 +496,7 @@ export function buildNodeFromSplits(
) {
const textDoc = doc as TextNode;
const node = new TextNode({
id_: idGenerator(i, textDoc),
id_: textDoc.id_ ?? idGenerator(i, textDoc),
text: textChunk,
embedding: textDoc.embedding,
excludedEmbedMetadataKeys: [...textDoc.excludedEmbedMetadataKeys],
+13
View File
@@ -1,5 +1,18 @@
# @llamaindex/experimental
## 0.0.93
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.0.92
### Patch Changes
- llamaindex@0.6.14
## 0.0.91
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/experimental",
"description": "Experimental package for LlamaIndexTS",
"version": "0.0.91",
"version": "0.0.93",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
+21
View File
@@ -1,5 +1,26 @@
# llamaindex
## 0.6.15
### Patch Changes
- 2a82413: fix(core): set `Settings.llm` to OpenAI by default and support lazy load openai
- Updated dependencies [2a82413]
- Updated dependencies [0b20ff9]
- @llamaindex/groq@0.0.11
- @llamaindex/openai@0.1.12
- @llamaindex/cloud@0.2.11
## 0.6.14
### Patch Changes
- Updated dependencies [b17d439]
- @llamaindex/core@0.2.9
- @llamaindex/ollama@0.0.4
- @llamaindex/openai@0.1.11
- @llamaindex/groq@0.0.10
## 0.6.13
### Patch Changes
@@ -1,5 +1,18 @@
# @llamaindex/cloudflare-worker-agent-test
## 0.0.77
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.0.76
### Patch Changes
- llamaindex@0.6.14
## 0.0.75
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.75",
"version": "0.0.77",
"type": "module",
"private": true,
"scripts": {
@@ -1,5 +1,12 @@
# @llamaindex/llama-parse-browser-test
## 0.0.7
### Patch Changes
- Updated dependencies [0b20ff9]
- @llamaindex/cloud@0.2.11
## 0.0.6
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/llama-parse-browser-test",
"private": true,
"version": "0.0.6",
"version": "0.0.7",
"type": "module",
"scripts": {
"dev": "vite",
@@ -1,5 +1,18 @@
# @llamaindex/next-agent-test
## 0.1.77
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.1.76
### Patch Changes
- llamaindex@0.6.14
## 0.1.75
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.75",
"version": "0.1.77",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,18 @@
# test-edge-runtime
## 0.1.76
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.1.75
### Patch Changes
- llamaindex@0.6.14
## 0.1.74
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.74",
"version": "0.1.76",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,18 @@
# @llamaindex/next-node-runtime
## 0.0.58
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.0.57
### Patch Changes
- llamaindex@0.6.14
## 0.0.56
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.0.56",
"version": "0.0.58",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,18 @@
# @llamaindex/waku-query-engine-test
## 0.0.77
### Patch Changes
- Updated dependencies [2a82413]
- llamaindex@0.6.15
## 0.0.76
### Patch Changes
- llamaindex@0.6.14
## 0.0.75
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.75",
"version": "0.0.77",
"type": "module",
"private": true,
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llamaindex",
"version": "0.6.13",
"version": "0.6.15",
"license": "MIT",
"type": "module",
"keywords": [
-7
View File
@@ -2,7 +2,6 @@ import {
type CallbackManager,
Settings as CoreSettings,
} from "@llamaindex/core/global";
import { OpenAI } from "@llamaindex/openai";
import { PromptHelper } from "@llamaindex/core/indices";
@@ -61,12 +60,6 @@ class GlobalSettings implements Config {
}
get llm(): LLM {
// fixme: we might need check internal error instead of try-catch here
try {
CoreSettings.llm;
} catch (error) {
CoreSettings.llm = new OpenAI();
}
return CoreSettings.llm;
}
@@ -2,7 +2,7 @@ import { getEnv } from "@llamaindex/env";
import { OpenAIEmbedding } from "@llamaindex/openai";
export class FireworksEmbedding extends OpenAIEmbedding {
constructor(init?: Partial<OpenAIEmbedding>) {
constructor(init?: Omit<Partial<OpenAIEmbedding>, "session">) {
const {
apiKey = getEnv("FIREWORKS_API_KEY"),
additionalSessionOptions = {},
@@ -2,7 +2,7 @@ import { getEnv } from "@llamaindex/env";
import { OpenAIEmbedding } from "@llamaindex/openai";
export class TogetherEmbedding extends OpenAIEmbedding {
constructor(init?: Partial<OpenAIEmbedding>) {
constructor(init?: Omit<Partial<OpenAIEmbedding>, "session">) {
const {
apiKey = getEnv("TOGETHER_API_KEY"),
additionalSessionOptions = {},
+14 -2
View File
@@ -1,3 +1,15 @@
//#region initial setup for OpenAI
import { OpenAI } from "@llamaindex/openai";
import { Settings } from "./Settings.js";
try {
Settings.llm;
} catch {
Settings.llm = new OpenAI();
}
//#endregion
export {
LlamaParseReader,
type Language,
@@ -28,12 +40,12 @@ export type {
JSONArray,
JSONObject,
JSONValue,
LlamaIndexEventMaps,
LLMEndEvent,
LLMStartEvent,
LLMStreamEvent,
LLMToolCallEvent,
LLMToolResultEvent,
LlamaIndexEventMaps,
} from "@llamaindex/core/global";
export * from "@llamaindex/core/indices";
export * from "@llamaindex/core/llms";
@@ -61,7 +73,7 @@ export * from "./postprocessors/index.js";
export * from "./QuestionGenerator.js";
export * from "./selectors/index.js";
export * from "./ServiceContext.js";
export { Settings } from "./Settings.js";
export * from "./storage/StorageContext.js";
export * from "./tools/index.js";
export * from "./types.js";
export { Settings };
+1 -1
View File
@@ -6,7 +6,7 @@ const DEFAULT_MODEL = "mistralai/Mixtral-8x22B-Instruct-v0.1";
const BASE_URL = "https://api.deepinfra.com/v1/openai";
export class DeepInfra extends OpenAI {
constructor(init?: Partial<OpenAI>) {
constructor(init?: Omit<Partial<OpenAI>, "session">) {
const {
apiKey = getEnv(ENV_VARIABLE_NAME),
additionalSessionOptions = {},
+3 -1
View File
@@ -10,7 +10,9 @@ type DeepSeekModelName = keyof typeof DEEPSEEK_MODELS;
const DEFAULT_MODEL: DeepSeekModelName = "deepseek-coder";
export class DeepSeekLLM extends OpenAI {
constructor(init?: Partial<OpenAI> & { model?: DeepSeekModelName }) {
constructor(
init?: Omit<Partial<OpenAI>, "session"> & { model?: DeepSeekModelName },
) {
const {
apiKey = getEnv("DEEPSEEK_API_KEY"),
additionalSessionOptions = {},
+1 -1
View File
@@ -2,7 +2,7 @@ import { getEnv } from "@llamaindex/env";
import { OpenAI } from "@llamaindex/openai";
export class FireworksLLM extends OpenAI {
constructor(init?: Partial<OpenAI>) {
constructor(init?: Omit<Partial<OpenAI>, "session">) {
const {
apiKey = getEnv("FIREWORKS_API_KEY"),
additionalSessionOptions = {},
+1 -1
View File
@@ -2,7 +2,7 @@ import { getEnv } from "@llamaindex/env";
import { OpenAI } from "@llamaindex/openai";
export class TogetherLLM extends OpenAI {
constructor(init?: Partial<OpenAI>) {
constructor(init?: Omit<Partial<OpenAI>, "session">) {
const {
apiKey = getEnv("TOGETHER_API_KEY"),
additionalSessionOptions = {},
@@ -27,7 +27,7 @@ describe("VectorStoreIndex", () => {
runs: number = 2,
): Promise<Array<number>> => {
const documents = [new Document({ text: "lorem ipsem", id_: "1" })];
const entries = [];
const entries: number[] = [];
for (let i = 0; i < runs; i++) {
await VectorStoreIndex.fromDocuments(documents, {
serviceContext,
@@ -43,7 +43,7 @@ describe("VectorStoreIndex", () => {
test("fromDocuments stores duplicates without a doc store strategy", async () => {
const entries = await testStrategy(DocStoreStrategy.NONE);
expect(entries[0]! + 1).toBe(entries[1]);
expect(entries[0]).toBe(entries[1]);
});
test("fromDocuments ignores duplicates with upserts doc store strategy", async () => {
+7
View File
@@ -0,0 +1,7 @@
import { expect, test, vi } from "vitest";
test("init without error", async () => {
vi.stubEnv("OPENAI_API_KEY", undefined);
const { Settings } = await import("llamaindex");
expect(Settings.llm).toBeDefined();
});
+14
View File
@@ -1,5 +1,19 @@
# @llamaindex/groq
## 0.0.11
### Patch Changes
- 2a82413: fix(core): set `Settings.llm` to OpenAI by default and support lazy load openai
- Updated dependencies [2a82413]
- @llamaindex/openai@0.1.12
## 0.0.10
### Patch Changes
- @llamaindex/openai@0.1.11
## 0.0.9
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/groq",
"description": "Groq Adapter for LlamaIndex",
"version": "0.0.9",
"version": "0.0.11",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
+6 -5
View File
@@ -4,7 +4,7 @@ import GroqSDK, { type ClientOptions } from "groq-sdk";
export class Groq extends OpenAI {
constructor(
init?: Partial<OpenAI> & {
init?: Omit<Partial<OpenAI>, "session"> & {
additionalSessionOptions?: ClientOptions;
},
) {
@@ -22,9 +22,10 @@ export class Groq extends OpenAI {
...rest,
});
this.session.openai = new GroqSDK({
apiKey,
...init?.additionalSessionOptions,
}) as any;
this.lazySession = async () =>
new GroqSDK({
apiKey,
...init?.additionalSessionOptions,
}) as any;
}
}
+7
View File
@@ -1,5 +1,12 @@
# @llamaindex/ollama
## 0.0.4
### Patch Changes
- Updated dependencies [b17d439]
- @llamaindex/core@0.2.9
## 0.0.3
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/ollama",
"description": "Ollama Adapter for LlamaIndex",
"version": "0.0.3",
"version": "0.0.4",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
+13
View File
@@ -1,5 +1,18 @@
# @llamaindex/openai
## 0.1.12
### Patch Changes
- 2a82413: fix(core): set `Settings.llm` to OpenAI by default and support lazy load openai
## 0.1.11
### Patch Changes
- Updated dependencies [b17d439]
- @llamaindex/core@0.2.9
## 0.1.10
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/openai",
"description": "OpenAI Adapter for LlamaIndex",
"version": "0.1.10",
"version": "0.1.12",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
+8 -17
View File
@@ -2,11 +2,6 @@ import { getEnv } from "@llamaindex/env";
import type { AzureClientOptions } from "openai";
export interface AzureOpenAIConfig extends AzureClientOptions {
/** @deprecated use "deployment" instead */
deploymentName?: string | undefined;
}
// NOTE we're not supporting the legacy models as they're not available for new deployments
// https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/legacy-models
// If you have a need for them, please open an issue on GitHub
@@ -85,14 +80,15 @@ const DEFAULT_API_VERSION = "2023-05-15";
//^ NOTE: this will change over time, if you want to pin it, use a specific version
export function getAzureConfigFromEnv(
init?: Partial<AzureOpenAIConfig> & { model?: string },
): AzureOpenAIConfig {
init?: Partial<AzureClientOptions> & { model?: string },
): AzureClientOptions {
const deployment =
init?.deploymentName ??
init?.deployment ??
getEnv("AZURE_OPENAI_DEPLOYMENT") ?? // From Azure docs
getEnv("AZURE_OPENAI_API_DEPLOYMENT_NAME") ?? // LCJS compatible
init?.model; // Fall back to model name, Python compatible
init && "deploymentName" in init && typeof init.deploymentName === "string"
? init?.deploymentName
: (init?.deployment ??
getEnv("AZURE_OPENAI_DEPLOYMENT") ?? // From Azure docs
getEnv("AZURE_OPENAI_API_DEPLOYMENT_NAME") ?? // LCJS compatible
init?.model); // Fall back to model name, Python compatible
return {
apiKey:
init?.apiKey ??
@@ -110,15 +106,10 @@ export function getAzureConfigFromEnv(
getEnv("OPENAI_API_VERSION") ?? // Python compatible
getEnv("AZURE_OPENAI_API_VERSION") ?? // LCJS compatible
DEFAULT_API_VERSION,
deploymentName: deployment, // LCJS compatible
deployment, // For Azure OpenAI
};
}
export function getAzureBaseUrl(config: AzureOpenAIConfig): string {
return `${config.endpoint}/openai/deployments/${config.deploymentName}`;
}
export function getAzureModel(openAIModel: string) {
for (const [key, value] of Object.entries(
ALL_AZURE_OPENAI_EMBEDDING_MODELS,
+52 -29
View File
@@ -1,14 +1,16 @@
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 { getEnv, Tokenizers } from "@llamaindex/env";
import type {
AzureClientOptions,
AzureOpenAI as AzureOpenAILLM,
ClientOptions as OpenAIClientOptions,
OpenAI as OpenAILLM,
} from "openai";
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": {
@@ -32,6 +34,8 @@ export const ALL_OPENAI_EMBEDDING_MODELS = {
type ModelKeys = keyof typeof ALL_OPENAI_EMBEDDING_MODELS;
type LLMInstance = Pick<AzureOpenAILLM | OpenAILLM, "embeddings" | "apiKey">;
export class OpenAIEmbedding extends BaseEmbedding {
/** embeddding model. defaults to "text-embedding-ada-002" */
model: string;
@@ -51,14 +55,26 @@ export class OpenAIEmbedding extends BaseEmbedding {
| Omit<Partial<OpenAIClientOptions>, "apiKey" | "maxRetries" | "timeout">
| undefined;
/** session object */
session: OpenAISession;
// use lazy here to avoid check OPENAI_API_KEY immediately
lazySession: () => Promise<LLMInstance>;
#session: Promise<LLMInstance> | null = null;
get session() {
if (!this.#session) {
this.#session = this.lazySession();
}
return this.#session;
}
/**
* OpenAI Embedding
* @param init - initial parameters
*/
constructor(init?: Partial<OpenAIEmbedding> & { azure?: AzureOpenAIConfig }) {
constructor(
init?: Omit<Partial<OpenAIEmbedding>, "lazySession"> & {
session?: LLMInstance | undefined;
azure?: AzureClientOptions;
},
) {
super();
this.model = init?.model ?? "text-embedding-ada-002";
@@ -77,7 +93,6 @@ export class OpenAIEmbedding extends BaseEmbedding {
if (key) {
this.embedInfo = ALL_OPENAI_EMBEDDING_MODELS[key];
}
if (init?.azure || shouldUseAzure()) {
const azureConfig = {
...getAzureConfigFromEnv({
@@ -85,26 +100,32 @@ export class OpenAIEmbedding extends BaseEmbedding {
}),
...init?.azure,
};
this.apiKey = azureConfig.apiKey;
this.session =
init?.session ??
getOpenAISession({
azure: true,
maxRetries: this.maxRetries,
timeout: this.timeout,
...this.additionalSessionOptions,
...azureConfig,
});
this.apiKey =
init?.session?.apiKey ?? azureConfig.apiKey ?? getEnv("OPENAI_API_KEY");
this.lazySession = async () =>
import("openai").then(
async ({ AzureOpenAI }) =>
init?.session ??
new AzureOpenAI({
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,
this.apiKey = init?.session?.apiKey ?? getEnv("OPENAI_API_KEY");
this.lazySession = async () =>
import("openai").then(({ OpenAI }) => {
return (
init?.session ??
new OpenAI({
apiKey: this.apiKey,
maxRetries: this.maxRetries,
timeout: this.timeout!,
...this.additionalSessionOptions,
})
);
});
}
}
@@ -118,7 +139,9 @@ export class OpenAIEmbedding extends BaseEmbedding {
// 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(
const { data } = await (
await this.session
).embeddings.create(
this.dimensions
? {
model: this.model,
-3
View File
@@ -10,9 +10,6 @@ export {
GPT4_MODELS,
O1_MODELS,
OpenAI,
OpenAISession,
type OpenAIAdditionalChatOptions,
type OpenAIAdditionalMetadata,
} from "./llm";
export { type AzureOpenAIConfig } from "./azure";
+45 -80
View File
@@ -1,12 +1,11 @@
import { getEnv } from "@llamaindex/env";
import type OpenAILLM from "openai";
import type {
ClientOptions,
AzureClientOptions,
AzureOpenAI as AzureOpenAILLM,
ClientOptions as OpenAIClientOptions,
OpenAI as OpenAILLM,
} from "openai";
import { AzureOpenAI, OpenAI as OrigOpenAI } from "openai";
import type { ChatModel } from "openai/resources/chat/chat";
import { isDeepEqual } from "remeda";
import { wrapEventCaller, wrapLLMEvent } from "@llamaindex/core/decorator";
import {
@@ -35,64 +34,12 @@ import type {
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,
@@ -182,6 +129,8 @@ export type OpenAIAdditionalChatOptions = Omit<
| "toolChoice"
>;
type LLMInstance = Pick<AzureOpenAILLM | OpenAILLM, "chat" | "apiKey">;
export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
model:
| ChatModel
@@ -196,14 +145,24 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
apiKey?: string | undefined = undefined;
maxRetries: number;
timeout?: number;
session: OpenAISession;
additionalSessionOptions?:
| undefined
| Omit<Partial<OpenAIClientOptions>, "apiKey" | "maxRetries" | "timeout">;
// use lazy here to avoid check OPENAI_API_KEY immediately
lazySession: () => Promise<LLMInstance>;
#session: Promise<LLMInstance> | null = null;
get session() {
if (!this.#session) {
this.#session = this.lazySession();
}
return this.#session;
}
constructor(
init?: Partial<OpenAI> & {
azure?: AzureOpenAIConfig;
init?: Omit<Partial<OpenAI>, "session"> & {
session?: LLMInstance | undefined;
azure?: AzureClientOptions;
},
) {
super();
@@ -216,6 +175,8 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
this.timeout = init?.timeout ?? 60 * 1000; // Default is 60 seconds
this.additionalChatOptions = init?.additionalChatOptions;
this.additionalSessionOptions = init?.additionalSessionOptions;
this.apiKey =
init?.session?.apiKey ?? init?.apiKey ?? getEnv("OPENAI_API_KEY");
if (init?.azure || shouldUseAzure()) {
const azureConfig = {
@@ -225,25 +186,26 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
...init?.azure,
};
this.apiKey = azureConfig.apiKey;
this.session =
this.lazySession = async () =>
init?.session ??
getOpenAISession({
azure: true,
maxRetries: this.maxRetries,
timeout: this.timeout,
...this.additionalSessionOptions,
...azureConfig,
import("openai").then(({ AzureOpenAI }) => {
return new AzureOpenAI({
maxRetries: this.maxRetries,
timeout: this.timeout!,
...this.additionalSessionOptions,
...azureConfig,
});
});
} else {
this.apiKey = init?.apiKey ?? undefined;
this.session =
this.lazySession = async () =>
init?.session ??
getOpenAISession({
apiKey: this.apiKey,
maxRetries: this.maxRetries,
timeout: this.timeout,
...this.additionalSessionOptions,
import("openai").then(({ OpenAI }) => {
return new OpenAI({
apiKey: this.apiKey,
maxRetries: this.maxRetries,
timeout: this.timeout!,
...this.additionalSessionOptions,
});
});
}
}
@@ -382,7 +344,9 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
}
// Non-streaming
const response = await this.session.openai.chat.completions.create({
const response = await (
await this.session
).chat.completions.create({
...baseRequestParams,
stream: false,
});
@@ -414,11 +378,12 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
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,
});
const stream: AsyncIterable<OpenAILLM.Chat.ChatCompletionChunk> = await (
await this.session
).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.
+4 -62
View File
@@ -360,10 +360,10 @@ importers:
specifier: ^0.53.0
version: 0.53.0(typescript@5.6.2)
'@llamaindex/core':
specifier: workspace:^0.2.8
specifier: workspace:*
version: link:../core
'@llamaindex/env':
specifier: workspace:^0.1.13
specifier: workspace:*
version: link:../env
bunchee:
specifier: 5.3.2
@@ -19518,8 +19518,8 @@ snapshots:
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
eslint: 8.57.0
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.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0)
eslint-plugin-react: 7.35.0(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
@@ -19566,25 +19566,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 8.57.0
eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.8.0
is-bun-module: 1.1.0
is-glob: 4.0.3
optionalDependencies:
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
transitivePeerDependencies:
- '@typescript-eslint/parser'
- eslint-import-resolver-node
- eslint-import-resolver-webpack
- supports-color
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
dependencies:
'@nolyfill/is-core-module': 1.0.39
@@ -19604,17 +19585,6 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-module-utils@2.8.2(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
eslint: 8.57.0
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.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0)
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.8.2(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
dependencies:
debug: 3.2.7
@@ -19626,33 +19596,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
debug: 3.2.7
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.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
minimatch: 3.1.2
object.fromentries: 2.0.8
object.groupby: 1.0.3
object.values: 1.2.0
semver: 6.3.1
tsconfig-paths: 3.15.0
optionalDependencies:
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
@@ -19679,7 +19622,6 @@ snapshots:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
optional: true
eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.5.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0):
dependencies: