Official TypeScript SDK for MQL - AI Proxy Gateway with smart routing, A/B testing, feedback collection, prompt hub, and analytics
npm install @metriqual/sdkOfficial TypeScript/JavaScript SDK for MQL - The AI Proxy Gateway with smart routing, provider fallback, usage tracking, and content filtering.


- ๐ OpenAI-Compatible API - Drop-in replacement for OpenAI SDK
- ๐ Streaming Support - Real-time streaming with async iterators
- ๐ Automatic Fallback - Seamless provider switching when limits are reached
- ๐งช A/B Testing - Run experiments to compare model performance
- ๐ฌ Feedback Collection - Gather user ratings and improve responses
- ๐ก๏ธ Content Filtering - PII protection, profanity filtering, custom rules
- ๐ Usage Analytics - Track costs, tokens, and latency
- ๐ข Multi-tenancy - Organization support with role-based access
- ๐ฏ System Prompts - Behavioral control through prompt injection
``bash`
npm install @metriqual/sdkor
yarn add @metriqual/sdkor
pnpm add @metriqual/sdk
`typescript
import { MQL } from '@metriqual/sdk';
// Initialize with your proxy key
const mql = new MQL({ apiKey: 'mql-your-proxy-key' });
// Make a chat completion request
const response = await mql.chat.create({
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
});
console.log(response.choices[0].message.content);
`
`typescript
// Using async iterator
for await (const chunk of mql.chat.stream({
messages: [{ role: 'user', content: 'Tell me a story' }]
})) {
process.stdout.write(chunk.choices[0].delta.content || '');
}
// Or with callbacks
await mql.chat.stream(
{ messages: [{ role: 'user', content: 'Tell me a story' }] },
{
onChunk: (chunk) => process.stdout.write(chunk.choices[0].delta.content || ''),
onComplete: (fullText) => console.log('\n\nDone!'),
}
);
`
`typescript`
// Just get the text response
const reply = await mql.chat.complete([
{ role: 'user', content: 'What is 2+2?' }
]);
console.log(reply); // "4"
Run experiments to compare different models, configurations, or prompts:
`typescript
const mql = new MQL({ token: 'your-supabase-jwt' });
// Create an experiment
const experiment = await mql.experiments.create({
name: "GPT-4 vs Claude Comparison",
description: "Compare response quality and latency",
traffic_percentage: 0.5 // Route 50% of traffic
});
// Add variants to test
await mql.experiments.createVariant(experiment.id, {
name: "GPT-4 Variant",
weight: 0.5,
config: { model: "gpt-4o", temperature: 0.7 }
});
await mql.experiments.createVariant(experiment.id, {
name: "Claude Variant",
weight: 0.5,
config: { model: "claude-3-5-sonnet-20241022", temperature: 0.7 }
});
// Start the experiment
await mql.experiments.start(experiment.id);
// Get analytics to see which variant performs better
const analytics = await mql.experiments.getAnalytics(experiment.id);
analytics.variants.forEach(v => {
console.log(${v.variant_name}: ${v.summary.request_count} requests, ${v.summary.avg_latency_ms}ms avg);
});
// Complete when done
await mql.experiments.complete(experiment.id);
`
Collect user feedback to improve your LLM responses:
`typescript
const mql = new MQL({ token: 'your-supabase-jwt' });
// Submit feedback for a request
await mql.feedback.submit({
request_id: "req_123", // From chat completion response
rating: 5,
thumbs_up: true,
comment: "Very helpful and accurate!",
tags: ["accurate", "concise", "helpful"]
});
// Get feedback analytics
const feedbackAnalytics = await mql.feedback.getAnalytics({
start_date: '2025-01-01',
end_date: '2025-01-31'
});
console.log(Average rating: ${feedbackAnalytics.avg_rating});Thumbs up: ${feedbackAnalytics.thumbs_up_percentage}%
console.log();Total feedback: ${feedbackAnalytics.total_feedback}
console.log();
// View feedback by model
feedbackAnalytics.by_model.forEach(m => {
console.log(${m.model}: ${m.avg_rating}/5 rating, ${m.thumbs_up_percentage}% thumbs up);
});
// Export feedback data for analysis
const jsonlData = await mql.feedback.export({
format: 'jsonl',
start_date: '2025-01-01',
limit: 1000
});
// Or export as CSV
const csvData = await mql.feedback.export({
format: 'csv',
tags: ['production']
});
`
For management operations (proxy keys, filters, organizations), you'll need a Supabase JWT token:
`typescript`
const mql = new MQL({
token: 'your-supabase-jwt',
baseUrl: 'https://api.metriqual.com' // or your self-hosted URL
});
`typescript
// Create a proxy key with fallback chain
const { proxyKey, providers } = await mql.proxyKeys.create({
providers: [
{ provider: 'openai', model: 'gpt-4o-mini', apiKey: 'sk-...', usageLimit: 100 },
{ provider: 'anthropic', model: 'claude-3-haiku', apiKey: 'sk-ant-...', usageLimit: 50 },
],
filterIds: ['filter-id-1'],
systemPromptIds: ['prompt-id-1'],
});
console.log(Created key: ${proxyKey});
// List your proxy keys
const { keys } = await mql.proxyKeys.list();
keys.forEach(key => {
console.log(${key.keyPreview} - Active: ${key.activeProvider});
});
// Get usage details
const usage = await mql.proxyKeys.getUsage('key-id');
console.log(All providers exhausted: ${usage.allExhausted});
// Regenerate a key
const { proxyKey: newKey } = await mql.proxyKeys.regenerate('key-id');
`
`typescript
// Create a PII filter
const filter = await mql.filters.create({
name: 'Block PII',
filterType: 'PII',
action: 'BLOCK',
applyTo: 'BOTH',
config: { types: ['email', 'ssn', 'credit_card'] },
});
// Get templates
const { templates } = await mql.filters.getTemplates();
templates.forEach(t => console.log(${t.name}: ${t.description}));
// Create from template
const piiFilter = await mql.filters.createFromTemplate({
templateId: 'pii-redact-all',
name: 'My PII Filter',
});
// Test a filter
const result = await mql.filters.test({
filterType: 'PII',
action: 'REDACT',
config: { types: ['email'] },
testContent: 'Contact me at test@example.com',
});
console.log(result.resultContent); // "Contact me at [REDACTED]"
// Toggle filter
const toggled = await mql.filters.toggle('filter-id');
`
`typescript
// Create a system prompt
const prompt = await mql.systemPrompts.create({
name: 'Safety Guidelines',
content: 'Always prioritize user safety. Never provide harmful information.',
injectionMode: 'prepend',
priority: 0,
});
// Get templates
const { templates } = await mql.systemPrompts.getTemplates();
// Create from template
const assistant = await mql.systemPrompts.createFromTemplate('helpful-assistant', {
name: 'My Assistant',
});
// Update
await mql.systemPrompts.update('prompt-id', { priority: 1 });
`
`typescript
// Create organization
const org = await mql.organizations.create({
name: 'my-company',
displayName: 'My Company Inc.',
});
// List your organizations
const { organizations } = await mql.organizations.list();
// Invite members
await mql.organizations.inviteMember(org.id, {
email: 'colleague@company.com',
role: 'developer',
});
// List members
const members = await mql.organizations.listMembers(org.id);
// Check pending invites
const myInvites = await mql.organizations.getMyInvites();
// Accept an invite
await mql.organizations.acceptInvite({ token: 'invite-id' });
`
`typescriptTotal cost: $${overview.totalCost.toFixed(2)}
// Get overview
const overview = await mql.analytics.getOverview({
startDate: '2024-01-01',
endDate: '2024-01-31',
});
console.log();
// Get timeseries data
const timeseries = await mql.analytics.getTimeseries({
startDate: new Date('2024-01-01'),
});
// Get provider breakdown
const stats = await mql.analytics.getProviderStats();
stats.forEach(s => {
console.log(${s.provider}/${s.model}: ${s.requests} requests, $${s.cost});`
});
`typescript
import { MQL, MQLAPIError } from '@metriqual/sdk';
try {
const response = await mql.chat.create({ messages: [...] });
} catch (error) {
if (error instanceof MQLAPIError) {
console.error(API Error: ${error.message});Status: ${error.status}
console.error();Code: ${error.code}
console.error();`
} else {
throw error;
}
}
`typescript`
const mql = new MQL({
// Base URL (default: https://api.metriqual.com)
baseUrl: 'http://localhost:8080',
// Proxy key for chat completions
apiKey: 'mql-...',
// Supabase JWT for management APIs
token: 'eyJ...',
// Request timeout in ms (default: 30000)
timeout: 60000,
// Retry attempts for failed requests (default: 3)
maxRetries: 5,
// Custom fetch implementation (for Node.js < 18)
fetch: customFetch,
});
`typescript
// Start with management token
const mql = new MQL({ token: 'jwt-token' });
// Create a proxy key
const { proxyKey } = await mql.proxyKeys.create({ providers: [...] });
// Create a new client with the proxy key for chat
const chatClient = new MQL({ apiKey: proxyKey });
const response = await chatClient.chat.create({ messages: [...] });
`
The SDK is written in TypeScript and provides full type definitions:
`typescript`
import {
MQL,
ChatCompletionRequest,
ChatCompletionResponse,
CreateProxyKeyRequest,
Filter,
SystemPrompt,
Organization,
Experiment,
ExperimentVariant,
ExperimentAnalytics,
Feedback,
FeedbackAnalytics,
} from '@metriqual/sdk';
The SDK works in both Node.js and browser environments. For older browsers without native fetch, provide a polyfill:
`typescript
import fetch from 'node-fetch';
const mql = new MQL({
apiKey: 'mql-...',
fetch: fetch as unknown as typeof globalThis.fetch,
});
`
If you're running your own MQL instance:
`typescript``
const mql = new MQL({
baseUrl: 'https://your-mql-instance.com',
apiKey: 'mql-...',
});
MIT