npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@metriqual/sdk

v0.5.0

Published

Official TypeScript SDK for MQL - AI Proxy Gateway with smart routing, usage tracking, and content filtering

Downloads

625

Readme

@metriqual/sdk

Official TypeScript/JavaScript SDK for MQL - The AI Proxy Gateway with smart routing, provider fallback, usage tracking, and content filtering.

npm version TypeScript

Features

  • 🔄 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
  • 🛡️ 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

Installation

npm install @metriqual/sdk
# or
yarn add @metriqual/sdk
# or
pnpm add @metriqual/sdk

Quick Start

Chat Completions

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);

Streaming

// 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!'),
  }
);

Simple Completion Helper

// Just get the text response
const reply = await mql.chat.complete([
  { role: 'user', content: 'What is 2+2?' }
]);
console.log(reply); // "4"

Management APIs

For management operations (proxy keys, filters, organizations), you'll need a Supabase JWT token:

const mql = new MQL({ 
  token: 'your-supabase-jwt',
  baseUrl: 'https://api.metriqual.com' // or your self-hosted URL
});

Proxy Keys

// 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');

Content Filters

// 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 [email protected]',
});
console.log(result.resultContent); // "Contact me at [REDACTED]"

// Toggle filter
const toggled = await mql.filters.toggle('filter-id');

System Prompts

// 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 });

Organizations

// 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: '[email protected]',
  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' });

Analytics

// Get overview
const overview = await mql.analytics.getOverview({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
});
console.log(`Total cost: $${overview.totalCost.toFixed(2)}`);

// 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}`);
});

Error Handling

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}`);
    console.error(`Status: ${error.status}`);
    console.error(`Code: ${error.code}`);
  } else {
    throw error;
  }
}

Configuration

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,
});

Switching Authentication

// 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: [...] });

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import { 
  MQL,
  ChatCompletionRequest,
  ChatCompletionResponse,
  CreateProxyKeyRequest,
  Filter,
  SystemPrompt,
  Organization,
} from '@metriqual/sdk';

Browser Support

The SDK works in both Node.js and browser environments. For older browsers without native fetch, provide a polyfill:

import fetch from 'node-fetch';

const mql = new MQL({
  apiKey: 'mql-...',
  fetch: fetch as unknown as typeof globalThis.fetch,
});

Self-Hosted Deployment

If you're running your own MQL instance:

const mql = new MQL({
  baseUrl: 'https://your-mql-instance.com',
  apiKey: 'mql-...',
});

License

MIT

Links