<!-- Markdown mirror. Canonical: https://empryo.com/docs/tools/typesafe -->

# TypeSafe (jev)

> Set up TypeSafe's jev classifier for find re-ranking and skill suggestions in Empryo, with costs, fallback rules, and measured limitations.

TypeSafe's `jev` is a classifier: send state and named questions, get labels with probabilities, not text.
Empryo uses it to suggest an installed skill or re-rank `find` candidates. Both features are off by default.
Read [the measurements and method](/typesafe) before enabling them.

## Get a key

Create an API key at [typesafe.ai](https://typesafe.ai).

In the terminal UI, type `/typesafe` to **open the TypeSafe panel**. The first row is the API key: press Enter on it, paste the key, press Enter again. It is stored as the `typesafe-api-key` secret, in the OS keychain when one is available. Every switch below it lives in the same panel.

`/websearch` is a different command: it toggles the web search tool.

On desktop, open settings and pick **TypeSafe**. Enter the key in the field with the **TYPESAFE_API_KEY** placeholder and save it.

Alternatively, set the environment variable before launching Empryo:

```bash
export TYPESAFE_API_KEY=apikey_...
```

## Turn it on

In the terminal, `/typesafe` lists every switch under the key row. Enter toggles the one under the cursor:

- **Use TypeSafe** is the master switch. Off means no call is ever made.
- **Search re-rank** applies to the `find` tool only.
- **Re-rank mode** is `shadow` or `apply`.
- **Skill suggestion** ranks installed skills once per turn.
- **Error triage** re-reads a failed model call, once, at the moment the turn would otherwise end.

`shadow` is the default. It computes and prices the proposed order, shows the result in chat, and gives the model the tool's original order. `apply` lets the proposed order through.

Desktop uses the same four labels in its TypeSafe settings section.

On the Telegram and Discord surfaces there is no panel, so the same switches are one-shot commands:

```text
/typesafe on
/typesafe-rerank on
/typesafe-rerank-mode shadow
/typesafe-skills on
/typesafe-triage on
```

Every feature needs its own switch, the master switch, and an API key.

## Error triage

Empryo decides what to do with a failed model call by matching the provider's error text with regular expressions (`packages/core/src/llm/transient.ts`). Three verdicts: retry it, shrink the conversation and resend, or end the turn. The file has needed ten fixes in two months, each one a provider wording the patterns did not cover.

With **Error triage** on, one classifier call runs at a single point: the regexes have said the failure is permanent, so the turn is about to end, and a wrong verdict costs the whole turn. If jev says the failure is a context overflow or a transient fault, and it is at least 0.7 confident, the turn recovers instead of dying.

It is never asked about an authentication failure. A classifier that turns a bad key into "retry" spends money in a loop and hides the one error you need to see.

Measured on the 24 incidents pinned in `transient.test.ts`, each one a real failure: the shipped regexes score 23 of 24, jev scores 24 of 24 with no tuning, at 263ms median. The case the regexes miss is a Codex overflow reported as `Input exceeds the maximum length of 1048576 characters`, whose text contains neither "context" nor "token"; jev calls it an overflow at 0.96 confidence. The harness is `marketing_local/bench/jev-error-triage.ts`.

Because it only runs on failures the regexes already gave up on, a healthy session makes no calls at all.

## What a classifier is not for

Two recipes were built, measured against the code they would replace, and lost to it.

Search re-ranking on `grep`: replayed over 220 real searches, the file the turn went on to read was in the top three 78.6% of the time with the tool's own order and 74.1% with jev's. Removed.

The forgotten-file check: git co-change proposes the five files that usually move with the ones you changed, and jev picks the one this change actually needs. Co-change's own first pick was right 62.1% of the time; jev's was right 52.6% (95 leave-one-out cases on real commits). The bare count wins, so `git status` ships the co-change line with no model call at all.

The pattern across every measurement here: jev reads **prose** better than the regexes we hand-wrote, and ranks **code artifacts** worse than the counting statistics already in the Genome.

## What you see and what it costs

Each call shows a chat cue with the decision, model, token count, and cost. Every call also writes one row to the tab total and one to the usage ledger.

One call costs about **$0.00005**, with **244ms median latency** and **283ms p90 latency**, measured over **290 calls**. jev costs **$0.042 per million input tokens**. Empryo carries that price itself because jev is not in any model catalog. Shadow mode still makes a paid call.

## Configuration

This config enables re-ranking in shadow mode and leaves skill suggestion off:

```json
{
  "typesafe": {
    "enabled": true,
    "rerank": true,
    "rerankMode": "shadow",
    "skillSuggestion": false,
    "model": "jev-latest",
    "rerankTimeoutMs": 800
  }
}
```

Use `~/.empryo/config.json` for all projects or `.empryo/config.json` for one project. Keep the key in the secret field or environment variable rather than in this block.

## How it fails

- **Missing key or disabled switch:** no call is made.
- **Timeout:** the re-ranker has an 800ms budget and falls back to the tool's own order.
- **API failure:** the tool's own order is kept.
- **Fewer than 3 candidates:** no call is made.
- **Flat probability distribution:** if the top probability is under 0.15, the order is left alone.
- **More than 8 searches in one turn:** the rest of the turn runs without re-ranking.
- **Two identical searches in one turn:** they are answered once, then the result is reused.

## What it will not do

Re-ranking is wired to **`find` only**. It reorders existing candidates; it cannot recover a file missing from the candidate list. It does not write code or replace the model running the turn.

It was also wired to `grep`, then removed after scoring worse on **220 replayed searches**. The answer-key file appeared in the first three candidates in **78.6%** of searches with the tool's order, compared with **74.1%** with jev's order. Re-ranking improved **21 searches** and made **31 searches** worse.

A review-verdict recipe was removed after **2 of 20 confident answers** said **PASS** where the report said **FAIL**. TypeSafe does not decide whether a review passes.

See [the measurements and replay method](/typesafe) for how these results were scored.
