> ## Documentation Index
> Fetch the complete documentation index at: https://docs.standardagentbuilder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# @standardagents/typesafe

> TypeSafe AI decision inference with typed questions, probabilities, and automatic thread logs

First-party TypeSafe AI decision inference for Standard Agents. Jev evaluates
explicit context against multiple independent questions in one request. The
package implements `DecisionProviderInterface` (`kind: 'decision'`, `decide()`),
independently of the conversational provider `generate()` and `stream()` methods.
Use it from hooks, tools, handlers, or thread endpoints; keep prompt-backed
conversation models configured separately with `defineModel`.

## Install and configure

```bash theme={null}
pnpm add @standardagents/typesafe
```

Set `TYPESAFE_AI_API_KEY` in local `.dev.vars` or production secrets for BYOK.
`state.decide()` resolves scoped provider credentials and hosted routing.
Provider and platform destinations come only from trusted instance-admin or
deployment configuration; user/thread URL overrides cannot redirect inherited
credentials.
Hosted requests use the platform TypeSafe route when supported and configured;
platform availability requires a platform-owned TypeSafe credential.

## Decide within a thread

```typescript theme={null}
import { typesafe } from '@standardagents/typesafe';

const result = await state.decide({
  provider: typesafe,
  model: 'jev-latest',
  context: { ticket: 'My payment failed twice. Please refund it.' },
  questions: {
    department: {
      type: 'choice',
      instructions: 'Which team should handle this ticket?',
      options: { billing: 'Payments and refunds', technical: 'Software failures', other: null },
    },
    severity: {
      type: 'score',
      instructions: 'How disruptive is this problem?',
      levels: ['Minor inconvenience', 'Work blocked', 'Critical outage'],
    },
    refund: {
      type: 'boolean',
      instructions: 'Does the customer explicitly request a refund?',
      criteria: { true: 'An explicit refund request', false: 'No refund requested' },
    },
  },
});

const team = result.answers.department.choice;
const refundRequested = result.answers.refund.probability >= 0.9;

```

`decide(state, options)` from `@standardagents/spec` or `@standardagents/builder`
is an equivalent SDK helper. In AgentBuilder, both forms record the request, response, duration,
status, usage, and known cost in the thread's application logs, including failure
information. They work outside an active conversation turn, and their logs
persist even before the thread has its first message. They do not read or
write conversation messages implicitly. If an answer belongs in conversation
history, explicitly call `state.injectMessage()` with the selected information.
Avoid logging the same decision cost again through `state.log()`.

Automatic logs, `state.log()`, and log attribution are AgentBuilder extensions,
not Standard Agent conformance requirements. Import log types such as
`ThreadLogEntry` from `@standardagents/builder`.

AgentBuilder adds optional `name` and `trigger` to the thread call to identify the operation
and its cause. Pass `signal` to cancel a request. Context is explicit: a string,
JSON object, or array. Select any relevant conversation content yourself rather
than assuming Jev receives the thread history. Pre-process images, audio, video,
and binary data into text or structured fields.

## Questions and native conversion

Every question has a stable name and `instructions`. Write the full question in
`instructions`: the question's map key is an answer identifier, not an instruction
sent to Jev. Instructions, option descriptions, rubric levels, and boolean
criteria may be strings, JSON objects, or arrays. Surface the domain's actual
options and scoring rubric in each invocation so the decision is unambiguous.

| Standard Agent request | Native TypeSafe request |
| - | - |
| `context` | `state`, preserving its JSON structure |
| `questions.<id>.type: 'choice'` with `options` | `type: 'choice'` with `criteria` |
| `questions.<id>.type: 'score'` with ordered `levels` | `type: 'score'` with ordered `criteria` |
| `questions.<id>.type: 'boolean'` with optional `criteria.true/false` | `type: 'noul'` with the same optional criteria |
| Each question's `instructions` and identifier | Preserved |

All questions share one state and are evaluated in one `POST /v1/systemone`
request. Choice accepts up to 255 options; use `null` for an option that needs no
extra description. Score accepts 2–10 ordered levels. Put rules and boundary
cases in instructions and criteria; do not put questions in provider connection
configuration or represent them as generated tool calls.

## Answers and thresholds

`result` contains the resolved `model`, named `answers`, standard `usage`, and
provider `metadata`. Every answer retains its question identifier:

* Choice: `{ type: 'choice', choice, probabilities, confidence }`.
* Score: `{ type: 'score', score, legend, probabilities, confidence }`. The score
  is a probability-weighted, zero-based rubric value and can be fractional.
* Boolean: `{ type: 'boolean', probability }`, converted from native `noul`.

Probabilities and confidence use **0–1**. Boolean results are never coerced to
JavaScript booleans; choose and validate a threshold for the application's
policy. Confidence is provider-reported and is distinct from an option's
probability. Preserve the full probability distribution, score legend, and
confidence when storing or presenting results. Native rounded distributions can
sum slightly above or below one; the provider preserves them without silently
renormalizing. `metadata.native` retains the native response, and `metadata.rounding` records
probability and score precision.

## Standalone use

```typescript theme={null}
import { typesafe } from '@standardagents/typesafe';

const provider = typesafe({ apiKey: 'your-typesafe-key' });
const result = await provider.decide({
  model: 'jev-latest',
  context: 'The customer asks to cancel their plan.',
  questions: {
    cancel: { type: 'boolean', instructions: 'Does this request cancellation?' },
  },
});
```

Direct `provider.decide()` calls have no thread and create no automatic thread
logs. Connection configuration supports `apiKey`, `baseUrl`, `timeout`,
`defaultHeaders`, and a custom `fetch`; the default base is
`https://api.typesafe.ai/v1`. For thread calls, trusted instance-admin or
deployment configuration can override it with `TYPESAFE_AI_BASE_URL`.
Authenticated `getModels()` uses `/models`. Each attempt
makes one HTTP request; the caller or runtime owns retry policy. Invalid
questions or mismatched answers raise a `ProviderError`.

## Usage and pricing

Native `usage.input_tokens` maps to `promptTokens`, `output_tokens` to
`completionTokens`, and their sum to `totalTokens`. Current Jev 1.13
(`jev-1.13.0`, and currently `jev-latest` / `jev-preview`) costs **\$0.042 per
million input tokens**, with free output. State is ingested once for all
questions: use provider-reported input usage unchanged, without multiplying it
by the question count. Hosted router fees are additional.

Aliases may move to new versions. `result.model` identifies the actual version;
re-audit rates when aliases change, or pin `jev-1.13.0` for a fixed version.
An unpriced resolved model does not receive an invented `usage.cost`.
Current context limits are 64k tokens for state plus all questions and 32k for
state plus the longest question. See the [TypeSafe model reference](https://docs.typesafe.ai/models)
and [native API reference](https://docs.typesafe.ai/api) for current limits.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.