Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 32 additions & 26 deletions docs/api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,18 @@ The chat method enables conversations with a language model (LLM) using your vec
{" "}

<ParamField path="sessionId" type="string">
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.
</ParamField>

{" "}

<ParamField path="namespace" type="string">
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).
</ParamField>

{" "}
Expand Down Expand Up @@ -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);
}
```

Expand Down Expand Up @@ -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}`);
}
```

Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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",
})
});
```

<Warning>
Expand Down Expand Up @@ -487,7 +492,7 @@ await history.addMessage({
},
sessionId: "user_456_weather_chat",
sessionTTL: 1800, // Session will expire after 30 minutes
})
});
```

### `deleteMessages`
Expand Down Expand Up @@ -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`);
```

<Warning>
Expand All @@ -537,14 +542,15 @@ The `getMessages` method retrieves several messages from a chat session's histor
<ParamField path="options" type="GetMessagesOptions">
<Expandable>
<ParamField path="sessionId" type="string" default="DEFAULT_CHAT_SESSION_ID">
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.
</ParamField>
<ParamField path="amount" type="number" default="DEFAULT_HISTORY_LENGTH">
The amount of messages to retrieve.
</ParamField>
<ParamField path="startIndex" type="number" default="0">
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).
</ParamField>
</Expandable>
</ParamField>
Expand Down Expand Up @@ -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})`);
});
```
8 changes: 7 additions & 1 deletion docs/gettingstarted.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
89 changes: 68 additions & 21 deletions docs/how-to.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
```
Expand All @@ -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;
},
});
```
Expand All @@ -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?");

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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}`,
},
})
});
```