JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 744
  • Score
    100M100P100Q87692F
  • License Apache-2.0

Official TypeScript SDK for the COHESION Judgment Independence Score API. Real-time oversight scoring for AI-assisted human decisions, per EU AI Act Article 14, Colorado SB 205, and NYC Local Law 144.

Package Exports

  • @cohesionauth/sdk
  • @cohesionauth/sdk/package.json

Readme

@cohesionauth/sdk

Save humanity by keeping judgment alive in the age of AI.

Official TypeScript SDK for the COHESION Judgment Independence Score API. Measure and certify human oversight of AI-assisted decisions in real time, per EU AI Act Article 14, Colorado SB 205, and NYC Local Law 144.

  • npm: @cohesionauth/sdk
  • License: Apache-2.0
  • Requires: Node.js 20 or later
  • Base URL: https://api.cohesionauth.com (human-readable docs at https://cohesionauth.com/api)

Install

npm install @cohesionauth/sdk

Quickstart

import { Cohesion } from "@cohesionauth/sdk";

const client = new Cohesion({ apiKey: process.env.COHESION_API_KEY! });

const result = await client.score({
  session_id: "sess_2026_04_22_001",
  operator_id: "analyst-42",
  domain: "financial",
  interaction: {
    ai_recommendation_presented: true,
    time_to_decision_ms: 3400,
    decision: "modified",
    modification_extent: 0.25,
    ai_available: true,
    scenario_type: "standard",
    outcome_correct: null,
    hover_events: 4,
    scroll_depth: 0.9,
    alternative_views_checked: 1,
  },
});

console.log(`JIS ${result.jis} (${result.band})`);

DRS gate — the Authorized Inference Gateway

cohesion.gate() wraps a regulated AI call with the Decision Risk Score engine. The contract is strict-gate, fail-closed: the SDK refuses to surface a final AI output unless DRS returned a clean routing_decision envelope.

import {
  Cohesion,
  gate,
  CohesionPolicyBlockedError,
  CohesionRequiresHumanReviewError,
  CohesionMalformedDecisionError,
} from "@cohesionauth/sdk";

const client = new Cohesion({ apiKey: process.env.COHESION_API_KEY! });

// 1. Pre-AI pass: ask DRS whether the input is admissible at all.
const preDecision = await gate(client, request, null);

if (preDecision.routing_decision !== "auto") {
  // must_review / async_review / forced_escalation — route to a human reviewer
  // BEFORE calling the AI provider. preDecision.review_queue_id is the handle.
  return routeToReviewer(preDecision);
}

// 2. Call the AI provider.
const aiOutput = await provider.complete(request);

// 3. Post-AI pass: ask DRS whether to surface the AI output.
try {
  const postDecision = await gate(client, request, aiOutput);
  // routing_decision === 'auto', no forced escalation — safe to surface.
  return aiOutput;
} catch (e) {
  if (e instanceof CohesionPolicyBlockedError) {
    // Hard block: never surface this AI output. e.decision.drs_reason_codes
    // and e.decision.policy_evaluation.hard_failures explain why.
    return blockResponse(e);
  }
  if (e instanceof CohesionRequiresHumanReviewError) {
    // Route to reviewer; e.decision.review_queue_id is the handle.
    return routeToReviewer(e.decision);
  }
  if (e instanceof CohesionMalformedDecisionError) {
    // Fail-closed sentinel: DRS returned 2xx but the envelope was malformed.
    // Treat as a hard block. Contact support with e.requestId.
    return blockResponse(e);
  }
  // Network / 5xx / retry-exhausted -> caller MUST treat as fail-closed.
  // Do NOT surface the AI output. The plain `CohesionError`, `ServerError`,
  // `NetworkError` types preserve `requestId` for incident tracing.
  return blockResponse(e);
}

The fail-closed contract on transport failure: if DRS does not return a 2xx envelope (network error, 5xx after retries, abort), gate() re-throws the underlying error unchanged. The caller MUST NOT surface the AI output. Treat any non-resolution as a hard block.

Error class taxonomy:

Error Thrown on Carries
CohesionPolicyBlockedError routing_decision === 'policy_blocked' on either pass decision.drs_reason_codes, decision.policy_evaluation.hard_failures, decision.ai_decision_log_id
CohesionRequiresHumanReviewError Post-AI must_review / async_review / non-empty forced_escalation_rules_triggered decision.review_queue_id
CohesionMalformedDecisionError 2xx with missing or unrecognized envelope fields (fail-CLOSED) observedKeys, missingFields
ServerError / NetworkError retry-exhausted transport failure requestId

Pre-AI must_review / async_review / forced escalation return the envelope without throwing — that branch is the caller's signal to route to a reviewer before the AI call.

See examples/07-live-gate.ts for a runnable end-to-end demonstration.

Side-by-side

The same request in three forms.

cURL

curl https://api.cohesionauth.com/v1/score \
  -H "X-API-Key: $COHESION_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d @payload.json

Python

from cohesion import Client

client = Client(api_key=os.environ["COHESION_API_KEY"])
result = client.score(
    session_id="sess_...",
    operator_id="analyst-42",
    domain="financial",
    interaction={...},
)

TypeScript

import { Cohesion } from "@cohesionauth/sdk";

const client = new Cohesion({ apiKey: process.env.COHESION_API_KEY! });
const result = await client.score({ /* ... */ });

5-minute integrations (1.1.0)

Three drop-in patterns. Pick the one that fits your stack.

Express

import express from "express";
import { Cohesion, cohesionExpress } from "@cohesionauth/sdk";

const cohesion = new Cohesion({ apiKey: process.env.COHESION_API_KEY! });
const app = express();

