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

@one-agent/reason

v0.0.11

Published

Structured reasoning interface and CLI for ONE.

Readme

@one-agent/reason

Structured reasoning interface and CLI for ONE.

Within this repository's Re in Act implementation, @one-agent/reason implements the required reason() interface: a bounded local judgment step that turns prompt text plus a required JSON shape into structured output.

Relevant public reference:

In the public spec, reason() is the only required interface. @one-agent/reason is this repository's reference implementation of that core contract.

Model Configuration

reason auth configures the model used by the reason CLI and by reason() calls inside the Reason-able Action Space.

This is separate from one auth:

  • one auth configures the main one agent model
  • reason auth configures the model used by reason()

By default, reason auth writes ~/.config/one/reason.json.

Environment variables still override file config. Common overrides include:

  • ONE_REASON_PROVIDER
  • ONE_REASON_MODEL
  • ONE_REASON_OPENAI_API_KEY
  • ONE_REASON_OPENAI_BASE_URL
  • ONE_REASON_REASONING_EFFORT

REASONING_EFFORT controls how much reasoning/thinking the model does. Valid values are off, low, medium, and high; when unset the provider's default is used. one-reason forwards it the way each provider expects:

  • OpenAI-compatible chat-completions endpoints receive the standard reasoning_effort field: low/medium/high pass through, and off sends "none", OpenAI's documented "no reasoning" value. Models that honor it include OpenAI gpt-5.1+ and Kimi K2.x; always-reasoning models (for example MiniMax M2) may ignore it or reject the parameter.
  • OpenAI receives reasoningEffort: "minimal" for off (the lowest effort the current AI SDK accepts) and low/medium/high otherwise. minimal is not accepted by every OpenAI model, so treat off as best-effort there too.
  • Anthropic enables thinking per model generation. Claude 4.6 and later plus the Claude 5 family (Sonnet 4.6/5, Opus 4.6/4.7/4.8/5, Fable 5) receive adaptive thinking (thinking: { type: "adaptive" }) together with the effort parameter, which is the only accepted form on Opus 4.7+/Claude 5. Older Claude models (4/4.1/4.5, Haiku 4.5, 3.x) receive the legacy thinking: { type: "enabled", budgetTokens } form with a fixed thinking budget per level (2048/8192/16384 tokens for low/medium/high). off sends thinking: { type: "disabled" }, so models that default to thinking on (for example Sonnet 5) stop; this requires @ai-sdk/anthropic

    = 3.0.93 because older SDK versions silently dropped the field.

The fields above are not universal: some providers gate thinking with their own body fields instead (for example Zhipu GLM uses thinking: { type: "enabled" | "disabled" } and ignores reasoning_effort), and some APIs reject values they do not recognize. Use a non-thinking model when you need thinking guaranteed off. The scoped fallback is ONE_REASONING_EFFORT, and it can also be set as REASONING_EFFORT in reason.json.

Example:

# Configure the model/provider used by reason()
reason auth

# Or use the namespaced binary
one-reason auth

Usage

cat build.log | reason --prompt "goal: detect failures" - '{"failed":false,"reason":""}'

The structure argument is required and must be valid JSON.

TypeSafe Jev providers

Jev is for control-node judgments (route / retry / boolean / score). It returns noul/choice/score probabilities only — it cannot generate free-form summaries or arbitrary structured prose.

Summary / synthesis reason() calls (e.g. { summary, findings, next }) stay on the LLM streamText + submit_result path. When a Jev backend is configured, reason() falls back to the LLM for free-text examples in mode: "jev" (see mode below).

Standalone Jev backend (recommended)

You can keep your primary LLM (ONE_REASON_PROVIDER=openai-compatible, anthropic, etc.) intact and configure Jev alongside it as an independent fast-decision engine. These variables only make Jev available; ONE_REASON_MODE controls the routing policy:

# Toggle Jev decision backend on or off (default: 1 if configured)
export ONE_REASON_JEV_ENABLED=1

# Execution mode: llm (default, backward-compatible), or jev
export ONE_REASON_MODE=jev

# TypeSafe official:
export TYPESAFE_API_KEY=apikey_...

# Or Vercel AI Gateway:
export AI_GATEWAY_API_KEY=vck_...

llm is the default for backward compatibility. jev enables automatic routing: decision-shaped examples go to the configured Jev backend and free-text/synthesis examples fall back to the LLM. Having Jev credentials present does not itself change the mode.

When TYPESAFE_API_KEY or AI_GATEWAY_API_KEY is present, reason() auto-detects the Jev provider. You can also explicitly specify ONE_REASON_JEV_PROVIDER=typesafe or gateway.

