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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hazeljs/ai

v1.0.6

Published

AI integration module for HazelJS framework

Downloads

1,443

Readme

@hazeljs/ai

Add AI to your API in minutes — not days.

Part of the HazelJS AI-Native Backend Framework. OpenAI, Anthropic, Gemini, Cohere, Ollama. Decorators for quick tasks and HCEL for fluent orchestration. Streaming, caching, retries, and type-safe outputs. Ship AI features without the glue code.

🚀 Trusted by 200K+ monthly downloads • 37+ GitHub stars • 15+ daily active developers

npm version npm downloads License: Apache-2.0

Why @hazeljs/ai?

Built for AI-native applications - not just another AI integration. When you combine @hazeljs/ai with @hazeljs/core, @hazeljs/agent, and @hazeljs/rag, you get a complete stack for intelligent backends.

Perfect for:

  • AI startups adding chat/completion features
  • Teams building AI-powered APIs without complexity
  • Developers who want decorator-based AI integration
  • Projects needing multiple AI providers in one interface

Features

  • HCEL Orchestration - Fluent chains for prompts, RAG, agents, ML, and observability
  • 🤖 Multiple Providers - OpenAI, Anthropic, Gemini, Cohere, Ollama
  • 🎨 Decorator-Based API - @AITask decorator for clean integration
  • 📡 Streaming Support - Real-time response streaming
  • 🔄 Retry Logic - Automatic retries with exponential backoff
  • 💾 Response Caching - Built-in caching with @hazeljs/cache
  • 🎯 Type Safety - Full TypeScript support with output types
  • 🔧 Flexible Configuration - Per-task or global configuration
  • 📊 Token Tracking - Monitor usage and costs

Installation

npm install @hazeljs/ai

Provider API keys

Provider SDKs are bundled with @hazeljs/ai. Set the API key for the provider you use:

# OpenAI (default)
export OPENAI_API_KEY=sk-...

# Anthropic
export ANTHROPIC_API_KEY=sk-ant-...

# Google Gemini
export GEMINI_API_KEY=...

# Cohere
export COHERE_API_KEY=...

# Ollama (local — no npm package; HTTP API)
export OLLAMA_ENABLED=true
export OLLAMA_BASE_URL=http://localhost:11434

Quick Start

Basic Usage with Decorator

import { Injectable } from '@hazeljs/core';
import { AIEnhancedService, AITask } from '@hazeljs/ai';

@Injectable()
export class ChatService {
  constructor(public aiService: AIEnhancedService) {}

  @AITask({
    name: 'chat',
    prompt: 'You are a helpful assistant. Respond to: {{input}}',
    provider: 'openai',
    model: 'gpt-4',
    outputType: 'string',
  })
  async chat(message: string): Promise<string> {
    return message; // Decorator handles AI execution
  }
}

// Usage
const response = await chatService.chat('Hello, how are you?');
console.log(response);

Direct AI Service Usage

import { AIEnhancedService } from '@hazeljs/ai';

const aiService = new AIEnhancedService();

const response = await aiService.complete({
  messages: [
    { role: 'system', content: 'You are a helpful assistant' },
    { role: 'user', content: 'What is TypeScript?' },
  ],
  model: 'gpt-4',
  provider: 'openai',
  temperature: 0.7,
  maxTokens: 500,
});

console.log(response.content);
console.log('Tokens used:', response.usage);

HCEL (Hazel Composable Expression Language)

HCEL is the fastest way to compose multi-step AI pipelines in TypeScript.
Instead of manually wiring outputs between services, you define one fluent chain.

Why HCEL is easier

  • No manual glue code between prompt, retrieval, agent, and ML steps
  • Implicit context passing across operations
  • Built-in observability hooks for production tracing

Example: Prompt -> RAG -> Agent -> ML

import { HazelAI } from '@hazeljs/ai';

