Compare commits

..

2 Commits

Author SHA1 Message Date
Marcus Schiesser b622f49845 add docs and unit test 2024-09-20 15:01:08 +07:00
Marcus Schiesser f02ecbff14 fix: context not working in contextchatengine 2024-09-20 12:58:26 +07:00
77 changed files with 445 additions and 2565 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"llamaindex": patch
"@llamaindex/core": patch
---
Fix context not being sent using ContextChatEngine
+5 -7
View File
@@ -167,13 +167,11 @@ export async function chatWithAgent(
// ... adding your tools here
],
});
const responseStream = await agent.chat(
{
message: question,
chatHistory: prevMessages,
},
true,
);
const responseStream = await agent.chat({
stream: true,
message: question,
chatHistory: prevMessages,
});
const uiStream = createStreamableUI(<div>loading...</div>);
responseStream
.pipeTo(
-30
View File
@@ -1,35 +1,5 @@
# docs
## 0.0.77
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.0.76
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.0.75
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.0.74
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.0.73
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.77",
"version": "0.0.73",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
+1 -1
View File
@@ -18,7 +18,7 @@ import readline from "node:readline/promises";
});
const chatEngine = new SimpleChatEngine({
llm,
memory: chatHistory,
chatHistory,
});
const rl = readline.createInterface({ input, output });
+6 -4
View File
@@ -27,10 +27,12 @@ async function main() {
// Query the index
const queryEngine = index.asQueryEngine();
const stream = await queryEngine.query({
query: "What did the author do in college?",
stream: true,
});
const stream = await queryEngine.query(
{
query: "What did the author do in college?",
},
true,
);
// Output response
for await (const chunk of stream) {
+6 -4
View File
@@ -37,10 +37,12 @@ async function main() {
// Query the index
const queryEngine = index.asQueryEngine();
const stream = await queryEngine.query({
query: "What did the author do in college?",
stream: true,
});
const stream = await queryEngine.query(
{
query: "What did the author do in college?",
},
true,
);
// Output response
for await (const chunk of stream) {
+1 -3
View File
@@ -1,5 +1,4 @@
// call pnpm tsx multimodal/load.ts first to init the storage
import { extractText } from "@llamaindex/core/utils";
import {
ContextChatEngine,
NodeWithScore,
@@ -26,9 +25,8 @@ Settings.callbackManager.on("retrieve-end", (event) => {
const textNodes = nodes.filter(
(node: NodeWithScore) => node.node.type === ObjectType.TEXT,
);
const text = extractText(query);
console.log(
`Retrieved ${textNodes.length} text nodes and ${imageNodes.length} image nodes for query: ${text}`,
`Retrieved ${textNodes.length} text nodes and ${imageNodes.length} image nodes for query: ${query}`,
);
});
+7 -7
View File
@@ -1,4 +1,3 @@
import { extractText } from "@llamaindex/core/utils";
import {
getResponseSynthesizer,
OpenAI,
@@ -17,8 +16,7 @@ Settings.llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 512 });
// Update callbackManager
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes, query } = event.detail;
const text = extractText(query);
console.log(`Retrieved ${nodes.length} nodes for query: ${text}`);
console.log(`Retrieved ${nodes.length} nodes for query: ${query}`);
});
async function main() {
@@ -32,10 +30,12 @@ async function main() {
responseSynthesizer: getResponseSynthesizer("multi_modal"),
retriever: index.asRetriever({ topK: { TEXT: 3, IMAGE: 1 } }),
});
const stream = await queryEngine.query({
query: "Tell me more about Vincent van Gogh's famous paintings",
stream: true,
});
const stream = await queryEngine.query(
{
query: "Tell me more about Vincent van Gogh's famous paintings",
},
true,
);
for await (const chunk of stream) {
process.stdout.write(chunk.response);
}
+1 -5
View File
@@ -40,11 +40,7 @@ async function main(args: any) {
const rdr = new SimpleDirectoryReader(callback);
const docs = await rdr.loadData({ directoryPath: sourceDir });
const pgvs = new PGVectorStore({
clientConfig: {
connectionString: process.env.PG_CONNECTION_STRING,
},
});
const pgvs = new PGVectorStore();
pgvs.setCollection(sourceDir);
await pgvs.clearCollection();
+1 -5
View File
@@ -7,11 +7,7 @@ async function main() {
});
try {
const pgvs = new PGVectorStore({
clientConfig: {
connectionString: process.env.PG_CONNECTION_STRING,
},
});
const pgvs = new PGVectorStore();
// Optional - set your collection name, default is no filter on this field.
// pgvs.setCollection();
-30
View File
@@ -1,35 +1,5 @@
# @llamaindex/autotool
## 3.0.8
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 3.0.7
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 3.0.6
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 3.0.5
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 3.0.4
### Patch Changes
@@ -1,39 +1,5 @@
# @llamaindex/autotool-01-node-example
## 0.0.17
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
- @llamaindex/autotool@3.0.8
## 0.0.16
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
- @llamaindex/autotool@3.0.7
## 0.0.15
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
- @llamaindex/autotool@3.0.6
## 0.0.14
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
- @llamaindex/autotool@3.0.5
## 0.0.13
### Patch Changes
@@ -13,5 +13,5 @@
"scripts": {
"start": "node --import tsx --import @llamaindex/autotool/node ./src/index.ts"
},
"version": "0.0.17"
"version": "0.0.13"
}
@@ -1,39 +1,5 @@
# @llamaindex/autotool-02-next-example
## 0.1.61
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
- @llamaindex/autotool@3.0.8
## 0.1.60
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
- @llamaindex/autotool@3.0.7
## 0.1.59
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
- @llamaindex/autotool@3.0.6
## 0.1.58
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
- @llamaindex/autotool@3.0.5
## 0.1.57
### Patch Changes
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool-02-next-example",
"private": true,
"version": "0.1.61",
"version": "0.1.57",
"scripts": {
"dev": "next dev",
"build": "next build",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/autotool",
"type": "module",
"version": "3.0.8",
"version": "3.0.4",
"description": "auto transpile your JS function to LLM Agent compatible",
"files": [
"dist",
-15
View File
@@ -1,20 +1,5 @@
# @llamaindex/community
## 0.0.40
### Patch Changes
- 50e6b57: feat: add Amazon Bedrock Retriever
- Updated dependencies [8b7fdba]
- @llamaindex/core@0.2.6
## 0.0.39
### Patch Changes
- Updated dependencies [d902cc3]
- @llamaindex/core@0.2.5
## 0.0.38
### Patch Changes
-1
View File
@@ -7,7 +7,6 @@
- Bedrock support for the Anthropic Claude Models [usage](https://ts.llamaindex.ai/modules/llms/available_llms/bedrock)
- Bedrock support for the Meta LLama 2, 3 and 3.1 Models [usage](https://ts.llamaindex.ai/modules/llms/available_llms/bedrock)
- Meta LLama3.1 405b tool call support
- Bedrock support for querying Knowledge Base
## LICENSE
+1 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/community",
"description": "Community package for LlamaIndexTS",
"version": "0.0.40",
"version": "0.0.38",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
@@ -47,7 +47,6 @@
},
"dependencies": {
"@aws-sdk/client-bedrock-runtime": "^3.642.0",
"@aws-sdk/client-bedrock-agent-runtime": "^3.642.0",
"@llamaindex/core": "workspace:*",
"@llamaindex/env": "workspace:*"
}
-1
View File
@@ -3,4 +3,3 @@ export {
BEDROCK_MODEL_MAX_TOKENS,
Bedrock,
} from "./llm/bedrock/index.js";
export { AmazonKnowledgeBaseRetriever } from "./retrievers/bedrock.js";
@@ -1,165 +0,0 @@
import type { KnowledgeBaseVectorSearchConfiguration } from "@aws-sdk/client-bedrock-agent-runtime";
import {
BedrockAgentRuntimeClient,
type BedrockAgentRuntimeClientConfig,
type RetrievalFilter,
RetrieveCommand,
type SearchType,
} from "@aws-sdk/client-bedrock-agent-runtime";
import type { QueryBundle } from "@llamaindex/core/query-engine";
import { BaseRetriever } from "@llamaindex/core/retriever";
import { Document, type NodeWithScore } from "@llamaindex/core/schema";
import { extractText } from "@llamaindex/core/utils";
/**
* Interface for the arguments required to initialize an
* AmazonKnowledgeBaseRetriever instance.
*/
export interface AmazonKnowledgeBaseRetrieverArgs {
knowledgeBaseId: string;
topK: number;
region: string;
clientOptions?: BedrockAgentRuntimeClientConfig;
filter?: RetrievalFilter;
overrideSearchType?: SearchType;
}
/**
* Class for interacting with Amazon Bedrock Knowledge Bases, a RAG workflow oriented service
* Extends the BaseRetriever class.
* @example
* ```typescript
* const retriever = new AmazonKnowledgeBaseRetriever({
* topK: 10,
* knowledgeBaseId: "YOUR_KNOWLEDGE_BASE_ID",
* region: "us-east-2",
* clientOptions: {
* credentials: {
* accessKeyId: "YOUR_ACCESS_KEY_ID",
* secretAccessKey: "YOUR_SECRET_ACCESS_KEY",
* },
* },
* });
*
* const docs = await retriever.retrieve({query: "How are clouds formed?"});
* ```
*/
export class AmazonKnowledgeBaseRetriever extends BaseRetriever {
static lc_name() {
return "AmazonKnowledgeBaseRetriever";
}
lc_namespace = ["llamaindex", "retrievers", "amazon_bedrock_knowledge_base"];
knowledgeBaseId: string;
topK: number;
bedrockAgentRuntimeClient: BedrockAgentRuntimeClient;
filter: RetrievalFilter | undefined;
overrideSearchType: SearchType | undefined;
constructor({
knowledgeBaseId,
topK = 10,
clientOptions,
region,
filter,
overrideSearchType,
}: AmazonKnowledgeBaseRetrieverArgs) {
super();
this.topK = topK;
this.filter = filter;
this.overrideSearchType = overrideSearchType;
this.bedrockAgentRuntimeClient = new BedrockAgentRuntimeClient({
region,
...clientOptions,
});
this.knowledgeBaseId = knowledgeBaseId;
}
/**
* Cleans the result text by replacing sequences of whitespace with a
* single space and removing ellipses.
* @param resText The result text to clean.
* @returns The cleaned result text.
*/
cleanResult(resText: string) {
const res = resText.replace(/\s+/g, " ").replace(/\.\.\./g, "");
return res;
}
async queryKnowledgeBase(
query: QueryBundle,
topK: number,
filter?: RetrievalFilter,
overrideSearchType?: SearchType,
): Promise<NodeWithScore[]> {
const retrieveCommand = new RetrieveCommand({
knowledgeBaseId: this.knowledgeBaseId,
retrievalQuery: {
text: extractText(query),
},
retrievalConfiguration: {
vectorSearchConfiguration: {
numberOfResults: topK,
overrideSearchType,
filter,
} as KnowledgeBaseVectorSearchConfiguration,
},
});
const retrieveResponse =
await this.bedrockAgentRuntimeClient.send(retrieveCommand);
return (
retrieveResponse.retrievalResults?.map((result) => {
let source;
switch (result.location?.type) {
case "CONFLUENCE":
source = result.location?.confluenceLocation?.url;
break;
case "S3":
source = result.location?.s3Location?.uri;
break;
case "SALESFORCE":
source = result.location?.salesforceLocation?.url;
break;
case "SHAREPOINT":
source = result.location?.sharePointLocation?.url;
break;
case "WEB":
source = result.location?.webLocation?.url;
break;
default:
source = result.location?.s3Location?.uri;
break;
}
return {
node: new Document({
text: this.cleanResult(result.content?.text || ""),
metadata: {
source,
score: result.score,
...result.metadata,
},
}),
score: result.score ?? 1.0,
};
}) ?? []
);
}
async _retrieve(query: QueryBundle): Promise<NodeWithScore[]> {
return await this.queryKnowledgeBase(
query,
this.topK,
this.filter,
this.overrideSearchType,
);
}
}
-15
View File
@@ -1,20 +1,5 @@
# @llamaindex/core
## 0.2.6
### Patch Changes
- 8b7fdba: refactor: move chat engine & retriever into core.
- `chatHistory` in BaseChatEngine now returns `ChatMessage[] | Promise<ChatMessage[]>`, instead of `BaseMemory`
- update `retrieve-end` type
## 0.2.5
### Patch Changes
- d902cc3: Fix context not being sent using ContextChatEngine
## 0.2.4
### Patch Changes
+1 -29
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/core",
"type": "module",
"version": "0.2.6",
"version": "0.2.4",
"description": "LlamaIndex Core Module",
"exports": {
"./node-parser": {
@@ -199,34 +199,6 @@
"types": "./dist/response-synthesizers/index.d.ts",
"default": "./dist/response-synthesizers/index.js"
}
},
"./chat-engine": {
"require": {
"types": "./dist/chat-engine/index.d.cts",
"default": "./dist/chat-engine/index.cjs"
},
"import": {
"types": "./dist/chat-engine/index.d.ts",
"default": "./dist/chat-engine/index.js"
},
"default": {
"types": "./dist/chat-engine/index.d.ts",
"default": "./dist/chat-engine/index.js"
}
},
"./retriever": {
"require": {
"types": "./dist/retriever/index.d.cts",
"default": "./dist/retriever/index.cjs"
},
"import": {
"types": "./dist/retriever/index.d.ts",
"default": "./dist/retriever/index.js"
},
"default": {
"types": "./dist/retriever/index.d.ts",
"default": "./dist/retriever/index.js"
}
}
},
"files": [
-36
View File
@@ -1,36 +0,0 @@
import type { ChatMessage, MessageContent } from "../llms";
import type { BaseMemory } from "../memory";
import { EngineResponse } from "../schema";
export interface BaseChatEngineParams<
AdditionalMessageOptions extends object = object,
> {
message: MessageContent;
/**
* Optional chat history if you want to customize the chat history.
*/
chatHistory?:
| ChatMessage<AdditionalMessageOptions>[]
| BaseMemory<AdditionalMessageOptions>;
}
export interface StreamingChatEngineParams<
AdditionalMessageOptions extends object = object,
> extends BaseChatEngineParams<AdditionalMessageOptions> {
stream: true;
}
export interface NonStreamingChatEngineParams<
AdditionalMessageOptions extends object = object,
> extends BaseChatEngineParams<AdditionalMessageOptions> {
stream?: false;
}
export abstract class BaseChatEngine {
abstract chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
abstract chat(
params: StreamingChatEngineParams,
): Promise<AsyncIterable<EngineResponse>>;
abstract chatHistory: ChatMessage[] | Promise<ChatMessage[]>;
}
@@ -11,7 +11,6 @@ import type {
SynthesizeEndEvent,
SynthesizeStartEvent,
} from "../../response-synthesizers";
import type { RetrieveEndEvent, RetrieveStartEvent } from "../../retriever";
import { TextNode } from "../../schema";
import { EventCaller, getEventCaller } from "../../utils";
import type { UUID } from "../type";
@@ -70,8 +69,6 @@ export interface LlamaIndexEventMaps {
"query-end": QueryEndEvent;
"synthesize-start": SynthesizeStartEvent;
"synthesize-end": SynthesizeEndEvent;
"retrieve-start": RetrieveStartEvent;
"retrieve-end": RetrieveEndEvent;
}
export class LlamaIndexCustomEvent<T = any> extends CustomEvent<T> {
+10 -25
View File
@@ -2,7 +2,7 @@ import { randomUUID } from "@llamaindex/env";
import { Settings } from "../global";
import type { MessageContent } from "../llms";
import { PromptMixin } from "../prompts";
import { EngineResponse, type NodeWithScore } from "../schema";
import { EngineResponse } from "../schema";
import { wrapEventCaller } from "../utils";
/**
@@ -18,18 +18,6 @@ export type QueryBundle = {
export type QueryType = string | QueryBundle;
export type BaseQueryParams = {
query: QueryType;
};
export interface StreamingQueryParams extends BaseQueryParams {
stream: true;
}
export interface NonStreamingQueryParams extends BaseQueryParams {
stream?: false;
}
export type QueryFn = (
strOrQueryBundle: QueryType,
stream?: boolean,
@@ -40,26 +28,23 @@ export abstract class BaseQueryEngine extends PromptMixin {
super();
}
async retrieve(params: QueryType): Promise<NodeWithScore[]> {
throw new Error(
"This query engine does not support retrieve, use query directly",
);
}
query(params: StreamingQueryParams): Promise<AsyncIterable<EngineResponse>>;
query(params: NonStreamingQueryParams): Promise<EngineResponse>;
query(
strOrQueryBundle: QueryType,
stream: true,
): Promise<AsyncIterable<EngineResponse>>;
query(strOrQueryBundle: QueryType, stream?: false): Promise<EngineResponse>;
@wrapEventCaller
async query(
params: StreamingQueryParams | NonStreamingQueryParams,
strOrQueryBundle: QueryType,
stream = false,
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
const { stream, query } = params;
const id = randomUUID();
const callbackManager = Settings.callbackManager;
callbackManager.dispatchEvent("query-start", {
id,
query,
query: strOrQueryBundle,
});
const response = await this._query(query, stream);
const response = await this._query(strOrQueryBundle, stream);
callbackManager.dispatchEvent("query-end", {
id,
response,
-112
View File
@@ -1,112 +0,0 @@
import { randomUUID } from "@llamaindex/env";
import { Settings } from "../global";
import type { MessageContent } from "../llms";
import { PromptMixin } from "../prompts";
import type { QueryBundle, QueryType } from "../query-engine";
import { BaseNode, IndexNode, type NodeWithScore, ObjectType } from "../schema";
export type RetrieveParams = {
query: MessageContent;
preFilters?: unknown;
};
export type RetrieveStartEvent = {
id: string;
query: QueryBundle;
};
export type RetrieveEndEvent = {
id: string;
query: QueryBundle;
nodes: NodeWithScore[];
};
export abstract class BaseRetriever extends PromptMixin {
objectMap: Map<string, unknown> = new Map();
protected _updatePrompts() {}
protected _getPrompts() {
return {};
}
protected _getPromptModules() {
return {};
}
protected constructor() {
super();
}
public async retrieve(params: QueryType): Promise<NodeWithScore[]> {
const cb = Settings.callbackManager;
const queryBundle = typeof params === "string" ? { query: params } : params;
const id = randomUUID();
cb.dispatchEvent("retrieve-start", { id, query: queryBundle });
let response = await this._retrieve(queryBundle);
response = await this._handleRecursiveRetrieval(queryBundle, response);
cb.dispatchEvent("retrieve-end", {
id,
query: queryBundle,
nodes: response,
});
return response;
}
abstract _retrieve(params: QueryBundle): Promise<NodeWithScore[]>;
async _handleRecursiveRetrieval(
params: QueryBundle,
nodes: NodeWithScore[],
): Promise<NodeWithScore[]> {
const retrievedNodes = [];
for (const { node, score = 1.0 } of nodes) {
if (node.type === ObjectType.INDEX) {
const indexNode = node as IndexNode;
const object = this.objectMap.get(indexNode.indexId);
if (object !== undefined) {
retrievedNodes.push(
...this._retrieveFromObject(object, params, score),
);
} else {
retrievedNodes.push({ node, score });
}
} else {
retrievedNodes.push({ node, score });
}
}
return nodes;
}
_retrieveFromObject(
object: unknown,
queryBundle: QueryBundle,
score: number,
): NodeWithScore[] {
if (object == null) {
throw new TypeError("Object is not retrievable");
}
if (typeof object !== "object") {
throw new TypeError("Object is not retrievable");
}
if ("node" in object && object.node instanceof BaseNode) {
return [
{
node: object.node,
score:
"score" in object && typeof object.score === "number"
? object.score
: score,
},
];
}
if (object instanceof BaseNode) {
return [{ node: object, score }];
} else {
// todo: support other types
// BaseQueryEngine
// BaseRetriever
// QueryComponent
throw new TypeError("Object is not retrievable");
}
}
}
-30
View File
@@ -1,35 +1,5 @@
# @llamaindex/experimental
## 0.0.86
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.0.85
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.0.84
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.0.83
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.0.82
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/experimental",
"description": "Experimental package for LlamaIndexTS",
"version": "0.0.86",
"version": "0.0.82",
"type": "module",
"types": "dist/type/index.d.ts",
"main": "dist/cjs/index.js",
-44
View File
@@ -1,49 +1,5 @@
# llamaindex
## 0.6.8
### Patch Changes
- 8b7fdba: refactor: move chat engine & retriever into core.
- `chatHistory` in BaseChatEngine now returns `ChatMessage[] | Promise<ChatMessage[]>`, instead of `BaseMemory`
- update `retrieve-end` type
- Updated dependencies [8b7fdba]
- @llamaindex/core@0.2.6
- @llamaindex/openai@0.1.8
- @llamaindex/groq@0.0.7
## 0.6.7
### Patch Changes
- 23bcc37: fix: add `serializer` in doc store
`PostgresDocumentStore` now will not use JSON.stringify for better performance
## 0.6.6
### Patch Changes
- d902cc3: Fix context not being sent using ContextChatEngine
- 025ffe6: fix: update `PostgresKVStore` constructor params
- a659574: Adds upstash vector store as a storage
- Updated dependencies [d902cc3]
- @llamaindex/core@0.2.5
- @llamaindex/openai@0.1.7
- @llamaindex/groq@0.0.6
## 0.6.5
### Patch Changes
- e9714db: feat: update `PGVectorStore`
- move constructor parameter `config.user` | `config.database` | `config.password` | `config.connectionString` into `config.clientConfig`
- if you pass `pg.Client` or `pg.Pool` instance to `PGVectorStore`, move it to `config.client`, setting `config.shouldConnect` to false if it's already connected
- default value of `PGVectorStore.collection` is now `"data"` instead of `""` (empty string)
## 0.6.4
### Patch Changes
@@ -1,35 +1,5 @@
# @llamaindex/cloudflare-worker-agent-test
## 0.0.70
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.0.69
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.0.68
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.0.67
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.0.66
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/cloudflare-worker-agent-test",
"version": "0.0.70",
"version": "0.0.66",
"type": "module",
"private": true,
"scripts": {
@@ -1,35 +1,5 @@
# @llamaindex/next-agent-test
## 0.1.70
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.1.69
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.1.68
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.1.67
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.1.66
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-agent-test",
"version": "0.1.70",
"version": "0.1.66",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,35 +1,5 @@
# test-edge-runtime
## 0.1.69
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.1.68
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.1.67
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.1.66
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.1.65
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/nextjs-edge-runtime-test",
"version": "0.1.69",
"version": "0.1.65",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,35 +1,5 @@
# @llamaindex/next-node-runtime
## 0.0.51
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.0.50
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.0.49
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.0.48
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.0.47
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/next-node-runtime-test",
"version": "0.0.51",
"version": "0.0.47",
"private": true,
"scripts": {
"dev": "next dev",
@@ -1,35 +1,5 @@
# @llamaindex/waku-query-engine-test
## 0.0.70
### Patch Changes
- Updated dependencies [8b7fdba]
- llamaindex@0.6.8
## 0.0.69
### Patch Changes
- Updated dependencies [23bcc37]
- llamaindex@0.6.7
## 0.0.68
### Patch Changes
- Updated dependencies [d902cc3]
- Updated dependencies [025ffe6]
- Updated dependencies [a659574]
- llamaindex@0.6.6
## 0.0.67
### Patch Changes
- Updated dependencies [e9714db]
- llamaindex@0.6.5
## 0.0.66
### Patch Changes
@@ -1,6 +1,6 @@
{
"name": "@llamaindex/waku-query-engine-test",
"version": "0.0.70",
"version": "0.0.66",
"type": "module",
"private": true,
"scripts": {
@@ -9,54 +9,43 @@ import { registerTypes } from "pgvector/pg";
config({ path: [".env.local", ".env", ".env.ci"] });
let pgClient: pg.Client | pg.Pool;
test.afterEach(async () => {
await pgClient.end();
});
const pgConfig = {
user: process.env.POSTGRES_USER ?? "user",
password: process.env.POSTGRES_PASSWORD ?? "password",
database: "llamaindex_node_test",
};
await test("init with client", async (t) => {
const pgClient = new pg.Client(pgConfig);
await test("init with client", async () => {
pgClient = new pg.Client(pgConfig);
await pgClient.connect();
await pgClient.query("CREATE EXTENSION IF NOT EXISTS vector");
await registerTypes(pgClient);
t.after(async () => {
await pgClient.end();
});
const vectorStore = new PGVectorStore({
client: pgClient,
shouldConnect: false,
});
const vectorStore = new PGVectorStore(pgClient);
assert.deepStrictEqual(await vectorStore.client(), pgClient);
});
await test("init with pool", async (t) => {
const pgClient = new pg.Pool(pgConfig);
await test("init with pool", async () => {
pgClient = new pg.Pool(pgConfig);
await pgClient.query("CREATE EXTENSION IF NOT EXISTS vector");
const client = await pgClient.connect();
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
await registerTypes(client);
t.after(async () => {
client.release();
await pgClient.end();
});
const vectorStore = new PGVectorStore({
shouldConnect: false,
client,
});
const vectorStore = new PGVectorStore(client);
assert.deepStrictEqual(await vectorStore.client(), client);
client.release();
});
await test("init without client", async (t) => {
const vectorStore = new PGVectorStore({ clientConfig: pgConfig });
const pgClient = (await vectorStore.client()) as pg.Client;
t.after(async () => {
await pgClient.end();
});
await test("init without client", async () => {
const vectorStore = new PGVectorStore(pgConfig);
pgClient = (await vectorStore.client()) as pg.Client;
assert.notDeepStrictEqual(pgClient, undefined);
});
await test("simple node", async (t) => {
await test("simple node", async () => {
const dimensions = 3;
const schemaName =
"llamaindex_vector_store_test_" + Math.random().toString(36).substring(7);
@@ -67,14 +56,10 @@ await test("simple node", async (t) => {
embedding: [0.1, 0.2, 0.3],
});
const vectorStore = new PGVectorStore({
clientConfig: pgConfig,
...pgConfig,
dimensions,
schemaName,
});
const pgClient = (await vectorStore.client()) as pg.Client;
t.after(async () => {
await pgClient.end();
});
await vectorStore.add([node]);
@@ -104,4 +89,6 @@ await test("simple node", async (t) => {
});
assert.deepStrictEqual(result.nodes, []);
}
pgClient = (await vectorStore.client()) as pg.Client;
});
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "llamaindex",
"version": "0.6.8",
"version": "0.6.4",
"license": "MIT",
"type": "module",
"keywords": [
@@ -43,7 +43,6 @@
"@types/node": "^22.5.1",
"@types/papaparse": "^5.3.14",
"@types/pg": "^8.11.8",
"@upstash/vector": "^1.1.5",
"@zilliz/milvus2-sdk-node": "^2.4.6",
"ajv": "^8.17.1",
"assemblyai": "^4.7.0",
+20
View File
@@ -0,0 +1,20 @@
import type { NodeWithScore } from "@llamaindex/core/schema";
import type { ServiceContext } from "./ServiceContext.js";
import type { MessageContent } from "./index.edge.js";
export type RetrieveParams = {
query: MessageContent;
preFilters?: unknown;
};
/**
* Retrievers retrieve the nodes that most closely match our query in similarity.
*/
export interface BaseRetriever {
retrieve(params: RetrieveParams): Promise<NodeWithScore[]>;
/**
* @deprecated to be deprecated soon
*/
serviceContext?: ServiceContext | undefined;
}
+9 -10
View File
@@ -1,9 +1,9 @@
import type {
NonStreamingChatEngineParams,
StreamingChatEngineParams,
} from "@llamaindex/core/chat-engine";
import type { EngineResponse } from "@llamaindex/core/schema";
import { Settings } from "../Settings.js";
import type {
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
EngineResponse,
} from "../index.edge.js";
import { Anthropic } from "../llm/anthropic.js";
import { LLMAgent, LLMAgentWorker, type LLMAgentParams } from "./llm.js";
@@ -24,13 +24,12 @@ export class AnthropicAgent extends LLMAgent {
});
}
async chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
async chat(params: StreamingChatEngineParams): Promise<never>;
async chat(params: ChatEngineParamsNonStreaming): Promise<EngineResponse>;
async chat(params: ChatEngineParamsStreaming): Promise<never>;
override async chat(
params: NonStreamingChatEngineParams | StreamingChatEngineParams,
params: ChatEngineParamsNonStreaming | ChatEngineParamsStreaming,
) {
const { stream } = params;
if (stream) {
if (params.stream) {
// Anthropic does support this, but looks like it's not supported in the LITS LLM
throw new Error("Anthropic does not support streaming");
}
+10 -10
View File
@@ -1,8 +1,3 @@
import {
BaseChatEngine,
type NonStreamingChatEngineParams,
type StreamingChatEngineParams,
} from "@llamaindex/core/chat-engine";
import type {
BaseToolWithCall,
ChatMessage,
@@ -15,6 +10,11 @@ import { EngineResponse } from "@llamaindex/core/schema";
import { wrapEventCaller } from "@llamaindex/core/utils";
import { randomUUID } from "@llamaindex/env";
import { Settings } from "../Settings.js";
import {
type ChatEngine,
type ChatEngineParamsNonStreaming,
type ChatEngineParamsStreaming,
} from "../engines/chat/index.js";
import { consoleLogger, emptyLogger } from "../internal/logger.js";
import { isReadableStream } from "../internal/utils.js";
import { ObjectRetriever } from "../objects/index.js";
@@ -207,7 +207,8 @@ export abstract class AgentRunner<
>
? AdditionalMessageOptions
: never,
> extends BaseChatEngine {
> implements ChatEngine
{
readonly #llm: AI;
readonly #tools:
| BaseToolWithCall[]
@@ -258,7 +259,6 @@ export abstract class AgentRunner<
protected constructor(
params: AgentRunnerParams<AI, Store, AdditionalMessageOptions>,
) {
super();
const { llm, chatHistory, systemPrompt, runner, tools, verbose } = params;
this.#llm = llm;
this.#chatHistory = chatHistory;
@@ -345,13 +345,13 @@ export abstract class AgentRunner<
});
}
async chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
async chat(params: ChatEngineParamsNonStreaming): Promise<EngineResponse>;
async chat(
params: StreamingChatEngineParams,
params: ChatEngineParamsStreaming,
): Promise<ReadableStream<EngineResponse>>;
@wrapEventCaller
async chat(
params: NonStreamingChatEngineParams | StreamingChatEngineParams,
params: ChatEngineParamsNonStreaming | ChatEngineParamsStreaming,
): Promise<EngineResponse | ReadableStream<EngineResponse>> {
let chatHistory: ChatMessage<AdditionalMessageOptions>[] = [];
@@ -1,6 +1,7 @@
import type { BaseQueryEngine } from "@llamaindex/core/query-engine";
import type { BaseSynthesizer } from "@llamaindex/core/response-synthesizers";
import type { Document, TransformComponent } from "@llamaindex/core/schema";
import type { BaseRetriever } from "../Retriever.js";
import { RetrieverQueryEngine } from "../engines/query/RetrieverQueryEngine.js";
import type { BaseNodePostprocessor } from "../postprocessors/types.js";
import type { CloudRetrieveParams } from "./LlamaCloudRetriever.js";
@@ -11,7 +12,6 @@ import { getAppBaseUrl, getProjectId, initService } from "./utils.js";
import { PipelinesService, ProjectsService } from "@llamaindex/cloud/api";
import { SentenceSplitter } from "@llamaindex/core/node-parser";
import type { BaseRetriever } from "@llamaindex/core/retriever";
import { getEnv } from "@llamaindex/env";
import { OpenAIEmbedding } from "@llamaindex/openai";
import { Settings } from "../Settings.js";
@@ -4,12 +4,11 @@ import {
type RetrievalParams,
type TextNodeWithScore,
} from "@llamaindex/cloud/api";
import { DEFAULT_PROJECT_NAME } from "@llamaindex/core/global";
import type { QueryBundle } from "@llamaindex/core/query-engine";
import { BaseRetriever } from "@llamaindex/core/retriever";
import { DEFAULT_PROJECT_NAME, Settings } from "@llamaindex/core/global";
import type { NodeWithScore } from "@llamaindex/core/schema";
import { jsonToNode, ObjectType } from "@llamaindex/core/schema";
import { extractText } from "@llamaindex/core/utils";
import { extractText, wrapEventCaller } from "@llamaindex/core/utils";
import type { BaseRetriever, RetrieveParams } from "../Retriever.js";
import type { ClientParams, CloudConstructorParams } from "./type.js";
import { getProjectId, initService } from "./utils.js";
@@ -18,7 +17,7 @@ export type CloudRetrieveParams = Omit<
"query" | "search_filters" | "dense_similarity_top_k"
> & { similarityTopK?: number; filters?: MetadataFilters };
export class LlamaCloudRetriever extends BaseRetriever {
export class LlamaCloudRetriever implements BaseRetriever {
clientParams: ClientParams;
retrieveParams: CloudRetrieveParams;
organizationId?: string;
@@ -43,7 +42,6 @@ export class LlamaCloudRetriever extends BaseRetriever {
}
constructor(params: CloudConstructorParams & CloudRetrieveParams) {
super();
this.clientParams = { apiKey: params.apiKey, baseUrl: params.baseUrl };
initService(this.clientParams);
this.retrieveParams = params;
@@ -56,7 +54,11 @@ export class LlamaCloudRetriever extends BaseRetriever {
}
}
async _retrieve(query: QueryBundle): Promise<NodeWithScore[]> {
@wrapEventCaller
async retrieve({
query,
preFilters,
}: RetrieveParams): Promise<NodeWithScore[]> {
const { data: pipelines } =
await PipelinesService.searchPipelinesApiV1PipelinesGet({
query: {
@@ -95,11 +97,19 @@ export class LlamaCloudRetriever extends BaseRetriever {
body: {
...this.retrieveParams,
query: extractText(query),
search_filters: this.retrieveParams.filters as MetadataFilters,
search_filters:
this.retrieveParams.filters ?? (preFilters as MetadataFilters),
dense_similarity_top_k: this.retrieveParams.similarityTopK!,
},
});
return this.resultNodesToNodeWithScore(results.retrieval_nodes);
const nodesWithScores = this.resultNodesToNodeWithScore(
results.retrieval_nodes,
);
Settings.callbackManager.dispatchEvent("retrieve-end", {
query,
nodes: nodesWithScores,
});
return nodesWithScores;
}
}
@@ -1,14 +1,10 @@
import {
BaseChatEngine,
type NonStreamingChatEngineParams,
type StreamingChatEngineParams,
} from "@llamaindex/core/chat-engine";
import type { ChatMessage, LLM } from "@llamaindex/core/llms";
import { BaseMemory, ChatMemoryBuffer } from "@llamaindex/core/memory";
import {
type CondenseQuestionPrompt,
defaultCondenseQuestionPrompt,
type ModuleRecord,
PromptMixin,
} from "@llamaindex/core/prompts";
import type { BaseQueryEngine } from "@llamaindex/core/query-engine";
import type { EngineResponse } from "@llamaindex/core/schema";
@@ -20,6 +16,11 @@ import {
} from "@llamaindex/core/utils";
import type { ServiceContext } from "../../ServiceContext.js";
import { llmFromSettingsOrContext } from "../../Settings.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
} from "./types.js";
/**
* CondenseQuestionChatEngine is used in conjunction with a Index (for example VectorStoreIndex).
@@ -31,16 +32,16 @@ import { llmFromSettingsOrContext } from "../../Settings.js";
* underlying data. It performs less well when the chat messages are not questions about the
* data, or are very referential to previous context.
*/
export class CondenseQuestionChatEngine extends BaseChatEngine {
export class CondenseQuestionChatEngine
extends PromptMixin
implements ChatEngine
{
queryEngine: BaseQueryEngine;
memory: BaseMemory;
chatHistory: BaseMemory;
llm: LLM;
condenseMessagePrompt: CondenseQuestionPrompt;
get chatHistory() {
return this.memory.getMessages();
}
constructor(init: {
queryEngine: BaseQueryEngine;
chatHistory: ChatMessage[];
@@ -50,7 +51,7 @@ export class CondenseQuestionChatEngine extends BaseChatEngine {
super();
this.queryEngine = init.queryEngine;
this.memory = new ChatMemoryBuffer({
this.chatHistory = new ChatMemoryBuffer({
chatHistory: init?.chatHistory,
});
this.llm = llmFromSettingsOrContext(init?.serviceContext);
@@ -87,13 +88,13 @@ export class CondenseQuestionChatEngine extends BaseChatEngine {
});
}
chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
chat(
params: StreamingChatEngineParams,
params: ChatEngineParamsStreaming,
): Promise<AsyncIterable<EngineResponse>>;
chat(params: ChatEngineParamsNonStreaming): Promise<EngineResponse>;
@wrapEventCaller
async chat(
params: NonStreamingChatEngineParams | StreamingChatEngineParams,
params: ChatEngineParamsStreaming | ChatEngineParamsNonStreaming,
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
const { message, stream } = params;
const chatHistory = params.chatHistory
@@ -103,7 +104,7 @@ export class CondenseQuestionChatEngine extends BaseChatEngine {
? await params.chatHistory.getMessages()
: params.chatHistory,
})
: this.memory;
: this.chatHistory;
const condensedQuestion = (
await this.condenseQuestion(chatHistory, extractText(message))
@@ -111,10 +112,12 @@ export class CondenseQuestionChatEngine extends BaseChatEngine {
chatHistory.put({ content: message, role: "user" });
if (stream) {
const stream = await this.queryEngine.query({
query: condensedQuestion,
stream: true,
});
const stream = await this.queryEngine.query(
{
query: condensedQuestion,
},
true,
);
return streamReducer({
stream,
initialValue: "",
@@ -137,6 +140,6 @@ export class CondenseQuestionChatEngine extends BaseChatEngine {
}
reset() {
this.memory.reset();
this.chatHistory.reset();
}
}
@@ -1,8 +1,3 @@
import type {
BaseChatEngine,
NonStreamingChatEngineParams,
StreamingChatEngineParams,
} from "@llamaindex/core/chat-engine";
import type {
ChatMessage,
LLM,
@@ -16,7 +11,6 @@ import {
PromptMixin,
type PromptsRecord,
} from "@llamaindex/core/prompts";
import type { BaseRetriever } from "@llamaindex/core/retriever";
import { EngineResponse, MetadataMode } from "@llamaindex/core/schema";
import {
extractText,
@@ -24,25 +18,27 @@ import {
streamReducer,
wrapEventCaller,
} from "@llamaindex/core/utils";
import type { BaseRetriever } from "../../Retriever.js";
import { Settings } from "../../Settings.js";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import { DefaultContextGenerator } from "./DefaultContextGenerator.js";
import type { ContextGenerator } from "./types.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
ContextGenerator,
} from "./types.js";
/**
* ContextChatEngine uses the Index to get the appropriate context for each query.
* The context is stored in the system prompt, and the chat history is chunk: ChatResponseChunk, nodes?: NodeWithScore<import("/Users/marcus/code/llamaindex/LlamaIndexTS/packages/core/src/Node").Metadata>[], nodes?: NodeWithScore<import("/Users/marcus/code/llamaindex/LlamaIndexTS/packages/core/src/Node").Metadata>[]lowing the appropriate context to be surfaced for each query.
*/
export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
export class ContextChatEngine extends PromptMixin implements ChatEngine {
chatModel: LLM;
memory: BaseMemory;
chatHistory: BaseMemory;
contextGenerator: ContextGenerator & PromptMixin;
systemPrompt?: string | undefined;
get chatHistory() {
return this.memory.getMessages();
}
constructor(init: {
retriever: BaseRetriever;
chatModel?: LLM | undefined;
@@ -54,7 +50,7 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
}) {
super();
this.chatModel = init.chatModel ?? Settings.llm;
this.memory = new ChatMemoryBuffer({ chatHistory: init?.chatHistory });
this.chatHistory = new ChatMemoryBuffer({ chatHistory: init?.chatHistory });
this.contextGenerator = new DefaultContextGenerator({
retriever: init.retriever,
contextSystemPrompt: init?.contextSystemPrompt,
@@ -83,13 +79,13 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
};
}
chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
chat(
params: StreamingChatEngineParams,
params: ChatEngineParamsStreaming,
): Promise<AsyncIterable<EngineResponse>>;
chat(params: ChatEngineParamsNonStreaming): Promise<EngineResponse>;
@wrapEventCaller
async chat(
params: StreamingChatEngineParams | NonStreamingChatEngineParams,
params: ChatEngineParamsStreaming | ChatEngineParamsNonStreaming,
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
const { message, stream } = params;
const chatHistory = params.chatHistory
@@ -99,7 +95,7 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
? await params.chatHistory.getMessages()
: params.chatHistory,
})
: this.memory;
: this.chatHistory;
const requestMessages = await this.prepareRequestMessages(
message,
chatHistory,
@@ -129,7 +125,7 @@ export class ContextChatEngine extends PromptMixin implements BaseChatEngine {
}
reset() {
this.memory.reset();
this.chatHistory.reset();
}
private async prepareRequestMessages(
@@ -5,10 +5,10 @@ import {
type ModuleRecord,
PromptMixin,
} from "@llamaindex/core/prompts";
import type { BaseRetriever } from "@llamaindex/core/retriever";
import { MetadataMode, type NodeWithScore } from "@llamaindex/core/schema";
import { createMessageContent } from "@llamaindex/core/utils";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import type { BaseRetriever } from "../../Retriever.js";
import type { Context, ContextGenerator } from "./types.js";
export class DefaultContextGenerator
@@ -1,8 +1,3 @@
import type {
BaseChatEngine,
NonStreamingChatEngineParams,
StreamingChatEngineParams,
} from "@llamaindex/core/chat-engine";
import type { LLM } from "@llamaindex/core/llms";
import { BaseMemory, ChatMemoryBuffer } from "@llamaindex/core/memory";
import { EngineResponse } from "@llamaindex/core/schema";
@@ -12,31 +7,32 @@ import {
wrapEventCaller,
} from "@llamaindex/core/utils";
import { Settings } from "../../Settings.js";
import type {
ChatEngine,
ChatEngineParamsNonStreaming,
ChatEngineParamsStreaming,
} from "./types.js";
/**
* SimpleChatEngine is the simplest possible chat engine. Useful for using your own custom prompts.
*/
export class SimpleChatEngine implements BaseChatEngine {
memory: BaseMemory;
export class SimpleChatEngine implements ChatEngine {
chatHistory: BaseMemory;
llm: LLM;
get chatHistory() {
return this.memory.getMessages();
}
constructor(init?: Partial<SimpleChatEngine>) {
this.memory = init?.memory ?? new ChatMemoryBuffer();
this.chatHistory = init?.chatHistory ?? new ChatMemoryBuffer();
this.llm = init?.llm ?? Settings.llm;
}
chat(params: NonStreamingChatEngineParams): Promise<EngineResponse>;
chat(
params: StreamingChatEngineParams,
params: ChatEngineParamsStreaming,
): Promise<AsyncIterable<EngineResponse>>;
chat(params: ChatEngineParamsNonStreaming): Promise<EngineResponse>;
@wrapEventCaller
async chat(
params: NonStreamingChatEngineParams | StreamingChatEngineParams,
params: ChatEngineParamsStreaming | ChatEngineParamsNonStreaming,
): Promise<EngineResponse | AsyncIterable<EngineResponse>> {
const { message, stream } = params;
@@ -47,7 +43,7 @@ export class SimpleChatEngine implements BaseChatEngine {
? await params.chatHistory.getMessages()
: params.chatHistory,
})
: this.memory;
: this.chatHistory;
chatHistory.put({ content: message, role: "user" });
if (stream) {
@@ -77,6 +73,6 @@ export class SimpleChatEngine implements BaseChatEngine {
}
reset() {
this.memory.reset();
this.chatHistory.reset();
}
}
+50 -2
View File
@@ -1,10 +1,58 @@
import type { ChatMessage } from "@llamaindex/core/llms";
import type { NodeWithScore } from "@llamaindex/core/schema";
import type { ChatMessage, MessageContent } from "@llamaindex/core/llms";
import type { BaseMemory } from "@llamaindex/core/memory";
import { EngineResponse, type NodeWithScore } from "@llamaindex/core/schema";
/**
* Represents the base parameters for ChatEngine.
*/
export interface ChatEngineParamsBase {
message: MessageContent;
/**
* Optional chat history if you want to customize the chat history.
*/
chatHistory?: ChatMessage[] | BaseMemory;
/**
* Optional flag to enable verbose mode.
* @default false
*/
verbose?: boolean;
}
export interface ChatEngineParamsStreaming extends ChatEngineParamsBase {
stream: true;
}
export interface ChatEngineParamsNonStreaming extends ChatEngineParamsBase {
stream?: false | null;
}
/**
* A ChatEngine is used to handle back and forth chats between the application and the LLM.
*/
export interface ChatEngine<
// synchronous response
R = EngineResponse,
// asynchronous response
AR extends AsyncIterable<unknown> = AsyncIterable<R>,
> {
/**
* Send message along with the class's current chat history to the LLM.
* @param params
*/
chat(params: ChatEngineParamsStreaming): Promise<AR>;
chat(params: ChatEngineParamsNonStreaming): Promise<R>;
/**
* Resets the chat history so that it's empty.
*/
reset(): void;
}
export interface Context {
message: ChatMessage;
nodes: NodeWithScore[];
}
/**
* A ContextGenerator is used to generate a context based on a message's text content
*/
@@ -1,11 +1,10 @@
import type { MessageContent } from "@llamaindex/core/llms";
import { BaseQueryEngine, type QueryType } from "@llamaindex/core/query-engine";
import { BaseQueryEngine } from "@llamaindex/core/query-engine";
import type { BaseSynthesizer } from "@llamaindex/core/response-synthesizers";
import { getResponseSynthesizer } from "@llamaindex/core/response-synthesizers";
import { BaseRetriever } from "@llamaindex/core/retriever";
import { type NodeWithScore } from "@llamaindex/core/schema";
import { extractText } from "@llamaindex/core/utils";
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
import type { BaseRetriever } from "../../Retriever.js";
/**
* A query engine that uses a retriever to query an index and then synthesizes the response.
@@ -68,10 +67,7 @@ export class RetrieverQueryEngine extends BaseQueryEngine {
};
}
private async applyNodePostprocessors(
nodes: NodeWithScore[],
query: MessageContent,
) {
private async applyNodePostprocessors(nodes: NodeWithScore[], query: string) {
let nodesWithScore = nodes;
for (const postprocessor of this.nodePostprocessors) {
@@ -84,10 +80,12 @@ export class RetrieverQueryEngine extends BaseQueryEngine {
return nodesWithScore;
}
override async retrieve(query: QueryType) {
const nodes = await this.retriever.retrieve(query);
private async retrieve(query: string) {
const nodes = await this.retriever.retrieve({
query,
preFilters: this.preFilters,
});
const messageContent = typeof query === "string" ? query : query.query;
return await this.applyNodePostprocessors(nodes, messageContent);
return await this.applyNodePostprocessors(nodes, query);
}
}
@@ -136,9 +136,7 @@ export class RouterQueryEngine extends BaseQueryEngine {
}
const selectedQueryEngine = this.queryEngines[engineInd.index]!;
responses.push(
await selectedQueryEngine.query({ query, stream: false }),
);
responses.push(await selectedQueryEngine.query(query));
}
if (responses.length > 1) {
@@ -103,8 +103,7 @@ export class FaithfulnessEvaluator
});
const responseObj = await queryEngine.query({
query: { query: response },
stream: false,
query: response,
});
const rawResponseTxt = responseObj.toString();
+4 -2
View File
@@ -1,6 +1,6 @@
import type { AgentEndEvent, AgentStartEvent } from "./agent/types.js";
import type { RetrievalEndEvent, RetrievalStartEvent } from "./llm/types.js";
export * from "@llamaindex/core/chat-engine";
export {
CallbackManager,
DEFAULT_BASE_URL,
@@ -35,11 +35,12 @@ export * from "@llamaindex/core/llms";
export * from "@llamaindex/core/prompts";
export * from "@llamaindex/core/query-engine";
export * from "@llamaindex/core/response-synthesizers";
export * from "@llamaindex/core/retriever";
export * from "@llamaindex/core/schema";
declare module "@llamaindex/core/global" {
export interface LlamaIndexEventMaps {
"retrieve-start": RetrievalStartEvent;
"retrieve-end": RetrievalEndEvent;
// agent events
"agent-start": AgentStartEvent;
"agent-end": AgentEndEvent;
@@ -65,6 +66,7 @@ export * from "./objects/index.js";
export * from "./OutputParser.js";
export * from "./postprocessors/index.js";
export * from "./QuestionGenerator.js";
export * from "./Retriever.js";
export * from "./selectors/index.js";
export * from "./ServiceContext.js";
export { Settings } from "./Settings.js";
+1 -1
View File
@@ -1,7 +1,7 @@
import type { BaseQueryEngine } from "@llamaindex/core/query-engine";
import type { BaseSynthesizer } from "@llamaindex/core/response-synthesizers";
import type { BaseRetriever } from "@llamaindex/core/retriever";
import type { BaseNode, Document } from "@llamaindex/core/schema";
import type { BaseRetriever } from "../Retriever.js";
import type { ServiceContext } from "../ServiceContext.js";
import { nodeParserFromSettingsOrContext } from "../Settings.js";
import { runTransformations } from "../ingestion/IngestionPipeline.js";
@@ -5,6 +5,7 @@ import type {
NodeWithScore,
} from "@llamaindex/core/schema";
import { MetadataMode } from "@llamaindex/core/schema";
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
import type { ServiceContext } from "../../ServiceContext.js";
import { serviceContextFromDefaults } from "../../ServiceContext.js";
import { RetrieverQueryEngine } from "../../engines/query/index.js";
@@ -28,11 +29,7 @@ import {
type KeywordExtractPrompt,
type QueryKeywordExtractPrompt,
} from "@llamaindex/core/prompts";
import type {
BaseQueryEngine,
QueryBundle,
} from "@llamaindex/core/query-engine";
import { BaseRetriever } from "@llamaindex/core/retriever";
import type { BaseQueryEngine } from "@llamaindex/core/query-engine";
import { extractText } from "@llamaindex/core/utils";
import { llmFromSettingsOrContext } from "../../Settings.js";
@@ -51,7 +48,7 @@ export enum KeywordTableRetrieverMode {
}
// Base Keyword Table Retriever
abstract class BaseKeywordTableRetriever extends BaseRetriever {
abstract class BaseKeywordTableRetriever implements BaseRetriever {
protected index: KeywordTableIndex;
protected indexStruct: KeywordTable;
protected docstore: BaseDocumentStore;
@@ -75,7 +72,6 @@ abstract class BaseKeywordTableRetriever extends BaseRetriever {
maxKeywordsPerQuery: number;
numChunksPerQuery: number;
}) {
super();
this.index = index;
this.indexStruct = index.indexStruct;
this.docstore = index.docStore;
@@ -91,7 +87,7 @@ abstract class BaseKeywordTableRetriever extends BaseRetriever {
abstract getKeywords(query: string): Promise<string[]>;
async _retrieve(query: QueryBundle): Promise<NodeWithScore[]> {
async retrieve({ query }: RetrieveParams): Promise<NodeWithScore[]> {
const keywords = await this.getKeywords(extractText(query));
const chunkIndicesCount: { [key: string]: number } = {};
const filteredKeywords = keywords.filter((keyword) =>
@@ -2,17 +2,16 @@ import {
type ChoiceSelectPrompt,
defaultChoiceSelectPrompt,
} from "@llamaindex/core/prompts";
import type { QueryBundle } from "@llamaindex/core/query-engine";
import type { BaseSynthesizer } from "@llamaindex/core/response-synthesizers";
import { getResponseSynthesizer } from "@llamaindex/core/response-synthesizers";
import { BaseRetriever } from "@llamaindex/core/retriever";
import type {
BaseNode,
Document,
NodeWithScore,
} from "@llamaindex/core/schema";
import { extractText } from "@llamaindex/core/utils";
import { extractText, wrapEventCaller } from "@llamaindex/core/utils";
import _ from "lodash";
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
import type { ServiceContext } from "../../ServiceContext.js";
import {
llmFromSettingsOrContext,
@@ -280,15 +279,15 @@ export type ListRetrieverMode = SummaryRetrieverMode;
/**
* Simple retriever for SummaryIndex that returns all nodes
*/
export class SummaryIndexRetriever extends BaseRetriever {
export class SummaryIndexRetriever implements BaseRetriever {
index: SummaryIndex;
constructor(index: SummaryIndex) {
super();
this.index = index;
}
async _retrieve(queryBundle: QueryBundle): Promise<NodeWithScore[]> {
@wrapEventCaller
async retrieve({ query }: RetrieveParams): Promise<NodeWithScore[]> {
const nodeIds = this.index.indexStruct.nodes;
const nodes = await this.index.docStore.getNodes(nodeIds);
return nodes.map((node) => ({
@@ -301,7 +300,7 @@ export class SummaryIndexRetriever extends BaseRetriever {
/**
* LLM retriever for SummaryIndex which lets you select the most relevant chunks.
*/
export class SummaryIndexLLMRetriever extends BaseRetriever {
export class SummaryIndexLLMRetriever implements BaseRetriever {
index: SummaryIndex;
choiceSelectPrompt: ChoiceSelectPrompt;
choiceBatchSize: number;
@@ -318,7 +317,6 @@ export class SummaryIndexLLMRetriever extends BaseRetriever {
parseChoiceSelectAnswerFn?: ChoiceSelectParserFunction,
serviceContext?: ServiceContext,
) {
super();
this.index = index;
this.choiceSelectPrompt = choiceSelectPrompt || defaultChoiceSelectPrompt;
this.choiceBatchSize = choiceBatchSize;
@@ -328,7 +326,7 @@ export class SummaryIndexLLMRetriever extends BaseRetriever {
this.serviceContext = serviceContext || index.serviceContext;
}
async _retrieve(query: QueryBundle): Promise<NodeWithScore[]> {
async retrieve({ query }: RetrieveParams): Promise<NodeWithScore[]> {
const nodeIds = this.index.indexStruct.nodes;
const results: NodeWithScore[] = [];
@@ -2,10 +2,9 @@ import {
DEFAULT_SIMILARITY_TOP_K,
type BaseEmbedding,
} from "@llamaindex/core/embeddings";
import { Settings } from "@llamaindex/core/global";
import type { MessageContent } from "@llamaindex/core/llms";
import type { QueryBundle } from "@llamaindex/core/query-engine";
import type { BaseSynthesizer } from "@llamaindex/core/response-synthesizers";
import { BaseRetriever } from "@llamaindex/core/retriever";
import {
ImageNode,
ModalityType,
@@ -15,6 +14,8 @@ 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";
import { RetrieverQueryEngine } from "../../engines/query/RetrieverQueryEngine.js";
@@ -387,7 +388,7 @@ export type VectorIndexRetrieverOptions = {
filters?: MetadataFilters;
};
export class VectorIndexRetriever extends BaseRetriever {
export class VectorIndexRetriever implements BaseRetriever {
index: VectorStoreIndex;
topK: TopKMap;
@@ -400,7 +401,6 @@ export class VectorIndexRetriever extends BaseRetriever {
topK,
filters,
}: VectorIndexRetrieverOptions) {
super();
this.index = index;
this.serviceContext = this.index.serviceContext;
this.topK = topK ?? {
@@ -417,17 +417,32 @@ export class VectorIndexRetriever extends BaseRetriever {
this.topK[ModalityType.TEXT] = similarityTopK;
}
async _retrieve(params: QueryBundle): Promise<NodeWithScore[]> {
const { query } = params;
@wrapEventCaller
async retrieve({
query,
preFilters,
}: RetrieveParams): Promise<NodeWithScore[]> {
Settings.callbackManager.dispatchEvent("retrieve-start", {
query,
});
const vectorStores = this.index.vectorStores;
let nodesWithScores: NodeWithScore[] = [];
for (const type in vectorStores) {
const vectorStore: VectorStore = vectorStores[type as ModalityType]!;
nodesWithScores = nodesWithScores.concat(
await this.retrieveQuery(query, type as ModalityType, vectorStore),
await this.retrieveQuery(
query,
type as ModalityType,
vectorStore,
preFilters as MetadataFilters,
),
);
}
Settings.callbackManager.dispatchEvent("retrieve-end", {
query,
nodes: nodesWithScores,
});
return nodesWithScores;
}
@@ -1,11 +1,7 @@
import type { BaseNode, TransformComponent } from "@llamaindex/core/schema";
import { MetadataMode } from "@llamaindex/core/schema";
import { createSHA256 } from "@llamaindex/env";
import {
docToJson,
jsonSerializer,
jsonToDoc,
} from "../storage/docStore/utils.js";
import { docToJson, jsonToDoc } from "../storage/docStore/utils.js";
import { SimpleKVStore } from "../storage/kvStore/SimpleKVStore.js";
import type { BaseKVStore } from "../storage/kvStore/types.js";
@@ -57,7 +53,7 @@ export class IngestionCache {
async put(hash: string, nodes: BaseNode[]) {
const val = {
[this.nodesKey]: nodes.map((node) => docToJson(node, jsonSerializer)),
[this.nodesKey]: nodes.map((node) => docToJson(node)),
};
await this.cache.put(hash, val, this.collection);
}
@@ -67,8 +63,6 @@ export class IngestionCache {
if (!json || !json[this.nodesKey] || !Array.isArray(json[this.nodesKey])) {
return undefined;
}
return json[this.nodesKey].map((doc: any) =>
jsonToDoc(doc, jsonSerializer),
);
return json[this.nodesKey].map((doc: any) => jsonToDoc(doc));
}
}
+10
View File
@@ -0,0 +1,10 @@
import type { MessageContent } from "@llamaindex/core/llms";
import type { NodeWithScore } from "@llamaindex/core/schema";
export type RetrievalStartEvent = {
query: MessageContent;
};
export type RetrievalEndEvent = {
query: MessageContent;
nodes: NodeWithScore[];
};
+5 -2
View File
@@ -1,8 +1,8 @@
import type { BaseTool, MessageContent } from "@llamaindex/core/llms";
import { BaseRetriever } from "@llamaindex/core/retriever";
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";
// Assuming that necessary interfaces and classes (like OT, TextNode, BaseNode, etc.) are defined elsewhere
@@ -49,6 +49,9 @@ export abstract class BaseObjectNodeMapping {
// You will need to implement specific subclasses of BaseObjectNodeMapping as per your project requirements.
// todo: multimodal support
type QueryType = MessageContent;
export class ObjectRetriever<T = unknown> {
_retriever: BaseRetriever;
_objectNodeMapping: BaseObjectNodeMapping;
@@ -67,7 +70,7 @@ export class ObjectRetriever<T = unknown> {
}
// Translating the retrieve method
async retrieve(strOrQueryBundle: MessageContent): Promise<T[]> {
async retrieve(strOrQueryBundle: QueryType): Promise<T[]> {
const nodes = await this.retriever.retrieve({
query: extractText(strOrQueryBundle),
});
@@ -29,7 +29,7 @@ export class KVDocumentStore extends BaseDocumentStore {
for (const key in jsonDict) {
const value = jsonDict[key];
if (isValidDocJson(value)) {
docs[key] = jsonToDoc(value, this.serializer);
docs[key] = jsonToDoc(value);
} else {
console.warn(`Invalid JSON for docId ${key}`);
}
@@ -52,7 +52,7 @@ export class KVDocumentStore extends BaseDocumentStore {
);
}
const nodeKey = doc.id_;
const data = docToJson(doc, this.serializer);
const data = docToJson(doc);
await this.kvstore.put(nodeKey, data, this.nodeCollection);
const metadata: DocMetaData = { docHash: doc.hash };
@@ -94,7 +94,7 @@ export class KVDocumentStore extends BaseDocumentStore {
if (!isValidDocJson(json)) {
throw new Error(`Invalid JSON for docId ${docId}`);
}
return jsonToDoc(json, this.serializer);
return jsonToDoc(json);
}
async getRefDocInfo(refDocId: string): Promise<RefDocInfo | undefined> {
@@ -1,32 +1,19 @@
import { DEFAULT_NAMESPACE } from "@llamaindex/core/global";
import {
PostgresKVStore,
type PostgresKVStoreConfig,
} from "../kvStore/PostgresKVStore.js";
import { PostgresKVStore } from "../kvStore/PostgresKVStore.js";
import { KVDocumentStore } from "./KVDocumentStore.js";
import { noneSerializer } from "./utils.js";
const DEFAULT_TABLE_NAME = "llamaindex_doc_store";
export type PostgresDocumentStoreConfig = PostgresKVStoreConfig & {
namespace?: string;
};
export class PostgresDocumentStore extends KVDocumentStore {
serializer = noneSerializer;
constructor(config?: PostgresDocumentStoreConfig) {
constructor(config?: {
schemaName?: string;
tableName?: string;
connectionString?: string;
namespace?: string;
}) {
const kvStore = new PostgresKVStore({
schemaName: config?.schemaName,
tableName: config?.tableName || DEFAULT_TABLE_NAME,
...(config && "clientConfig" in config
? { clientConfig: config.clientConfig }
: config && "client" in config
? {
client: config.client,
shouldConnect: config.shouldConnect ?? false,
}
: {}),
});
const namespace = config?.namespace || DEFAULT_NAMESPACE;
super(kvStore, namespace);
@@ -3,7 +3,6 @@ import {
DEFAULT_PERSIST_DIR,
} from "@llamaindex/core/global";
import { BaseNode } from "@llamaindex/core/schema";
import { jsonSerializer, type Serializer } from "./utils.js";
const defaultPersistPath = `${DEFAULT_PERSIST_DIR}/${DEFAULT_DOC_STORE_PERSIST_FILENAME}`;
@@ -13,8 +12,6 @@ export interface RefDocInfo {
}
export abstract class BaseDocumentStore {
serializer: Serializer<any> = jsonSerializer;
// Save/load
persist(persistPath: string = defaultPersistPath): void {
// Persist the docstore to a file.
@@ -4,35 +4,12 @@ import { Document, ObjectType, TextNode } from "@llamaindex/core/schema";
const TYPE_KEY = "__type__";
const DATA_KEY = "__data__";
export interface Serializer<T> {
toPersistence(data: Record<string, unknown>): T;
fromPersistence(data: T): Record<string, unknown>;
}
export const jsonSerializer: Serializer<string> = {
toPersistence(data) {
return JSON.stringify(data);
},
fromPersistence(data) {
return JSON.parse(data);
},
};
export const noneSerializer: Serializer<Record<string, unknown>> = {
toPersistence(data) {
return data;
},
fromPersistence(data) {
return data;
},
};
type DocJson<Data> = {
type DocJson = {
[TYPE_KEY]: ObjectType;
[DATA_KEY]: Data;
[DATA_KEY]: string;
};
export function isValidDocJson(docJson: any): docJson is DocJson<unknown> {
export function isValidDocJson(docJson: any): docJson is DocJson {
return (
typeof docJson === "object" &&
docJson !== null &&
@@ -41,22 +18,16 @@ export function isValidDocJson(docJson: any): docJson is DocJson<unknown> {
);
}
export function docToJson(
doc: BaseNode,
serializer: Serializer<unknown>,
): DocJson<unknown> {
export function docToJson(doc: BaseNode): DocJson {
return {
[DATA_KEY]: serializer.toPersistence(doc.toJSON()),
[DATA_KEY]: JSON.stringify(doc.toJSON()),
[TYPE_KEY]: doc.type,
};
}
export function jsonToDoc<Data>(
docDict: DocJson<Data>,
serializer: Serializer<Data>,
): BaseNode {
export function jsonToDoc(docDict: DocJson): BaseNode {
const docType = docDict[TYPE_KEY];
const dataDict = serializer.fromPersistence(docDict[DATA_KEY]) as any;
const dataDict = JSON.parse(docDict[DATA_KEY]);
let doc: BaseNode;
if (docType === ObjectType.DOCUMENT) {
@@ -1,29 +1,19 @@
import { DEFAULT_NAMESPACE } from "@llamaindex/core/global";
import {
PostgresKVStore,
type PostgresKVStoreConfig,
} from "../kvStore/PostgresKVStore.js";
import { PostgresKVStore } from "../kvStore/PostgresKVStore.js";
import { KVIndexStore } from "./KVIndexStore.js";
const DEFAULT_TABLE_NAME = "llamaindex_index_store";
export type PostgresIndexStoreConfig = PostgresKVStoreConfig & {
namespace?: string;
};
export class PostgresIndexStore extends KVIndexStore {
constructor(config?: PostgresIndexStoreConfig) {
constructor(config?: {
schemaName?: string;
tableName?: string;
connectionString?: string;
namespace?: string;
}) {
const kvStore = new PostgresKVStore({
schemaName: config?.schemaName,
tableName: config?.tableName || DEFAULT_TABLE_NAME,
...(config && "clientConfig" in config
? { clientConfig: config.clientConfig }
: config && "client" in config
? {
client: config.client,
shouldConnect: config.shouldConnect ?? false,
}
: {}),
});
const namespace = config?.namespace || DEFAULT_NAMESPACE;
super(kvStore, namespace);
@@ -7,76 +7,41 @@ export type DataType = Record<string, Record<string, any>>;
const DEFAULT_SCHEMA_NAME = "public";
const DEFAULT_TABLE_NAME = "llamaindex_kv_store";
export type PostgresKVStoreBaseConfig = {
schemaName?: string | undefined;
tableName?: string | undefined;
};
export type PostgresKVStoreClientConfig =
| {
/**
* Client configuration options for the pg client.
*
* {@link https://node-postgres.com/apis/client#new-client PostgresSQL Client API}
*/
clientConfig?: pg.ClientConfig | undefined;
}
| {
/**
* A pg client or pool client instance.
* If provided, make sure it is not connected to the database yet, or it will throw an error.
*/
shouldConnect?: boolean | undefined;
client?: pg.Client | pg.PoolClient;
};
export type PostgresKVStoreConfig = PostgresKVStoreBaseConfig &
PostgresKVStoreClientConfig;
export class PostgresKVStore extends BaseKVStore {
private schemaName: string;
private tableName: string;
private connectionString: string | undefined = undefined;
private db?: pg.Client;
private isDBConnected: boolean = false;
private clientConfig: pg.ClientConfig | undefined = undefined;
private db?: pg.ClientBase | undefined = undefined;
constructor(config?: PostgresKVStoreConfig) {
constructor(config?: {
schemaName?: string | undefined;
tableName?: string | undefined;
connectionString?: string | undefined;
}) {
super();
this.schemaName = config?.schemaName || DEFAULT_SCHEMA_NAME;
this.tableName = config?.tableName || DEFAULT_TABLE_NAME;
if (config) {
if ("clientConfig" in config) {
this.clientConfig = config.clientConfig;
} else if ("client" in config) {
this.isDBConnected =
config?.shouldConnect !== undefined ? !config.shouldConnect : false;
this.db = config.client;
this.connectionString = config?.connectionString;
}
private async getDb(): Promise<pg.Client> {
if (!this.db) {
try {
const pg = await import("pg");
const { Client } = pg.default ? pg.default : pg;
const db = new Client({ connectionString: this.connectionString });
await db.connect();
await this.checkSchema(db);
this.db = db;
} catch (err) {
console.error(err);
return Promise.reject(err instanceof Error ? err : new Error(`${err}`));
}
}
return Promise.resolve(this.db);
}
private async getDb(): Promise<pg.ClientBase> {
if (!this.db) {
const pg = await import("pg");
const { Client } = pg.default ? pg.default : pg;
const db = new Client({ ...this.clientConfig });
await db.connect();
this.isDBConnected = true;
this.db = db;
}
if (this.db && !this.isDBConnected) {
await this.db.connect();
this.isDBConnected = true;
}
this.db.on("end", () => {
this.isDBConnected = false;
});
await this.checkSchema(this.db);
return this.db;
}
private async checkSchema(db: pg.ClientBase) {
private async checkSchema(db: pg.Client) {
await db.query(`CREATE SCHEMA IF NOT EXISTS ${this.schemaName}`);
const tbl = `CREATE TABLE IF NOT EXISTS ${this.schemaName}.${this.tableName} (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
@@ -132,7 +97,7 @@ export class PostgresKVStore extends BaseKVStore {
const sql = `SELECT * FROM ${this.schemaName}.${this.tableName} WHERE key = $1 AND collection = $2`;
const result = await db.query(sql, [key, collection]);
await db.query("COMMIT");
return result.rows[0]?.value;
return result.rows[0].value;
} catch (error) {
await db.query("ROLLBACK");
throw error;
@@ -14,44 +14,25 @@ import {
import { escapeLikeString } from "./utils.js";
import type { BaseEmbedding } from "@llamaindex/core/embeddings";
import { DEFAULT_COLLECTION } from "@llamaindex/core/global";
import type { BaseNode, Metadata } from "@llamaindex/core/schema";
import { Document, MetadataMode } from "@llamaindex/core/schema";
export const PGVECTOR_SCHEMA = "public";
export const PGVECTOR_TABLE = "llamaindex_embedding";
export const DEFAULT_DIMENSIONS = 1536;
type PGVectorStoreBaseConfig = {
export type PGVectorStoreConfig = Pick<
pg.ClientConfig,
"user" | "database" | "password" | "connectionString"
> & {
schemaName?: string | undefined;
tableName?: string | undefined;
dimensions?: number | undefined;
embedModel?: BaseEmbedding | undefined;
};
export type PGVectorStoreConfig = PGVectorStoreBaseConfig &
(
| {
/**
* Client configuration options for the pg client.
*
* {@link https://node-postgres.com/apis/client#new-client PostgresSQL Client API}
*/
clientConfig: pg.ClientConfig;
}
| {
/**
* A pg client or pool client instance.
* If provided, make sure it is not connected to the database yet, or it will throw an error.
*/
shouldConnect?: boolean | undefined;
client: pg.Client | pg.PoolClient;
}
);
/**
* Provides support for writing and querying vector data in Postgres.
* Note: Can't be used with data created using the Python version of the vector store (https://docs.llamaindex.ai/en/stable/examples/vector_stores/postgres/)
* Note: Can't be used with data created using the Python version of the vector store (https://docs.llamaindex.ai/en/stable/examples/vector_stores/postgres.html)
*/
export class PGVectorStore
extends VectorStoreBase
@@ -59,26 +40,52 @@ export class PGVectorStore
{
storesText: boolean = true;
private collection: string = DEFAULT_COLLECTION;
private readonly schemaName: string = PGVECTOR_SCHEMA;
private readonly tableName: string = PGVECTOR_TABLE;
private readonly dimensions: number = DEFAULT_DIMENSIONS;
private collection: string = "";
private schemaName: string = PGVECTOR_SCHEMA;
private tableName: string = PGVECTOR_TABLE;
private isDBConnected: boolean = false;
private db: pg.ClientBase | null = null;
private readonly clientConfig: pg.ClientConfig | null = null;
private user: pg.ClientConfig["user"] | undefined = undefined;
private password: pg.ClientConfig["password"] | undefined = undefined;
private database: pg.ClientConfig["database"] | undefined = undefined;
private connectionString: pg.ClientConfig["connectionString"] | undefined =
undefined;
constructor(config: PGVectorStoreConfig) {
super(config?.embedModel);
this.schemaName = config?.schemaName ?? PGVECTOR_SCHEMA;
this.tableName = config?.tableName ?? PGVECTOR_TABLE;
this.dimensions = config?.dimensions ?? DEFAULT_DIMENSIONS;
if ("clientConfig" in config) {
this.clientConfig = config.clientConfig;
private dimensions: number = 1536;
private db?: pg.ClientBase;
/**
* Constructs a new instance of the PGVectorStore
*
* If the `connectionString` is not provided the following env variables are
* used to connect to the DB:
* PGHOST=your database host
* PGUSER=your database user
* PGPASSWORD=your database password
* PGDATABASE=your database name
* PGPORT=your database port
*/
constructor(configOrClient?: PGVectorStoreConfig | pg.ClientBase) {
// We cannot import pg from top level, it might have side effects
// so we only check if the config.connect function exists
if (
configOrClient &&
"connect" in configOrClient &&
typeof configOrClient.connect === "function"
) {
const db = configOrClient as pg.ClientBase;
super();
this.db = db;
} else {
this.isDBConnected =
config.shouldConnect !== undefined ? !config.shouldConnect : false;
this.db = config.client;
const config = configOrClient as PGVectorStoreConfig;
super(config?.embedModel);
this.schemaName = config?.schemaName ?? PGVECTOR_SCHEMA;
this.tableName = config?.tableName ?? PGVECTOR_TABLE;
this.user = config?.user;
this.password = config?.password;
this.database = config?.database;
this.connectionString = config?.connectionString;
this.dimensions = config?.dimensions ?? 1536;
}
}
@@ -106,41 +113,39 @@ export class PGVectorStore
private async getDb(): Promise<pg.ClientBase> {
if (!this.db) {
const pg = await import("pg");
const { Client } = pg.default ? pg.default : pg;
try {
const pg = await import("pg");
const { Client } = pg.default ? pg.default : pg;
const { registerTypes } = await import("pgvector/pg");
// Create DB connection
// Read connection params from env - see comment block above
const db = new Client({
...this.clientConfig,
});
const { registerType } = await import("pgvector/pg");
// Create DB connection
// Read connection params from env - see comment block above
const db = new Client({
user: this.user,
password: this.password,
database: this.database,
connectionString: this.connectionString,
});
await db.connect();
await db.connect();
this.isDBConnected = true;
// Check vector extension
await db.query("CREATE EXTENSION IF NOT EXISTS vector");
await registerType(db);
// Check vector extension
await db.query("CREATE EXTENSION IF NOT EXISTS vector");
await registerTypes(db);
// All good? Keep the connection reference
this.db = db;
// All good? Keep the connection reference
this.db = db;
} catch (err) {
console.error(err);
return Promise.reject(err instanceof Error ? err : new Error(`${err}`));
}
}
if (this.db && !this.isDBConnected) {
await this.db.connect();
this.isDBConnected = true;
}
this.db.on("end", () => {
// Connection closed
this.isDBConnected = false;
});
const db = this.db;
// Check schema, table(s), index(es)
await this.checkSchema(this.db);
await this.checkSchema(db);
return this.db;
return Promise.resolve(this.db);
}
private async checkSchema(db: pg.ClientBase) {
@@ -1,237 +0,0 @@
import {
VectorStoreBase,
type IEmbedModel,
type MetadataFilter,
type MetadataFilters,
type VectorStoreNoEmbedModel,
type VectorStoreQuery,
type VectorStoreQueryResult,
} from "./types.js";
import type { BaseNode, Metadata, TextNode } from "@llamaindex/core/schema";
import { getEnv } from "@llamaindex/env";
import { Index } from "@upstash/vector";
import { metadataDictToNode, nodeToMetadata } from "./utils.js";
type UpstashParams = {
namespace?: string;
token?: string;
endpoint?: string;
maxBatchSize?: number;
} & IEmbedModel;
/**
* Provides support for writing and querying vector data in Upstash.
*/
export class UpstashVectorStore
extends VectorStoreBase
implements VectorStoreNoEmbedModel
{
storesText: boolean = true;
private db: Index;
private maxBatchSize: number;
namespace: string;
/**
* @param namespace namespace to use
* @param token upstash vector token. if not set, `process.env.UPSTASH_VECTOR_REST_TOKEN` is used.
* @param endpoint upstash vector endpoint. If not set, `process.env.UPSTASH_VECTOR_REST_URL` is used.
* @param maxBatchSize maximum number of vectors upserted at once. Default is 1000.
*
* @example
* ```ts
* const vectorStore = new UpstashVectorStore({ namespace: "my-namespace" })
* ```
*/
constructor(params?: UpstashParams) {
super(params?.embedModel);
this.namespace = params?.namespace ?? "";
this.maxBatchSize = params?.maxBatchSize ?? 1000;
const token = params?.token ?? getEnv("UPSTASH_VECTOR_REST_TOKEN");
const endpoint = params?.endpoint ?? getEnv("UPSTASH_VECTOR_REST_URL");
if (!token) {
throw new Error(
"Must specify UPSTASH_VECTOR_REST_TOKEN via env variable.",
);
}
if (!endpoint) {
throw new Error("Must specify UPSTASH_VECTOR_REST_URL via env variable.");
}
this.db = new Index({ token, url: endpoint });
}
private async getDb(): Promise<Index> {
if (!this.db) {
const { Index } = await import("@upstash/vector");
this.db = new Index();
}
return this.db;
}
/**
* Connects to the database specified in environment vars.
* @returns A connection to the database, or the error encountered while connecting/setting up.
*/
client(): Promise<Index> {
return this.getDb();
}
/**
* Adds vector record(s) to the table.
* @param embeddingResults The Nodes to be inserted, optionally including metadata tuples.
* @returns ids of the embeddings (infered from the id_ field of embeddingResults objects)
*/
async add(embeddingResults: BaseNode<Metadata>[]): Promise<string[]> {
if (embeddingResults.length == 0) {
return [];
}
const nodes = embeddingResults.map(this.nodeToRecord);
const result = await this.upsertInBatches(nodes);
if (result != "OK") {
throw new Error("Failed to save chunk");
}
return nodes.map((node) => node.id);
}
/**
* Adds plain text record(s) to the table. Upstash take cares of embedding conversion.
* @param text The Nodes to be inserted, optionally including metadata tuples.
* @returns ids of the embeddings (infered from the id_ field of embeddingResults objects)
*/
async addPlainText(text: TextNode<Metadata>[]): Promise<string[]> {
if (text.length == 0) {
return [];
}
const nodes = text.map(this.textNodeToRecord);
const result = await this.upsertInBatches(nodes);
if (result != "OK") {
throw new Error("Failed to save chunk");
}
return nodes.map((node) => node.id);
}
private async upsertInBatches(
nodes:
| ReturnType<UpstashVectorStore["textNodeToRecord"]>[]
| ReturnType<UpstashVectorStore["nodeToRecord"]>[],
) {
const promises: Promise<string>[] = [];
for (let i = 0; i < nodes.length; i += this.maxBatchSize) {
const batch = nodes.slice(i, i + this.maxBatchSize);
promises.push(this.db.upsert(batch, { namespace: this.namespace }));
}
const results = await Promise.all(promises);
return results.every((result) => result === "OK") ? "OK" : "NOT-OK";
}
/**
* Deletes a single record from the database by id.
* NOTE: Uses the collection property controlled by setCollection/getCollection.
* @param refDocId Unique identifier for the record to delete.
* @returns Promise that resolves if the delete query did not throw an error.
*/
async delete(refDocId: string): Promise<void> {
await this.db.namespace(this.namespace).delete(refDocId);
}
/**
* Deletes a single record from the database by id.
* NOTE: Uses the collection property controlled by setCollection/getCollection.
* @param refDocId Unique identifier for the record to delete.
* @param deleteKwargs Required by VectorStore interface. Currently ignored.
* @returns Promise that resolves if the delete query did not throw an error.
*/
async deleteMany(refDocId: string[]): Promise<void> {
await this.db.namespace(this.namespace).delete(refDocId);
}
/**
* Query the vector store for the closest matching data to the query embeddings
* @param query The VectorStoreQuery to be used
* @param options Required by VectorStore interface. Currently ignored.
* @returns Zero or more Document instances with data from the vector store.
*/
async query(
query: VectorStoreQuery,
_options?: any,
): Promise<VectorStoreQueryResult> {
const filter = this.toUpstashFilter(query.filters);
const defaultOptions: any = {
vector: query.queryEmbedding,
topK: query.similarityTopK,
includeVectors: true,
includeMetadata: true,
filter,
};
const db = this.db;
const results = await db.query(defaultOptions, {
namespace: this.namespace,
});
const nodes = results.map((result) => {
const node = metadataDictToNode(result.metadata as Record<string, any>, {
fallback: {
id: result.id,
metadata: result.metadata,
embedding: result.vector,
},
});
return node;
});
const ret = {
nodes: nodes,
similarities: results.map((row) => row.score || 999),
ids: results.map((row) => String(row.id)),
};
return ret;
}
toFilterString(filter: MetadataFilter) {
return `${filter.key} ${filter.operator} ${filter.value}`;
}
toUpstashFilter(stdFilters?: MetadataFilters) {
if (!stdFilters?.filters) return;
for (const item of stdFilters.filters) {
if (item.operator === "==") {
//@ts-expect-error Upstash equal operator uses only one equal sign, so we have to replace it.
item.operator = "=";
}
}
const filterStrings = stdFilters.filters.map(this.toFilterString);
if (filterStrings.length === 1) {
return filterStrings[0];
}
return filterStrings.join(` ${stdFilters.condition ?? "and"} `);
}
nodeToRecord(node: BaseNode<Metadata>) {
const id: any = node.id_.length ? node.id_ : null;
return {
id: id,
vector: node.getEmbedding(),
metadata: nodeToMetadata(node),
};
}
textNodeToRecord(node: TextNode<Metadata>) {
const id: any = node.id_.length ? node.id_ : null;
return {
id,
data: node.text,
metadata: nodeToMetadata(node),
};
}
}
-12
View File
@@ -1,17 +1,5 @@
# @llamaindex/groq
## 0.0.7
### Patch Changes
- @llamaindex/openai@0.1.8
## 0.0.6
### Patch Changes
- @llamaindex/openai@0.1.7
## 0.0.5
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/groq",
"description": "Groq Adapter for LlamaIndex",
"version": "0.0.7",
"version": "0.0.5",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
-14
View File
@@ -1,19 +1,5 @@
# @llamaindex/openai
## 0.1.8
### Patch Changes
- Updated dependencies [8b7fdba]
- @llamaindex/core@0.2.6
## 0.1.7
### Patch Changes
- Updated dependencies [d902cc3]
- @llamaindex/core@0.2.5
## 0.1.6
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@llamaindex/openai",
"description": "OpenAI Adapter for LlamaIndex",
"version": "0.1.8",
"version": "0.1.6",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
+16 -1113
View File
File diff suppressed because it is too large Load Diff