diff --git a/docs/api.mdx b/docs/api.mdx
index f74f160..3dc3f5f 100644
--- a/docs/api.mdx
+++ b/docs/api.mdx
@@ -99,13 +99,18 @@ The chat method enables conversations with a language model (LLM) using your vec
{" "}
- Chat session ID of the user interacting with the application
+ Chat session ID of the user interacting with the application. If omitted, all clients share the
+ default session and therefore the same chat history. Pass a unique value per conversation (or per
+ user) to isolate histories.
{" "}
- Limit included context elements to a specific namespace (i.e. results for a specific user)
+ Limit included context elements to a specific namespace (i.e. results for a specific user). This
+ is a **top-level** chat option — do not nest it under `options`. When adding context, `namespace`
+ goes under `options` on `context.add`; when chatting, pass `namespace` directly on `chat` (and
+ keep it aligned with the namespace you ingested into).
{" "}
@@ -161,19 +166,19 @@ const chatResponse = await ragChat.chat({
topK: 3,
streaming: true,
onContextFetched: (context) => {
- console.log("Retrieved context:", context)
- return context
+ console.log("Retrieved context:", context);
+ return context;
},
metadata: { source: "product_inquiry" },
},
-})
+});
if (chatResponse.isStream) {
for await (const chunk of chatResponse.output) {
- console.log(chunk)
+ console.log(chunk);
}
} else {
- console.log(chatResponse.output)
+ console.log(chatResponse.output);
}
```
@@ -282,12 +287,12 @@ const result = await context.add({
fileSource: "./document.pdf",
pdfConfig: { splitPages: true },
options: { metadata: { source: "company_report" } },
-})
+});
if (result.success) {
- console.log(`Added ${result.ids.length} context items`)
+ console.log(`Added ${result.ids.length} context items`);
} else {
- console.error(`Failed to add context: ${result.error}`)
+ console.error(`Failed to add context: ${result.error}`);
}
```
@@ -336,13 +341,13 @@ The method doesn't return a value, but it's asynchronous, so you should wait for
await context.delete({
id: "item_123",
namespace: "product_catalog",
-})
+});
// Deleting multiple items
await context.delete({
id: ["item_456", "item_789", "item_101"],
namespace: "customer_data",
-})
+});
```
### `deleteEntireContext`
@@ -378,13 +383,13 @@ The method doesn't return a value, but it's asynchronous, so you should wait for
```javascript
// Resetting the entire vector database
-await context.deleteEntireContext()
-console.log("Entire context deleted successfully")
+await context.deleteEntireContext();
+console.log("Entire context deleted successfully");
// Resetting a specific namespace
await context.deleteEntireContext({
namespace: "temporary_data",
-})
+});
```
@@ -487,7 +492,7 @@ await history.addMessage({
},
sessionId: "user_456_weather_chat",
sessionTTL: 1800, // Session will expire after 30 minutes
-})
+});
```
### `deleteMessages`
@@ -516,11 +521,11 @@ The method doesn't return a value, but it's asynchronous, so you should wait for
#### Example:
```javascript
-const sessionIdToDelete = "user_789_support_chat"
+const sessionIdToDelete = "user_789_support_chat";
-await history.deleteMessages({ sessionId: sessionIdToDelete })
+await history.deleteMessages({ sessionId: sessionIdToDelete });
-console.log(`All messages in session ${sessionIdToDelete} have been deleted`)
+console.log(`All messages in session ${sessionIdToDelete} have been deleted`);
```
@@ -537,14 +542,15 @@ The `getMessages` method retrieves several messages from a chat session's histor
- Chat session ID from which to retrieve messages. If not provided, a default
- session ID will be used.
+ Chat session ID from which to retrieve messages. If not provided, a default session ID will be
+ used.
The amount of messages to retrieve.
- The starting index from which to retrieve messages (i.e. for pagination). Defaults to 0 (most recent message).
+ The starting index from which to retrieve messages (i.e. for pagination). Defaults to 0 (most
+ recent message).
@@ -598,10 +604,10 @@ const messages = await history.getMessages({
sessionId: "user_123_support_chat",
amount: 10,
startIndex: 0,
-})
+});
-console.log(`Retrieved ${messages.length} messages:`)
+console.log(`Retrieved ${messages.length} messages:`);
messages.forEach((msg) => {
- console.log(`${msg.role}: ${msg.content} (ID: ${msg.id})`)
-})
+ console.log(`${msg.role}: ${msg.content} (ID: ${msg.id})`);
+});
```
diff --git a/docs/gettingstarted.mdx b/docs/gettingstarted.mdx
index 7639221..372e5f6 100644
--- a/docs/gettingstarted.mdx
+++ b/docs/gettingstarted.mdx
@@ -5,7 +5,6 @@ title: Getting Started
Upstash RAG Chat is **TypeScript toolkit for building powerful RAG applications**. With Upstash RAG Chat, you can focus on building a high-quality chatbot without having to deal with complicated AI orchestration tools.
You can find the Github Repository [here](https://github.com/upstash/rag-chat).
-
### Installation
@@ -132,6 +131,13 @@ await ragChat.context.add({
// optional 👇: only add this knowledge to a specific namespace
options: { namespace: "user-123-documents" },
});
+
+// When querying that knowledge, pass the same namespace at the top level of chat options
+// (not nested under `options` — that shape is only for `context.add`).
+await ragChat.chat("Summarize the PDF", {
+ namespace: "user-123-documents",
+ sessionId: "user-123-session", // optional 👇: isolate this user's chat history
+});
```
#### Adding Web Content
diff --git a/docs/how-to.mdx b/docs/how-to.mdx
index 8be165e..e7fdb4d 100644
--- a/docs/how-to.mdx
+++ b/docs/how-to.mdx
@@ -19,26 +19,71 @@ const result = await ragChat.chat("THIS_IS_USERS_QUESTION", {
```
#### Adjust the context quality
+
If your chatbot is negatively affected by the provided context, you can adjust the context quality using the `similarityThreshold` option. The similarityThreshold is a number between 0 and 1, with a default value of 0.5. Increasing this value will improve quality, but the chatbot may reject more queries due to lack of relevant data.
```ts
ragChat.chat("Tell me about machine learning", {
- similarityThreshold: 0.5
+ similarityThreshold: 0.5,
});
```
+#### Use namespaces correctly
+
+Namespaces isolate knowledge in the vector index (for example per user or tenant).
+
+- When **adding** context, pass `namespace` under `options`.
+- When **chatting**, pass `namespace` at the **top level** of the chat options — not nested under `options`.
+
+```ts
+const namespace = "user-123-documents";
+
+await ragChat.context.add({
+ type: "text",
+ data: "The speed of light is approximately 299,792,458 meters per second.",
+ options: { namespace },
+});
+
+// Correct: namespace is a top-level chat option
+const reply = await ragChat.chat("What is the speed of light?", {
+ namespace,
+});
+
+// Incorrect: nesting under `options` is ignored for chat retrieval
+// await ragChat.chat("What is the speed of light?", {
+// options: { namespace },
+// });
+```
+
+If add and chat use different namespaces (or chat omits `namespace`), retrieval will look in the wrong index and the model may answer as if no context was provided.
+
+#### Isolate chat history with sessionId
+
+If you do not set `sessionId`, every client shares the default session (`upstash-rag-chat-session`) and therefore the same history.
+
+Pass a unique `sessionId` per conversation (or per user) on `chat`, and use the same id when reading or deleting history:
+
+```ts
+const sessionId = "user-123-support-chat";
+
+await ragChat.chat("Hello", { sessionId });
+
+const history = await ragChat.history.getMessages({ sessionId, amount: 10 });
+await ragChat.history.deleteMessages({ sessionId });
+```
+
#### Disable RAG to bypass context
When RAG disabled, RAG chat skips the vector store and directly sends the question to the LLM model.
```ts
const result = await ragChat.chat("THIS_IS_USERS_QUESTION", {
- disableRAG: true
+ disableRAG: true,
});
```
-
#### Enable debug logs
+
```ts
new RAGChat({ debug: true });
```
@@ -50,21 +95,21 @@ You can access and update the context by using the `onContextFetched` callback.
```ts
let response = await ragChat.chat(question, {
onContextFetched: (context) => {
- console.log("Retrieved context:", context)
- return context
+ console.log("Retrieved context:", context);
+ return context;
},
});
```
-
#### Access the chat history
+
You can access chat history by using the `onChatHistoryFetched` callback. This callback is called after the chat history is fetched from the Redis (or memory) before the prompt is sent to the LLM.
```ts
let response = await ragChat.chat(question, {
onChatHistoryFetched: (messages) => {
- console.log("Retrieved chat history:", messages)
- return messages
+ console.log("Retrieved chat history:", messages);
+ return messages;
},
});
```
@@ -78,7 +123,7 @@ export const rag = new RAGChat();
await rag.context.add({
type: "text",
data: "Mississippi is a state in the United States of America",
- options: { metadata: { source: "wikipedia" }}
+ options: { metadata: { source: "wikipedia" } },
});
const response = await rag.chat("Where is Mississippi?");
@@ -87,6 +132,7 @@ console.log(response.metadata);
```
#### Access the ratelimit details
+
You can see how much allowance a user has by using the ratelimitDetails hook.
```ts
@@ -99,6 +145,7 @@ await ragChat.chat("You shall not pass", {
```
#### Access the output during streaming
+
You can access, read, or modify your streamed data.
```ts
@@ -118,32 +165,32 @@ await ragChat.chat("", {
#### Store metadata in the chat history and access context
```ts
-let messages: UpstashMessage[] = []
-let context: PrepareChatResult = []
+let messages: UpstashMessage[] = [];
+let context: PrepareChatResult = [];
const response = await ragChat.chat(question, {
onChatHistoryFetched(_messages) {
- messages = _messages
+ messages = _messages;
this.metadata = {
...this.metadata,
usedHistory: JSON.stringify(
messages.map((message) => {
- delete message.metadata?.usedHistory
- delete message.metadata?.usedContext
- return message
+ delete message.metadata?.usedHistory;
+ delete message.metadata?.usedContext;
+ return message;
})
),
- }
- return _messages
+ };
+ return _messages;
},
onContextFetched(_context) {
- context = _context
- this.metadata = { ...this.metadata, usedContext: context.map((x) => x.data.replace("-", "")) }
- return _context
+ context = _context;
+ this.metadata = { ...this.metadata, usedContext: context.map((x) => x.data.replace("-", "")) };
+ return _context;
},
streaming: true,
metadata: {
modelNameWithProvider: `${LLM_MODELS[llmModel].provider}_${llmModel}`,
},
-})
+});
```