const ai = HazelAI.create({
  defaultProvider: 'openai',
  model: 'gpt-4o',
});

const result = await ai.hazel
  .prompt('Summarize this support request: {{input}}')
  .rag('support-kb')
  .agent('support-specialist')
  .ml('sentiment')
  .execute('Customer reports repeated payment failures after card update.');

Example: Context + Observability

const chain = ai.hazel
  .prompt('Analyze this feedback: {{feedback}}')
  .ml('sentiment')
  .context({ userId: 'u-123', sessionId: 's-456' })
  .observe((event) => {
    console.log(`[${event.type}]`, event.timestamp);
  });

const output = await chain.execute();

Example: Parallel Operations

const parallelResult = await ai.hazel
  .parallel(ai.hazel.prompt('Summarize: {{input}}'), ai.hazel.ml('sentiment'))
  .execute('HazelJS made our AI backend migration much simpler.');

Providers

OpenAI

import { AIEnhancedService } from '@hazeljs/ai';

const aiService = new AIEnhancedService();

// GPT-4
const response = await aiService.complete({
  messages: [{ role: 'user', content: 'Hello!' }],
  model: 'gpt-4',
  provider: 'openai',
});

// GPT-3.5 Turbo
const response2 = await aiService.complete({
  messages: [{ role: 'user', content: 'Hello!' }],
  model: 'gpt-3.5-turbo',
  provider: 'openai',
});

Anthropic Claude

const response = await aiService.complete({
  messages: [{ role: 'user', content: 'Explain quantum computing' }],
  model: 'claude-3-opus-20240229',
  provider: 'anthropic',
  maxTokens: 1000,
});

Google Gemini

const response = await aiService.complete({
  messages: [{ role: 'user', content: 'Write a poem' }],
  model: 'gemini-pro',
  provider: 'gemini',
});

Cohere

const response = await aiService.complete({
  messages: [{ role: 'user', content: 'Summarize this text' }],
  model: 'command',
  provider: 'cohere',
});

Ollama (Local LLMs)

const response = await aiService.complete({
  messages: [{ role: 'user', content: 'Hello!' }],
  model: 'llama2',
  provider: 'ollama',
  baseURL: 'http://localhost:11434',
});

Streaming

import { AIEnhancedService } from '@hazeljs/ai';

const aiService = new AIEnhancedService();

// Stream responses in real-time
for await (const chunk of aiService.streamComplete({
  messages: [{ role: 'user', content: 'Tell me a long story' }],
  provider: 'openai',
  model: 'gpt-4',
})) {
  process.stdout.write(chunk.delta);
}

Streaming with Decorator

@AITask({
  name: 'stream-chat',
  prompt: 'You are a storyteller. Tell a story about: {{topic}}',
  provider: 'openai',
  model: 'gpt-4',
  stream: true,
})
async streamStory(topic: string): AsyncGenerator<string> {
  return topic; // Returns async generator
}

// Usage
for await (const chunk of chatService.streamStory('dragons')) {
  console.log(chunk);
}

Advanced Features

Response Caching

import { AITask } from '@hazeljs/ai';

@AITask({
  name: 'cached-completion',
  prompt: 'Explain {{concept}}',
  provider: 'openai',
  model: 'gpt-4',
  cache: {
    enabled: true,
    ttl: 3600, // 1 hour
    key: 'explain-{{concept}}',
  },
})
async explainConcept(concept: string): Promise<string> {
  return concept;
}

Retry Logic

const response = await aiService.complete({
  messages: [{ role: 'user', content: 'Hello' }],
  provider: 'openai',
  model: 'gpt-4',
  retry: {
    maxRetries: 3,
    initialDelay: 1000,
    maxDelay: 10000,
    backoffMultiplier: 2,
  },
});

Output Type Validation

interface UserProfile {
  name: string;
  age: number;
  interests: string[];
}

