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

@mullion/core

v0.3.0

Published

Core types and utilities for Mullion

Readme


Live Demos

Try Mullion in action (requires Google sign-in, 20 requests/day):

  • 🎫 Helpdesk Demo — Scope isolation preventing internal notes from leaking to customers
  • 📚 RAG Demo — Fork/merge patterns with role-based access control

Installation

npm install @mullion/core

Project Generator

Scaffold a full Nuxt app with Mullion pre-wired:

npm create mullion@latest

Note: create-mullion currently scaffolds Nuxt templates only. Next.js support is planned.

See: https://github.com/mullionlabs/mullion-ts/tree/main/packages/create-mullion

Overview

The core package provides fundamental types and utilities for Mullion's type-safe context management system. Use this package if you want to build custom integrations or don't need the Vercel AI SDK wrapper.

Features

  • Type-safe contexts - Owned<T, S> with compile-time scope tracking
  • Semantic values - Extended outputs with alternatives and reasoning
  • Explicit bridging - Traceable data flow across trust boundaries
  • Fork/merge system - Parallel execution with type-safe aggregation
  • 6 merge strategies - Categorical, continuous, object, array, custom, consensus
  • OpenTelemetry tracing - Zero-dependency OTLP exporter with presets
  • Bridge utilities - Advanced provenance tracking and metadata
  • Zero runtime overhead - Compile-time safety without runtime cost

Key Types

Owned<T, S>

Wraps LLM-generated values with scope tracking and metadata:

import type {Owned} from '@mullion/core';

interface Owned<T, S extends string> {
  value: T; // The actual data
  confidence: number; // 0-1 confidence score
  __scope: S; // Compile-time scope tracking
  traceId: string; // Unique identifier for audit trails
}

Context<S>

Provides scoped execution environment for LLM operations:

import type {Context} from '@mullion/core';

interface Context<S extends string> {
  readonly scope: S;

  // Infer structured data from unstructured input
  infer<T>(
    schema: Schema<T>,
    input: string,
    options?: InferOptions,
  ): Promise<Owned<T, S>>;

  // Transfer value from another scope
  bridge<T, OS extends string>(owned: Owned<T, OS>): Owned<T, S | OS>;

  // Extract raw value (scope-safe)
  use<T>(owned: Owned<T, S>): T;
}

Utilities

createOwned()

Factory function for creating Owned values:

import {createOwned} from '@mullion/core';

const data = createOwned({
  value: {name: 'John', age: 30},
  scope: 'user-data',
  confidence: 0.95,
  traceId: 'trace-123',
});

console.log(data.__scope); // 'user-data'

isOwned()

Type guard for checking if a value is Owned:

import {isOwned} from '@mullion/core';

if (isOwned(someValue)) {
  // TypeScript knows someValue is Owned<unknown, string>
  console.log(someValue.confidence);
}

Example: Custom Integration

import {createOwned, isOwned} from '@mullion/core';
import type {Context, Owned} from '@mullion/core';

// Create a custom context implementation
class MyContext<S extends string> implements Context<S> {
  constructor(public readonly scope: S) {}

  async infer<T>(schema: any, input: string): Promise<Owned<T, S>> {
    // Your custom LLM integration here
    const result = await myLLM.generate(schema, input);

    return createOwned({
      value: result.data,
      scope: this.scope,
      confidence: result.confidence,
      traceId: `${this.scope}-${Date.now()}`,
    });
  }

  bridge<T, OS extends string>(owned: Owned<T, OS>): Owned<T, S | OS> {
    return {
      ...owned,
      __scope: this.scope as S | OS,
    };
  }

  use<T>(owned: Owned<T, S>): T {
    if (owned.__scope !== this.scope) {
      throw new Error(`Scope mismatch: ${owned.__scope} !== ${this.scope}`);
    }
    return owned.value;
  }
}

// Usage
const ctx = new MyContext('my-scope');
const result = await ctx.infer(schema, 'analyze this text');

if (result.confidence > 0.8) {
  console.log('High confidence result:', ctx.use(result));
}

SemanticValue

SemanticValue<T, S> extends Owned<T, S> with additional fields for LLM reasoning:

import {createSemanticValue} from '@mullion/core';
import type {SemanticValue, Alternative} from '@mullion/core';

