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

decision-os-sdk

v0.2.0

Published

Official TypeScript/JavaScript SDK for Decision OS — AI decision governance platform

Readme

decision-os-sdk

Official TypeScript SDK for Decision OS — the AI governance control plane.

Log decisions, capture runtime snapshots, and enforce policies across your AI agents with a single lightweight dependency.

Installation

npm install decision-os-sdk

No peer dependencies. Works in Node.js 18+, Edge Runtime, and Bun.

Quickstart

import { DecisionOS } from "decision-os-sdk";

const dos = new DecisionOS({
  apiKey: process.env.DECISION_OS_API_KEY!,
  agentId: "your-agent-id",          // bind once, reuse across calls
  baseUrl: "https://decisionos.com", // your Decision OS instance
});

// Log a decision with inline policy evaluation
const { decision_id, policy_eval } = await dos.logDecision({
  context: "Route this support ticket to the right team",
  options: [
    { key: "engineering", label: "Engineering" },
    { key: "billing",     label: "Billing" },
    { key: "security",    label: "Security" },
  ],
  constraints: ["SLA < 4h", "Tier: enterprise"],
  chosen: "engineering",
  confidence: 0.91,
  run_policy_eval: true, // evaluate against the agent's active policy
});

console.log(decision_id);  // "d_..." — immutable ledger entry
console.log(policy_eval);  // { ok: true, diff: {...} }

Configuration

const dos = new DecisionOS({
  apiKey:    string;   // required — Bearer token from Settings → API Keys
  baseUrl?:  string;   // default: "https://decisionos.com"
  agentId?:  string;   // bind a default agent_id (overridable per call)
  timeoutMs?: number;  // default: 8000 (8 seconds)
  retries?:   number;  // default: 2 (exponential backoff on 5xx / 429)
  userAgent?: string;  // optional x-client header for tracing
});

Methods

logDecision(input)

Writes a decision to the immutable Decision OS ledger. Returns a decision_id that anchors all downstream records (snapshots, outcomes, replays).

const response = await dos.logDecision(input: LogDecisionInput);

Parameters

| Field | Type | Required | Description | |---|---|---|---| | context | string | ✅ | The decision prompt, question, or situation | | chosen | string | ✅ | The key of the option the agent selected | | agent_id | string | if not in config | ID of the governed agent | | decision_type | string | — | Default: "action_selection" | | options | DecisionOption[] | — | All considered options with labels and probabilities | | constraints | string[] | — | Constraints that were active at decision time | | assumptions | DecisionAssumption[] | — | Assumptions the agent operated under | | confidence | number | — | Agent confidence 0–1 | | policy_version_id | string | — | Pin to a specific policy version | | runner | string | — | Runner identifier (e.g. "gpt_runner") | | model | string | — | Model used (e.g. "gpt-4o") | | prompt_version | string | — | Prompt version string | | parameters | Record<string, unknown> | — | Runner parameters (temperature, top_p, etc.) | | trace_id | string | — | OTel / LangSmith trace ID | | run_id | string | — | Run or thread ID | | span_id | string | — | Span ID for distributed tracing | | parent_span_id | string | — | Parent span ID | | request_id | string | — | Idempotency key — duplicate calls return the original | | run_policy_eval | boolean | — | Run inline policy evaluation and return the diff |

Response

type LogDecisionResponse = {
  decision_id: string;                         // immutable ledger ID
  status: "draft" | "committed" | string;
  policy_eval?: {                              // present if run_policy_eval: true
    ok: boolean;
    replay_id?: string;
    policy_version_id?: string;
    diff?: Record<string, unknown>;
    error?: string;
  };
};

Full example