@AITask({
  name: 'extract-profile',
  prompt: 'Extract user profile from: {{text}}',
  provider: 'openai',
  model: 'gpt-4',
  outputType: 'json',
})
async extractProfile(text: string): Promise<UserProfile> {
  return text;
}

const profile = await service.extractProfile('John is 25 and loves coding');
console.log(profile.name); // Type-safe!

Function Calling

const response = await aiService.complete({
  messages: [{ role: 'user', content: 'What is the weather in NYC?' }],
  provider: 'openai',
  model: 'gpt-4',
  functions: [
    {
      name: 'get_weather',
      description: 'Get the current weather in a location',
      parameters: {
        type: 'object',
        properties: {
          location: {
            type: 'string',
            description: 'The city and state, e.g. San Francisco, CA',
          },
          unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
        },
        required: ['location'],
      },
    },
  ],
  functionCall: 'auto',
});

if (response.functionCall) {
  console.log('Function:', response.functionCall.name);
  console.log('Arguments:', response.functionCall.arguments);
}

Configuration

Global Configuration

import { AIModule } from '@hazeljs/ai';

@HazelModule({
  imports: [
    AIModule.forRoot({
      providers: {
        openai: {
          apiKey: process.env.OPENAI_API_KEY,
          organization: process.env.OPENAI_ORG,
        },
        anthropic: {
          apiKey: process.env.ANTHROPIC_API_KEY,
        },
        gemini: {
          apiKey: process.env.GEMINI_API_KEY,
        },
      },
      defaultProvider: 'openai',
      defaultModel: 'gpt-4',
      cache: {
        enabled: true,
        ttl: 3600,
      },
    }),
  ],
})
export class AppModule {}

Per-Task Configuration

@AITask({
  name: 'custom-task',
  prompt: 'Process: {{input}}',
  provider: 'openai',
  model: 'gpt-4',
  temperature: 0.7,
  maxTokens: 1000,
  topP: 0.9,
  frequencyPenalty: 0.5,
  presencePenalty: 0.5,
  stop: ['\n\n'],
})
async processInput(input: string): Promise<string> {
  return input;
}

Use Cases

Chatbot

@Injectable()
export class ChatbotService {
  private conversationHistory: Array<{ role: string; content: string }> = [];

  @AITask({
    name: 'chat',
    provider: 'openai',
    model: 'gpt-4',
  })
  async chat(message: string): Promise<string> {
    this.conversationHistory.push({ role: 'user', content: message });

    const response = await this.aiService.complete({
      messages: this.conversationHistory,
      provider: 'openai',
      model: 'gpt-4',
    });

    this.conversationHistory.push({
      role: 'assistant',
      content: response.content,
    });

    return response.content;
  }
}

Content Generation

@Injectable()
export class ContentService {
  @AITask({
    name: 'generate-blog',
    prompt: `Write a blog post about {{topic}}.
    
    Requirements:
    - Length: {{length}} words
    - Tone: {{tone}}
    - Include SEO keywords: {{keywords}}`,
    provider: 'openai',
    model: 'gpt-4',
    outputType: 'string',
  })
  async generateBlogPost(
    topic: string,
    length: number,
    tone: string,
    keywords: string[]
  ): Promise<string> {
    return topic;
  }
}

Data Extraction

interface ExtractedData {
  entities: string[];
  sentiment: 'positive' | 'negative' | 'neutral';
  summary: string;
}

@Injectable()
export class AnalysisService {
  @AITask({
    name: 'analyze-text',
    prompt: `Analyze the following text and extract:
    1. Named entities (people, places, organizations)
    2. Overall sentiment
    3. Brief summary
    
    Text: {{text}}
    
    Return as JSON.`,
    provider: 'openai',
    model: 'gpt-4',
    outputType: 'json',
  })
  async analyzeText(text: string): Promise<ExtractedData> {
    return text;
  }
}

API Reference

AIEnhancedService

