| .. | ||
| src | ||
| tests | ||
| README.md | ||
| tsup.config.ts | ||
| vitest.config.ts | ||
OpenRAG TypeScript SDK
Official TypeScript/JavaScript SDK for the OpenRAG API.
Installation
npm install openrag-sdk
# or
yarn add openrag-sdk
# or
pnpm add openrag-sdk
Quick Start
import { OpenRAGClient } from "openrag-sdk";
// Client auto-discovers OPENRAG_API_KEY and OPENRAG_URL from environment
const client = new OpenRAGClient();
// Simple chat
const response = await client.chat.create({ message: "What is RAG?" });
console.log(response.response);
console.log(`Chat ID: ${response.chatId}`);
Configuration
The SDK can be configured via environment variables or constructor arguments:
| Environment Variable | Constructor Option | Description |
|---|---|---|
OPENRAG_API_KEY |
apiKey |
API key for authentication (required) |
OPENRAG_URL |
baseUrl |
Base URL for the API (default: http://localhost:8080) |
// Using environment variables
const client = new OpenRAGClient();
// Using explicit arguments
const client = new OpenRAGClient({
apiKey: "orag_...",
baseUrl: "https://api.example.com",
});
Chat
Non-streaming
const response = await client.chat.create({ message: "What is RAG?" });
console.log(response.response);
console.log(`Chat ID: ${response.chatId}`);
// Continue conversation
const followup = await client.chat.create({
message: "Tell me more",
chatId: response.chatId,
});
Streaming with create({ stream: true })
Returns an async iterator directly:
let chatId: string | null = null;
for await (const event of await client.chat.create({
message: "Explain RAG",
stream: true,
})) {
if (event.type === "content") {
process.stdout.write(event.delta);
} else if (event.type === "sources") {
for (const source of event.sources) {
console.log(`\nSource: ${source.filename}`);
}
} else if (event.type === "done") {
chatId = event.chatId;
}
}
Streaming with stream() (Disposable pattern)
Provides additional helpers for convenience:
// Full event iteration with Disposable pattern
{
using stream = await client.chat.stream({ message: "Explain RAG" });
for await (const event of stream) {
if (event.type === "content") {
process.stdout.write(event.delta);
}
}
// Access aggregated data after iteration
console.log(`\nChat ID: ${stream.chatId}`);
console.log(`Full text: ${stream.text}`);
console.log(`Sources: ${stream.sources}`);
}
// Just text deltas
{
using stream = await client.chat.stream({ message: "Explain RAG" });
for await (const text of stream.textStream) {
process.stdout.write(text);
}
}
// Get final text directly
{
using stream = await client.chat.stream({ message: "Explain RAG" });
const text = await stream.finalText();
console.log(text);
}
Conversation History
// List all conversations
const conversations = await client.chat.list();
for (const conv of conversations.conversations) {
console.log(`${conv.chatId}: ${conv.title}`);
}
// Get specific conversation with messages
const conversation = await client.chat.get(chatId);
for (const msg of conversation.messages) {
console.log(`${msg.role}: ${msg.content}`);
}
// Delete conversation
await client.chat.delete(chatId);
Search
// Basic search
const results = await client.search.query("document processing");
for (const result of results.results) {
console.log(`${result.filename} (score: ${result.score})`);
console.log(` ${result.text.slice(0, 100)}...`);
}
// Search with filters
const results = await client.search.query("API documentation", {
filters: {
data_sources: ["api-docs.pdf"],
document_types: ["application/pdf"],
},
limit: 5,
scoreThreshold: 0.5,
});
Documents
// Ingest a file (Node.js)
const result = await client.documents.ingest({
filePath: "./report.pdf",
});
console.log(`Document ID: ${result.document_id}`);
console.log(`Chunks: ${result.chunks}`);
// Ingest from File object (browser)
const file = new File([...], "report.pdf");
const result = await client.documents.ingest({
file,
filename: "report.pdf",
});
// Delete a document
const result = await client.documents.delete("report.pdf");
console.log(`Deleted ${result.deleted_chunks} chunks`);
Settings
const settings = await client.settings.get();
console.log(`LLM Provider: ${settings.agent.llm_provider}`);
console.log(`LLM Model: ${settings.agent.llm_model}`);
console.log(`Embedding Model: ${settings.knowledge.embedding_model}`);
Error Handling
import {
OpenRAGError,
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError,
} from "openrag-sdk";
try {
const response = await client.chat.create({ message: "Hello" });
} catch (e) {
if (e instanceof AuthenticationError) {
console.log(`Invalid API key: ${e.message}`);
} else if (e instanceof NotFoundError) {
console.log(`Resource not found: ${e.message}`);
} else if (e instanceof ValidationError) {
console.log(`Invalid request: ${e.message}`);
} else if (e instanceof RateLimitError) {
console.log(`Rate limited: ${e.message}`);
} else if (e instanceof ServerError) {
console.log(`Server error: ${e.message}`);
} else if (e instanceof OpenRAGError) {
console.log(`API error: ${e.message} (status: ${e.statusCode})`);
}
}
Browser Support
This SDK works in both Node.js and browser environments. The main difference is file ingestion:
- Node.js: Use
filePathoption - Browser: Use
fileoption with aFileorBlobobject
TypeScript
This SDK is written in TypeScript and provides full type definitions. All types are exported from the main module:
import type {
ChatResponse,
StreamEvent,
SearchResponse,
IngestResponse,
SettingsResponse,
} from "openrag-sdk";
License
MIT