Compare commits

..

5 Commits

Author SHA1 Message Date
github-actions[bot] 3ae832ca28 Release 0.5.0 (#1024)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: himself65 <himself65@users.noreply.github.com>
2024-07-08 17:16:46 -07:00
Alex Yang 16ef5dd631 feat: simplify callback manager (#1027) 2024-07-08 16:44:54 -07:00
Alex Yang c4bd0a5215 refactor: move llm & callback manager to core module (#1026) 2024-07-08 15:48:59 -07:00
Alex Yang f5c8ca7dfb chore: use bunchee bundler for all (#1025) 2024-07-08 09:45:55 -07:00
Sacha Bron 36ddec44af fix: typo in custom page separator parameter for LlamaParse (#1023) 2024-07-08 09:27:51 -07:00
113 changed files with 954 additions and 1315 deletions
+11
View File
@@ -1,5 +1,16 @@
# docs
## 0.0.41
### Patch Changes
- 36ddec4: fix: typo in custom page separator parameter for LlamaParse
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
- @llamaindex/examples@0.0.7
## 0.0.40
### Patch Changes
@@ -27,25 +27,25 @@ They can be divided into two groups.
- `apiKey` is required. Can be set as an environment variable `LLAMA_CLOUD_API_KEY`
- `checkInterval` is the interval in seconds to check if the parsing is done. Default is `1`.
- `maxTimeout` is the maximum timout to wait for parsing to finish. Default is `2000`
- `maxTimeout` is the maximum timeout to wait for parsing to finish. Default is `2000`
- `verbose` shows progress of the parsing. Default is `true`
- `ignoreErrors` set to false to get errors while parsing. Default is `true` and returns an empty array on error.
#### Advanced params:
- `resultType` can be set to `markdown`, `text` or `json`. Defaults to `text`. More information about `json` mode on the next pages.
- `language` primarly helps with OCR recognition. Defaults to `en`. Click [here](../../../api/type-aliases/Language.md) for a list of supported languages.
- `language` primarily helps with OCR recognition. Defaults to `en`. Click [here](../../../api/type-aliases/Language.md) for a list of supported languages.
- `parsingInstructions?` Optional. Can help with complicated document structures. See this [LlamaIndex Blog Post](https://www.llamaindex.ai/blog/launching-the-first-genai-native-document-parsing-platform) for an example.
- `skipDiagonalText?` Optional. Set to true to ignore diagonal text. (Text that is not rotated 0, 90, 180 or 270 degrees)
- `invalidateCache?` Optional. Set to true to ignore the LlamaCloud cache. All document are kept in cache for 48hours after the job was completed to avoid processing the same document twice. Can be useful for testing when trying to re-parse the same document with, e.g. different `parsingInstructions`.
- `doNotCache?` Optional. Set to true to not cache the document.
- `fastMode?` Optional. Set to true to use the fast mode. This mode will skip OCR of images, and table/heading reconstruction. Note: Non-compatible with `gpt4oMode`.
- `doNotUnrollColumns?` Optional. Set to true to keep the text according to document layout. Reduce reconstruction accuracy, and LLM's/embedings performances in most cases.
- `pageSeperator?` Optional. The page seperator to use. Defaults is `\\n---\\n`.
- `doNotUnrollColumns?` Optional. Set to true to keep the text according to document layout. Reduce reconstruction accuracy, and LLMs/embeddings performances in most cases.
- `pageSeparator?` Optional. The page separator to use. Defaults is `\\n---\\n`.
- `gpt4oMode` set to true to use GPT-4o to extract content. Default is `false`.
- `gpt4oApiKey?` Optional. Set the GPT-4o API key. Lowers the cost of parsing by using your own API key. Your OpenAI account will be charged. Can also be set in the environment variable `LLAMA_CLOUD_GPT4O_API_KEY`.
- `boundingBox?` Optional. Specify an area of the document to parse. Expects the bounding box margins as a string in clockwise order, e.g. `boundingBox = "0.1,0,0,0"` to not parse the top 10% of the document.
- `targetPages?` Optional. Specify which pages to parse by specifying them as a comma-seperated list. First page is `0`.
- `targetPages?` Optional. Specify which pages to parse by specifying them as a comma-separated list. First page is `0`.
- `numWorkers` as in the python version, is set in `SimpleDirectoryReader`. Default is 1.
### LlamaParse with SimpleDirectoryReader
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.40",
"version": "0.0.41",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
+10
View File
@@ -1,5 +1,15 @@
# examples
## 0.0.7
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
- @llamaindex/core@0.1.0
## 0.0.6
### Patch Changes
+1 -1
View File
@@ -2,7 +2,7 @@ import { Anthropic, FunctionTool, Settings, WikipediaTool } from "llamaindex";
import { AnthropicAgent } from "llamaindex/agent/anthropic";
Settings.callbackManager.on("llm-tool-call", (event) => {
console.log("llm-tool-call", event.detail.payload.toolCall);
console.log("llm-tool-call", event.detail.toolCall);
});
const anthropic = new Anthropic({
+2 -3
View File
@@ -4,7 +4,6 @@ import {
NodeWithScore,
ObjectType,
OpenAI,
RetrievalEndEvent,
Settings,
VectorStoreIndex,
} from "llamaindex";
@@ -18,8 +17,8 @@ Settings.chunkOverlap = 20;
Settings.llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 512 });
// Update callbackManager
Settings.callbackManager.on("retrieve-end", (event: RetrievalEndEvent) => {
const { nodes, query } = event.detail.payload;
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes, query } = event.detail;
const imageNodes = nodes.filter(
(node: NodeWithScore) => node.node.type === ObjectType.IMAGE_DOCUMENT,
);
+2 -3
View File
@@ -1,7 +1,6 @@
import {
MultiModalResponseSynthesizer,
OpenAI,
RetrievalEndEvent,
Settings,
VectorStoreIndex,
} from "llamaindex";
@@ -15,8 +14,8 @@ Settings.chunkOverlap = 20;
Settings.llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 512 });
// Update callbackManager
Settings.callbackManager.on("retrieve-end", (event: RetrievalEndEvent) => {
const { nodes, query } = event.detail.payload;
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes, query } = event.detail;
console.log(`Retrieved ${nodes.length} nodes for query: ${query}`);
});
+3 -2
View File
@@ -1,11 +1,12 @@
{
"name": "@llamaindex/examples",
"private": true,
"version": "0.0.6",
"version": "0.0.7",
"dependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
"@azure/identity": "^4.2.1",
"@datastax/astra-db-ts": "^1.2.1",
"@llamaindex/core": "^0.1.0",
"@notionhq/client": "^2.2.15",
"@pinecone-database/pinecone": "^2.2.2",
"@zilliz/milvus2-sdk-node": "^2.4.2",
@@ -13,7 +14,7 @@
"commander": "^12.1.0",
"dotenv": "^16.4.5",
"js-tiktoken": "^1.0.12",
"llamaindex": "^0.4.3",
"llamaindex": "^0.5.0",
"mongodb": "^6.7.0",
"pathe": "^1.1.2"
},
+7 -8
View File
@@ -1,8 +1,8 @@
import * as dotenv from "dotenv";
import {
CallbackManager,
Document,
MetadataMode,
NodeWithScore,
QdrantVectorStore,
Settings,
VectorStoreIndex,
@@ -10,13 +10,12 @@ import {
} from "llamaindex";
// Update callback manager
Settings.callbackManager = new CallbackManager({
onRetrieve: (data) => {
console.log(
"The retrieved nodes are:",
data.nodes.map((node) => node.node.getContent(MetadataMode.NONE)),
);
},
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes } = event.detail;
console.log(
"The retrieved nodes are:",
nodes.map((node: NodeWithScore) => node.node.getContent(MetadataMode.NONE)),
);
});
// Load environment variables from local .env file
+5 -5
View File
@@ -1,7 +1,7 @@
import { extractText } from "@llamaindex/core/utils";
import { encodingForModel } from "js-tiktoken";
import { ChatMessage, OpenAI, type LLMStartEvent } from "llamaindex";
import { ChatMessage, OpenAI } from "llamaindex";
import { Settings } from "llamaindex/Settings";
import { extractText } from "llamaindex/llm/utils";
const encoding = encodingForModel("gpt-4-0125-preview");
@@ -12,8 +12,8 @@ const llm = new OpenAI({
let tokenCount = 0;
Settings.callbackManager.on("llm-start", (event: LLMStartEvent) => {
const { messages } = event.detail.payload;
Settings.callbackManager.on("llm-start", (event) => {
const { messages } = event.detail;
messages.reduce((count: number, message: ChatMessage) => {
return count + encoding.encode(extractText(message.content)).length;
}, 0);
@@ -24,7 +24,7 @@ Settings.callbackManager.on("llm-start", (event: LLMStartEvent) => {
});
Settings.callbackManager.on("llm-stream", (event) => {
const { chunk } = event.detail.payload;
const { chunk } = event.detail;
const { delta } = chunk;
tokenCount += encoding.encode(extractText(delta)).length;
if (tokenCount > 20) {
-3
View File
@@ -39,9 +39,6 @@
"trim": "1.0.1",
"@babel/traverse": "7.23.2",
"protobufjs": "7.2.6"
},
"patchedDependencies": {
"bunchee@5.2.1": "patches/bunchee@5.2.1.patch"
}
},
"lint-staged": {
+9
View File
@@ -1,5 +1,14 @@
# @llamaindex/autotool
## 2.0.0
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 1.0.0
### Patch Changes
@@ -1,5 +1,15 @@
# @llamaindex/autotool-02-next-example
## 0.1.25
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
- @llamaindex/autotool@2.0.0
## 0.1.24
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool-02-next-example",
"private": true,
"version": "0.1.24",
"version": "0.1.25",
"scripts": {
"dev": "next dev",
"build": "next build",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool",
"type": "module",
"version": "1.0.0",
"version": "2.0.0",
"description": "auto transpile your JS function to LLM Agent compatible",
"files": [
"dist",
@@ -51,7 +51,7 @@
"unplugin": "^1.10.1"
},
"peerDependencies": {
"llamaindex": "^0.4.14",
"llamaindex": "^0.5.0",
"openai": "^4",
"typescript": "^4"
},
@@ -70,7 +70,7 @@
"@swc/types": "^0.1.8",
"@types/json-schema": "^7.0.15",
"@types/node": "^20.12.11",
"bunchee": "^5.2.1",
"bunchee": "5.3.0-beta.0",
"llamaindex": "workspace:*",
"next": "14.2.3",
"rollup": "^4.18.0",
+6
View File
@@ -1,5 +1,11 @@
# @llamaindex/cloud
## 0.1.4
### Patch Changes
- 36ddec4: fix: typo in custom page separator parameter for LlamaParse
## 0.1.3
### Patch Changes
+2 -2
View File
@@ -12113,9 +12113,9 @@
"description": "Template for how metadata is formatted, with {key} and {value} placeholders.",
"default": "{key}: {value}"
},
"metadata_seperator": {
"metadata_separator": {
"type": "string",
"title": "Metadata Seperator",
"title": "Metadata Separator",
"description": "Separator between metadata fields when converting to string.",
"default": "\n"
},
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloud",
"version": "0.1.3",
"version": "0.1.4",
"type": "module",
"license": "MIT",
"scripts": {
@@ -35,6 +35,6 @@
},
"devDependencies": {
"@hey-api/openapi-ts": "^0.48.0",
"bunchee": "^5.2.1"
"bunchee": "5.3.0-beta.0"
}
}
+9
View File
@@ -1,5 +1,14 @@
# @llamaindex/community
## 0.0.19
### Patch Changes
- 16ef5dd: refactor: depends on core pacakge instead of llamaindex
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- @llamaindex/core@0.1.0
## 0.0.18
### Patch Changes
+6 -11
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/community",
"description": "Community package for LlamaIndexTS",
"version": "0.0.18",
"version": "0.0.19",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
@@ -38,20 +38,15 @@
"directory": "packages/community"
},
"scripts": {
"build": "rm -rf ./dist && pnpm run build:code && pnpm run build:type",
"build:code": "tsup",
"build:type": "tsc -p tsconfig.json",
"dev": "concurrently \"pnpm run build:esm --watch\" \"pnpm run build:cjs --watch\" \"pnpm run build:type --watch\""
"build": "bunchee",
"dev": "bunchee --watch"
},
"devDependencies": {
"@swc/cli": "^0.3.12",
"@swc/core": "^1.6.3",
"concurrently": "^8.2.2",
"tsup": "^8.1.0"
"@types/node": "^20.14.2",
"bunchee": "5.3.0-beta.0"
},
"dependencies": {
"@aws-sdk/client-bedrock-runtime": "^3.600.0",
"@types/node": "^20.14.2",
"llamaindex": "workspace:*"
"@llamaindex/core": "workspace:*"
}
}
+13 -12
View File
@@ -4,18 +4,19 @@ import {
InvokeModelCommand,
InvokeModelWithResponseStreamCommand,
} from "@aws-sdk/client-bedrock-runtime";
import type {
ChatMessage,
ChatResponse,
CompletionResponse,
LLMChatParamsNonStreaming,
LLMChatParamsStreaming,
LLMCompletionParamsNonStreaming,
LLMCompletionParamsStreaming,
LLMMetadata,
ToolCallLLMMessageOptions,
} from "llamaindex";
import { streamConverter, ToolCallLLM, wrapLLMEvent } from "llamaindex";
import {
type ChatMessage,
type ChatResponse,
type CompletionResponse,
type LLMChatParamsNonStreaming,
type LLMChatParamsStreaming,
type LLMCompletionParamsNonStreaming,
type LLMCompletionParamsStreaming,
type LLMMetadata,
ToolCallLLM,
type ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { streamConverter, wrapLLMEvent } from "@llamaindex/core/utils";
import {
type BedrockAdditionalChatOptions,
type BedrockChatStreamResponse,
@@ -8,9 +8,9 @@ import {
type ChatMessage,
type ChatResponseChunk,
type LLMMetadata,
streamConverter,
type ToolCallLLMMessageOptions,
} from "llamaindex";
} from "@llamaindex/core/llms";
import { streamConverter } from "@llamaindex/core/utils";
import type { ToolChoice } from "./types";
import { toUtf8 } from "./utils";
@@ -10,7 +10,7 @@ import type {
PartialToolCall,
ToolCall,
ToolCallLLMMessageOptions,
} from "llamaindex";
} from "@llamaindex/core/llms";
import {
type BedrockAdditionalChatOptions,
type BedrockChatStreamResponse,
@@ -2,7 +2,7 @@ import type {
InvokeModelCommandInput,
InvokeModelWithResponseStreamCommandInput,
} from "@aws-sdk/client-bedrock-runtime";
import type { ChatMessage, LLMMetadata } from "llamaindex";
import type { ChatMessage, LLMMetadata } from "@llamaindex/core/llms";
import type { MetaNoneStreamingResponse, MetaStreamEvent } from "../types";
import {
mapChatMessagesToMetaLlama2Messages,
+2 -2
View File
@@ -1,13 +1,13 @@
import type { JSONObject } from "@llamaindex/core/global";
import type {
BaseTool,
ChatMessage,
JSONObject,
MessageContent,
MessageContentDetail,
MessageContentTextDetail,
ToolCallLLMMessageOptions,
ToolMetadata,
} from "llamaindex";
} from "@llamaindex/core/llms";
import type {
AnthropicContent,
AnthropicImageContent,
-9
View File
@@ -1,9 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist/script/type",
"tsBuildInfoFile": "./dist/script/.tsbuildinfo",
"emitDeclarationOnly": true
},
"include": ["./tsup.config.ts"]
}
-9
View File
@@ -1,9 +0,0 @@
import { defineConfig } from "tsup";
export default defineConfig([
{
entry: ["src/index.ts", "src/llm/bedrock/base.ts"],
format: ["cjs", "esm"],
sourcemap: true,
},
]);
+15
View File
@@ -1,5 +1,20 @@
# @llamaindex/core
## 0.1.0
### Minor Changes
- 16ef5dd: refactor: simplify callback manager
Change `event.detail.payload` to `event.detail`
### Patch Changes
- 16ef5dd: refactor: move callback manager & llm to core module
For people who import `llamaindex/llms/base` or `llamaindex/llms/utils`,
use `@llamaindex/core/llms` and `@llamaindex/core/utils` instead.
## 0.0.3
### Patch Changes
+16 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/core",
"type": "module",
"version": "0.0.3",
"version": "0.1.0",
"description": "LlamaIndex Core Module",
"exports": {
"./llms": {
@@ -59,6 +59,20 @@
"types": "./dist/schema/index.d.ts",
"default": "./dist/schema/index.js"
}
},
"./utils": {
"require": {
"types": "./dist/utils/index.d.cts",
"default": "./dist/utils/index.cjs"
},
"import": {
"types": "./dist/utils/index.d.ts",
"default": "./dist/utils/index.js"
},
"default": {
"types": "./dist/utils/index.d.ts",
"default": "./dist/utils/index.js"
}
}
},
"files": [
@@ -75,7 +89,7 @@
},
"devDependencies": {
"ajv": "^8.16.0",
"bunchee": "^5.2.1"
"bunchee": "5.3.0-beta.0"
},
"dependencies": {
"@llamaindex/env": "workspace:*",
+10
View File
@@ -1 +1,11 @@
export { Settings } from "./settings";
export { CallbackManager } from "./settings/callback-manager";
export type {
LLMEndEvent,
LLMStartEvent,
LLMStreamEvent,
LLMToolCallEvent,
LLMToolResultEvent,
LlamaIndexEventMaps,
} from "./settings/callback-manager";
export type { JSONArray, JSONObject, JSONValue } from "./type";
+21
View File
@@ -1,3 +1,9 @@
import {
type CallbackManager,
getCallbackManager,
setCallbackManager,
withCallbackManager,
} from "./settings/callback-manager";
import {
getChunkSize,
setChunkSize,
@@ -14,4 +20,19 @@ export const Settings = {
withChunkSize<Result>(chunkSize: number, fn: () => Result): Result {
return withChunkSize(chunkSize, fn);
},
get callbackManager(): CallbackManager {
return getCallbackManager();
},
set callbackManager(callbackManager: CallbackManager) {
setCallbackManager(callbackManager);
},
withCallbackManager<Result>(
callbackManager: CallbackManager,
fn: () => Result,
): Result {
return withCallbackManager(callbackManager, fn);
},
};
@@ -0,0 +1,140 @@
import { AsyncLocalStorage, CustomEvent } from "@llamaindex/env";
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
ToolCall,
ToolOutput,
} from "../../llms";
import { EventCaller, getEventCaller } from "../../utils/event-caller";
import type { UUID } from "../type";
export type LLMStartEvent = {
id: UUID;
messages: ChatMessage[];
};
export type LLMToolCallEvent = {
toolCall: ToolCall;
};
export type LLMToolResultEvent = {
toolCall: ToolCall;
toolResult: ToolOutput;
};
export type LLMEndEvent = {
id: UUID;
response: ChatResponse;
};
export type LLMStreamEvent = {
id: UUID;
chunk: ChatResponseChunk;
};
export interface LlamaIndexEventMaps {
"llm-start": LLMStartEvent;
"llm-end": LLMEndEvent;
"llm-tool-call": LLMToolCallEvent;
"llm-tool-result": LLMToolResultEvent;
"llm-stream": LLMStreamEvent;
}
export class LlamaIndexCustomEvent<T = any> extends CustomEvent<T> {
reason: EventCaller | null = null;
private constructor(
event: string,
options?: CustomEventInit & {
reason?: EventCaller | null;
},
) {
super(event, options);
this.reason = options?.reason ?? null;
}
static fromEvent<Type extends keyof LlamaIndexEventMaps>(
type: Type,
detail: LlamaIndexEventMaps[Type],
) {
return new LlamaIndexCustomEvent(type, {
detail: detail,
reason: getEventCaller(),
});
}
}
type EventHandler<Event> = (event: LlamaIndexCustomEvent<Event>) => void;
export class CallbackManager {
#handlers = new Map<keyof LlamaIndexEventMaps, EventHandler<any>[]>();
on<K extends keyof LlamaIndexEventMaps>(
event: K,
handler: EventHandler<LlamaIndexEventMaps[K]>,
) {
if (!this.#handlers.has(event)) {
this.#handlers.set(event, []);
}
this.#handlers.get(event)!.push(handler);
return this;
}
off<K extends keyof LlamaIndexEventMaps>(
event: K,
handler: EventHandler<LlamaIndexEventMaps[K]>,
) {
if (!this.#handlers.has(event)) {
return this;
}
const cbs = this.#handlers.get(event)!;
const index = cbs.indexOf(handler);
if (index > -1) {
cbs.splice(index, 1);
}
return this;
}
dispatchEvent<K extends keyof LlamaIndexEventMaps>(
event: K,
detail: LlamaIndexEventMaps[K],
) {
const cbs = this.#handlers.get(event);
if (!cbs) {
return;
}
queueMicrotask(() => {
cbs.forEach((handler) =>
handler(
LlamaIndexCustomEvent.fromEvent(event, structuredClone(detail)),
),
);
});
}
}
export const globalCallbackManager = new CallbackManager();
const callbackManagerAsyncLocalStorage =
new AsyncLocalStorage<CallbackManager>();
let currentCallbackManager: CallbackManager | null = null;
export function getCallbackManager(): CallbackManager {
return (
callbackManagerAsyncLocalStorage.getStore() ??
currentCallbackManager ??
globalCallbackManager
);
}
export function setCallbackManager(callbackManager: CallbackManager) {
currentCallbackManager = callbackManager;
}
export function withCallbackManager<Result>(
callbackManager: CallbackManager,
fn: () => Result,
): Result {
return callbackManagerAsyncLocalStorage.run(callbackManager, fn);
}
@@ -1,3 +1,5 @@
import { streamConverter } from "../utils";
import { extractText } from "../utils/llms";
import type {
ChatResponse,
ChatResponseChunk,
@@ -9,8 +11,7 @@ import type {
LLMCompletionParamsStreaming,
LLMMetadata,
ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { extractText, streamConverter } from "./utils.js";
} from "./type";
export abstract class BaseLLM<
AdditionalChatOptions extends object = object,
+1
View File
@@ -1,3 +1,4 @@
export { BaseLLM, ToolCallLLM } from "./base";
export type {
BaseTool,
BaseToolWithCall,
@@ -1,5 +1,14 @@
import { AsyncLocalStorage, randomUUID } from "@llamaindex/env";
import { isAsyncIterable, isIterable } from "../utils.js";
export const isAsyncIterable = (
obj: unknown,
): obj is AsyncIterable<unknown> => {
return obj != null && typeof obj === "object" && Symbol.asyncIterator in obj;
};
export const isIterable = (obj: unknown): obj is Iterable<unknown> => {
return obj != null && typeof obj === "object" && Symbol.iterator in obj;
};
const eventReasonAsyncLocalStorage = new AsyncLocalStorage<EventCaller>();
+54
View File
@@ -0,0 +1,54 @@
export { wrapEventCaller } from "./event-caller";
export async function* streamConverter<S, D>(
stream: AsyncIterable<S>,
converter: (s: S) => D | null,
): AsyncIterable<D> {
for await (const data of stream) {
const newData = converter(data);
if (newData === null) {
return;
}
yield newData;
}
}
export async function* streamCallbacks<S>(
stream: AsyncIterable<S>,
callbacks: {
finished?: (value?: S) => void;
},
): AsyncIterable<S> {
let value: S | undefined;
for await (value of stream) {
yield value;
}
if (callbacks.finished) {
callbacks.finished(value);
}
}
export async function* streamReducer<S, D>(params: {
stream: AsyncIterable<S>;
reducer: (previousValue: D, currentValue: S) => D;
initialValue: D;
finished?: (value: D) => void;
}): AsyncIterable<S> {
let value = params.initialValue;
for await (const data of params.stream) {
value = params.reducer(value, data);
yield data;
}
if (params.finished) {
params.finished(value);
}
}
export { wrapLLMEvent } from "./wrap-llm-event";
export {
extractDataUrlComponents,
extractImage,
extractSingleText,
extractText,
} from "./llms";
+79
View File
@@ -0,0 +1,79 @@
import type {
MessageContent,
MessageContentDetail,
MessageContentTextDetail,
} from "../llms";
import type { ImageType } from "../schema";
/**
* Extracts just the text from a multi-modal message or the message itself if it's just text.
*
* @param message The message to extract text from.
* @returns The extracted text
*/
export function extractText(message: MessageContent): string {
if (typeof message !== "string" && !Array.isArray(message)) {
console.warn(
"extractText called with non-MessageContent message, this is likely a bug.",
);
return `${message}`;
} else if (typeof message !== "string" && Array.isArray(message)) {
// message is of type MessageContentDetail[] - retrieve just the text parts and concatenate them
// so we can pass them to the context generator
return message
.filter((c): c is MessageContentTextDetail => c.type === "text")
.map((c) => c.text)
.join("\n\n");
} else {
return message;
}
}
/**
* Extracts a single text from a multi-modal message content
*
* @param message The message to extract images from.
* @returns The extracted images
*/
export function extractSingleText(
message: MessageContentDetail,
): string | null {
if (message.type === "text") {
return message.text;
}
return null;
}
/**
* Extracts an image from a multi-modal message content
*
* @param message The message to extract images from.
* @returns The extracted images
*/
export function extractImage(message: MessageContentDetail): ImageType | null {
if (message.type === "image_url") {
return new URL(message.image_url.url);
}
return null;
}
export const extractDataUrlComponents = (
dataUrl: string,
): {
mimeType: string;
base64: string;
} => {
const parts = dataUrl.split(";base64,");
if (parts.length !== 2 || !parts[0].startsWith("data:")) {
throw new Error("Invalid data URL");
}
const mimeType = parts[0].slice(5);
const base64 = parts[1];
return {
mimeType,
base64,
};
};
+80
View File
@@ -0,0 +1,80 @@
import { AsyncLocalStorage, randomUUID } from "@llamaindex/env";
import { getCallbackManager } from "../global/settings/callback-manager";
import type { ChatResponse, ChatResponseChunk, LLM, LLMChat } from "../llms";
export function wrapLLMEvent<
AdditionalChatOptions extends object = object,
AdditionalMessageOptions extends object = object,
>(
originalMethod: LLMChat<
AdditionalChatOptions,
AdditionalMessageOptions
>["chat"],
_context: ClassMethodDecoratorContext,
) {
return async function withLLMEvent(
this: LLM<AdditionalChatOptions, AdditionalMessageOptions>,
...params: Parameters<
LLMChat<AdditionalChatOptions, AdditionalMessageOptions>["chat"]
>
): ReturnType<
LLMChat<AdditionalChatOptions, AdditionalMessageOptions>["chat"]
> {
const id = randomUUID();
getCallbackManager().dispatchEvent("llm-start", {
id,
messages: params[0].messages,
});
const response = await originalMethod.call(this, ...params);
if (Symbol.asyncIterator in response) {
// save snapshot to restore it after the response is done
const snapshot = AsyncLocalStorage.snapshot();
const originalAsyncIterator = {
[Symbol.asyncIterator]: response[Symbol.asyncIterator].bind(response),
};
response[Symbol.asyncIterator] = async function* () {
const finalResponse = {
raw: [] as ChatResponseChunk[],
message: {
content: "",
role: "assistant",
options: {},
},
} satisfies ChatResponse;
let firstOne = false;
for await (const chunk of originalAsyncIterator) {
if (!firstOne) {
firstOne = true;
finalResponse.message.content = chunk.delta;
} else {
finalResponse.message.content += chunk.delta;
}
if (chunk.options) {
finalResponse.message.options = {
...finalResponse.message.options,
...chunk.options,
};
}
getCallbackManager().dispatchEvent("llm-stream", {
id,
chunk,
});
finalResponse.raw.push(chunk);
yield chunk;
}
snapshot(() => {
getCallbackManager().dispatchEvent("llm-end", {
id,
response: finalResponse,
});
});
};
} else {
getCallbackManager().dispatchEvent("llm-end", {
id,
response,
});
}
return response;
};
}
+67
View File
@@ -0,0 +1,67 @@
import { CallbackManager, Settings } from "@llamaindex/core/global";
import { beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest";
declare module "@llamaindex/core/global" {
interface LlamaIndexEventMaps {
test: {
value: number;
};
}
}
describe("event system", () => {
beforeEach(() => {
Settings.callbackManager = new CallbackManager();
});
test("type system", () => {
Settings.callbackManager.on("test", (event) => {
const data = event.detail;
expectTypeOf(data).not.toBeAny();
expectTypeOf(data).toEqualTypeOf<{
value: number;
}>();
});
});
test("dispatch event", async () => {
let callback;
Settings.callbackManager.on(
"test",
(callback = vi.fn((event) => {
const data = event.detail;
expect(data.value).toBe(42);
})),
);
Settings.callbackManager.dispatchEvent("test", {
value: 42,
});
expect(callback).toHaveBeenCalledTimes(0);
await new Promise((resolve) => process.nextTick(resolve));
expect(callback).toHaveBeenCalledTimes(1);
});
// rollup doesn't support decorators for now
// test('wrap event caller', async () => {
// class A {
// @wrapEventCaller
// fn() {
// Settings.callbackManager.dispatchEvent('test', {
// value: 42
// });
// }
// }
// const a = new A();
// let callback;
// Settings.callbackManager.on('test', callback = vi.fn((event) => {
// const data = event.detail;
// expect(event.reason!.caller).toBe(a);
// expect(data.value).toBe(42);
// }));
// a.fn();
// expect(callback).toHaveBeenCalledTimes(0);
// await new Promise((resolve) => process.nextTick(resolve));
// expect(callback).toHaveBeenCalledTimes(1);
// })
});
+1
View File
@@ -8,6 +8,7 @@
"moduleResolution": "Bundler",
"skipLibCheck": true,
"strict": true,
"lib": ["ESNext", "DOM"],
"types": ["node"]
},
"include": ["./src"],
+9
View File
@@ -1,5 +1,14 @@
# @llamaindex/experimental
## 0.0.50
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 0.0.49
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/experimental",
"description": "Experimental package for LlamaIndexTS",
"version": "0.0.49",
"version": "0.0.50",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
+23 -1
View File
@@ -1,5 +1,27 @@
# llamaindex
## 0.5.0
### Minor Changes
- 16ef5dd: refactor: simplify callback manager
Change `event.detail.payload` to `event.detail`
### Patch Changes
- 16ef5dd: refactor: move callback manager & llm to core module
For people who import `llamaindex/llms/base` or `llamaindex/llms/utils`,
use `@llamaindex/core/llms` and `@llamaindex/core/utils` instead.
- 36ddec4: fix: typo in custom page separator parameter for LlamaParse
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- @llamaindex/core@0.1.0
- @llamaindex/cloud@0.1.4
## 0.4.14
### Patch Changes
@@ -125,7 +147,7 @@
### Patch Changes
- 6bc5bdd: feat: add cache disabling, fast mode, do not unroll columns mode and custom page seperator to LlamaParseReader
- 6bc5bdd: feat: add cache disabling, fast mode, do not unroll columns mode and custom page separator to LlamaParseReader
- bf25ff6: fix: polyfill for cloudflare worker
- e6d6576: chore: use `unpdf`
@@ -1,5 +1,14 @@
# @llamaindex/cloudflare-worker-agent-test
## 0.0.34
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 0.0.33
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.33",
"version": "0.0.34",
"type": "module",
"private": true,
"scripts": {
@@ -1,5 +1,14 @@
# @llamaindex/next-agent-test
## 0.1.34
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 0.1.33
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.33",
"version": "0.1.34",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,14 @@
# test-edge-runtime
## 0.1.33
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 0.1.32
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.32",
"version": "0.1.33",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,5 +1,14 @@
# @llamaindex/next-node-runtime
## 0.0.15
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 0.0.14
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.0.14",
"version": "0.0.15",
"private": true,
"scripts": {
"dev": "next dev",
@@ -19,10 +19,10 @@ Settings.embedModel = new HuggingFaceEmbedding({
quantized: false,
});
Settings.callbackManager.on("llm-tool-call", (event) => {
console.log(event.detail.payload);
console.log(event.detail);
});
Settings.callbackManager.on("llm-tool-result", (event) => {
console.log(event.detail.payload);
console.log(event.detail);
});
export async function getOpenAIModelRequest(query: string) {
@@ -1,5 +1,14 @@
# @llamaindex/waku-query-engine-test
## 0.0.34
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
## 0.0.33
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.33",
"version": "0.0.34",
"type": "module",
"private": true,
"scripts": {
@@ -1,3 +1,4 @@
import { extractText } from "@llamaindex/core/utils";
import type {
ChatResponse,
ChatResponseChunk,
@@ -8,7 +9,6 @@ import type {
LLMCompletionParamsNonStreaming,
LLMCompletionParamsStreaming,
} from "llamaindex";
import { extractText } from "llamaindex/llm/utils";
import { deepStrictEqual, strictEqual } from "node:assert";
import { llmCompleteMockStorage } from "../../node/utils.js";
+1 -1
View File
@@ -1,7 +1,7 @@
import { extractText } from "@llamaindex/core/utils";
import { consola } from "consola";
import { Anthropic, FunctionTool, Settings, type LLM } from "llamaindex";
import { AnthropicAgent } from "llamaindex/agent/anthropic";
import { extractText } from "llamaindex/llm/utils";
import { ok } from "node:assert";
import { beforeEach, test } from "node:test";
import { getWeatherTool, sumNumbersTool } from "./fixtures/tools.js";
+1 -1
View File
@@ -1,3 +1,4 @@
import { extractText } from "@llamaindex/core/utils";
import { consola } from "consola";
import {
Document,
@@ -14,7 +15,6 @@ import {
VectorStoreIndex,
type LLM,
} from "llamaindex";
import { extractText } from "llamaindex/llm/utils";
import { ok, strictEqual } from "node:assert";
import { readFile } from "node:fs/promises";
import { join } from "node:path";
+1 -1
View File
@@ -1,5 +1,5 @@
import { extractText } from "@llamaindex/core/utils";
import { OpenAI, ReActAgent, Settings, type LLM } from "llamaindex";
import { extractText } from "llamaindex/llm/utils";
import { ok } from "node:assert";
import { beforeEach, test } from "node:test";
import { getWeatherTool } from "./fixtures/tools.js";
+14 -13
View File
@@ -4,16 +4,17 @@ import {
type LLMEndEvent,
type LLMStartEvent,
type LLMStreamEvent,
} from "llamaindex";
} from "@llamaindex/core/global";
import { CustomEvent } from "@llamaindex/env";
import { readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { type test } from "node:test";
import { fileURLToPath } from "node:url";
type MockStorage = {
llmEventStart: LLMStartEvent["detail"]["payload"][];
llmEventEnd: LLMEndEvent["detail"]["payload"][];
llmEventStream: LLMStreamEvent["detail"]["payload"][];
llmEventStart: LLMStartEvent[];
llmEventEnd: LLMEndEvent[];
llmEventStream: LLMStreamEvent[];
};
export const llmCompleteMockStorage: MockStorage = {
@@ -36,35 +37,35 @@ export async function mockLLMEvent(
llmEventStream: [],
};
function captureLLMStart(event: LLMStartEvent) {
idMap.set(event.detail.payload.id, `PRESERVE_${counter++}`);
function captureLLMStart(event: CustomEvent<LLMStartEvent>) {
idMap.set(event.detail.id, `PRESERVE_${counter++}`);
newLLMCompleteMockStorage.llmEventStart.push({
...event.detail.payload,
...event.detail,
// @ts-expect-error id is not UUID, but it is fine for testing
id: idMap.get(event.detail.payload.id)!,
});
}
function captureLLMEnd(event: LLMEndEvent) {
function captureLLMEnd(event: CustomEvent<LLMEndEvent>) {
newLLMCompleteMockStorage.llmEventEnd.push({
...event.detail.payload,
...event.detail,
// @ts-expect-error id is not UUID, but it is fine for testing
id: idMap.get(event.detail.payload.id)!,
response: {
...event.detail.payload.response,
...event.detail.response,
// hide raw object since it might too big
raw: null,
},
});
}
function captureLLMStream(event: LLMStreamEvent) {
function captureLLMStream(event: CustomEvent<LLMStreamEvent>) {
newLLMCompleteMockStorage.llmEventStream.push({
...event.detail.payload,
...event.detail,
// @ts-expect-error id is not UUID, but it is fine for testing
id: idMap.get(event.detail.payload.id)!,
chunk: {
...event.detail.payload.chunk,
...event.detail.chunk,
// hide raw object since it might too big
raw: null,
},
+1
View File
@@ -10,6 +10,7 @@
},
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@llamaindex/core": "workspace:*",
"@types/node": "^20.12.11",
"consola": "^3.2.3",
"llamaindex": "workspace:*",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "llamaindex",
"version": "0.4.14",
"version": "0.5.0",
"license": "MIT",
"type": "module",
"keywords": [
+1 -1
View File
@@ -1,9 +1,9 @@
import type { ChatMessage, LLM, MessageType } from "@llamaindex/core/llms";
import { extractText } from "@llamaindex/core/utils";
import { tokenizers, type Tokenizer } from "@llamaindex/env";
import type { SummaryPrompt } from "./Prompt.js";
import { defaultSummaryPrompt, messagesToHistoryStr } from "./Prompt.js";
import { OpenAI } from "./llm/openai.js";
import { extractText } from "./llm/utils.js";
/**
* A ChatHistory is used to keep the state of back and forth chat messages
+1 -1
View File
@@ -4,7 +4,7 @@ import type {
ChatResponseChunk,
} from "@llamaindex/core/llms";
import type { NodeWithScore } from "@llamaindex/core/schema";
import { extractText } from "./llm/utils.js";
import { extractText } from "@llamaindex/core/utils";
export class EngineResponse implements ChatResponse, ChatResponseChunk {
sourceNodes?: NodeWithScore[];
+7 -10
View File
@@ -1,5 +1,7 @@
import { Settings as CoreSettings } from "@llamaindex/core/global";
import { CallbackManager } from "./callbacks/CallbackManager.js";
import {
type CallbackManager,
Settings as CoreSettings,
} from "@llamaindex/core/global";
import { OpenAI } from "./llm/openai.js";
import { PromptHelper } from "./PromptHelper.js";
@@ -9,11 +11,6 @@ import type { LLM } from "@llamaindex/core/llms";
import { AsyncLocalStorage, getEnv } from "@llamaindex/env";
import type { ServiceContext } from "./ServiceContext.js";
import type { BaseEmbedding } from "./embeddings/types.js";
import {
getCallbackManager,
setCallbackManager,
withCallbackManager,
} from "./internal/settings/CallbackManager.js";
import {
getEmbeddedModel,
setEmbeddedModel,
@@ -129,18 +126,18 @@ class GlobalSettings implements Config {
}
get callbackManager(): CallbackManager {
return getCallbackManager();
return CoreSettings.callbackManager;
}
set callbackManager(callbackManager: CallbackManager) {
setCallbackManager(callbackManager);
CoreSettings.callbackManager = callbackManager;
}
withCallbackManager<Result>(
callbackManager: CallbackManager,
fn: () => Result,
): Result {
return withCallbackManager(callbackManager, fn);
return CoreSettings.withCallbackManager(callbackManager, fn);
}
set chunkSize(chunkSize: number | undefined) {
+5 -10
View File
@@ -5,6 +5,7 @@ import type {
MessageContent,
ToolOutput,
} from "@llamaindex/core/llms";
import { wrapEventCaller } from "@llamaindex/core/utils";
import { ReadableStream, TransformStream, randomUUID } from "@llamaindex/env";
import { ChatHistory } from "../ChatHistory.js";
import { EngineResponse } from "../EngineResponse.js";
@@ -14,9 +15,7 @@ import {
type ChatEngineParamsNonStreaming,
type ChatEngineParamsStreaming,
} from "../engines/chat/index.js";
import { wrapEventCaller } from "../internal/context/EventCaller.js";
import { consoleLogger, emptyLogger } from "../internal/logger.js";
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
import { isAsyncIterable } from "../internal/utils.js";
import { ObjectRetriever } from "../objects/index.js";
import type {
@@ -69,10 +68,8 @@ export function createTaskOutputStream<
taskOutputs.push(output);
controller.enqueue(output);
};
getCallbackManager().dispatchEvent("agent-start", {
payload: {
startStep: step,
},
Settings.callbackManager.dispatchEvent("agent-start", {
startStep: step,
});
context.logger.log("Starting step(id, %s).", step.id);
@@ -93,10 +90,8 @@ export function createTaskOutputStream<
"Final step(id, %s) reached, closing task.",
step.id,
);
getCallbackManager().dispatchEvent("agent-end", {
payload: {
endStep: step,
},
Settings.callbackManager.dispatchEvent("agent-end", {
endStep: step,
});
controller.close();
}
+2 -2
View File
@@ -1,3 +1,4 @@
import type { JSONObject, JSONValue } from "@llamaindex/core/global";
import type {
BaseTool,
ChatMessage,
@@ -5,15 +6,14 @@ import type {
ChatResponseChunk,
LLM,
} from "@llamaindex/core/llms";
import { extractText } from "@llamaindex/core/utils";
import { randomUUID, ReadableStream } from "@llamaindex/env";
import { getReACTAgentSystemHeader } from "../internal/prompt/react.js";
import {
isAsyncIterable,
stringifyJSONToMessageContent,
} from "../internal/utils.js";
import { extractText } from "../llm/utils.js";
import { Settings } from "../Settings.js";
import type { JSONObject, JSONValue } from "../types.js";
import { AgentRunner, AgentWorker, type AgentParamsBase } from "./base.js";
import type { TaskHandler } from "./types.js";
import {
+4 -5
View File
@@ -9,7 +9,6 @@ import type {
} from "@llamaindex/core/llms";
import { ReadableStream } from "@llamaindex/env";
import type { Logger } from "../internal/logger.js";
import type { BaseEvent } from "../internal/type.js";
import type { UUID } from "../types.js";
export type AgentTaskContext<
@@ -90,9 +89,9 @@ export type TaskHandler<
) => void,
) => Promise<void>;
export type AgentStartEvent = BaseEvent<{
export type AgentStartEvent = {
startStep: TaskStep;
}>;
export type AgentEndEvent = BaseEvent<{
};
export type AgentEndEvent = {
endStep: TaskStep;
}>;
};
+10 -11
View File
@@ -1,3 +1,8 @@
import {
type JSONObject,
type JSONValue,
Settings,
} from "@llamaindex/core/global";
import type {
BaseTool,
ChatMessage,
@@ -14,13 +19,11 @@ import { baseToolWithCallSchema } from "@llamaindex/core/schema";
import { ReadableStream } from "@llamaindex/env";
import { z } from "zod";
import type { Logger } from "../internal/logger.js";
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
import {
isAsyncIterable,
prettifyError,
stringifyJSONToMessageContent,
} from "../internal/utils.js";
import type { JSONObject, JSONValue } from "../types.js";
import type { AgentParamsBase } from "./base.js";
import type { TaskHandler } from "./types.js";
@@ -221,10 +224,8 @@ export async function callTool(
};
}
try {
getCallbackManager().dispatchEvent("llm-tool-call", {
payload: {
toolCall: { ...toolCall, input },
},
Settings.callbackManager.dispatchEvent("llm-tool-call", {
toolCall: { ...toolCall, input },
});
output = await call.call(tool, input);
logger.log(
@@ -237,11 +238,9 @@ export async function callTool(
output,
isError: false,
};
getCallbackManager().dispatchEvent("llm-tool-result", {
payload: {
toolCall: { ...toolCall, input },
toolResult: { ...toolOutput },
},
Settings.callbackManager.dispatchEvent("llm-tool-result", {
toolCall: { ...toolCall, input },
toolResult: { ...toolOutput },
});
return toolOutput;
} catch (e) {
@@ -1,230 +0,0 @@
import type { Anthropic } from "@anthropic-ai/sdk";
import type { MessageContent } from "@llamaindex/core/llms";
import type { NodeWithScore } from "@llamaindex/core/schema";
import { CustomEvent } from "@llamaindex/env";
import type { AgentEndEvent, AgentStartEvent } from "../agent/types.js";
import {
EventCaller,
getEventCaller,
} from "../internal/context/EventCaller.js";
import type {
LLMEndEvent,
LLMStartEvent,
LLMStreamEvent,
LLMToolCallEvent,
LLMToolResultEvent,
RetrievalEndEvent,
RetrievalStartEvent,
} from "../llm/types.js";
export class LlamaIndexCustomEvent<T = any> extends CustomEvent<T> {
reason: EventCaller | null;
private constructor(
event: string,
options?: CustomEventInit & {
reason?: EventCaller | null;
},
) {
super(event, options);
this.reason = options?.reason ?? null;
}
static fromEvent<Type extends keyof LlamaIndexEventMaps>(
type: Type,
detail: LlamaIndexEventMaps[Type]["detail"],
) {
return new LlamaIndexCustomEvent(type, {
detail: detail,
reason: getEventCaller(),
});
}
}
/**
* This type is used to define the event maps.
*/
export interface LlamaIndexEventMaps {
/**
* @deprecated
*/
retrieve: CustomEvent<RetrievalCallbackResponse>;
"retrieve-start": RetrievalStartEvent;
"retrieve-end": RetrievalEndEvent;
/**
* @deprecated
*/
stream: CustomEvent<StreamCallbackResponse>;
// llm events
"llm-start": LLMStartEvent;
"llm-end": LLMEndEvent;
"llm-tool-call": LLMToolCallEvent;
"llm-tool-result": LLMToolResultEvent;
"llm-stream": LLMStreamEvent;
// agent events
"agent-start": AgentStartEvent;
"agent-end": AgentEndEvent;
}
//#region @deprecated remove in the next major version
//Specify StreamToken per mainstream LLM
export interface DefaultStreamToken {
id: string;
object: string;
created: number;
model: string;
choices: {
index: number;
delta: {
content?: string | null;
role?: "user" | "assistant" | "system" | "function" | "tool";
};
finish_reason: string | null;
}[];
}
//OpenAI stream token schema is the default.
//Note: Anthropic and Replicate also use similar token schemas.
export type OpenAIStreamToken = DefaultStreamToken;
export type AnthropicStreamToken = Anthropic.Completion;
//
//Callback Responses
//
//TODO: Write Embedding Callbacks
//StreamCallbackResponse should let practitioners implement callbacks out of the box...
//When custom streaming LLMs are involved, people are expected to write their own StreamCallbackResponses
export interface StreamCallbackResponse {
index: number;
isDone?: boolean;
token?: DefaultStreamToken;
}
export interface RetrievalCallbackResponse {
query: MessageContent;
nodes: NodeWithScore[];
}
interface CallbackManagerMethods {
/**
* onLLMStream is called when a token is streamed from the LLM. Defining this
* callback auto sets the stream = True flag on the openAI createChatCompletion request.
* @deprecated will be removed in the next major version
*/
onLLMStream: (params: StreamCallbackResponse) => Promise<void> | void;
/**
* onRetrieve is called as soon as the retriever finishes fetching relevant nodes.
* This callback allows you to handle the retrieved nodes even if the synthesizer
* is still running.
* @deprecated will be removed in the next major version
*/
onRetrieve: (params: RetrievalCallbackResponse) => Promise<void> | void;
}
//#endregion
const noop: (...args: any[]) => any = () => void 0;
type EventHandler<Event extends CustomEvent> = (
event: Event & {
reason: EventCaller | null;
},
) => void;
export class CallbackManager implements CallbackManagerMethods {
/**
* @deprecated will be removed in the next major version
*/
get onLLMStream(): CallbackManagerMethods["onLLMStream"] {
return async (response) => {
await Promise.all(
this.#handlers
.get("stream")!
.map((handler) =>
handler(LlamaIndexCustomEvent.fromEvent("stream", response)),
),
);
};
}
/**
* @deprecated will be removed in the next major version
*/
get onRetrieve(): CallbackManagerMethods["onRetrieve"] {
return async (response) => {
await Promise.all(
this.#handlers
.get("retrieve")!
.map((handler) =>
handler(LlamaIndexCustomEvent.fromEvent("retrieve", response)),
),
);
};
}
/**
* @deprecated will be removed in the next major version
*/
set onLLMStream(_: never) {
throw new Error("onLLMStream is deprecated. Use on('stream') instead");
}
/**
* @deprecated will be removed in the next major version
*/
set onRetrieve(_: never) {
throw new Error("onRetrieve is deprecated. Use `on('retrieve')` instead");
}
#handlers = new Map<keyof LlamaIndexEventMaps, EventHandler<CustomEvent>[]>();
constructor(handlers?: Partial<CallbackManagerMethods>) {
const onLLMStream = handlers?.onLLMStream ?? noop;
this.on("stream", (event) => onLLMStream(event.detail));
const onRetrieve = handlers?.onRetrieve ?? noop;
this.on("retrieve", (event) => onRetrieve(event.detail));
}
on<
K extends keyof LlamaIndexEventMaps,
H extends EventHandler<LlamaIndexEventMaps[K]>,
>(event: K, handler: H) {
if (!this.#handlers.has(event)) {
this.#handlers.set(event, []);
}
this.#handlers.get(event)!.push(handler);
return this;
}
off<
K extends keyof LlamaIndexEventMaps,
H extends EventHandler<LlamaIndexEventMaps[K]>,
>(event: K, handler: H) {
if (!this.#handlers.has(event)) {
return;
}
const handlers = this.#handlers.get(event)!;
const index = handlers.indexOf(handler);
if (index > -1) {
handlers.splice(index, 1);
}
return this;
}
dispatchEvent<K extends keyof LlamaIndexEventMaps>(
event: K,
detail: LlamaIndexEventMaps[K]["detail"],
) {
const handlers = this.#handlers.get(event);
if (!handlers) {
return;
}
queueMicrotask(() => {
handlers.forEach((handler) =>
handler(
LlamaIndexCustomEvent.fromEvent(event, {
...detail,
}),
),
);
});
}
}
@@ -4,12 +4,11 @@ import {
type RetrievalParams,
type TextNodeWithScore,
} from "@llamaindex/cloud/api";
import { Settings } from "@llamaindex/core/global";
import type { NodeWithScore } from "@llamaindex/core/schema";
import { jsonToNode, ObjectType } from "@llamaindex/core/schema";
import { extractText, wrapEventCaller } from "@llamaindex/core/utils";
import type { BaseRetriever, RetrieveParams } from "../Retriever.js";
import { wrapEventCaller } from "../internal/context/EventCaller.js";
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
import { extractText } from "../llm/utils.js";
import type { ClientParams, CloudConstructorParams } from "./constants.js";
import { DEFAULT_PROJECT_NAME } from "./constants.js";
import { initService } from "./utils.js";
@@ -92,11 +91,9 @@ export class LlamaCloudRetriever implements BaseRetriever {
const nodesWithScores = this.resultNodesToNodeWithScore(
results.retrieval_nodes,
);
getCallbackManager().dispatchEvent("retrieve-end", {
payload: {
query,
nodes: nodesWithScores,
},
Settings.callbackManager.dispatchEvent("retrieve-end", {
query,
nodes: nodesWithScores,
});
return nodesWithScores;
}
@@ -1,6 +1,6 @@
import type { MessageContentDetail } from "@llamaindex/core/llms";
import { extractSingleText } from "@llamaindex/core/utils";
import { getEnv } from "@llamaindex/env";
import { extractSingleText } from "../llm/utils.js";
import { BaseEmbedding } from "./types.js";
const DEFAULT_MODEL = "sentence-transformers/clip-ViT-B-32";
@@ -7,7 +7,7 @@ import {
type BaseNode,
type ImageType,
} from "@llamaindex/core/schema";
import { extractImage, extractSingleText } from "../llm/utils.js";
import { extractImage, extractSingleText } from "@llamaindex/core/utils";
import { BaseEmbedding, batchEmbeddings } from "./types.js";
/*
+1 -1
View File
@@ -1,9 +1,9 @@
import type { MessageContentDetail } from "@llamaindex/core/llms";
import type { BaseNode } from "@llamaindex/core/schema";
import { MetadataMode } from "@llamaindex/core/schema";
import { extractSingleText } from "@llamaindex/core/utils";
import { type Tokenizers } from "@llamaindex/env";
import type { TransformComponent } from "../ingestion/types.js";
import { extractSingleText } from "../llm/utils.js";
import { truncateMaxTokens } from "./tokenizer.js";
import { SimilarityType, similarity } from "./utils.js";
@@ -1,4 +1,9 @@
import type { ChatMessage, LLM } from "@llamaindex/core/llms";
import {
extractText,
streamReducer,
wrapEventCaller,
} from "@llamaindex/core/utils";
import type { ChatHistory } from "../../ChatHistory.js";
import { getHistory } from "../../ChatHistory.js";
import type { EngineResponse } from "../../EngineResponse.js";
@@ -9,8 +14,6 @@ import {
} from "../../Prompt.js";
import type { ServiceContext } from "../../ServiceContext.js";
import { llmFromSettingsOrContext } from "../../Settings.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import { extractText, streamReducer } from "../../llm/utils.js";
import { PromptMixin } from "../../prompts/index.js";
import type { QueryEngine } from "../../types.js";
import type {
@@ -4,18 +4,18 @@ import type {
MessageContent,
MessageType,
} from "@llamaindex/core/llms";
import {
extractText,
streamConverter,
streamReducer,
wrapEventCaller,
} from "@llamaindex/core/utils";
import type { ChatHistory } from "../../ChatHistory.js";
import { getHistory } from "../../ChatHistory.js";
import { EngineResponse } from "../../EngineResponse.js";
import type { ContextSystemPrompt } from "../../Prompt.js";
import type { BaseRetriever } from "../../Retriever.js";
import { Settings } from "../../Settings.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import {
extractText,
streamConverter,
streamReducer,
} from "../../llm/utils.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import { PromptMixin } from "../../prompts/Mixin.js";
import { DefaultContextGenerator } from "./DefaultContextGenerator.js";
@@ -1,10 +1,13 @@
import type { LLM } from "@llamaindex/core/llms";
import {
streamConverter,
streamReducer,
wrapEventCaller,
} from "@llamaindex/core/utils";
import type { ChatHistory } from "../../ChatHistory.js";
import { getHistory } from "../../ChatHistory.js";
import { EngineResponse } from "../../EngineResponse.js";
import { Settings } from "../../Settings.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import { streamConverter, streamReducer } from "../../llm/utils.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
@@ -1,9 +1,9 @@
import type { NodeWithScore } from "@llamaindex/core/schema";
import { wrapEventCaller } from "@llamaindex/core/utils";
import type { EngineResponse } from "../../EngineResponse.js";
import type { BaseRetriever } from "../../Retriever.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import { PromptMixin } from "../../prompts/Mixin.js";
import type { BaseRetriever } from "../../Retriever.js";
import type { BaseSynthesizer } from "../../synthesizers/index.js";
import { ResponseSynthesizer } from "../../synthesizers/index.js";
import type {
@@ -17,7 +17,7 @@ import type {
} from "../../types.js";
import type { BaseTool, ToolMetadata } from "@llamaindex/core/llms";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import { wrapEventCaller } from "@llamaindex/core/utils";
import type { BaseQuestionGenerator, SubQuestion } from "./types.js";
/**
@@ -1,6 +1,6 @@
import type { ChatMessage, LLM } from "@llamaindex/core/llms";
import { MetadataMode } from "@llamaindex/core/schema";
import { extractText } from "../llm/utils.js";
import { extractText } from "@llamaindex/core/utils";
import { PromptMixin } from "../prompts/Mixin.js";
import type { ServiceContext } from "../ServiceContext.js";
import { llmFromSettingsOrContext } from "../Settings.js";
+24 -1
View File
@@ -1,7 +1,30 @@
import type { AgentEndEvent, AgentStartEvent } from "./agent/types.js";
import type { RetrievalEndEvent, RetrievalStartEvent } from "./llm/types.js";
declare module "@llamaindex/core/global" {
export interface LlamaIndexEventMaps {
"retrieve-start": RetrievalStartEvent;
"retrieve-end": RetrievalEndEvent;
// agent events
"agent-start": AgentStartEvent;
"agent-end": AgentEndEvent;
}
}
export { CallbackManager } from "@llamaindex/core/global";
export type {
JSONArray,
JSONObject,
JSONValue,
LLMEndEvent,
LLMStartEvent,
LLMStreamEvent,
LLMToolCallEvent,
LLMToolResultEvent,
} from "@llamaindex/core/global";
export * from "@llamaindex/core/llms";
export * from "@llamaindex/core/schema";
export * from "./agent/index.js";
export * from "./callbacks/CallbackManager.js";
export * from "./ChatHistory.js";
export * from "./cloud/index.js";
export * from "./constants.js";
@@ -32,8 +32,8 @@ import {
} from "./utils.js";
import type { LLM } from "@llamaindex/core/llms";
import { extractText } from "@llamaindex/core/utils";
import { llmFromSettingsOrContext } from "../../Settings.js";
import { extractText } from "../../llm/utils.js";
export interface KeywordIndexOptions {
nodes?: BaseNode[];
@@ -3,19 +3,17 @@ import type {
Document,
NodeWithScore,
} from "@llamaindex/core/schema";
import { extractText, wrapEventCaller } from "@llamaindex/core/utils";
import _ from "lodash";
import type { ChoiceSelectPrompt } from "../../Prompt.js";
import { defaultChoiceSelectPrompt } from "../../Prompt.js";
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
import type { ServiceContext } from "../../ServiceContext.js";
import {
Settings,
llmFromSettingsOrContext,
nodeParserFromSettingsOrContext,
} from "../../Settings.js";
import { RetrieverQueryEngine } from "../../engines/query/index.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import { extractText } from "../../llm/utils.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import type { StorageContext } from "../../storage/StorageContext.js";
import { storageContextFromDefaults } from "../../storage/StorageContext.js";
@@ -296,17 +294,10 @@ export class SummaryIndexRetriever implements BaseRetriever {
async retrieve({ query }: RetrieveParams): Promise<NodeWithScore[]> {
const nodeIds = this.index.indexStruct.nodes;
const nodes = await this.index.docStore.getNodes(nodeIds);
const result = nodes.map((node) => ({
return nodes.map((node) => ({
node: node,
score: 1,
}));
Settings.callbackManager.dispatchEvent("retrieve", {
query,
nodes: result,
});
return result;
}
}
@@ -376,11 +367,6 @@ export class SummaryIndexLLMRetriever implements BaseRetriever {
results.push(...nodeWithScores);
}
Settings.callbackManager.dispatchEvent("retrieve", {
query,
nodes: results,
});
return results;
}
}
@@ -1,3 +1,4 @@
import { Settings } from "@llamaindex/core/global";
import type { MessageContent } from "@llamaindex/core/llms";
import {
ImageNode,
@@ -8,6 +9,7 @@ import {
type Document,
type NodeWithScore,
} from "@llamaindex/core/schema";
import { wrapEventCaller } from "@llamaindex/core/utils";
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
import type { ServiceContext } from "../../ServiceContext.js";
import { nodeParserFromSettingsOrContext } from "../../Settings.js";
@@ -22,8 +24,6 @@ import {
DocStoreStrategy,
createDocStoreStrategy,
} from "../../ingestion/strategies/index.js";
import { wrapEventCaller } from "../../internal/context/EventCaller.js";
import { getCallbackManager } from "../../internal/settings/CallbackManager.js";
import type { BaseNodePostprocessor } from "../../postprocessors/types.js";
import type { StorageContext } from "../../storage/StorageContext.js";
import { storageContextFromDefaults } from "../../storage/StorageContext.js";
@@ -413,10 +413,8 @@ export class VectorIndexRetriever implements BaseRetriever {
query,
preFilters,
}: RetrieveParams): Promise<NodeWithScore[]> {
getCallbackManager().dispatchEvent("retrieve-start", {
payload: {
query,
},
Settings.callbackManager.dispatchEvent("retrieve-start", {
query,
});
const vectorStores = this.index.vectorStores;
let nodesWithScores: NodeWithScore[] = [];
@@ -432,14 +430,7 @@ export class VectorIndexRetriever implements BaseRetriever {
),
);
}
getCallbackManager().dispatchEvent("retrieve-end", {
payload: {
query,
nodes: nodesWithScores,
},
});
// send deprecated event
getCallbackManager().dispatchEvent("retrieve", {
Settings.callbackManager.dispatchEvent("retrieve-end", {
query,
nodes: nodesWithScores,
});
@@ -1,25 +0,0 @@
import { AsyncLocalStorage } from "@llamaindex/env";
import { CallbackManager } from "../../callbacks/CallbackManager.js";
const callbackManagerAsyncLocalStorage =
new AsyncLocalStorage<CallbackManager>();
let globalCallbackManager: CallbackManager | null = null;
export function getCallbackManager(): CallbackManager {
if (globalCallbackManager === null) {
globalCallbackManager = new CallbackManager();
}
return callbackManagerAsyncLocalStorage.getStore() ?? globalCallbackManager;
}
export function setCallbackManager(callbackManager: CallbackManager) {
globalCallbackManager = callbackManager;
}
export function withCallbackManager<Result>(
callbackManager: CallbackManager,
fn: () => Result,
): Result {
return callbackManagerAsyncLocalStorage.run(callbackManager, fn);
}
-5
View File
@@ -1,5 +0,0 @@
import type { CustomEvent } from "@llamaindex/env";
export type BaseEvent<Payload extends Record<string, unknown>> = CustomEvent<{
payload: Readonly<Payload>;
}>;
+1 -1
View File
@@ -1,4 +1,4 @@
import type { JSONValue } from "../types.js";
import type { JSONValue } from "@llamaindex/core/global";
export const isAsyncIterable = (
obj: unknown,
+2 -2
View File
@@ -26,10 +26,10 @@ import type {
LLMChatParamsStreaming,
ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { ToolCallLLM } from "@llamaindex/core/llms";
import { extractText, wrapLLMEvent } from "@llamaindex/core/utils";
import { getEnv } from "@llamaindex/env";
import _ from "lodash";
import { ToolCallLLM } from "./base.js";
import { extractText, wrapLLMEvent } from "./utils.js";
export class AnthropicSession {
anthropic: SDKAnthropic;
+2 -2
View File
@@ -15,9 +15,9 @@ import type {
ToolCall,
ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { ToolCallLLM } from "@llamaindex/core/llms";
import { streamConverter, wrapLLMEvent } from "@llamaindex/core/utils";
import { getEnv, randomUUID } from "@llamaindex/env";
import { ToolCallLLM } from "../base.js";
import { streamConverter, wrapLLMEvent } from "../utils.js";
import {
GEMINI_BACKENDS,
GEMINI_MODEL,
+1 -1
View File
@@ -15,7 +15,7 @@ import type {
MessageType,
ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { extractDataUrlComponents } from "../utils.js";
import { extractDataUrlComponents } from "@llamaindex/core/utils";
import type {
ChatContext,
FileDataPart,
+1 -1
View File
@@ -19,8 +19,8 @@ import type {
ToolCall,
ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { streamConverter } from "@llamaindex/core/utils";
import { getEnv, randomUUID } from "@llamaindex/env";
import { streamConverter } from "../utils.js";
import { DEFAULT_SAFETY_SETTINGS, getFunctionCalls, getText } from "./utils.js";
/* To use Google's Vertex AI backend, it doesn't use api key authentication.
+11 -10
View File
@@ -1,21 +1,22 @@
import { HfInference } from "@huggingface/inference";
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
LLMChatParamsNonStreaming,
LLMChatParamsStreaming,
LLMMetadata,
ToolCallLLMMessageOptions,
import "@llamaindex/core/llms";
import {
BaseLLM,
type ChatMessage,
type ChatResponse,
type ChatResponseChunk,
type LLMChatParamsNonStreaming,
type LLMChatParamsStreaming,
type LLMMetadata,
type ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
import { streamConverter, wrapLLMEvent } from "@llamaindex/core/utils";
import type {
PreTrainedModel,
PreTrainedTokenizer,
Tensor,
} from "@xenova/transformers";
import { lazyLoadTransformers } from "../internal/deps/transformers.js";
import { BaseLLM } from "./base.js";
import { streamConverter, wrapLLMEvent } from "./utils.js";
// TODO workaround issue with @huggingface/inference@2.7.0
interface HfInferenceOptions {
-2
View File
@@ -4,10 +4,8 @@ export {
ALL_AVAILABLE_V3_MODELS,
Anthropic,
} from "./anthropic.js";
export { ToolCallLLM } from "./base.js";
export { FireworksLLM } from "./fireworks.js";
export { Gemini, GeminiSession } from "./gemini/base.js";
export { streamConverter, streamReducer, wrapLLMEvent } from "./utils.js";
export {
GEMINI_MODEL,
+7 -19
View File
@@ -1,14 +1,12 @@
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
LLMChatParamsNonStreaming,
LLMChatParamsStreaming,
import {
BaseLLM,
type ChatMessage,
type ChatResponse,
type ChatResponseChunk,
type LLMChatParamsNonStreaming,
type LLMChatParamsStreaming,
} from "@llamaindex/core/llms";
import { getEnv } from "@llamaindex/env";
import { Settings } from "../Settings.js";
import { type StreamCallbackResponse } from "../callbacks/CallbackManager.js";
import { BaseLLM } from "./base.js";
export const ALL_AVAILABLE_MISTRAL_MODELS = {
"mistral-tiny": { contextWindow: 32000 },
@@ -123,16 +121,6 @@ export class MistralAI extends BaseLLM {
if (!part.choices.length) continue;
part.choices[0].index = idx_counter;
const isDone: boolean =
part.choices[0].finish_reason === "stop" ? true : false;
const stream_callback: StreamCallbackResponse = {
index: idx_counter,
isDone: isDone,
token: part,
};
Settings.callbackManager.dispatchEvent("stream", stream_callback);
idx_counter++;
+1 -1
View File
@@ -9,6 +9,7 @@ import type {
LLMCompletionParamsStreaming,
LLMMetadata,
} from "@llamaindex/core/llms";
import { extractText, streamConverter } from "@llamaindex/core/utils";
import { BaseEmbedding } from "../embeddings/types.js";
import {
Ollama as OllamaBase,
@@ -30,7 +31,6 @@ import {
type ShowResponse,
type StatusResponse,
} from "../internal/deps/ollama.js";
import { extractText, streamConverter } from "./utils.js";
const messageAccessor = (part: OllamaChatResponse): ChatResponseChunk => {
return {
+18 -24
View File
@@ -7,19 +7,25 @@ import type {
} from "openai";
import { AzureOpenAI, OpenAI as OrigOpenAI } from "openai";
import type {
BaseTool,
ChatMessage,
ChatResponse,
ChatResponseChunk,
LLM,
LLMChatParamsNonStreaming,
LLMChatParamsStreaming,
LLMMetadata,
MessageType,
PartialToolCall,
ToolCallLLMMessageOptions,
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,
@@ -31,16 +37,12 @@ import type {
ChatCompletionUserMessageParam,
} from "openai/resources/chat/completions";
import type { ChatCompletionMessageParam } from "openai/resources/index.js";
import { wrapEventCaller } from "../internal/context/EventCaller.js";
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
import type { AzureOpenAIConfig } from "./azure.js";
import {
getAzureConfigFromEnv,
getAzureModel,
shouldUseAzure,
} from "./azure.js";
import { ToolCallLLM } from "./base.js";
import { extractText, wrapLLMEvent } from "./utils.js";
export class OpenAISession {
openai: Pick<OrigOpenAI, "chat" | "embeddings">;
@@ -390,8 +392,6 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
});
// TODO: add callback to streamConverter and use streamConverter here
//Indices
let idxCounter: number = 0;
// 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>();
@@ -428,12 +428,6 @@ export class OpenAI extends ToolCallLLM<OpenAIAdditionalChatOptions> {
const isDone: boolean = choice.finish_reason !== null;
getCallbackManager().dispatchEvent("stream", {
index: idxCounter++,
isDone: isDone,
token: part,
});
if (isDone && currentToolCall) {
// for the last one, we need to emit the tool call
shouldEmitToolCall = {
+10 -23
View File
@@ -1,20 +1,18 @@
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
LLMChatParamsNonStreaming,
LLMChatParamsStreaming,
LLMMetadata,
MessageType,
import {
BaseLLM,
type ChatMessage,
type ChatResponse,
type ChatResponseChunk,
type LLMChatParamsNonStreaming,
type LLMChatParamsStreaming,
type LLMMetadata,
type MessageType,
} from "@llamaindex/core/llms";
import { extractText, wrapLLMEvent } from "@llamaindex/core/utils";
import { getEnv } from "@llamaindex/env";
import _ from "lodash";
import type { LLMOptions } from "portkey-ai";
import { Portkey as OrigPortKey } from "portkey-ai";
import { type StreamCallbackResponse } from "../callbacks/CallbackManager.js";
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
import { BaseLLM } from "./base.js";
import { extractText, wrapLLMEvent } from "./utils.js";
interface PortkeyOptions {
apiKey?: string;
@@ -136,18 +134,7 @@ export class Portkey extends BaseLLM {
//Indices
let idx_counter: number = 0;
for await (const part of chunkStream) {
//Increment
part.choices[0].index = idx_counter;
const is_done: boolean =
part.choices[0].finish_reason === "stop" ? true : false;
//onLLMStream Callback
const stream_callback: StreamCallbackResponse = {
index: idx_counter,
isDone: is_done,
// token: part,
};
getCallbackManager().dispatchEvent("stream", stream_callback);
idx_counter++;
+11 -11
View File
@@ -1,20 +1,20 @@
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
LLMChatParamsNonStreaming,
LLMChatParamsStreaming,
MessageType,
import {
BaseLLM,
type ChatMessage,
type ChatResponse,
type ChatResponseChunk,
type LLMChatParamsNonStreaming,
type LLMChatParamsStreaming,
type MessageType,
} from "@llamaindex/core/llms";
import { getEnv } from "@llamaindex/env";
import Replicate from "../internal/deps/replicate.js";
import { BaseLLM } from "./base.js";
import {
extractText,
streamCallbacks,
streamConverter,
wrapLLMEvent,
} from "./utils.js";
} from "@llamaindex/core/utils";
import { getEnv } from "@llamaindex/env";
import Replicate from "../internal/deps/replicate.js";
export class ReplicateSession {
replicateKey: string | null = null;
+5 -33
View File
@@ -1,38 +1,10 @@
import type {
ChatMessage,
ChatResponse,
ChatResponseChunk,
MessageContent,
ToolCall,
ToolOutput,
} from "@llamaindex/core/llms";
import type { MessageContent } from "@llamaindex/core/llms";
import type { NodeWithScore } from "@llamaindex/core/schema";
import type { BaseEvent } from "../internal/type.js";
import type { UUID } from "../types.js";
export type RetrievalStartEvent = BaseEvent<{
export type RetrievalStartEvent = {
query: MessageContent;
}>;
export type RetrievalEndEvent = BaseEvent<{
};
export type RetrievalEndEvent = {
query: MessageContent;
nodes: NodeWithScore[];
}>;
export type LLMStartEvent = BaseEvent<{
id: UUID;
messages: ChatMessage[];
}>;
export type LLMToolCallEvent = BaseEvent<{
toolCall: ToolCall;
}>;
export type LLMToolResultEvent = BaseEvent<{
toolCall: ToolCall;
toolResult: ToolOutput;
}>;
export type LLMEndEvent = BaseEvent<{
id: UUID;
response: ChatResponse;
}>;
export type LLMStreamEvent = BaseEvent<{
id: UUID;
chunk: ChatResponseChunk;
}>;
};
-217
View File
@@ -1,217 +0,0 @@
import type {
ChatResponse,
ChatResponseChunk,
LLM,
LLMChat,
MessageContent,
MessageContentDetail,
MessageContentTextDetail,
} from "@llamaindex/core/llms";
import type { ImageType } from "@llamaindex/core/schema";
import { AsyncLocalStorage, randomUUID } from "@llamaindex/env";
import { getCallbackManager } from "../internal/settings/CallbackManager.js";
export async function* streamConverter<S, D>(
stream: AsyncIterable<S>,
converter: (s: S) => D | null,
): AsyncIterable<D> {
for await (const data of stream) {
const newData = converter(data);
if (newData === null) {
return;
}
yield newData;
}
}
export async function* streamCallbacks<S>(
stream: AsyncIterable<S>,
callbacks: {
finished?: (value?: S) => void;
},
): AsyncIterable<S> {
let value: S | undefined;
for await (value of stream) {
yield value;
}
if (callbacks.finished) {
callbacks.finished(value);
}
}
export async function* streamReducer<S, D>(params: {
stream: AsyncIterable<S>;
reducer: (previousValue: D, currentValue: S) => D;
initialValue: D;
finished?: (value: D) => void;
}): AsyncIterable<S> {
let value = params.initialValue;
for await (const data of params.stream) {
value = params.reducer(value, data);
yield data;
}
if (params.finished) {
params.finished(value);
}
}
/**
* Extracts just the text from a multi-modal message or the message itself if it's just text.
*
* @param message The message to extract text from.
* @returns The extracted text
*/
export function extractText(message: MessageContent): string {
if (typeof message !== "string" && !Array.isArray(message)) {
console.warn(
"extractText called with non-MessageContent message, this is likely a bug.",
);
return `${message}`;
} else if (typeof message !== "string" && Array.isArray(message)) {
// message is of type MessageContentDetail[] - retrieve just the text parts and concatenate them
// so we can pass them to the context generator
return message
.filter((c): c is MessageContentTextDetail => c.type === "text")
.map((c) => c.text)
.join("\n\n");
} else {
return message;
}
}
/**
* Extracts a single text from a multi-modal message content
*
* @param message The message to extract images from.
* @returns The extracted images
*/
export function extractSingleText(
message: MessageContentDetail,
): string | null {
if (message.type === "text") {
return message.text;
}
return null;
}
/**
* Extracts an image from a multi-modal message content
*
* @param message The message to extract images from.
* @returns The extracted images
*/
export function extractImage(message: MessageContentDetail): ImageType | null {
if (message.type === "image_url") {
return new URL(message.image_url.url);
}
return null;
}
export const extractDataUrlComponents = (
dataUrl: string,
): {
mimeType: string;
base64: string;
} => {
const parts = dataUrl.split(";base64,");
if (parts.length !== 2 || !parts[0].startsWith("data:")) {
throw new Error("Invalid data URL");
}
const mimeType = parts[0].slice(5);
const base64 = parts[1];
return {
mimeType,
base64,
};
};
/**
* @internal
*/
export function wrapLLMEvent<
AdditionalChatOptions extends object = object,
AdditionalMessageOptions extends object = object,
>(
originalMethod: LLMChat<
AdditionalChatOptions,
AdditionalMessageOptions
>["chat"],
_context: ClassMethodDecoratorContext,
) {
return async function withLLMEvent(
this: LLM<AdditionalChatOptions, AdditionalMessageOptions>,
...params: Parameters<
LLMChat<AdditionalChatOptions, AdditionalMessageOptions>["chat"]
>
): ReturnType<
LLMChat<AdditionalChatOptions, AdditionalMessageOptions>["chat"]
> {
const id = randomUUID();
getCallbackManager().dispatchEvent("llm-start", {
payload: {
id,
messages: params[0].messages,
},
});
const response = await originalMethod.call(this, ...params);
if (Symbol.asyncIterator in response) {
// save snapshot to restore it after the response is done
const snapshot = AsyncLocalStorage.snapshot();
const originalAsyncIterator = {
[Symbol.asyncIterator]: response[Symbol.asyncIterator].bind(response),
};
response[Symbol.asyncIterator] = async function* () {
const finalResponse = {
raw: [] as ChatResponseChunk[],
message: {
content: "",
role: "assistant",
options: {},
},
} satisfies ChatResponse;
let firstOne = false;
for await (const chunk of originalAsyncIterator) {
if (!firstOne) {
firstOne = true;
finalResponse.message.content = chunk.delta;
} else {
finalResponse.message.content += chunk.delta;
}
if (chunk.options) {
finalResponse.message.options = {
...finalResponse.message.options,
...chunk.options,
};
}
getCallbackManager().dispatchEvent("llm-stream", {
payload: {
id,
chunk,
},
});
finalResponse.raw.push(chunk);
yield chunk;
}
snapshot(() => {
getCallbackManager().dispatchEvent("llm-end", {
payload: {
id,
response: finalResponse,
},
});
});
};
} else {
getCallbackManager().dispatchEvent("llm-end", {
payload: {
id,
response,
},
});
}
return response;
};
}
+1 -1
View File
@@ -1,9 +1,9 @@
import type { BaseTool, MessageContent } from "@llamaindex/core/llms";
import type { BaseNode, Metadata } from "@llamaindex/core/schema";
import { TextNode } from "@llamaindex/core/schema";
import { extractText } from "@llamaindex/core/utils";
import type { BaseRetriever } from "../Retriever.js";
import type { VectorStoreIndex } from "../indices/vectorStore/index.js";
import { extractText } from "../llm/utils.js";
// Assuming that necessary interfaces and classes (like OT, TextNode, BaseNode, etc.) are defined elsewhere
// Import statements (e.g., for TextNode, BaseNode) should be added based on your project's structure

Some files were not shown because too many files have changed in this diff Show More