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

@molecule/api-ai-decisions-laya

v1.1.0

Published

Laya decisions provider for molecule.dev — typed choice/score/yes-no answers from the open-weights Laya model on your own laya-serve host

Downloads

475

Readme

@molecule/api-ai-decisions-laya

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Laya decisions provider for molecule.dev — typed decisions from the open-weights Laya model (Apache-2.0) on a laya-serve host you run.

Laya is a ~421M-parameter encoder (ModernBERT-large; a 322M multilingual checkpoint covers 100+ languages) that answers choice, score and yes/no questions in one forward pass — about 33–40 ms per question on a T4 GPU, with no text generation. This bond speaks laya-serve's /v1/systemone route, the same wire protocol as TypeSafe's Jev, so swapping to @molecule/api-ai-decisions-jev is a one-line change.

Quick Start

# Run the model server (CPU works; a GPU is ~10x faster)
pip install "laya[serve]"
LAYA_API_KEY=change-me laya-serve        # http://0.0.0.0:8000
# or: docker compose up   (compose.yaml in github.com/NandhaKishorM/laya)
import { setProvider, requireProvider } from '@molecule/api-ai-decisions'
import { provider } from '@molecule/api-ai-decisions-laya'

setProvider(provider) // reads LAYA_URL + LAYA_API_KEY on first use

const { answers } = await requireProvider().decide({
  state: 'My card was charged twice, please refund one of them',
  questions: {
    queue: {
      type: 'choice',
      instructions: 'Which team?',
      criteria: { billing: 'charges, refunds', tech: 'bugs, login' },
    },
    refund: { type: 'yesNo', instructions: 'The customer wants a refund.' },
  },
})
answers.queue.choice // 'billing'
answers.refund.probability // 0.96

Type

provider

Installation

npm install @molecule/api-ai-decisions-laya @molecule/api-ai-decisions @molecule/api-secrets

API

Interfaces

LayaConfig

Configuration for the Laya decisions provider.

interface LayaConfig {
  /** Base URL of the `laya-serve` host. Defaults to `LAYA_URL`, then `http://localhost:8000`. */
  baseUrl?: string
  /** Bearer token, when the server sets `LAYA_API_KEY`. Defaults to the `LAYA_API_KEY` env var. */
  apiKey?: string
  /**
   * Extra request headers, resolved before each call and merged over the
   * defaults — for a host whose auth expires or is not a bearer token (a Cloud
   * Run ID token, Modal proxy auth). Pair with `@molecule/api-model-hosting`:
   * `headers: () => hosting.authHeaders(endpoint.id)`.
   */
  headers?: () => Record<string, string> | Promise<Record<string, string>>
  /**
   * Default checkpoint: `'english'`, `'multilingual'` or `'typed-decisions'`
   * (or a Hugging Face id such as `'convaiinnovations/laya-multilingual'`).
   * Omit to let the server route by the input's language.
   */
  model?: string
}

PostOptions

Options for {@link postSystemOne}.

interface PostOptions {
  /** Full endpoint URL. */
  url: string
  /** Bearer token, if any. */
  apiKey?: string
  /** Extra headers resolved before the request (merged over the defaults). */
  headers?: () => Record<string, string> | Promise<Record<string, string>>
  /** Request body. */
  body: Record<string, unknown>
  /** Abort signal. */
  signal?: AbortSignal
  /** Label for error messages (`'Laya'`, `'Jev'`). */
  label: string
  /** Max retries on a retryable status (default 3). */
  maxRetries?: number
}

WireAnswer

One answer as received on the wire (only the fields we read).

interface WireAnswer {
  type?: string
  choice?: string
  score?: number
  noul?: number
  probabilities?: Record<string, number>
}

WireQuestion

One question as sent on the wire.

interface WireQuestion {
  type: 'choice' | 'score' | 'noul'
  instructions: string
  criteria?: Record<string, string> | string[]
}

WireResponse

The response body (only the fields we read).

interface WireResponse {
  model?: string
  answers?: Record<string, WireAnswer>
  usage?: { input_tokens?: number; output_tokens?: number }
}

Functions

createProvider(config)

Creates a Laya decisions provider.

function createProvider(config?: LayaConfig): AIDecisionsProvider
  • config — Base URL, API key and default checkpoint.

Returns: An AIDecisionsProvider backed by a laya-serve host.

fromWireAnswer(id, question, wire, minConfidence)

Converts one wire answer into the core's answer for question.

