Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

@llamaindex/core

Package Overview
Dependencies
Maintainers
5
Versions
94
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@llamaindex/core - npm Package Compare versions

Comparing version
0.2.1
to
0.2.2
+204
dist/memory/index.cjs
Object.defineProperty(exports, '__esModule', { value: true });
var index_cjs$1 = require('../global/index.cjs');
var index_cjs$2 = require('../storage/chat-store/index.cjs');
var index_cjs = require('../utils/index.cjs');
var env = require('@llamaindex/env');
var index_cjs$3 = require('../prompts/index.cjs');
const DEFAULT_TOKEN_LIMIT_RATIO = 0.75;
const DEFAULT_CHAT_STORE_KEY = "chat_history";
/**
* A ChatMemory is used to keep the state of back and forth chat messages
*/ class BaseMemory {
_tokenCountForMessages(messages) {
if (messages.length === 0) {
return 0;
}
const tokenizer = index_cjs$1.Settings.tokenizer;
const str = messages.map((m)=>index_cjs.extractText(m.content)).join(" ");
return tokenizer.encode(str).length;
}
}
class BaseChatStoreMemory extends BaseMemory {
constructor(chatStore = new index_cjs$2.SimpleChatStore(), chatStoreKey = DEFAULT_CHAT_STORE_KEY){
super();
this.chatStore = chatStore;
this.chatStoreKey = chatStoreKey;
}
getAllMessages() {
return this.chatStore.getMessages(this.chatStoreKey);
}
put(messages) {
this.chatStore.addMessage(this.chatStoreKey, messages);
}
set(messages) {
this.chatStore.setMessages(this.chatStoreKey, messages);
}
reset() {
this.chatStore.deleteMessages(this.chatStoreKey);
}
}
class ChatMemoryBuffer extends BaseChatStoreMemory {
constructor(options){
super(options?.chatStore, options?.chatStoreKey);
const llm = options?.llm ?? index_cjs$1.Settings.llm;
const contextWindow = llm.metadata.contextWindow;
this.tokenLimit = options?.tokenLimit ?? Math.ceil(contextWindow * DEFAULT_TOKEN_LIMIT_RATIO);
if (options?.chatHistory) {
this.chatStore.setMessages(this.chatStoreKey, options.chatHistory);
}
}
getMessages(input, initialTokenCount = 0) {
const messages = this.getAllMessages();
if (initialTokenCount > this.tokenLimit) {
throw new Error("Initial token count exceeds token limit");
}
let messageCount = messages.length;
let currentMessages = messages.slice(-messageCount);
let tokenCount = this._tokenCountForMessages(messages) + initialTokenCount;
while(tokenCount > this.tokenLimit && messageCount > 1){
messageCount -= 1;
if (messages.at(-messageCount).role === "assistant") {
messageCount -= 1;
}
currentMessages = messages.slice(-messageCount);
tokenCount = this._tokenCountForMessages(currentMessages) + initialTokenCount;
}
if (tokenCount > this.tokenLimit && messageCount <= 0) {
return [];
}
return messages.slice(-messageCount);
}
}
class ChatSummaryMemoryBuffer extends BaseMemory {
constructor(options){
super();
this.messages = options?.messages ?? [];
this.summaryPrompt = options?.summaryPrompt ?? index_cjs$3.defaultSummaryPrompt;
this.llm = options?.llm ?? index_cjs$1.Settings.llm;
if (!this.llm.metadata.maxTokens) {
throw new Error("LLM maxTokens is not set. Needed so the summarizer ensures the context window size of the LLM.");
}
this.tokenizer = options?.tokenizer ?? env.tokenizers.tokenizer();
this.tokensToSummarize = this.llm.metadata.contextWindow - this.llm.metadata.maxTokens;
if (this.tokensToSummarize < this.llm.metadata.contextWindow * 0.25) {
throw new Error("The number of tokens that trigger the summarize process are less than 25% of the context window. Try lowering maxTokens or use a model with a larger context window.");
}
}
async summarize() {
// get the conversation messages to create summary
const messagesToSummarize = this.calcConversationMessages();
let promptMessages;
do {
promptMessages = [
{
content: this.summaryPrompt.format({
context: index_cjs.messagesToHistory(messagesToSummarize)
}),
role: "user",
options: {}
}
];
// remove oldest message until the chat history is short enough for the context window
messagesToSummarize.shift();
}while (this.tokenizer.encode(promptMessages[0].content).length > this.tokensToSummarize)
const response = await this.llm.chat({
messages: promptMessages
});
return {
content: response.message.content,
role: "memory"
};
}
// Find last summary message
get lastSummaryIndex() {
const reversedMessages = this.messages.slice().reverse();
const index = reversedMessages.findIndex((message)=>message.role === "memory");
if (index === -1) {
return null;
}
return this.messages.length - 1 - index;
}
getLastSummary() {
const lastSummaryIndex = this.lastSummaryIndex;
return lastSummaryIndex ? this.messages[lastSummaryIndex] : null;
}
get systemMessages() {
// get array of all system messages
return this.messages.filter((message)=>message.role === "system");
}
get nonSystemMessages() {
// get array of all non-system messages
return this.messages.filter((message)=>message.role !== "system");
}
/**
* Calculates the messages that describe the conversation so far.
* If there's no memory, all non-system messages are used.
* If there's a memory, uses all messages after the last summary message.
*/ calcConversationMessages(transformSummary) {
const lastSummaryIndex = this.lastSummaryIndex;
if (!lastSummaryIndex) {
// there's no memory, so just use all non-system messages
return this.nonSystemMessages;
} else {
// there's a memory, so use all messages after the last summary message
// and convert summary message so it can be send to the LLM
const summaryMessage = transformSummary ? {
content: `Summary of the conversation so far: ${this.messages[lastSummaryIndex].content}`,
role: "system"
} : this.messages[lastSummaryIndex];
return [
summaryMessage,
...this.messages.slice(lastSummaryIndex + 1)
];
}
}
calcCurrentRequestMessages() {
// TODO: check order: currently, we're sending:
// system messages first, then transient messages and then the messages that describe the conversation so far
return [
...this.systemMessages,
...this.calcConversationMessages(true)
];
}
reset() {
this.messages = [];
}
async getMessages() {
const requestMessages = this.calcCurrentRequestMessages();
// get tokens of current request messages and the transient messages
const tokens = requestMessages.reduce((count, message)=>count + this.tokenizer.encode(index_cjs.extractText(message.content)).length, 0);
if (tokens > this.tokensToSummarize) {
// if there are too many tokens for the next request, call summarize
const memoryMessage = await this.summarize();
const lastMessage = this.messages.at(-1);
if (lastMessage && lastMessage.role === "user") {
// if last message is a user message, ensure that it's sent after the new memory message
this.messages.pop();
this.messages.push(memoryMessage);
this.messages.push(lastMessage);
} else {
// otherwise just add the memory message
this.messages.push(memoryMessage);
}
// TODO: we still might have too many tokens
// e.g. too large system messages or transient messages
// how should we deal with that?
return this.calcCurrentRequestMessages();
}
return requestMessages;
}
async getAllMessages() {
return this.getMessages();
}
put(message) {
this.messages.push(message);
}
}
exports.BaseMemory = BaseMemory;
exports.ChatMemoryBuffer = ChatMemoryBuffer;
exports.ChatSummaryMemoryBuffer = ChatSummaryMemoryBuffer;
import { MessageContent, ChatMessage, LLM } from '../llms/index.cjs';
import { BaseChatStore } from '../storage/chat-store/index.cjs';
import { Tokenizer } from '@llamaindex/env';
import { SummaryPrompt } from '../prompts/index.cjs';
/**
* A ChatMemory is used to keep the state of back and forth chat messages
*/
declare abstract class BaseMemory<AdditionalMessageOptions extends object = object> {
abstract getMessages(input?: MessageContent | undefined): ChatMessage<AdditionalMessageOptions>[] | Promise<ChatMessage<AdditionalMessageOptions>[]>;
abstract getAllMessages(): ChatMessage<AdditionalMessageOptions>[] | Promise<ChatMessage<AdditionalMessageOptions>[]>;
abstract put(messages: ChatMessage<AdditionalMessageOptions>): void;
abstract reset(): void;
protected _tokenCountForMessages(messages: ChatMessage[]): number;
}
declare abstract class BaseChatStoreMemory<AdditionalMessageOptions extends object = object> extends BaseMemory<AdditionalMessageOptions> {
chatStore: BaseChatStore<AdditionalMessageOptions>;
chatStoreKey: string;
protected constructor(chatStore?: BaseChatStore<AdditionalMessageOptions>, chatStoreKey?: string);
getAllMessages(): ChatMessage<AdditionalMessageOptions>[];
put(messages: ChatMessage<AdditionalMessageOptions>): void;
set(messages: ChatMessage<AdditionalMessageOptions>[]): void;
reset(): void;
}
type ChatMemoryBufferOptions<AdditionalMessageOptions extends object = object> = {
tokenLimit?: number | undefined;
chatStore?: BaseChatStore<AdditionalMessageOptions> | undefined;
chatStoreKey?: string | undefined;
chatHistory?: ChatMessage<AdditionalMessageOptions>[] | undefined;
llm?: LLM<object, AdditionalMessageOptions> | undefined;
};
declare class ChatMemoryBuffer<AdditionalMessageOptions extends object = object> extends BaseChatStoreMemory<AdditionalMessageOptions> {
tokenLimit: number;
constructor(options?: Partial<ChatMemoryBufferOptions<AdditionalMessageOptions>>);
getMessages(input?: MessageContent | undefined, initialTokenCount?: number): ChatMessage<AdditionalMessageOptions>[];
}
declare class ChatSummaryMemoryBuffer extends BaseMemory {
/**
* Tokenizer function that converts text to tokens,
* this is used to calculate the number of tokens in a message.
*/
tokenizer: Tokenizer;
tokensToSummarize: number;
messages: ChatMessage[];
summaryPrompt: SummaryPrompt;
llm: LLM;
constructor(options?: Partial<ChatSummaryMemoryBuffer>);
private summarize;
private get lastSummaryIndex();
getLastSummary(): ChatMessage | null;
private get systemMessages();
private get nonSystemMessages();
/**
* Calculates the messages that describe the conversation so far.
* If there's no memory, all non-system messages are used.
* If there's a memory, uses all messages after the last summary message.
*/
private calcConversationMessages;
private calcCurrentRequestMessages;
reset(): void;
getMessages(): Promise<ChatMessage[]>;
getAllMessages(): Promise<ChatMessage[]>;
put(message: ChatMessage): void;
}
export { BaseMemory, ChatMemoryBuffer, ChatSummaryMemoryBuffer };
import { MessageContent, ChatMessage, LLM } from '../llms/index.js';
import { BaseChatStore } from '../storage/chat-store/index.js';
import { Tokenizer } from '@llamaindex/env';
import { SummaryPrompt } from '../prompts/index.js';
/**
* A ChatMemory is used to keep the state of back and forth chat messages
*/
declare abstract class BaseMemory<AdditionalMessageOptions extends object = object> {
abstract getMessages(input?: MessageContent | undefined): ChatMessage<AdditionalMessageOptions>[] | Promise<ChatMessage<AdditionalMessageOptions>[]>;
abstract getAllMessages(): ChatMessage<AdditionalMessageOptions>[] | Promise<ChatMessage<AdditionalMessageOptions>[]>;
abstract put(messages: ChatMessage<AdditionalMessageOptions>): void;
abstract reset(): void;
protected _tokenCountForMessages(messages: ChatMessage[]): number;
}
declare abstract class BaseChatStoreMemory<AdditionalMessageOptions extends object = object> extends BaseMemory<AdditionalMessageOptions> {
chatStore: BaseChatStore<AdditionalMessageOptions>;
chatStoreKey: string;
protected constructor(chatStore?: BaseChatStore<AdditionalMessageOptions>, chatStoreKey?: string);
getAllMessages(): ChatMessage<AdditionalMessageOptions>[];
put(messages: ChatMessage<AdditionalMessageOptions>): void;
set(messages: ChatMessage<AdditionalMessageOptions>[]): void;
reset(): void;
}
type ChatMemoryBufferOptions<AdditionalMessageOptions extends object = object> = {
tokenLimit?: number | undefined;
chatStore?: BaseChatStore<AdditionalMessageOptions> | undefined;
chatStoreKey?: string | undefined;
chatHistory?: ChatMessage<AdditionalMessageOptions>[] | undefined;
llm?: LLM<object, AdditionalMessageOptions> | undefined;
};
declare class ChatMemoryBuffer<AdditionalMessageOptions extends object = object> extends BaseChatStoreMemory<AdditionalMessageOptions> {
tokenLimit: number;
constructor(options?: Partial<ChatMemoryBufferOptions<AdditionalMessageOptions>>);
getMessages(input?: MessageContent | undefined, initialTokenCount?: number): ChatMessage<AdditionalMessageOptions>[];
}
declare class ChatSummaryMemoryBuffer extends BaseMemory {
/**
* Tokenizer function that converts text to tokens,
* this is used to calculate the number of tokens in a message.
*/
tokenizer: Tokenizer;
tokensToSummarize: number;
messages: ChatMessage[];
summaryPrompt: SummaryPrompt;
llm: LLM;
constructor(options?: Partial<ChatSummaryMemoryBuffer>);
private summarize;
private get lastSummaryIndex();
getLastSummary(): ChatMessage | null;
private get systemMessages();
private get nonSystemMessages();
/**
* Calculates the messages that describe the conversation so far.
* If there's no memory, all non-system messages are used.
* If there's a memory, uses all messages after the last summary message.
*/
private calcConversationMessages;
private calcCurrentRequestMessages;
reset(): void;
getMessages(): Promise<ChatMessage[]>;
getAllMessages(): Promise<ChatMessage[]>;
put(message: ChatMessage): void;
}
export { BaseMemory, ChatMemoryBuffer, ChatSummaryMemoryBuffer };
import { Settings } from '../global/index.js';
import { SimpleChatStore } from '../storage/chat-store/index.js';
import { extractText, messagesToHistory } from '../utils/index.js';
import { tokenizers } from '@llamaindex/env';
import { defaultSummaryPrompt } from '../prompts/index.js';
const DEFAULT_TOKEN_LIMIT_RATIO = 0.75;
const DEFAULT_CHAT_STORE_KEY = "chat_history";
/**
* A ChatMemory is used to keep the state of back and forth chat messages
*/ class BaseMemory {
_tokenCountForMessages(messages) {
if (messages.length === 0) {
return 0;
}
const tokenizer = Settings.tokenizer;
const str = messages.map((m)=>extractText(m.content)).join(" ");
return tokenizer.encode(str).length;
}
}
class BaseChatStoreMemory extends BaseMemory {
constructor(chatStore = new SimpleChatStore(), chatStoreKey = DEFAULT_CHAT_STORE_KEY){
super();
this.chatStore = chatStore;
this.chatStoreKey = chatStoreKey;
}
getAllMessages() {
return this.chatStore.getMessages(this.chatStoreKey);
}
put(messages) {
this.chatStore.addMessage(this.chatStoreKey, messages);
}
set(messages) {
this.chatStore.setMessages(this.chatStoreKey, messages);
}
reset() {
this.chatStore.deleteMessages(this.chatStoreKey);
}
}
class ChatMemoryBuffer extends BaseChatStoreMemory {
constructor(options){
super(options?.chatStore, options?.chatStoreKey);
const llm = options?.llm ?? Settings.llm;
const contextWindow = llm.metadata.contextWindow;
this.tokenLimit = options?.tokenLimit ?? Math.ceil(contextWindow * DEFAULT_TOKEN_LIMIT_RATIO);
if (options?.chatHistory) {
this.chatStore.setMessages(this.chatStoreKey, options.chatHistory);
}
}
getMessages(input, initialTokenCount = 0) {
const messages = this.getAllMessages();
if (initialTokenCount > this.tokenLimit) {
throw new Error("Initial token count exceeds token limit");
}
let messageCount = messages.length;
let currentMessages = messages.slice(-messageCount);
let tokenCount = this._tokenCountForMessages(messages) + initialTokenCount;
while(tokenCount > this.tokenLimit && messageCount > 1){
messageCount -= 1;
if (messages.at(-messageCount).role === "assistant") {
messageCount -= 1;
}
currentMessages = messages.slice(-messageCount);
tokenCount = this._tokenCountForMessages(currentMessages) + initialTokenCount;
}
if (tokenCount > this.tokenLimit && messageCount <= 0) {
return [];
}
return messages.slice(-messageCount);
}
}
class ChatSummaryMemoryBuffer extends BaseMemory {
constructor(options){
super();
this.messages = options?.messages ?? [];
this.summaryPrompt = options?.summaryPrompt ?? defaultSummaryPrompt;
this.llm = options?.llm ?? Settings.llm;
if (!this.llm.metadata.maxTokens) {
throw new Error("LLM maxTokens is not set. Needed so the summarizer ensures the context window size of the LLM.");
}
this.tokenizer = options?.tokenizer ?? tokenizers.tokenizer();
this.tokensToSummarize = this.llm.metadata.contextWindow - this.llm.metadata.maxTokens;
if (this.tokensToSummarize < this.llm.metadata.contextWindow * 0.25) {
throw new Error("The number of tokens that trigger the summarize process are less than 25% of the context window. Try lowering maxTokens or use a model with a larger context window.");
}
}
async summarize() {
// get the conversation messages to create summary
const messagesToSummarize = this.calcConversationMessages();
let promptMessages;
do {
promptMessages = [
{
content: this.summaryPrompt.format({
context: messagesToHistory(messagesToSummarize)
}),
role: "user",
options: {}
}
];
// remove oldest message until the chat history is short enough for the context window
messagesToSummarize.shift();
}while (this.tokenizer.encode(promptMessages[0].content).length > this.tokensToSummarize)
const response = await this.llm.chat({
messages: promptMessages
});
return {
content: response.message.content,
role: "memory"
};
}
// Find last summary message
get lastSummaryIndex() {
const reversedMessages = this.messages.slice().reverse();
const index = reversedMessages.findIndex((message)=>message.role === "memory");
if (index === -1) {
return null;
}
return this.messages.length - 1 - index;
}
getLastSummary() {
const lastSummaryIndex = this.lastSummaryIndex;
return lastSummaryIndex ? this.messages[lastSummaryIndex] : null;
}
get systemMessages() {
// get array of all system messages
return this.messages.filter((message)=>message.role === "system");
}
get nonSystemMessages() {
// get array of all non-system messages
return this.messages.filter((message)=>message.role !== "system");
}
/**
* Calculates the messages that describe the conversation so far.
* If there's no memory, all non-system messages are used.
* If there's a memory, uses all messages after the last summary message.
*/ calcConversationMessages(transformSummary) {
const lastSummaryIndex = this.lastSummaryIndex;
if (!lastSummaryIndex) {
// there's no memory, so just use all non-system messages
return this.nonSystemMessages;
} else {
// there's a memory, so use all messages after the last summary message
// and convert summary message so it can be send to the LLM
const summaryMessage = transformSummary ? {
content: `Summary of the conversation so far: ${this.messages[lastSummaryIndex].content}`,
role: "system"
} : this.messages[lastSummaryIndex];
return [
summaryMessage,
...this.messages.slice(lastSummaryIndex + 1)
];
}
}
calcCurrentRequestMessages() {
// TODO: check order: currently, we're sending:
// system messages first, then transient messages and then the messages that describe the conversation so far
return [
...this.systemMessages,
...this.calcConversationMessages(true)
];
}
reset() {
this.messages = [];
}
async getMessages() {
const requestMessages = this.calcCurrentRequestMessages();
// get tokens of current request messages and the transient messages
const tokens = requestMessages.reduce((count, message)=>count + this.tokenizer.encode(extractText(message.content)).length, 0);
if (tokens > this.tokensToSummarize) {
// if there are too many tokens for the next request, call summarize
const memoryMessage = await this.summarize();
const lastMessage = this.messages.at(-1);
if (lastMessage && lastMessage.role === "user") {
// if last message is a user message, ensure that it's sent after the new memory message
this.messages.pop();
this.messages.push(memoryMessage);
this.messages.push(lastMessage);
} else {
// otherwise just add the memory message
this.messages.push(memoryMessage);
}
// TODO: we still might have too many tokens
// e.g. too large system messages or transient messages
// how should we deal with that?
return this.calcCurrentRequestMessages();
}
return requestMessages;
}
async getAllMessages() {
return this.getMessages();
}
put(message) {
this.messages.push(message);
}
}
export { BaseMemory, ChatMemoryBuffer, ChatSummaryMemoryBuffer };
Object.defineProperty(exports, '__esModule', { value: true });
class BaseChatStore {
}
class SimpleChatStore extends BaseChatStore {
#store;
setMessages(key, messages) {
this.#store.set(key, messages);
}
getMessages(key) {
return this.#store.get(key) ?? [];
}
addMessage(key, message, idx) {
const messages = this.#store.get(key) ?? [];
if (idx === undefined) {
messages.push(message);
} else {
messages.splice(idx, 0, message);
}
this.#store.set(key, messages);
}
deleteMessages(key) {
this.#store.delete(key);
}
deleteMessage(key, idx) {
const messages = this.#store.get(key) ?? [];
messages.splice(idx, 1);
this.#store.set(key, messages);
}
getKeys() {
return this.#store.keys();
}
constructor(...args){
super(...args);
this.#store = new Map();
}
}
exports.BaseChatStore = BaseChatStore;
exports.SimpleChatStore = SimpleChatStore;
import { ChatMessage } from '../../llms/index.cjs';
declare abstract class BaseChatStore<AdditionalMessageOptions extends object = object> {
abstract setMessages(key: string, messages: ChatMessage<AdditionalMessageOptions>[]): void;
abstract getMessages(key: string): ChatMessage<AdditionalMessageOptions>[];
abstract addMessage(key: string, message: ChatMessage<AdditionalMessageOptions>, idx?: number): void;
abstract deleteMessages(key: string): void;
abstract deleteMessage(key: string, idx: number): void;
abstract getKeys(): IterableIterator<string>;
}
declare class SimpleChatStore<AdditionalMessageOptions extends object = object> extends BaseChatStore<AdditionalMessageOptions> {
#private;
setMessages(key: string, messages: ChatMessage<AdditionalMessageOptions>[]): void;
getMessages(key: string): ChatMessage<AdditionalMessageOptions>[];
addMessage(key: string, message: ChatMessage<AdditionalMessageOptions>, idx?: number): void;
deleteMessages(key: string): void;
deleteMessage(key: string, idx: number): void;
getKeys(): MapIterator<string>;
}
export { BaseChatStore, SimpleChatStore };
import { ChatMessage } from '../../llms/index.js';
declare abstract class BaseChatStore<AdditionalMessageOptions extends object = object> {
abstract setMessages(key: string, messages: ChatMessage<AdditionalMessageOptions>[]): void;
abstract getMessages(key: string): ChatMessage<AdditionalMessageOptions>[];
abstract addMessage(key: string, message: ChatMessage<AdditionalMessageOptions>, idx?: number): void;
abstract deleteMessages(key: string): void;
abstract deleteMessage(key: string, idx: number): void;
abstract getKeys(): IterableIterator<string>;
}
declare class SimpleChatStore<AdditionalMessageOptions extends object = object> extends BaseChatStore<AdditionalMessageOptions> {
#private;
setMessages(key: string, messages: ChatMessage<AdditionalMessageOptions>[]): void;
getMessages(key: string): ChatMessage<AdditionalMessageOptions>[];
addMessage(key: string, message: ChatMessage<AdditionalMessageOptions>, idx?: number): void;
deleteMessages(key: string): void;
deleteMessage(key: string, idx: number): void;
getKeys(): MapIterator<string>;
}
export { BaseChatStore, SimpleChatStore };
class BaseChatStore {
}
class SimpleChatStore extends BaseChatStore {
#store;
setMessages(key, messages) {
this.#store.set(key, messages);
}
getMessages(key) {
return this.#store.get(key) ?? [];
}
addMessage(key, message, idx) {
const messages = this.#store.get(key) ?? [];
if (idx === undefined) {
messages.push(message);
} else {
messages.splice(idx, 0, message);
}
this.#store.set(key, messages);
}
deleteMessages(key) {
this.#store.delete(key);
}
deleteMessage(key, idx) {
const messages = this.#store.get(key) ?? [];
messages.splice(idx, 1);
this.#store.set(key, messages);
}
getKeys() {
return this.#store.keys();
}
constructor(...args){
super(...args);
this.#store = new Map();
}
}
export { BaseChatStore, SimpleChatStore };
+70
-18