class AIEnhancedService {
  complete(options: AICompletionOptions): Promise<AIResponse>;
  streamComplete(options: AICompletionOptions): AsyncGenerator<AIStreamChunk>;
  embed(text: string, options?: EmbedOptions): Promise<number[]>;
}

@AITask Decorator

@AITask({
  name: string;
  prompt?: string;
  provider: 'openai' | 'anthropic' | 'gemini' | 'cohere' | 'ollama';
  model: string;
  outputType?: 'string' | 'json' | 'number' | 'boolean';
  stream?: boolean;
  temperature?: number;
  maxTokens?: number;
  cache?: CacheOptions;
  retry?: RetryOptions;
})

Examples

See the examples directory for complete working examples.

Testing

npm test

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

🚀 New: HazelJS Unified AI Platform

Single entry point for all AI capabilities - Introducing the HazelAI class that brings together all AI features in one elegant API.

What's New?

🎯 Unified API

import { HazelAI } from '@hazeljs/ai';

// One class for everything
const ai = HazelAI.create({
  defaultProvider: 'openai',
  model: 'gpt-4o',
});

// All AI capabilities through one interface
await ai.chat('Hello');
await ai.stream('Tell me a story');
await ai.sentiment('I love this!');
await ai.score('Rate this text', { items, criteria });
await ai.workflow('process').step(...).run(data);
const assistant = ai.assistant({ memory: true });

🏗️ 6 AI Facades

  • ChatFacade - Simple chat and streaming
  • RAGFacade - Document Q&A with retrieval
  • AgentFacade - Specialized AI agents
  • MLFacade - Classification, sentiment, scoring
  • WorkflowFacade - Chain multiple AI steps
  • AssistantFacade - Memory-enabled conversations

📊 Built-in Metrics

const metrics = ai.getMetrics();
console.log(`Requests: ${metrics.totalRequests}`);
console.log(`Tokens: ${metrics.totalTokens}`);
console.log(`Latency: ${metrics.averageLatencyMs}ms`);
console.log(`Cost: $${metrics.costEstimate}`);

Benefits

🚀 Developer Experience

  • Single Import - import { HazelAI } from '@hazeljs/ai'
  • HCEL Fluent API - Compose AI pipelines with a single chain
  • Type Safety - Full TypeScript support with autocomplete
  • Consistent API - Same patterns across all AI features
  • Zero Boilerplate - Get started in 3 lines of code

💪 Powerful Features

  • Multi-Provider - Switch between OpenAI, Anthropic, Gemini, Cohere, Ollama
  • Graceful Fallbacks - Automatic provider switching on errors
  • Memory Management - Built-in conversation history for assistants
  • Workflow Orchestration - Chain AI steps with timing and error handling

🔧 Production Ready

  • Token Tracking - Monitor usage and costs per provider
  • Retry Logic - Automatic retries with exponential backoff
  • Error Handling - Graceful degradation for optional dependencies
  • Performance - Optimized for high-throughput applications

Quick Examples

Basic Chat

import { HazelAI } from '@hazeljs/ai';

const ai = HazelAI.create({ defaultProvider: 'openai' });

// Simple chat
const response = await ai.chat('What is HazelJS?');
console.log(response.content);

// Streaming chat
for await (const chunk of ai.stream('Tell me a story')) {
  process.stdout.write(chunk);
}

ML Operations

// Sentiment analysis
const sentiment = await ai.sentiment('I love using HazelJS!');
console.log(`${sentiment.sentiment} (${sentiment.score})`);

// Classification
const category = await ai.classify('This is about technology', {
  labels: ['tech', 'sports', 'politics'],
});

// Scoring
const scores = await ai.score('Rate for accuracy', {
  items: [{ id: '1', text: 'TypeScript is typed JavaScript' }],
  criteria: 'Technical accuracy',
});

Workflows