const { decision_id, policy_eval } = await dos.logDecision({
  context: "Should we approve this loan application? Credit score: 720, DTI: 38%",
  options: [
    { key: "approve",        label: "Approve",              probability: 0.72 },
    { key: "decline",        label: "Decline",              probability: 0.18 },
    { key: "manual_review",  label: "Send to underwriting", probability: 0.10 },
  ],
  constraints: ["Regulatory: ECOA", "Max DTI: 43%"],
  assumptions: [
    { text: "Credit score is current",      confidence: 0.99 },
    { text: "Income is verified",           confidence: 0.95 },
    { text: "No adverse employment events", confidence: 0.87 },
  ],
  chosen:     "approve",
  confidence: 0.72,
  runner:     "lending_runner_v2",
  model:      "gpt-4o",
  prompt_version: "lending-v3.1",
  trace_id:   opentelemetrySpan.traceId,
  run_id:     workflowRunId,
  request_id: transactionId,   // idempotency — safe to retry
  run_policy_eval: true,
});

if (policy_eval && !policy_eval.ok) {
  // Active policy flagged this decision — alert or escalate
  await sendAlert(decision_id, policy_eval.error);
}

captureSnapshot(input)

Attaches runtime evidence to an existing decision: model telemetry, tool call traces, timing data, and evaluation results. Use this immediately after the agent produces its output.

const response = await dos.captureSnapshot(input: CaptureSnapshotInput);

Parameters

| Field | Type | Required | Description | |---|---|---|---| | decision_id | string | ✅ | The decision_id from logDecision | | snapshot | Record<string, unknown> | ✅ | Freeform runtime state to preserve | | agent_id | string | if not in config | ID of the governed agent | | event_id | string | — | Source event ID for the snapshot | | policy_version_id | string | — | Policy version active at capture time | | schema_version | string | — | Snapshot schema version string | | captured_at | string | — | ISO 8601 timestamp (defaults to now) | | trace_id | string | — | OTel trace ID | | run_id | string | — | Run or thread ID | | span_id | string | — | Span ID | | parent_span_id | string | — | Parent span ID | | request_id | string | — | Idempotency key | | tool_calls | Record<string, unknown> | — | Tool call records (inputs, outputs, errors) | | model_usage | Record<string, unknown> | — | Token counts: { input_tokens, output_tokens, total_tokens } | | timings | Record<string, unknown> | — | Latency data: { latency_ms, first_token_ms } | | eval | Record<string, unknown> | — | Evaluation results (rubric scores, pass/fail) | | eval_score | number | — | Scalar evaluation score 0–1 | | eval_pass | boolean | — | Whether the evaluation passed |

Response

type CaptureSnapshotResponse = {
  snapshot_id: string;
};

Full example

const { snapshot_id } = await dos.captureSnapshot({
  decision_id: decision_id,          // from logDecision
  snapshot: {
    input:    userMessage,
    output:   agentResponse,
    state:    graphState,
  },
  tool_calls: {
    search: { query: "loan regulations DTI", results_count: 14, latency_ms: 340 },
  },
  model_usage: {
    input_tokens:  1842,
    output_tokens: 287,
    total_tokens:  2129,
  },
  timings: {
    latency_ms:      1240,
    first_token_ms:  380,
  },
  eval:       evalResult,
  eval_score: 0.94,
  eval_pass:  true,
  trace_id:   opentelemetrySpan.traceId,
  run_id:     workflowRunId,
});

logOutcome(input)

Closes the governance loop by recording what actually happened after a decision was made. The outcome is appended to the workspace outcome chain with a tamper-evident hash linking it to the original decision.

const outcome = await dos.logOutcome({
  decision_id: decision_id, // from logDecision
  status:      "success",   // "success" | "partial" | "fail" | "unknown"
  notes:       "Resolved in 2h by engineering team",
  actual:      { resolution_type: "human_override", override_by: "agent_supervisor" },
});

console.log(outcome.outcome_id);   // immutable outcome ledger ID
console.log(outcome.chain_index);  // position in the outcome chain
console.log(outcome.content_hash); // SHA-256 hash for this outcome

Parameters

| Field | Type | Required | Description | |---|---|---|---| | decision_id | string | ✅ | The decision_id from logDecision | | status | string | ✅ | "success" | "partial" | "fail" | "unknown" | | notes | string \| null | — | Human-readable outcome summary | | actual | Record<string, unknown> \| null | — | Structured outcome data |


verifyChain(options?)