@@ -76,23 +76,36 @@ Object.defineProperty(exports, '__esModule', { value: true });

class BaseEmbedding extends index_cjs.TransformComponent {
constructor(){
super(async (nodes, options)=>{
const texts = nodes.map((node)=>node.getContent(index_cjs.MetadataMode.EMBED));
const embeddings = await this.getTextEmbeddingsBatch(texts, options);
for(let i = 0; i < nodes.length; i++){
nodes[i].embedding = embeddings[i];
}
return nodes;
});
this.embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
/**
constructor(transformFn){
if (transformFn) {
super(transformFn);
this.embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
/**
* Optionally override this method to retrieve multiple embeddings in a single request
* @param texts
*/ this.getTextEmbeddings = async (texts)=>{
const embeddings = [];
for (const text of texts){
const embedding = await this.getTextEmbedding(text);
embeddings.push(embedding);
}
return embeddings;
};
const embeddings = [];
for (const text of texts){
const embedding = await this.getTextEmbedding(text);
embeddings.push(embedding);
}
return embeddings;
};
} else {
super(async (nodes, options)=>{
const texts = nodes.map((node)=>node.getContent(index_cjs.MetadataMode.EMBED));
const embeddings = await this.getTextEmbeddingsBatch(texts, options);
for(let i = 0; i < nodes.length; i++){
nodes[i].embedding = embeddings[i];
}
return nodes;
});
this.embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
this.getTextEmbeddings = async (texts)=>{
const embeddings = [];
for (const text of texts){
const embedding = await this.getTextEmbedding(text);
embeddings.push(embedding);
}
return embeddings;
};
}
}

