@natyapp/langchain
v1.1.0
Published
TypeScript client for Naty LangChain API with Chat, File Upload, and Streaming support
Downloads
656
Readme
Naty LangChain Client
TypeScript client for the Naty LangChain API - Updated for OpenAPI 3.1.0 specification with full support for RAG, Chat, and File Upload features.
🚀 New Features
- Chat API with Streaming: Professional chat with hybrid RAG (history + vector search)
- File Upload APIs: Upload and process Excel, PDF, Word, and CSV files
- Health Check: Monitor system status and dependencies
- Enhanced Types: Comprehensive TypeScript interfaces for all endpoints
- Streaming Support: Real-time responses with Server-Sent Events (SSE)
Installation
npm install @natyapp/langchain
# or
yarn add @natyapp/langchainQuick Start
Initialize Client
import { NatyLangChainClient } from '@natyapp/langchain';
const client = new NatyLangChainClient({
baseURL: 'http://localhost:8000',
apiKey: 'nlck-key_prod_1', // X-API-Key authentication
tenantId: 'demo-tenant', // X-Tenant-ID header (for multi-tenancy)
requestId: 'custom-request-id', // Optional: Custom X-Request-ID
});Basic QA
const response = await client.qa.ask({
question: 'Como funciona o RAG?',
k: 3,
});
console.log(response.answer);💬 Chat API with Streaming
Professional Chat with Hybrid RAG
import { ChatMessage, ChatQARequest } from '@natyapp/langchain';
const chatHistory: ChatMessage[] = [
{ role: 'user', content: 'Olá!' },
{ role: 'assistant', content: 'Oi! Como posso ajudá-lo?' }
];
const request: ChatQARequest = {
question: 'Como funciona o sistema de RAG?',
system_prompt: 'Você é um especialista em IA',
chat_history: chatHistory,
rag_enabled: true,
k: 5,
max_history_messages: 10,
strict_context: true,
include_metadata: false
};
// Non-streaming response (NEW)
const response = await client.chat.chat(request);
console.log(response.answer);
console.log(`Used ${response.rag_documents_used} documents`);
// Streaming response
const stream = await client.chat.stream(request);
const reader = stream.getReader();
// Or use async iterator
for await (const chunk of client.chat.streamIterator(request)) {
if (chunk.type === 'content') {
console.log(chunk.data.text);
}
}📁 File Upload APIs
Upload Excel Files
import { ExcelUploadOptions } from '@natyapp/langchain';
const files = [excelFile1, excelFile2]; // File objects
const options: ExcelUploadOptions = {
chunk_size: 1000,
text_format: 'structured',
include_sheets: 'Sheet1,Sheet2',
max_rows: 1000
};
const result = await client.fileUpload.uploadExcel(files, options);
console.log(`Processed ${result.sheets_processed.length} sheets`);Preview Excel Content
const preview = await client.fileUpload.previewExcel(excelFile, {
max_rows: 10,
text_format: 'csv'
});Upload PDF Files
import { PDFUploadOptions } from '@natyapp/langchain';
const options: PDFUploadOptions = {
extract_by_page: true,
chunk_size: 800,
page_range_start: 1,
page_range_end: 10
};
const result = await client.fileUpload.uploadPDF(pdfFiles, options);Upload Word Documents
import { WordUploadOptions } from '@natyapp/langchain';
const options: WordUploadOptions = {
extract_by_paragraph: false,
include_tables: true,
include_headers_footers: true,
preserve_formatting: false
};
const result = await client.fileUpload.uploadWord(wordFiles, options);Upload CSV Files
import { CSVUploadOptions } from '@natyapp/langchain';
const options: CSVUploadOptions = {
delimiter: ',',
encoding: 'utf-8',
output_format: 'structured',
row_chunk_size: 100,
skip_empty_rows: true
};
const result = await client.fileUpload.uploadCSV(csvFiles, options);🏥 Health Check
const health = await client.health.check();
console.log(`Status: ${health.status}`);
console.log(`Checks:`, health.checks);⚡ Custom QA with Streaming
import { CustomQAStreamRequest } from '@natyapp/langchain';
const request: CustomQAStreamRequest = {
system_prompt: 'Responda como especialista técnico',
question: 'Explique machine learning',
contexts_text: 'Machine Learning é...', // Optional explicit context
strict_context: true,
k: 4
};
const stream = await client.customQA.stream(request);
// Process streaming response...Backward Compatibility
import { NatyClient } from '@natyapp/langchain';
// Legacy client still works (shows deprecation warning)
const legacyClient = new NatyClient({
baseURL: 'http://localhost:8000',
token: 'legacy-token', // Will be used as X-API-Key
tenantId: 'demo-tenant',
});cURL Equivalent
The following client usage:
const client = new NatyLangChainClient({
baseURL: 'http://localhost:8000',
apiKey: 'nlck-key_prod_1',
tenantId: 'demo-tenant',
requestId: 'demo-request-id',
});
await client.qa.ask({ question: 'Olá?', k: 3 });Is equivalent to this cURL command:
curl -X POST http://localhost:8000/v1/qa \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: demo-tenant" \
-H "X-API-Key: nlck-key_prod_1" \
-H "X-Request-ID: demo-request-id" \
-d '{"question": "Olá?", "k": 3}'API Reference
Configuration
interface NatyLangChainClientConfig {
baseURL: string;
apiKey?: string; // API key for X-API-Key header
tenantId?: string; // Tenant ID for X-Tenant-ID header
requestId?: string; // Custom request ID (auto-generated if not provided)
}
// Backward compatibility
interface NatyClientConfig extends NatyLangChainClientConfig {
token?: string; // Legacy token (deprecated, use apiKey)
}Authentication & Headers
The client automatically manages the following headers:
Content-Type: application/json- Always includedX-API-Key- API key authentication (replaces Bearer tokens)X-Tenant-ID- Multi-tenant support (when tenantId provided)X-Request-ID- Request tracking (auto-generated UUID if not provided)
Available APIs
QA API
// Simple QA request
const qaResponse = await client.qa.ask({
question: 'What is LangChain?',
k: 4, // Optional: number of documents to retrieve
filters: { // Optional: vector store filters
category: { $eq: 'tech' }
}
});
// Override tenant ID per request
const response = await client.qa.ask(request, 'different-tenant-id');Custom QA API
// Custom QA with system prompt
const customResponse = await client.customQA.ask({
system_prompt: 'You are a helpful assistant that responds in Portuguese.',
question: 'Como posso ajudar você hoje?',
contexts_text: 'Optional explicit context', // Optional
filters: { tenant_id: { $eq: 'demo-tenant' } }, // Optional
k: 4, // Optional
strict_context: true, // Optional
});
// Streaming custom QA
const stream = await client.customQA.stream({
system_prompt: 'You are a helpful assistant.',
question: 'Tell me about AI',
strict_context: false,
});
// Process stream
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(new TextDecoder().decode(value));
}Documents API
// Create documents
const createResponse = await client.documents.create([
{
text: 'Document content here',
metadata: {
title: 'Document Title',
category: 'technology',
source: 'internal',
},
},
]);
// Create documents in batch (async operation)
const batchResponse = await client.documents.createBatch([...documents]);
// List documents
const listResponse = await client.documents.list();
// Search documents
const searchResponse = await client.documents.search({
query: 'search term',
filters: { category: { $eq: 'technology' } },
k: 5,
});
// Delete documents by IDs
const deleteResponse = await client.documents.delete(['doc-id-1', 'doc-id-2']);Error Handling
The client uses enhanced error handling with NatyLangChainError:
import { NatyLangChainError } from '@natyapp/langchain';
try {
const response = await client.qa.ask({ question: 'Test' });
} catch (error) {
if (error instanceof NatyLangChainError) {
console.error('API Error:', error.message);
console.error('Status:', error.status); // HTTP status code
console.error('Code:', error.code); // Error code
console.error('Details:', error.details); // Additional error details
} else {
console.error('Unknown error:', error);
}
}Logging
The client automatically logs request headers (with API key masking for security):
// Example log output:
// Request headers: {
// 'X-Tenant-ID': 'demo-tenant',
// 'X-Request-ID': 'a90e-fb3b-4931-8dc4-51cc8adabf4e',
// 'X-API-Key': 'nlck...od_1' // Masked for security
// }Utility Functions
import { generateRequestId, maskApiKey } from '@natyapp/langchain';
// Generate UUID-like request ID
const requestId = generateRequestId();
console.log(requestId); // "a90e-fb3b-4931-8dc4-51cc8adabf4e"
// Mask API key for logging
const maskedKey = maskApiKey('nlck-key_prod_1234567890');
console.log(maskedKey); // "nlck...7890"Migration Guide
From v1.x to v2.x
Update client initialization:
// Old const client = new NatyClient({ baseURL: 'http://localhost:8000', token: 'bearer-token', tenantId: 'tenant-id', }); // New const client = new NatyLangChainClient({ baseURL: 'http://localhost:8000', apiKey: 'nlck-key_prod_1', // Changed from token tenantId: 'tenant-id', });Update API URLs:
- Documents:
/documents→/v1/documents - QA:
/v1/qa(unchanged) - Custom QA:
/v1/qa/custom(unchanged)
- Documents:
Remove query parameters:
- No longer need to pass
llm,embeddings,retrieverquery parameters - These are now handled by the API internally
- No longer need to pass
Update error handling:
// Old catch (error) { console.error(error.message); } // New catch (error) { if (error instanceof NatyLangChainError) { console.error('Status:', error.status); console.error('Code:', error.code); console.error('Message:', error.message); } }
Development
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Run integration tests only
npm test -- tests/integration.test.ts
# Lint
npm run lint
# Format code
npm run formatExamples
See the examples/ directory for complete usage examples:
examples/usage-example.ts- Comprehensive usage demonstration
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT License
