@ai-universe/second-opinion-client
v2.1.1
Published
TypeScript client library for AI Universe MCP Server - Complete MCP tool access including multi-model consultation and conversation management
Downloads
75
Maintainers
Readme
@ai-universe/second-opinion-client
TypeScript/JavaScript client library for AI Universe MCP Server - Complete MCP tool access including multi-model consultation, conversation management, and authentication.
Features
- 🤖 Multi-Model Consultation - Get opinions from Cerebras, Claude, Gemini, Perplexity, OpenAI, and Grok
- 🔄 Intelligent Synthesis - AI-powered synthesis combining all model responses
- 💬 Full Conversation Management - Send messages, list conversations, get history, delete conversations
- 🔐 Firebase Authentication - Built-in authentication with Google sign-in
- 📊 Rate Limit Management - Check and monitor your rate limits
- 🏥 Health Checks - Server and conversation service health monitoring
- 🛡️ Type-Safe - Full TypeScript support with comprehensive types
- ⚡ Flexible - Works in Node.js, browsers, and edge runtimes
- 🎯 Simple API - Intuitive interface with sensible defaults
- 📋 Complete MCP Access - All backend MCP tools exposed via clean API
Installation
npm install @ai-universe/second-opinion-clientor
yarn add @ai-universe/second-opinion-clientor
pnpm add @ai-universe/second-opinion-clientQuick Start
Basic Usage (Anonymous)
import { SecondOpinionClient } from '@ai-universe/second-opinion-client';
// Create client
const client = new SecondOpinionClient();
// Ask a question
const response = await client.ask('What is machine learning?');
// Access primary model response
console.log(response.primary.response);
// Access secondary opinions
response.secondaryOpinions?.forEach((opinion) => {
console.log(`${opinion.modelDisplayName}: ${opinion.response}`);
});
// Access multi-model synthesis
console.log(response.synthesis?.response);Authenticated Usage (Higher Rate Limits)
import { SecondOpinionClient } from '@ai-universe/second-opinion-client';
// Create client with Firebase config (example uses AI Universe production config)
const client = new SecondOpinionClient({
firebaseConfig: {
apiKey: 'AIzaSyDWT4aEG2UoKEtTxozniGC6uPZi1fgjtG8',
authDomain: 'ai-universe-b3551.firebaseapp.com',
projectId: 'ai-universe-b3551',
},
});
// Sign in with Google
await client.signInWithGoogle();
// Now make requests with higher rate limits
const response = await client.ask('What is deep learning?');Follow-up Questions (Conversation Threading)
// First question
const response1 = await client.ask('What is quantum computing?');
// Follow-up question in same conversation
const response2 = await client.ask({
question: 'How does it differ from classical computing?',
conversationId: response1.conversationId,
});
// Get conversation history
const history = await client.getConversationHistory(response1.conversationId);API Reference
Constructor
new SecondOpinionClient(config?: SecondOpinionClientConfig)Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| baseUrl | string | https://ai-universe-backend-final.onrender.com | Base URL of the AI Universe backend |
| firebaseConfig | object | undefined | Firebase configuration for authentication |
| timeout | number | 120000 (2 minutes) | Request timeout in milliseconds |
| headers | object | {} | Custom headers to include in all requests |
| debug | boolean | false | Enable debug logging |
Methods
ask(questionOrOptions)
Ask a question and get multi-model second opinions.
Parameters:
questionOrOptions:string | SecondOpinionRequestOptions
Simple Usage:
const response = await client.ask('What is AI?');Advanced Usage:
const response = await client.ask({
question: 'What is neural network architecture?',
primaryModel: 'claude', // Choose primary model
secondaryModels: ['gemini', 'grok'], // Choose secondary models
maxOpinions: 2, // Number of secondary opinions (0-10)
conversationId: 'abc123', // For follow-up questions
userId: 'user-123', // Optional user ID
});Request Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| question | string | required | The question to ask (max 320,000 chars) |
| primaryModel | PrimaryModelName | 'cerebras' | Primary model to use |
| secondaryModels | SecondaryModelName[] | Auto-selected | Secondary models to consult |
| maxOpinions | number | 4 | Number of secondary opinions (0-10) |
| conversationId | string | Auto-generated | Conversation ID for follow-ups |
| userId | string | Auto-generated | User ID for tracking |
| sessionId | string | undefined | Session ID for grouping |
Available Models:
- Primary Models:
cerebras,grok,claude,gemini,perplexity,openai - Secondary Models:
gemini,perplexity,openai,grok,cerebras
Response:
interface SecondOpinionResponse {
// Core response data
primary: ModelOpinion;
secondaryOpinions?: ModelOpinion[];
synthesis: Synthesis | null;
// Conversation tracking
conversationId: string;
conversationCreated?: boolean;
conversationTitle?: string | null;
// Summary statistics
summary?: {
totalModels: number;
totalTokens: number;
totalCost: number;
totalLatencyMs: number;
};
// Latency breakdown
latency?: {
totalMs: number;
primary?: number;
secondary?: number;
synthesis?: number;
};
// Additional metadata
metadata?: object;
persistenceStatus?: object;
thinkingLog?: Array<object>;
}Model Opinion Structure:
interface ModelOpinion {
model: string; // Model name
modelDisplayName?: string; // Human-readable name
response: string; // Model's response
tokensUsed?: number; // Tokens consumed
latencyMs?: number; // Response time
cost?: number; // API cost
citations?: CitationSource[]; // Search citations (Perplexity)
error?: boolean; // Error flag
}Authentication Methods
signInWithGoogle()
Sign in with Google using Firebase Authentication.
const authState = await client.signInWithGoogle();
console.log('User:', authState.user?.displayName);signOut()
Sign out the current user.
await client.signOut();getAuthState()
Get current authentication state.
const authState = await client.getAuthState();
if (authState.isAuthenticated) {
console.log('User:', authState.user?.email);
console.log('Token expires:', new Date(authState.expiresAt!));
}isAuthenticated()
Check if user is currently authenticated.
if (client.isAuthenticated()) {
console.log('User is signed in');
}onAuthStateChange(callback)
Listen to authentication state changes.
const unsubscribe = client.onAuthStateChange((state) => {
console.log('Auth state changed:', state.isAuthenticated);
});
// Later, stop listening
unsubscribe();Conversation Methods
getConversationHistory(conversationId)
Get all messages in a conversation.
const history = await client.getConversationHistory('conversation-id');
history.forEach((message) => {
console.log(`${message.role}: ${message.content}`);
});listConversations(userId?)
List user's conversations.
const conversations = await client.listConversations();
conversations.forEach((conv) => {
console.log(`${conv.title} - ${conv.messageCount} messages`);
});sendMessage(options)
Send a message to a conversation.
const response = await client.sendMessage({
content: 'Hello, world!',
conversationId: 'conv-123', // Optional, auto-creates if omitted
role: 'user', // Optional, defaults to 'user'
title: 'My Conversation', // Optional
metadata: { source: 'web' }, // Optional
});
console.log('Message ID:', response.message.id);
console.log('Assistant reply:', response.assistantMessage?.content);deleteConversation(conversationId, userId)
Delete a conversation.
await client.deleteConversation('conversation-id', 'user-id');conversationHealth()
Check conversation service health.
const health = await client.conversationHealth();
console.log('Status:', health.status); // 'healthy' or 'unhealthy'Authentication & Rate Limiting
getFirebaseInfo()
Get Firebase authentication setup instructions.
const info = await client.getFirebaseInfo();
console.log('Instructions:', info.instructions);
console.log('Config:', info.config);getRateLimitStatus()
Get current rate limit status (requires authentication).
// Must be authenticated first
await client.signInWithGoogle();
const status = await client.getRateLimitStatus();
console.log('Limit:', status.limit);
console.log('Remaining:', status.remaining);
console.log('Resets at:', new Date(status.resetTime));Server Health
getServerHealth()
Get MCP server health status (includes all tools).
const health = await client.getServerHealth();
console.log('Server status:', health.status);
console.log('Version:', health.version);
console.log('Services:', health.services);checkHealth()
Check HTTP server health (simple health check endpoint).
const health = await client.checkHealth();
console.log('Status:', health.status); // 'healthy' or 'unhealthy'Usage Examples
Example 1: Simple Question
const client = new SecondOpinionClient();
const response = await client.ask('What is machine learning?');
console.log('Primary:', response.primary.response);
console.log('Synthesis:', response.synthesis?.response);Example 2: Custom Model Selection
const response = await client.ask({
question: 'What are the latest AI trends?',
primaryModel: 'perplexity', // Good for recent info
secondaryModels: ['claude', 'gemini'],
maxOpinions: 2,
});Example 3: Primary-Only Mode (No Synthesis)
const response = await client.ask({
question: 'Quick factual question',
maxOpinions: 0, // Skip secondary opinions and synthesis
});
// Only response.primary will be populatedExample 4: Multi-Turn Conversation
// Start conversation
const r1 = await client.ask('What is blockchain?');
// Follow-up questions
const r2 = await client.ask({
question: 'How does it ensure security?',
conversationId: r1.conversationId,
});
const r3 = await client.ask({
question: 'What are practical applications?',
conversationId: r1.conversationId,
});
// Get full history
const history = await client.getConversationHistory(r1.conversationId);Example 5: Error Handling
import {
SecondOpinionClient,
ValidationError,
RateLimitError,
NetworkError,
TimeoutError,
} from '@ai-universe/second-opinion-client';
const client = new SecondOpinionClient();
try {
const response = await client.ask('What is AI?');
} catch (error) {
if (error instanceof ValidationError) {
console.error('Invalid request:', error.message);
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded. Retry after:', error.retryAfter);
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
} else if (error instanceof TimeoutError) {
console.error('Request timed out');
} else {
console.error('Unknown error:', error);
}
}Example 6: Custom Configuration
const client = new SecondOpinionClient({
baseUrl: 'http://localhost:2000', // Local development
timeout: 60000, // 1 minute timeout
debug: true, // Enable debug logs
headers: {
'X-Custom-Header': 'value',
},
});Example 7: Accessing Citations (Perplexity)
const response = await client.ask({
question: 'What are recent breakthroughs in AI?',
primaryModel: 'perplexity', // Includes citations
});
response.primary.citations?.forEach((citation) => {
console.log(`${citation.title}: ${citation.url}`);
});Rate Limits
| User Type | Rate Limit | |-----------|------------| | Anonymous | 10 requests / 5 minutes | | Authenticated | 50 requests / 5 minutes | | Admin | 1000 requests / 5 minutes |
Recommendation: Use authentication for production applications to get higher rate limits.
Error Types
| Error Class | Description |
|-------------|-------------|
| ValidationError | Request validation failed (empty question, invalid params, etc.) |
| RateLimitError | Rate limit exceeded (includes retryAfter in seconds) |
| AuthenticationError | Firebase authentication failed |
| NetworkError | Network request failed |
| TimeoutError | Request exceeded timeout limit |
| ApiError | API returned error response (includes status code) |
| SecondOpinionClientError | Base error class for all client errors |
TypeScript Support
This library is written in TypeScript and provides full type definitions.
import type {
SecondOpinionResponse,
ModelOpinion,
Synthesis,
CitationSource,
AuthState,
Conversation,
} from '@ai-universe/second-opinion-client';Browser Support
This library works in modern browsers with ES2020+ support. For older browsers, use a transpiler like Babel.
Note: Firebase Authentication requires browser environment for Google sign-in popup.
Node.js Support
Requires Node.js 18 or later.
Note: Firebase Authentication in Node.js requires additional setup for OAuth flow. Consider using the CLI authentication tool from the main AI Universe repository for server-side usage.
Environment Variables (Optional)
For authenticated usage examples:
export AI_UNIVERSE_FIREBASE_API_KEY="your-api-key"
export AI_UNIVERSE_FIREBASE_AUTH_DOMAIN="your-auth-domain"
export AI_UNIVERSE_FIREBASE_PROJECT_ID="your-project-id"Development
Build
npm run buildTest
npm testLint
npm run lintClean
npm run cleanExamples
See the examples/ directory for complete working examples:
basic-usage.ts- Anonymous usage examplesauthenticated-usage.ts- Firebase authentication examples
License
MIT
Support
For issues and questions:
- GitHub Issues: https://github.com/your-org/ai-universe
- Documentation: https://docs.ai-universe.dev
Credits
Built by the AI Universe Team with ❤️