CLI mode & switches

In the CLI, control behavior via flags:

# Force Jev evaluation
reason --mode jev "The user wants a refund" '{"is_refund":false}'

# Force LLM generation
reason --mode llm "Summarize findings" '{"summary":""}'

# Explicitly use Jev routing for decision-shaped examples
reason --mode jev "Check status" '{"ok":false,"route":{"$jev":"choice","options":["approve","manual","deny"]}}'

TypeSafe official API details

export ONE_REASON_JEV_PROVIDER=typesafe
export TYPESAFE_API_KEY=apikey_...
export ONE_REASON_JEV_BASE_URL=https://api.typesafe.ai/v1   # optional default
export ONE_REASON_JEV_MODEL=jev-latest                     # optional default

Calls POST {baseURL}/systemone with Bearer auth. Question types on the wire are noul | choice | score.

Vercel AI Gateway details

export ONE_REASON_JEV_PROVIDER=gateway
export AI_GATEWAY_API_KEY=vck_...
export ONE_REASON_GATEWAY_BASE_URL=https://ai-gateway.vercel.sh/v4/ai   # optional default
export ONE_REASON_GATEWAY_MODEL=typesafe-ai/jev                        # optional default

Gateway evaluation calls:

POST {baseURL}/evaluation-model

with headers:

  • ai-evaluation-model-specification-version: 4
  • ai-model-id: <model>
  • ai-gateway-protocol-version: 0.0.1
  • Authorization: Bearer <key>

Question types on the wire are boolean | choice | score (Gateway uses boolean instead of TypeSafe's noul). No ai@7 dependency is required.

Legacy Jev provider configuration

If you explicitly set ONE_REASON_PROVIDER=typesafe or gateway, reason() continues to support this. When free-text synthesis is needed in mode: "jev", it falls back to ONE_REASON_FALLBACK_* or ~/.config/one/one.json:

export ONE_REASON_PROVIDER=typesafe
export ONE_REASON_OPENAI_API_KEY=...
export ONE_REASON_FALLBACK_PROVIDER=openai-compatible
export ONE_REASON_FALLBACK_OPENAI_API_KEY=...
export ONE_REASON_FALLBACK_MODEL=gpt-4.1-mini

reason(prompt, example, options?)

The third argument is optional and backward compatible:

import { reason } from "@one-agent/reason";

// Decision / control node → Jev (when PROVIDER=typesafe|gateway)
await reason("goal: should we retry?", {
  retry: false,
  route: {
    $jev: "choice",
    options: ["a", "b", "c"],
  },
});

// Summary / synthesis → LLM fallback under Jev mode
await reason("goal: summarize the log", {
  summary: "",
  findings: "",
  next: "",
});

// Force LLM even if PROVIDER is typesafe
await reason(prompt, example, { mode: "llm" });

// Force Jev (errors if example has free-text)
await reason(prompt, { retry: false }, { mode: "jev" });

// Optional state / threshold overrides
await reason(prompt, { ok: false }, {
  mode: "jev",
  state: { goal: "...", observation: "..." },
  booleanThreshold: 0.6,
});

| mode | Behavior | | --- | --- | | omitted / llm | Always use the LLM path (backward-compatible default) | | jev | Decision-shaped example → Jev; free-text example or unavailable Jev → LLM fallback |

Example → question mapping (decision-shaped)

For Jev, prompt (or options.state) becomes evaluation state, and questions are always derived from example:

| Example field | Jev question | | --- | --- | | boolean | noul / boolean | | number | score (auto level 0 .. level N criteria) | | plain string | not Jev → LLM synthesis / Jev-mode fallback | | { "$jev": "noul"\|"choice"\|"score", ... } | explicit question |

Choice options must be declared explicitly in the example; a string value or string array is not reinterpreted as a choice set:

{
  route: {
    $jev: "choice",
    options: ["approve", "manual", "deny"],
  },
}

This keeps reason(prompt, example) aligned with the example's JSON shape: an array remains an array, and a string remains a string.

Score ranges can be declared explicitly without parsing prompt text:

{
  risk: {
    $jev: "score",
    range: [0, 100],
    instructions: "评估退款风险",
  },
}

The Jev backend still receives at most 10 score levels; the returned level is mapped back into the declared range. Use levels (2–10) or custom criteria when you need different score granularity.

Nested objects are flattened to dotted question ids and rebuilt into the example shape when answers are applied.

Errors 401 / 422 / 429 / 529 return clear messages; 429 and 529 are retried lightly with backoff.