function fromWireAnswer(
  id: string,
  question: DecisionQuestion,
  wire: WireAnswer | undefined,
  minConfidence?: number,
): DecisionAnswer
  • id — The question id (for error messages).
  • question — The question that was asked.
  • wire — The wire answer.
  • minConfidence — Optional low-confidence threshold.

Returns: The typed answer.

fromWireResponse(questions, body, minConfidence)

Converts a whole wire response into the core's result.

function fromWireResponse(questions: Q, body: WireResponse, minConfidence?: number): DecideResult<Q>
  • questions — The questions that were asked.
  • body — The parsed response body.
  • minConfidence — Optional low-confidence threshold.

Returns: The typed result.

postSystemOne(opts)

POSTs a /v1/systemone request with retry on 429/5xx-busy, honouring Retry-After. Throws an Error carrying status on a non-2xx response.

function postSystemOne(opts: PostOptions): Promise<WireResponse>
  • opts — Request options.

Returns: The parsed response body.

toWireQuestions(questions)

Converts the core's questions into wire questions (yesNo → noul).

function toWireQuestions(questions: Record<string, DecisionQuestion>): Record<string, WireQuestion>
  • questions — The questions keyed by id.

Returns: The wire questions object.

Constants

aiDecisionsLayaSecretDefinitions

Secret definitions used by the Laya decisions bond.

const aiDecisionsLayaSecretDefinitions: SecretDefinition[]

DEFAULT_LAYA_URL

laya-serve's default bind (LAYA_PORT defaults to 8000).

const DEFAULT_LAYA_URL: 'http://localhost:8000'

provider

The provider implementation — lazy, so env vars are read on first use.

const provider: AIDecisionsProvider

Core Interface

Implements @molecule/api-ai-decisions interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setProvider } from '@molecule/api-ai-decisions'
import { provider } from '@molecule/api-ai-decisions-laya'

export function setupAiDecisionsLaya(): void {
  setProvider(provider)
}

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-ai-decisions ^1.0.0
  • @molecule/api-secrets ^1.0.1

Environment Variables

Runtime Dependencies

  • @molecule/api-ai-decisions

  • @molecule/api-secrets

  • You run the model. LAYA_URL (default http://localhost:8000) points at a laya-serve host; set LAYA_API_KEY on BOTH sides to require a bearer token — without it the server is open to anyone who can reach it, so never expose an unauthenticated one publicly.

  • Any /v1/systemone server works. LAYA_URL can point at another self-hosted server of the same protocol — e.g. Kev (github.com/jaredpalmer/kev, Apache-2.0 LoRA adapters on Qwen, 0.8B–27B, needs a GPU or Apple MLX) — with no code change.

  • Checkpoints: pass model: 'english' | 'multilingual' | 'typed-decisions' (per call or createProvider({ model })); omit it and the server routes by the input's script/language. Any other value (e.g. a Jev id) is ignored by the server, not rejected.

  • Server limits (each a 413): 64 questions/request, 100 options per choice, 32 levels per score, 512 options total, 50,000-char state, 2 MiB body. Option texts must also fit a ~192-token window (else 422) — keep descriptions short. Busy servers answer 503 + Retry-After; this bond retries 429/503/529 up to 3 times.

  • Accuracy is yours to measure. Base checkpoints are near chance on unfamiliar decision sets and ship over-confident; fine-tune (the repo has a free Kaggle notebook) and calibrate on your own labelled data, and gate on minConfidence. See the core's remarks.

  • Hosted on rented compute? Pass headers: () => hosting.authHeaders(endpoint.id) (@molecule/api-model-hosting) when the host's auth expires or is not a bearer token — e.g. a Cloud Run ID token or Modal proxy auth. It runs before every request and is merged over the defaults.

  • Use the core's setProvider, not bond('ai-decisions', …) directly.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • [ ] Each flow that makes a decision (routing, triage, moderation, a guardrail) runs it from the real UI, and the answer DRIVES what happens next (the item lands in the chosen queue, the badge shows, the action is blocked) — not just printed.
  • [ ] Both directions: a clearly-billing input routes to billing AND a clearly-technical one routes elsewhere. One label for every input is a broken integration.
  • [ ] A low-confidence answer takes the app's fallback path (human review, "unsure" state) instead of being acted on.
  • [ ] Provider errors (service down, bad key) show a visible, recoverable state — never a blank screen or an unhandled rejection.
  • [ ] The call runs server-side: no provider request or key in the browser's Network tab.