app.use(
  cohesionExpress({
    client: cohesion,
    domain: "financial",
    operatorIdResolver: (req) => String(req.headers["x-user-id"] ?? "anon"),
  }),
);

Next.js (App Router route handler)

import { Cohesion, cohesionNextRoute } from "@cohesionauth/sdk";

const cohesion = new Cohesion({ apiKey: process.env.COHESION_API_KEY! });

export const POST = cohesionNextRoute(
  async (req) => Response.json({ ok: true }),
  {
    client: cohesion,
    domain: "general", // SOC alert-triage maps here per the v1.2 spec
    operatorIdResolver: (req) => req.headers.get("x-user-id") ?? "anon",
  },
);

Decorator (any function — class method or HOF wrap)

import { measure } from "@cohesionauth/sdk";

const handle = measure({
  client: cohesion,
  domain: "financial",
  operatorIdResolver: ([req]: [{ userId: string }]) => req.userId,
})(originalHandle);

domain is one of healthcare | aviation | financial | legal | pharmaceutical | general. SOC use cases map to general per v1.2 §4 Option A.

For chat-completion patterns (OpenAI / Anthropic / LangChain / Vercel AI), see Provider integrations below or import the chat namespace:

import { chat } from "@cohesionauth/sdk";
const wrapped = chat.wrapOpenAI(openai, cohesion, ctx);

Six full integration examples live under examples/.

Client options

new Cohesion({
  apiKey: string,                                  // required
  baseUrl?: string,        // default "https://api.cohesionauth.com"
  timeout?: number,        // default 30000 ms
  maxRetries?: number,     // default 3
  logger?: Logger,         // default createDefaultLogger()
  enableTelemetry?: boolean, // default false (opt-in Sentry)
});

Method reference

Method HTTP Notes
client.score(req) POST /v1/score Idempotency-Key auto-generated
client.scoreBatch(req) POST /v1/score/batch up to 100 interactions
client.operatorProfile(operatorId) GET /v1/operator/:id/profile includes JIS history
client.organizationDashboard() GET /v1/organization/dashboard aggregate metrics
client.maintenanceRecommend(req) POST /v1/maintenance/recommend judgment-maintenance exercises
client.complianceReport() GET /v1/compliance/report EU AI Act Article 14 rollup
client.adminKeyRotate() POST /v1/admin/key/rotate returns new key ONCE
client.adminKeyRevoke() POST /v1/admin/key/revoke sets org inactive
client.adminAuditLog(opts?) GET /v1/admin/audit-log own-org events only

AI-provider wrappers

Instrument OpenAI, Anthropic, Azure OpenAI, Vercel AI SDK, or LangChain.

import OpenAI from "openai";
import { Cohesion, wrapOpenAI } from "@cohesionauth/sdk";

const cohesion = new Cohesion({ apiKey: process.env.COHESION_API_KEY! });
const openai = wrapOpenAI(new OpenAI(), cohesion, {
  operatorId: "analyst-42",
  sessionId: "sess_...",
  domain: "financial",
});

const { response, recordDecision } = await openai.chat.completions.create({
  model: "gpt-4",
  messages: [{ role: "user", content: "Draft SAR narrative" }],
});

// Present `response` to the human. After they decide:
const score = await recordDecision({
  decision: "modified",
  modificationExtent: 0.3,
});

Equivalent helpers: wrapAnthropic, wrapAzureOpenAI, vercelAIMiddleware, langChainHandler.

Errors

Every SDK error carries requestId and nextStep.

Class HTTP Extra fields nextStep example
AuthenticationError 401 "Check the 8-character prefix of your key. New customers get a key at cohesionauth.com/signup; existing customers rotate at cohesionauth.com/dashboard/api-keys."
RateLimitError 429 retryAfter: number "Retry after 7 seconds."
ValidationError 400, 413, 422 field, allowedValues "scenario_type must be one of: standard, independent, trap, split."
ServerError 5xx populated only when actionable
NetworkError transport cause "Check connectivity to api.cohesionauth.com and ensure TLS 1.3 egress is permitted from your environment."
CohesionError base hierarchy root
import { RateLimitError } from "@cohesionauth/sdk";

try {
  await client.score(req);
} catch (err) {
  if (err instanceof RateLimitError) {
    console.log(`Retry in ${err.retryAfter}s. Hint: ${err.nextStep}`);
  } else {
    throw err;
  }
}

CLI

npx cohesion score --operator-id analyst-42 --from-file payload.json
# or via stdin:
cat payload.json | npx cohesion score --operator-id analyst-42 --from-file -

Retry and idempotency

  • Exponential backoff with full jitter. Default max 3 retries.
  • Retries only on 429 and 5xx. All 4xx (except 429) fail fast.
  • Honors Retry-After header (integer seconds or HTTP-date).
  • Every POST auto-populates Idempotency-Key with a UUIDv4 so retries are safe to replay.

Environment variables

Name Purpose
COHESION_API_KEY API key. Required for the CLI.
COHESION_BASE_URL Override the base URL (staging, self-hosted).
COHESION_LOG_FORMAT Set to json for structured logs.
COHESION_LOG_LEVEL debug, info, warn, or error.
COHESION_TEST_API_KEY Enables the live integration test.
COHESION_SENTRY_DSN or SENTRY_DSN Opt-in telemetry, only when enableTelemetry: true.

Logging and redaction

The default logger redacts API keys (ck_live_*) and operator_id values before emit. Set COHESION_LOG_FORMAT=json for structured output suitable for Datadog, Sentry, or Cloudflare Logpush.

License

Apache License 2.0. See LICENSE and NOTICE.

The COHESION Judgment Independence Score methodology, scoring engine, and intervention protocol are subject to the provisional patent filed 2026-04-13.