@@ -142,6 +155,45 @@ similarity(embedding1, embedding2, mode = exports.SimilarityType.DEFAULT) {

/*
* Base class for Multi Modal embeddings.
*/ class MultiModalEmbedding extends BaseEmbedding {
constructor(){
super(async (nodes, options)=>{
const nodeMap = index_cjs.splitNodesByType(nodes);
const imageNodes = nodeMap[index_cjs.ModalityType.IMAGE] ?? [];
const textNodes = nodeMap[index_cjs.ModalityType.TEXT] ?? [];
const embeddings = await batchEmbeddings(textNodes.map((node)=>node.getContent(index_cjs.MetadataMode.EMBED)), this.getTextEmbeddings.bind(this), this.embedBatchSize, options);
for(let i = 0; i < textNodes.length; i++){
textNodes[i].embedding = embeddings[i];
}
const imageEmbeddings = await batchEmbeddings(imageNodes.map((n)=>n.image), this.getImageEmbeddings.bind(this), this.embedBatchSize, options);
for(let i = 0; i < imageNodes.length; i++){
imageNodes[i].embedding = imageEmbeddings[i];
}
return nodes;
});
}
/**
* Optionally override this method to retrieve multiple image embeddings in a single request
* @param images
*/ async getImageEmbeddings(images) {
return Promise.all(images.map((imgFilePath)=>this.getImageEmbedding(imgFilePath)));
}
async getQueryEmbedding(query) {
const image = index_cjs$1.extractImage(query);
if (image) {
return await this.getImageEmbedding(image);
}
const text = index_cjs$1.extractSingleText(query);
if (text) {
return await this.getTextEmbedding(text);
}
return null;
}
}
exports.BaseEmbedding = BaseEmbedding;
exports.DEFAULT_SIMILARITY_TOP_K = DEFAULT_SIMILARITY_TOP_K;
exports.MultiModalEmbedding = MultiModalEmbedding;
exports.batchEmbeddings = batchEmbeddings;
exports.similarity = similarity;
exports.truncateMaxTokens = truncateMaxTokens;
import { Tokenizers } from '@llamaindex/env';
import { MessageContentDetail } from '../llms/index.cjs';
import { TransformComponent } from '../schema/index.cjs';
import { TransformComponent, BaseNode, ImageType } from '../schema/index.cjs';

@@ -36,3 +36,3 @@ declare const DEFAULT_SIMILARITY_TOP_K = 2;

embedInfo?: EmbeddingInfo;
constructor();
protected constructor(transformFn?: (nodes: BaseNode[], options?: BaseEmbeddingOptions) => Promise<BaseNode[]>);
similarity(embedding1: number[], embedding2: number[], mode?: SimilarityType): number;

@@ -56,4 +56,15 @@ abstract getTextEmbedding(text: string): Promise<number[]>;

declare abstract class MultiModalEmbedding extends BaseEmbedding {
abstract getImageEmbedding(images: ImageType): Promise<number[]>;
protected constructor();
/**
* Optionally override this method to retrieve multiple image embeddings in a single request
* @param images
*/
getImageEmbeddings(images: ImageType[]): Promise<number[][]>;
getQueryEmbedding(query: MessageContentDetail): Promise<number[] | null>;
}
declare function truncateMaxTokens(tokenizer: Tokenizers, value: string, maxTokens: number): string;
export { BaseEmbedding, type BaseEmbeddingOptions, DEFAULT_SIMILARITY_TOP_K, type EmbeddingInfo, SimilarityType, batchEmbeddings, similarity, truncateMaxTokens };
export { BaseEmbedding, type BaseEmbeddingOptions, DEFAULT_SIMILARITY_TOP_K, type EmbeddingInfo, MultiModalEmbedding, SimilarityType, batchEmbeddings, similarity, truncateMaxTokens };
import { Tokenizers } from '@llamaindex/env';
import { MessageContentDetail } from '../llms/index.js';
import { TransformComponent } from '../schema/index.js';
import { TransformComponent, BaseNode, ImageType } from '../schema/index.js';

@@ -36,3 +36,3 @@ declare const DEFAULT_SIMILARITY_TOP_K = 2;

embedInfo?: EmbeddingInfo;
constructor();
protected constructor(transformFn?: (nodes: BaseNode[], options?: BaseEmbeddingOptions) => Promise<BaseNode[]>);
similarity(embedding1: number[], embedding2: number[], mode?: SimilarityType): number;

@@ -56,4 +56,15 @@ abstract getTextEmbedding(text: string): Promise<number[]>;

declare abstract class MultiModalEmbedding extends BaseEmbedding {
abstract getImageEmbedding(images: ImageType): Promise<number[]>;
protected constructor();
/**
* Optionally override this method to retrieve multiple image embeddings in a single request
* @param images
*/
getImageEmbeddings(images: ImageType[]): Promise<number[][]>;
getQueryEmbedding(query: MessageContentDetail): Promise<number[] | null>;
}
declare function truncateMaxTokens(tokenizer: Tokenizers, value: string, maxTokens: number): string;
export { BaseEmbedding, type BaseEmbeddingOptions, DEFAULT_SIMILARITY_TOP_K, type EmbeddingInfo, SimilarityType, batchEmbeddings, similarity, truncateMaxTokens };
export { BaseEmbedding, type BaseEmbeddingOptions, DEFAULT_SIMILARITY_TOP_K, type EmbeddingInfo, MultiModalEmbedding, SimilarityType, batchEmbeddings, similarity, truncateMaxTokens };

@@ -1,3 +0,3 @@

import { TransformComponent, MetadataMode } from '../schema/index.js';
import { extractSingleText } from '../utils/index.js';
import { TransformComponent, MetadataMode, splitNodesByType, ModalityType } from '../schema/index.js';
import { extractSingleText, extractImage } from '../utils/index.js';
import { tokenizers } from '@llamaindex/env';

@@ -74,23 +74,36 @@

class BaseEmbedding extends TransformComponent {
constructor(){
super(async (nodes, options)=>{
const texts = nodes.map((node)=>node.getContent(MetadataMode.EMBED));
const embeddings = await this.getTextEmbeddingsBatch(texts, options);
for(let i = 0; i < nodes.length; i++){
nodes[i].embedding = embeddings[i];
}
return nodes;
});
this.embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
/**
constructor(transformFn){
if (transformFn) {
super(transformFn);
this.embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
/**
* Optionally override this method to retrieve multiple embeddings in a single request
* @param texts
*/ this.getTextEmbeddings = async (texts)=>{
const embeddings = [];
for (const text of texts){
const embedding = await this.getTextEmbedding(text);
embeddings.push(embedding);
}
return embeddings;
};
const embeddings = [];
for (const text of texts){
const embedding = await this.getTextEmbedding(text);
embeddings.push(embedding);
}
return embeddings;
};
} else {
super(async (nodes, options)=>{
const texts = nodes.map((node)=>node.getContent(MetadataMode.EMBED));
const embeddings = await this.getTextEmbeddingsBatch(texts, options);
for(let i = 0; i < nodes.length; i++){
nodes[i].embedding = embeddings[i];
}
return nodes;
});
this.embedBatchSize = DEFAULT_EMBED_BATCH_SIZE;
this.getTextEmbeddings = async (texts)=>{
const embeddings = [];
for (const text of texts){
const embedding = await this.getTextEmbedding(text);
embeddings.push(embedding);
}
return embeddings;
};
}
}