const result = await ai
  .workflow('process')
  .step('extract', async (text: string) => {
    return text.split(' ');
  })
  .step('analyze', async (words: string[]) => {
    return {
      count: words.length,
      avgLength: words.reduce((sum, w) => sum + w.length, 0) / words.length,
    };
  })
  .run('Hello world');

console.log(result.output); // { count: 2, avgLength: 5 }
console.log(result.totalDuration); // 5ms

Assistants with Memory

const assistant = ai.assistant({
  name: 'HelpBot',
  systemPrompt: 'You are a helpful assistant',
  memory: true,
});

await assistant.chat('My name is John');
await assistant.chat('What is my name?'); // Remembers "John"

console.log(assistant.sessionId); // Unique session
console.log(assistant.getHistory()); // Full conversation

Migration Guide

From AIEnhancedService

// Before
import { AIEnhancedService } from '@hazeljs/ai';
const ai = new AIEnhancedService();
await ai.complete({ messages, provider: 'openai' });

// After
import { HazelAI } from '@hazeljs/ai';
const ai = HazelAI.create({ defaultProvider: 'openai' });
await ai.chat('Hello');

From Multiple Imports

// Before
import { ChatService } from '@hazeljs/ai';
import { MLService } from '@hazeljs/ml';
import { AgentService } from '@hazeljs/agent';

// After
import { HazelAI } from '@hazeljs/ai';
const ai = HazelAI.create();
// All services available through ai.*

Advanced Usage

Provider Configuration

const ai = HazelAI.create({
  defaultProvider: 'openai',
  providers: {
    openai: { apiKey: process.env.OPENAI_API_KEY },
    anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
  },
  model: 'gpt-4o',
  temperature: 0.7,
});

Error Handling

try {
  const response = await ai.chat('Hello');
} catch (error) {
  if (error.message.includes('Provider not available')) {
    // Fallback to another provider
    const response = await ai.chat('Hello', { provider: 'ollama' });
  }
}

Custom Workflows

const dataProcessor = ai.workflow('data-pipeline');

const result = await dataProcessor
  .step('validate', async (data) => {
    if (!data.isValid) throw new Error('Invalid data');
    return data;
  })
  .step('transform', async (data) => {
    return { ...data, processed: true };
  })
  .step('store', async (data) => {
    await database.save(data);
    return data.id;
  })
  .run(inputData);

What's Under the Hood?

The Unified AI Platform is built on the same robust foundation you trust:

  • AIEnhancedService - Core AI engine with provider management
  • TokenTracker - Usage and cost monitoring
  • Retry Logic - Automatic error recovery
  • Caching - Response caching with TTL
  • Type Safety - Full TypeScript coverage

The HazelAI class is a thin, opinionated wrapper that combines:

  • All facades into one interface
  • Consistent configuration management
  • Unified error handling
  • Centralized metrics collection

Examples Repository

Check out the examples/ directory for complete, runnable examples:

  • simple-demo.ts - Basic functionality without API keys
  • unified-platform-example.ts - Full demo with all features
  • README.md - Detailed setup and usage instructions

Run examples:

npm run demo:simple  # Basic demo
npm run demo:full    # Full demo (requires API keys)

Backward Compatibility

All existing APIs continue to work unchanged. The Unified AI Platform is an additional layer on top of the existing architecture.

// This still works exactly as before
import { AIEnhancedService } from '@hazeljs/ai';
const service = new AIEnhancedService();
await service.complete({ messages, provider: 'openai' });

// Decorators still work
@AITask({ name: 'chat', prompt: 'Respond to: {{input}}' })
async chat(input: string): Promise<string> { return input; }

Next Steps

  1. Try the simple demo - npm run demo:simple
  2. Set up API keys and run the full demo - npm run demo:full
  3. Read the examples in examples/README.md
  4. Check the API docs for detailed method signatures
  5. Join our Discord for community support

License

Apache 2.0 © HazelJS

Links