const analysis: SemanticValue<Classification, 'analysis'> = createSemanticValue(
  {
    value: {category: 'technical', priority: 'high'},
    scope: 'analysis',
    confidence: 0.85,
    traceId: 'trace-456',
    reasoning: 'Based on technical keywords and urgency indicators',
    alternatives: [
      {value: {category: 'support', priority: 'high'}, confidence: 0.75},
      {
        value: {category: 'technical', priority: 'medium'},
        confidence: 0.65,
      },
    ],
  },
);

// Access reasoning chain
console.log(analysis.reasoning);
// "Based on technical keywords and urgency indicators"

// Explore alternatives
analysis.alternatives.forEach((alt, i) => {
  console.log(
    `Alternative ${i + 1}:`,
    alt.value,
    `(confidence: ${alt.confidence})`,
  );
});

Use SemanticValue when:

  • You need to understand LLM's reasoning process
  • Want to provide alternative interpretations to users
  • Building systems that require explainability
  • Implementing human-in-the-loop workflows with fallbacks

Fork & Merge

Run multiple LLM inferences in parallel with intelligent cache optimization.

Fork Strategies

import {fork} from '@mullion/core';

// Fast parallel: All branches execute immediately
const result = await fork(ctx, {
  branches: {
    compliance: (c) => c.infer(ComplianceSchema, prompt),
    quality: (c) => c.infer(QualitySchema, prompt),
    tags: (c) => c.infer(TagsSchema, prompt),
  },
  strategy: 'fast-parallel',
});

// Cache optimized: Warm up cache first for cost savings
const result = await fork(ctx, {
  branches: {
    model1: (c) => c.infer(schema, prompt),
    model2: (c) => c.infer(schema, prompt),
    model3: (c) => c.infer(schema, prompt),
  },
  strategy: 'cache-optimized',
  warmup: 'first-branch',
});

Merge Strategies

Aggregate parallel results with 6 built-in strategies:

import {
  categorical,
  continuous,
  object,
  array,
  custom,
  requireConsensus
} from '@mullion/core';

// 1. Categorical weighted vote - for enums/categories
const merged = categorical.weightedVote(results, {
  tiebreaker: 'highest-confidence',
});

// 2. Continuous weighted average - for numbers
const merged = continuous.weightedAverage(results, {
  field: 'score',
  outlierThreshold: 2.0,
});

// 3. Object fieldwise - merge objects field-by-field
const merged = object.fieldwise(results, {
  fieldStrategies: {
    title: categorical.weightedVote(),
    score: continuous.weightedAverage(),
    tags: array.concat(),
  },
});

// 4. Array concatenation - combine arrays with deduplication
const merged = array.concat(results, {
  deduplicate: true,
  maxItems: 20,
});

// 5. Custom merge function - your own logic
const merged = custom((values) => ({
  value: /* your aggregation */,
  confidence: /* your calculation */,
  provenance: values.map(v => v.traceId),
}));

// 6. Require consensus - enforce k-of-n agreement
const merged = requireConsensus({
  k: 2, // Require 2 out of 3 agreement
  baseStrategy: categorical.weightedVote(),
  onFailure: 'error',
})(results);

Learn more: See docs/reference/fork.md and docs/reference/merge-strategies.md

Bridge Utilities

Advanced bridging utilities for complex dataflow scenarios:

import {
  bridgeMultiple,
  bridgeWithMetadata,
  getProvenance,
  isBridged,
} from '@mullion/core';

// Bridge multiple values at once
const [a, b, c] = bridgeMultiple(ctx, [valueA, valueB, valueC]);

// Add custom metadata to bridges
const bridged = bridgeWithMetadata(ctx, value, {
  reason: 'Approved for public display',
  reviewedBy: 'admin-123',
  approvedAt: new Date().toISOString(),
});

// Inspect provenance history
const history = getProvenance(bridged);
console.log(`Value crossed ${history.length} scope boundaries`);
history.forEach((hop, i) => {
  console.log(`Hop ${i + 1}: ${hop.fromScope} → ${hop.toScope}`);
  console.log(`  Reason: ${hop.metadata?.reason}`);
});

// Check if value has been bridged
if (isBridged(value)) {
  console.log('This value has crossed scope boundaries');
}

Tracing & Observability

Mullion includes production-ready OpenTelemetry-compatible tracing for LLM workflow observability.

Quick Start

import {TracingPresets} from '@mullion/core';

// Enable tracing with one line
TracingPresets.jaeger(); // Local development

// Or for production
TracingPresets.honeycomb(process.env.HONEYCOMB_API_KEY!);

