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

ai-contract-kit

v1.0.0

Published

A lightweight contract layer for building reliable AI systems with structured inputs and outputs.

Downloads

12

Readme

ai-contract-kit

A tiny, practical contract layer for AI systems.

This project solves a very common problem in AI applications: inputs and outputs are often treated as loose text instead of predictable interfaces. That makes systems harder to validate, debug, monitor, and improve.

ai-contract-kit provides a lightweight envelope for:

  • requests to a model
  • responses from a model
  • validation of required fields
  • normalization of uncertainty, refusal, and fallback states

It can be used as both a reference implementation and a lightweight standard for structuring AI interactions.

Why this project exists

Most AI applications still rely on ad hoc conventions.

One workflow stores prompts as strings. Another expects JSON. A third checks for a few fields manually. A fourth breaks when a model returns a differently shaped answer.

The result is glue code, silent failures, and inconsistent behavior.

This package creates a simple contract that sits between your application and the model layer.

Mental model

Think of the package as a small interface boundary:

App -> AI Request Contract -> Model -> AI Response Contract -> App

The contract sits between your application logic and the model, creating a predictable boundary on both input and output.

This does not replace model SDKs.

It standardizes how your system talks to them.

What is included

  • Request envelope builder
  • Response envelope builder
  • Validation helpers
  • Status normalization for success, uncertain, refusal, and error
  • Minimal example showing how to wrap a model call
  • Basic tests

Install

npm install ai-contract-kit

Example

import {
  createRequestEnvelope,
  createResponseEnvelope,
  validateRequestEnvelope,
  validateResponseEnvelope
} from "ai-contract-kit";

const request = createRequestEnvelope({
  task: "summarization",
  prompt: "Summarize the following article in 3 sentences.",
  context: [
    {
      id: "article-1",
      content: "Long article text goes here"
    }
  ],
  constraints: {
    format: "plain_text",
    maxTokens: 250
  }
});

validateRequestEnvelope(request);

const response = createResponseEnvelope({
  status: "success",
  output: {
    text: "This is the short summary.",
    structured: null
  },
  meta: {
    model: "example-model-v1",
    latencyMs: 842
  }
});

validateResponseEnvelope(response);

Request contract

A request envelope looks like this:

{
  "version": "1.0",
  "task": "summarization",
  "prompt": "Summarize the following article in 3 sentences.",
  "context": [
    {
      "id": "article-1",
      "content": "Long article text goes here",
      "source": null,
      "priority": 1
    }
  ],
  "constraints": {
    "format": "plain_text",
    "maxTokens": 250
  },
  "meta": {
    "traceId": "...",
    "createdAt": "..."
  }
}

Response contract

A response envelope looks like this:

{
  "version": "1.0",
  "status": "success",
  "output": {
    "text": "This is the short summary.",
    "structured": null
  },
  "issues": [],
  "meta": {
    "model": "example-model-v1",
    "latencyMs": 842,
    "createdAt": "..."
  }
}

Status model

The response status is intentionally narrow:

  • success means the system produced a usable result.
  • uncertain means the result may be incomplete or low-confidence.
  • refusal means the model declined to answer.
  • error means the system failed to produce a valid result.

This is useful because most AI systems currently treat all non-ideal results as generic failures. That makes debugging and fallback handling harder than it needs to be.

Quick wrapper example

import {
  createRequestEnvelope,
  createResponseEnvelope,
  validateRequestEnvelope,
  validateResponseEnvelope,
  toUncertainResponse,
  toErrorResponse
} from "ai-contract-kit";

async function runModel(modelClient, inputText) {
  const request = createRequestEnvelope({
    task: "extraction",
    prompt: "Extract the key entities from the input.",
    context: [{ id: "input", content: inputText }],
    constraints: { format: "json" }
  });

  validateRequestEnvelope(request);

  try {
    const raw = await modelClient.generate(request);

    if (!raw?.text) {
      return toUncertainResponse("Model returned no text output", {
        model: raw?.model ?? "unknown"
      });
    }

    const response = createResponseEnvelope({
      status: "success",
      output: {
        text: raw.text,
        structured: raw.structured ?? null
      },
      meta: {
        model: raw.model ?? "unknown",
        latencyMs: raw.latencyMs ?? null
      }
    });

    validateResponseEnvelope(response);
    return response;
  } catch (error) {
    return toErrorResponse(error instanceof Error ? error.message : "Unknown error");
  }
}

Design Principles

This project is intentionally minimal.

It defines a small, explicit contract layer rather than a full framework. The goal is to provide a stable boundary for AI interactions that is easy to understand, easy to adopt, and easy to extend.

The design emphasizes:

  • Simplicity over abstraction
  • Explicit structure over implicit behavior
  • Reliability over flexibility
  • Composability over completeness

This allows the contract to be used across different models, tools, and systems without introducing unnecessary complexity.

Roadmap

This project is designed as a foundation for more reliable AI systems. Future extensions may include:

  • JSON Schema export for validation and interoperability
  • TypeScript types for stronger developer ergonomics
  • Adapters for common model providers
  • Observability hooks for logging and debugging
  • Fallback and retry policies
  • Evaluation fixtures and reproducible test cases

License

MIT