@shinrag/sdk
v0.6.0
Published
Official SDK for ShinRAG - Enterprise RAG Platform
Downloads
16
Maintainers
Readme
@shinrag/sdk
Official TypeScript/JavaScript SDK for the ShinRAG Enterprise RAG Platform. Provides full API coverage for agents, pipelines, indexes, integrations, widgets, usage/billing, cost tracking, and more.
Installation
npm install @shinrag/sdk
# or
pnpm add @shinrag/sdk
# or
yarn add @shinrag/sdkRequirements: Node.js 18+ (uses native fetch). No runtime dependencies.
Quick Start
import { ShinRAGClient } from '@shinrag/sdk';
const client = new ShinRAGClient({
apiKey: 'sk_your_api_key_here',
organizationId: 'org_123', // Optional: for org-scoped resources
});
// Query a pipeline
const result = await client.executePipeline('pipeline-id', {
input: 'What are the key features mentioned in the documentation?',
});
console.log(result.output);
console.log('Tokens used:', result.totalTokensUsed);
// Query an agent
const agentResult = await client.queryAgent('agent-id', {
question: 'What are the key features?',
maxResults: 5,
});
console.log(agentResult.answer);
console.log('Sources:', agentResult.sources);
// Search an index
const indexResult = await client.queryIndex({
indexId: 'index-id',
queryText: 'What are the key features?',
limit: 10,
});
console.log(indexResult.results);API Reference
ShinRAGClient
The main client class for interacting with the ShinRAG API.
Constructor
new ShinRAGClient(config: ShinRAGClientConfig)Parameters:
config.apiKey(string, required): Your API key (must start withsk_)config.baseUrl(string, optional): Base URL for the API (defaults tohttps://api.shinrag.com/v1)config.organizationId(string, optional): Organization ID for accessing org-scoped resources
Agents
// List all agents
const agents = await client.listAgents();
// Get a specific agent
const agent = await client.getAgent('agent-id');
// Create an agent
const newAgent = await client.createAgent({
name: 'My Agent',
description: 'A helpful assistant',
provider: 'openai',
model: 'gpt-4o',
indexIds: ['index-id'],
});
// Update an agent
const updated = await client.updateAgent('agent-id', { name: 'Updated Name' });
// Delete an agent
await client.deleteAgent('agent-id');
// Query an agent (RAG)
const answer = await client.queryAgent('agent-id', {
question: 'How do I reset my password?',
maxResults: 5, // optional
temperature: 0.7, // optional
maxTokens: 1000, // optional
});QueryAgentResponse:
{
answer: string | null;
sources: Array<{ dataset?: string; index?: string; score: number; text: string }>;
tokensUsed: number;
model: string;
warning?: string;
diagnostic?: { totalResultsFound: number; threshold: number | null; topScores: number[] };
}Pipelines
// List all pipelines
const pipelines = await client.listPipelines();
// Get a specific pipeline
const pipeline = await client.getPipeline('pipeline-id');
// Execute a pipeline
const result = await client.executePipeline('pipeline-id', {
input: 'What is the return policy?',
});
// Or use the convenience alias:
const result2 = await client.queryPipeline('pipeline-id', {
input: 'What is the return policy?',
});
// Get execution status
const status = await client.getPipelineExecutionStatus('pipeline-id', 'execution-id');
// Get execution details
const execution = await client.getPipelineExecution('pipeline-id', 'execution-id');
// List executions with pagination
const executions = await client.getPipelineExecutions('pipeline-id', {
cursor: undefined,
limit: 20,
});ExecutePipelineResponse:
{
executionId: string;
status: string;
output?: string;
outputs?: Array<{ nodeId: string; label?: string; output: string }>;
error?: string;
nodeResults: Array<{ nodeId: string; status: string; output?: string; tokensUsed: number; warning?: string }>;
totalTokensUsed: number;
}Indexes
// List all indexes
const indexes = await client.listIndexes();
// Get a specific index
const index = await client.getIndex('index-id');
// Create an index
import { PineconeEmbeddingModel } from '@shinrag/sdk';
const newIndex = await client.createIndex({
name: 'My Index',
pineconeIndexName: 'my-pinecone-index',
embeddingModel: PineconeEmbeddingModel.OPENAI_SMALL,
metric: 'cosine', // optional: 'cosine' | 'euclidean' | 'dotproduct'
});
// Query an index (semantic search)
const results = await client.queryIndex({
indexId: 'index-id',
queryText: 'authentication',
limit: 10,
filter: { category: 'docs' }, // optional metadata filter
});
// Or use the convenience alias:
const results2 = await client.searchIndex({
indexId: 'index-id',
queryText: 'authentication',
});
// Get records with pagination
const records = await client.getIndexRecords('index-id', {
limit: 50,
paginationToken: 'token',
prefix: 'doc_',
});
// Update records
await client.updateIndexRecords('index-id', {
records: [
{ id: 'rec_1', metadata: { text: 'Updated content' } },
{ id: 'rec_2', metadata: { text: 'New content' }, isNew: true },
{ id: 'rec_3', metadata: {}, isDeleted: true },
],
});
// Check ingestion job status
const job = await client.getIngestionStatus('job-id');Integrations
// List all integrations
const integrations = await client.listIntegrations();
// Get integration types and categories
const types = await client.getIntegrationTypes();
const byCategory = await client.getIntegrationTypesByCategory();
// Create an integration (e.g., PostgreSQL)
const integration = await client.createIntegration({
type: 'postgres',
name: 'My Database',
credentials: { host: 'localhost', port: 5432, database: 'mydb', user: 'user', password: 'pass' },
validateCredentials: true,
});
// Test an integration
const testResult = await client.testIntegration('integration-id');
// Execute an integration
const execResult = await client.executeIntegration('integration-id', {
config: { query: 'SELECT * FROM users LIMIT 10' },
input: 'Fetch user data',
});
// Slack OAuth flow
const { url } = await client.getSlackAuthUrl();
// Redirect user to url, then on callback:
const slackIntegration = await client.completeSlackOAuth(code);
const { channels } = await client.refreshSlackChannels('integration-id');
// GitHub OAuth flow
const { url: ghUrl } = await client.getGitHubAuthUrl();
const ghIntegration = await client.completeGitHubOAuth(code);
const { repositories } = await client.refreshGitHubRepositories('integration-id');
const { issues } = await client.getGitHubIssues('integration-id', 'owner', 'repo', 'open');
const { pullRequests } = await client.getGitHubPullRequests('integration-id', 'owner', 'repo');Supported integration types: slack, discord, webhook, github, postgres, mysql, mongodb, snowflake, bigquery, perplexity, tavily, http
Widgets
// Manage widgets (authenticated)
const widgets = await client.listWidgets();
const widget = await client.createWidget({ name: 'Support Chat', agentId: 'agent-id' });
await client.updateWidget('widget-id', { isActive: false });
await client.deleteWidget('widget-id');
// Public widget endpoints (can be used without API key auth)
const widgetInfo = await client.getWidgetByKey('widget-key');
const response = await client.queryWidget('widget-key', {
question: 'How do I get started?',
sessionId: 'session_123', // optional: for conversation continuity
});
const history = await client.getWidgetSessionHistory('widget-key', 'session_123');API Keys
const keys = await client.listApiKeys();
const newKey = await client.createApiKey({ name: 'Production Key' });
console.log(newKey.key); // sk_... (only shown once!)
await client.deleteApiKey('key-id');Usage & Billing
const usage = await client.getUsage();
const pricing = await client.getV2Pricing();
const usageSummary = await client.getV2UsageSummary();
const cacheStatus = await client.getV2CacheStatus();
// Checkout for upgrading tier
const { checkoutUrl } = await client.createV2Checkout({
tier: 'developer',
successUrl: 'https://myapp.com/success',
cancelUrl: 'https://myapp.com/cancel',
});
// Downgrade management
const downgradeStatus = await client.getV2DowngradeStatus();
await client.scheduleV2Downgrade('sandbox');
await client.cancelV2PendingDowngrade();
// Cancel subscription
await client.cancelV2Subscription();Cost Tracking
const summary = await client.getCostSummary(30); // last 30 days
const pipelineCosts = await client.getPipelineCosts(7); // last 7 days
const trend = await client.getCostTrend(30); // daily breakdown
const execCost = await client.getExecutionCost('execution-id');
const rates = await client.getCostRates();Batch Execution
const batch = await client.createBatch('pipeline-id', {
inputs: ['Question 1', 'Question 2', 'Question 3'],
name: 'Test Batch',
});
// Poll for completion
let status = await client.getBatchStatus(batch.batchId);
while (status.status === 'pending' || status.status === 'processing') {
await new Promise(r => setTimeout(r, 2000));
status = await client.getBatchStatus(batch.batchId);
}
console.log('Batch complete:', status.results);Webhooks
const webhooks = await client.listWebhooks('pipeline-id');
const webhook = await client.createWebhook('pipeline-id', {
name: 'My Webhook',
description: 'Triggers on incoming data',
secretToken: 'my-secret', // optional
inputMapping: '{{body.query}}', // optional
});
await client.deleteWebhook('pipeline-id', 'webhook-id');Schedules
const schedules = await client.listSchedules('pipeline-id');
const schedule = await client.createSchedule('pipeline-id', {
name: 'Daily Report',
cronExpression: '0 9 * * *', // Every day at 9 AM
inputTemplate: 'Generate daily summary',
timezone: 'America/New_York', // optional
});
await client.deleteSchedule('pipeline-id', 'schedule-id');Templates
const templates = await client.listTemplates('pipeline-id');
const template = await client.createTemplate('pipeline-id', {
name: 'FAQ Template',
inputTemplate: 'Answer the following FAQ: {{question}}',
});Execution History
const history = await client.getExecutionHistory('pipeline-id', {
limit: 20,
status: 'completed', // optional: 'pending' | 'running' | 'completed' | 'failed'
source: 'api', // optional: 'manual' | 'api' | 'schedule' | 'webhook' | 'batch'
cursor: 'next-page-cursor', // optional: for pagination
});
const detail = await client.getExecution('execution-id');Support
const issue = await client.createIssue({
title: 'Bug: Pipeline fails on large input',
description: 'When input exceeds 10k chars...',
issueType: 'bug',
});Advanced: Custom Authentication
The SDK exports BaseApiClient for use with custom authentication (e.g., JWT in the frontend):
import { BaseApiClient } from '@shinrag/sdk/core';
const client = new BaseApiClient({
baseUrl: 'http://localhost:1337',
headers: { 'Authorization': `Bearer ${jwtToken}` },
organizationId: 'org_123',
});
// All the same API methods are available
const agents = await client.listAgents();Error Handling
The SDK throws ShinRAGError for API errors:
import { ShinRAGClient, ShinRAGError } from '@shinrag/sdk';
try {
const result = await client.executePipeline('pipeline-id', {
input: 'Your query here',
});
} catch (error) {
if (error instanceof ShinRAGError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Response:', error.response);
} else {
console.error('Unknown error:', error);
}
}Type Exports
All types are available as named exports:
import type {
Agent, CreateAgentRequest, QueryAgentRequest, QueryAgentResponse,
Pipeline, ExecutePipelineRequest, ExecutePipelineResponse,
IndexMetadata, QueryIndexOptions, QueryIndexResponse,
Integration, IntegrationType, IntegrationCategory,
Widget, QueryWidgetRequest, QueryWidgetResponse,
V2Tier, V2UsageSummary, CostSummary,
ShinRAGClientConfig, RequestConfig,
// ... and many more
} from '@shinrag/sdk';
// Enum (value import, not type-only)
import { PineconeEmbeddingModel, ShinRAGError } from '@shinrag/sdk';Development
For local development, point to your local API:
const client = new ShinRAGClient({
apiKey: 'sk_your_api_key_here',
baseUrl: 'http://localhost:1337',
});Run the example test suite:
cd apps/example
cp .env.example .env # Set your API key
npx tsx index.ts --allLicense
MIT