Features

  • ✅ Zero-dependency OTLP exporter
  • ✅ One-liner setup for major backends (Jaeger, Honeycomb, Datadog, New Relic, Grafana)
  • ✅ Mullion-specific attributes (scope, confidence, cost, cache metrics)
  • ✅ Zero overhead by default (disabled until exporter attached)
  • ✅ Full OpenTelemetry compatibility

Manual Instrumentation

import {getGlobalTraceCollector, setupMullionTracing} from '@mullion/core';

setupMullionTracing({
  endpoint: 'http://localhost:4318/v1/traces',
});

const collector = getGlobalTraceCollector();

const spanCtx = collector.startSpan({
  name: 'mullion.infer',
  kind: 'client',
  attributes: {
    'mullion.scope.id': 'admin',
    'mullion.operation': 'infer',
  },
});

try {
  // Your operation
  await performOperation();
  await collector.endSpan(spanCtx, {status: 'ok'});
} catch (error) {
  await collector.endSpan(spanCtx, {
    status: 'error',
    statusMessage: error.message,
  });
  throw error;
}

Learn More

See TRACING.md for complete guide including:

  • Production setup for all major backends
  • Configuration options
  • Mullion attribute schema
  • Manual instrumentation patterns
  • Performance tuning
  • Troubleshooting

API Reference

Core Types

  • Owned<T, S> - Scoped value wrapper with confidence and provenance
  • SemanticValue<T, S> - Extended Owned with alternatives and reasoning
  • Alternative<T> - Alternative interpretation with confidence
  • Context<S> - Execution context interface
  • Schema<T> - Schema interface (usually Zod)
  • InferOptions - Options for inference operations
  • BridgeMetadata - Custom metadata for bridge operations

Fork/Merge Types

  • ForkStrategy - Fork execution strategy ('fast-parallel' | 'cache-optimized')
  • WarmupStrategy - Cache warmup strategy
  • ForkOptions - Fork configuration options
  • ForkResult<T> - Fork execution results
  • MergeStrategy - Merge strategy type
  • MergeResult<T> - Merged result with provenance
  • ConflictResolution - How to handle merge conflicts

Tracing Types

  • MullionSpan - OpenTelemetry-compatible span
  • SpanContext - Active span context
  • SpanExporter - Exporter interface
  • MullionAttributes - Span attributes
  • MullionOperation - Operation types for tracing

Core Functions

Owned & SemanticValue:

  • createOwned(params) - Create Owned value
  • isOwned(value) - Type guard for Owned values
  • createSemanticValue(params) - Create SemanticValue
  • isSemanticValue(value) - Type guard for SemanticValue

Scope:

  • scope(name, fn) - Create scoped execution context

Bridging:

  • bridge(ctx, owned) - Bridge value to new scope
  • bridgeSemantic(ctx, semantic) - Bridge SemanticValue
  • bridgeMultiple(ctx, values) - Bridge multiple values at once
  • bridgeWithMetadata(ctx, value, metadata) - Bridge with custom metadata
  • getProvenance(value) - Get provenance history
  • isBridged(value) - Check if value has been bridged

Fork & Merge:

  • fork(ctx, options) - Execute parallel branches
  • merge(results, strategy) - Merge parallel results
  • mergeResults(results, strategy) - Convenience wrapper for merge

Merge Strategies:

  • categorical.weightedVote(options?) - Voting for categorical values
  • continuous.weightedAverage(options?) - Weighted average for numbers
  • object.fieldwise(options) - Per-field merging
  • array.concat(options?) - Array concatenation with deduplication
  • custom(fn) - Custom merge function
  • requireConsensus(options) - Enforce k-of-n agreement

Tracing:

  • setupMullionTracing(options) - One-liner tracing setup
  • TracingPresets.jaeger() - Jaeger preset
  • TracingPresets.honeycomb(apiKey) - Honeycomb preset
  • TracingPresets.datadog(apiKey) - Datadog preset
  • TracingPresets.newRelic(key) - New Relic preset
  • TracingPresets.grafana(instanceId, apiKey) - Grafana preset
  • getGlobalTraceCollector() - Get global collector
  • setGlobalTraceCollector(collector) - Set global collector
  • clearGlobalTraceCollector() - Clear global collector
  • disableMullionTracing() - Graceful shutdown

Classes

  • TraceCollector - Span collection and export
  • OTLPHttpExporter - OTLP/HTTP exporter

Related Packages

Documentation

Contributing

Found a bug or want to contribute? See CONTRIBUTING.md for guidelines.

License

MIT - see LICENSE for details.