@orchata-ai/sdk
v1.3.0
Published
Official TypeScript SDK for Orchata
Maintainers
Readme
Infrastructure for intelligent applications
Orchata TypeScript SDK
The official TypeScript/JavaScript SDK for Orchata.
Features
- Type-safe - Full TypeScript support with auto-completion
- Universal - Works with Node.js 18+, Deno, Bun, and browsers
- Zero runtime dependencies - Uses native
fetchfor HTTP requests - Modern - ESM-first with CommonJS fallback
- AI-ready - Built-in tools for Vercel AI SDK v5+ integration
Installation
# npm
npm install @orchata-ai/sdk
# pnpm
pnpm add @orchata-ai/sdk
# yarn
yarn add @orchata-ai/sdk
# bun
bun add @orchata-ai/sdkOptional: AI SDK Integration
If you want to use the Vercel AI SDK tools (@orchata-ai/sdk/ai), also install:
npm install ai@^5.0.0 zod@^3.22.0Quick Start
import { Orchata } from '@orchata-ai/sdk';
const client = new Orchata({
apiKey: 'oai_your_api_key' // Get one at https://app.orchata.ai
});
// Query your knowledge base
const { results } = await client.query({
spaceIds: 'space_123',
query: 'How do I reset my password?'
});
console.log(results[0].chunk.content);Usage
Spaces
Spaces are knowledge bases that contain your documents.
// List all spaces
const { spaces, total } = await client.spaces.list();
// Create a new space
const { space } = await client.spaces.create({
name: 'Documentation',
description: 'Product documentation and guides',
icon: 'book'
});
// Get a specific space
const { space } = await client.spaces.get('space_123');
// Update a space
const { space } = await client.spaces.update('space_123', {
name: 'Updated Name',
description: 'New description'
});
// Delete a space
await client.spaces.delete('space_123');
// Get space usage limits
const limits = await client.spaces.getLimits('space_123');
console.log(`${limits.documents.current} / ${limits.documents.max} documents`);Documents
Documents are the content you want to query.
// List documents in a space
const { documents } = await client.documents.list({
spaceId: 'space_123'
});
// Upload a document (raw content)
const { document } = await client.documents.upload({
spaceId: 'space_123',
content: '# My Document\n\nSome markdown content...',
filename: 'my-doc.md',
metadata: { category: 'guides' }
});
// Upload a file (browser)
const { document } = await client.documents.uploadFile({
spaceId: 'space_123',
file: fileInput.files[0]
});
// Batch upload multiple documents
const result = await client.documents.batchUpload({
spaceId: 'space_123',
documents: [
{ filename: 'doc1.md', content: '# Doc 1\n\nContent...' },
{ filename: 'doc2.md', content: '# Doc 2\n\nContent...' },
]
});
console.log(`Uploaded: ${result.totalSuccessful}, Failed: ${result.totalFailed}`);
// Get processed content
const { content } = await client.documents.getContent('doc_123', 'space_123');
// Upsert a document (create or update by filename)
const { document, created } = await client.documents.upsert({
spaceId: 'space_123',
filename: 'readme.md',
content: '# Updated README\n\nNew content...',
metadata: { version: '2.0' }
});
console.log(created ? 'Created' : 'Updated', document.id);
// Append content to a document
const { document } = await client.documents.append('doc_123', {
spaceId: 'space_123',
content: '## New Section\n\nAdditional content...',
separator: '\n\n---\n\n' // Optional
});
// Get a document by filename
const doc = await client.documents.getByFilename({
spaceId: 'space_123',
filename: 'readme.md'
});
console.log(doc.content);
// Delete a document
await client.documents.delete('doc_123', 'space_123');Queries
Query your knowledge base using semantic search.
// Simple query
const { results } = await client.query({
spaceIds: 'space_123',
query: 'How do I authenticate?'
});
// Query multiple spaces
const { results } = await client.query({
spaceIds: ['space_123', 'space_456'],
query: 'authentication',
topK: 5 // Return top 5 results
});
// Filter by metadata
const { results } = await client.query({
spaceIds: 'space_123',
query: 'API reference',
metadata: { category: 'docs' }
});
// Group results by space
const { groupedBySpace } = await client.query({
spaceIds: ['space_123', 'space_456'],
query: 'authentication',
groupBySpace: true
});
// Process results
for (const result of results) {
console.log(`Score: ${result.similarity}`);
console.log(`Content: ${result.chunk.content}`);
console.log(`Document: ${result.document.filename}`);
console.log(`Space: ${result.space.name}`);
}Smart Query
Discover which spaces are most relevant for a query.
// Find relevant spaces
const { relevantSpaces } = await client.smartQuery({
query: 'How do I authenticate users?',
maxSpaces: 3
});
// Use different relevance methods
const { relevantSpaces } = await client.smartQuery({
query: 'authentication',
relevanceMethod: 'hybrid', // 'keyword', 'embedding', or 'hybrid'
keywordWeight: 0.5
});
// Full workflow: discover then query
const { relevantSpaces } = await client.smartQuery({
query: 'user authentication'
});
const { results } = await client.query({
spaceIds: relevantSpaces.map(s => s.space.id),
query: 'user authentication'
});Vercel AI SDK Integration
The SDK includes tools for the Vercel AI SDK v5+, allowing AI models to query your knowledge base.
Installation
# Install the SDK with AI SDK dependencies
npm install @orchata-ai/sdk ai zod
# Or with specific versions
npm install @orchata-ai/sdk ai@^5.0.0 zod@^3.22.0Note: The AI tools require
aiv5.0.0+ andzodv3.22.0+ as peer dependencies. These are optional - if you don't need AI SDK integration, you can use the core SDK without them.
Basic Usage
import { Orchata } from '@orchata-ai/sdk';
import { createOrchataTools } from '@orchata-ai/sdk/ai';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const client = new Orchata({ apiKey: 'oai_xxx' });
const tools = createOrchataTools(client);
const { text } = await generateText({
model: openai('gpt-4-turbo'),
tools,
prompt: 'What does our documentation say about authentication?'
});Available Tools
The createOrchataTools function creates these tools:
| Tool | Description |
|------|-------------|
| queryKnowledge | Search the knowledge base for relevant information |
| findRelevantSpaces | Discover which spaces are most relevant for a query |
| listSpaces | List all available knowledge spaces |
| getDocumentContent | Get the full content of a specific document |
| uploadDocument | Upload new content (disabled by default) |
| createSpace | Create a new space (disabled by default) |
Simple Query Tool
For simple use cases, use the createQueryTool helper:
import { Orchata } from '@orchata-ai/sdk';
import { createQueryTool } from '@orchata-ai/sdk/ai';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const client = new Orchata({ apiKey: 'oai_xxx' });
// Create a tool that queries a specific space
const queryTool = createQueryTool(client, 'space_123');
const { text } = await generateText({
model: openai('gpt-4-turbo'),
tools: { query: queryTool },
prompt: 'What is our refund policy?'
});Configuration Options
const tools = createOrchataTools(client, {
// Restrict which spaces the AI can access
allowedSpaceIds: ['space_123', 'space_456'],
// Default number of results (default: 5)
defaultTopK: 10,
// Enable document upload (default: false)
enableUpload: true,
// Enable space creation (default: false)
enableSpaceCreation: true,
});With Streaming
import { streamText } from 'ai';
const result = streamText({
model: openai('gpt-4-turbo'),
tools,
prompt: 'Summarize our API documentation'
});
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}Error Handling
The SDK throws typed errors for different scenarios:
import {
Orchata,
OrchataError,
AuthenticationError,
NotFoundError,
RateLimitError
} from '@orchata-ai/sdk';
try {
const { results } = await client.query({
spaceIds: 'space_123',
query: 'test'
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof NotFoundError) {
console.error('Space not found');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
} else if (error instanceof OrchataError) {
console.error(`API error: ${error.message} (${error.status})`);
} else {
throw error;
}
}Error Types
| Error | Status | Description |
|-------|--------|-------------|
| BadRequestError | 400 | Invalid request parameters |
| AuthenticationError | 401 | Missing or invalid API key |
| PermissionDeniedError | 403 | Insufficient permissions |
| NotFoundError | 404 | Resource not found |
| ConflictError | 409 | Resource conflict |
| UnprocessableEntityError | 422 | Validation error |
| RateLimitError | 429 | Too many requests |
| InternalServerError | 5xx | Server error |
| TimeoutError | - | Request timeout |
| ConnectionError | - | Network connectivity issue |
Configuration
const client = new Orchata({
// Required: Your API key
apiKey: 'oai_xxx',
// Optional: Custom base URL (default: https://api.orchata.ai)
baseUrl: 'https://api.orchata.ai',
// Optional: Request timeout in ms (default: 30000)
timeout: 30000,
// Optional: Custom fetch implementation
fetch: customFetch
});Runtime Support
| Runtime | Supported | Notes | |---------|-----------|-------| | Node.js 18+ | ✅ | Uses native fetch | | Node.js 16-17 | ⚠️ | Requires fetch polyfill | | Deno | ✅ | Full support | | Bun | ✅ | Full support | | Browsers | ✅ | Modern browsers | | Cloudflare Workers | ✅ | Full support |
TypeScript
The SDK is written in TypeScript and provides full type definitions:
import type {
Space,
Document,
QueryParams,
QueryResponse,
QueryResultItem
} from '@orchata-ai/sdk';
// Types are automatically inferred
const { spaces } = await client.spaces.list();
// ^? Space[]
const { results } = await client.query({ spaceIds: 'x', query: 'test' });
// ^? QueryResultItem[]Contributing
Contributions are welcome! Please read our Contributing Guide for details.
License
MIT License - see LICENSE for details.