@@ -140,2 +153,40 @@ similarity(embedding1, embedding2, mode = SimilarityType.DEFAULT) {

export { BaseEmbedding, DEFAULT_SIMILARITY_TOP_K, SimilarityType, batchEmbeddings, similarity, truncateMaxTokens };
/*
* Base class for Multi Modal embeddings.
*/ class MultiModalEmbedding extends BaseEmbedding {
constructor(){
super(async (nodes, options)=>{
const nodeMap = splitNodesByType(nodes);
const imageNodes = nodeMap[ModalityType.IMAGE] ?? [];
const textNodes = nodeMap[ModalityType.TEXT] ?? [];
const embeddings = await batchEmbeddings(textNodes.map((node)=>node.getContent(MetadataMode.EMBED)), this.getTextEmbeddings.bind(this), this.embedBatchSize, options);
for(let i = 0; i < textNodes.length; i++){
textNodes[i].embedding = embeddings[i];
}
const imageEmbeddings = await batchEmbeddings(imageNodes.map((n)=>n.image), this.getImageEmbeddings.bind(this), this.embedBatchSize, options);
for(let i = 0; i < imageNodes.length; i++){
imageNodes[i].embedding = imageEmbeddings[i];
}
return nodes;
});
}
/**
* Optionally override this method to retrieve multiple image embeddings in a single request
* @param images
*/ async getImageEmbeddings(images) {
return Promise.all(images.map((imgFilePath)=>this.getImageEmbedding(imgFilePath)));
}
async getQueryEmbedding(query) {
const image = extractImage(query);
if (image) {
return await this.getImageEmbedding(image);
}
const text = extractSingleText(query);
if (text) {
return await this.getTextEmbedding(text);
}
return null;
}
}
export { BaseEmbedding, DEFAULT_SIMILARITY_TOP_K, MultiModalEmbedding, SimilarityType, batchEmbeddings, similarity, truncateMaxTokens };
{
"name": "@llamaindex/core",
"type": "module",
"version": "0.2.1",
"version": "0.2.2",
"description": "LlamaIndex Core Module",

@@ -160,2 +160,30 @@ "exports": {

}
},
"./memory": {
"require": {
"types": "./dist/memory/index.d.cts",
"default": "./dist/memory/index.cjs"
},
"import": {
"types": "./dist/memory/index.d.ts",
"default": "./dist/memory/index.js"
},
"default": {
"types": "./dist/memory/index.d.ts",
"default": "./dist/memory/index.js"
}
},
"./storage/chat-store": {
"require": {
"types": "./dist/storage/chat-store/index.d.cts",
"default": "./dist/storage/chat-store/index.cjs"
},
"import": {
"types": "./dist/storage/chat-store/index.d.ts",
"default": "./dist/storage/chat-store/index.js"
},
"default": {
"types": "./dist/storage/chat-store/index.d.ts",
"default": "./dist/storage/chat-store/index.js"
}
}

@@ -162,0 +190,0 @@ },