Cryptographically verifies the workspace decision and outcome chains by recomputing SHA-256 hashes and confirming prev_hash links. Returns a verification report for compliance attestation.

const report = await dos.verifyChain({ lastN: 100 });

if (!report.ok) {
  console.error("Chain integrity failure:", report.decisions.error_details);
}

console.log(`Verified ${report.decisions.checked} decisions — ${report.decisions.errors} errors`);
console.log(`Verified ${report.outcomes.checked} outcomes  — ${report.outcomes.errors} errors`);

Parameters

| Field | Type | Description | |---|---|---| | lastN | number | Verify the N most recent records in each chain. Default: 50 |


Error handling

The SDK throws DecisionOSApiError for non-retriable API errors (4xx). Transient errors (5xx, 429, timeouts) are retried automatically up to retries times with exponential backoff.

import { DecisionOS } from "decision-os-sdk";

try {
  const result = await dos.logDecision({ ... });
} catch (err) {
  if (err instanceof Error) {
    // err.message includes the HTTP status and API error text
    // e.g. "DecisionOS: API error 401 Unauthorized - invalid api key"
    console.error(err.message);
  }
}

Network timeouts abort after timeoutMs (default 8s) and are retried.


TypeScript types

import type {
  DecisionOSConfig,
  LogDecisionInput,
  LogDecisionResponse,
  CaptureSnapshotInput,
  CaptureSnapshotResponse,
  DecisionOption,
  DecisionAssumption,
} from "decision-os-sdk";

Integration examples

LangGraph (TypeScript)

import { StateGraph, END } from "@langchain/langgraph";
import { DecisionOS } from "decision-os-sdk";

const dos = new DecisionOS({
  apiKey:  process.env.DECISION_OS_API_KEY!,
  agentId: "fraud-review-agent",
  baseUrl: "https://decisionos.com",
});

async function reviewNode(state: { summary: string; runId: string }) {
  const verdict = await runFraudModel(state.summary);

  const { decision_id } = await dos.logDecision({
    context:    state.summary,
    options:    [{ key: "approve" }, { key: "decline" }, { key: "review" }],
    chosen:     verdict.action,
    confidence: verdict.confidence,
    run_id:     state.runId,
    run_policy_eval: true,
  });

  return { ...state, decisionId: decision_id };
}

const graph = new StateGraph({ channels: stateSchema })
  .addNode("review", reviewNode)
  .addEdge("review", END);

Full guide: LangGraph + Decision OS integration

OpenAI Assistants API + Chat Completions

Use the built-in integration helpers for zero-boilerplate logging. They automatically extract model, usage, latency, and thread metadata.

import { DecisionOS } from "decision-os-sdk";
import { logAssistantRun, logChatCompletion } from "decision-os-sdk/integrations/openai";
import OpenAI from "openai";

const dos = new DecisionOS({
  apiKey:  process.env.DECISION_OS_API_KEY!,
  agentId: "support-router",
});

const openai = new OpenAI();

// ── Assistants API ─────────────────────────────────────────────────────────
const run = await openai.beta.threads.runs.poll(thread.id, run.id);

await logAssistantRun(dos, run, {
  decisionContext: "Classify and route support ticket #8820",
  chosen:          lastAssistantMessage,
  // model, usage, latency, thread_id extracted automatically
});

// ── Chat Completions ───────────────────────────────────────────────────────
const completion = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: prompt }],
});

await logChatCompletion(dos, completion, {
  decisionContext: "Route support ticket",
  chosen:          completion.choices[0].message.content ?? "unknown",
  // model, usage extracted automatically; snapshot captured fire-and-forget
});

REST API (any language)

curl -X POST https://decisionos.com/api/public/v1/decisions \
  -H "Authorization: Bearer dos_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "your-agent-id",
    "context": "Classify this document",
    "chosenOptionKey": "contract",
    "confidence": 0.94,
    "options": [
      { "key": "contract" },
      { "key": "invoice" },
      { "key": "other" }
    ],
    "runPolicyEval": true
  }'

Resources

License

MIT