#12372·oh-my-pi

Official TypeSafe Jev skill suggestion (core, not a copy-paste example)

Author: kvnlooCreated Sep 17, 2026Updated Sep 17, 2026

A PR that implements this is coming in the same turn (kvnloo:feat/typesafe-skill-suggestion). Please do not have robomp pick this up independently.

Follow-up to #12363 / #12364 (copy-paste examples/extensions/typesafe-jev.ts). Related-but-different from #9429 (deterministic skill_search / allowlist — not TypeSafe).

What is missing

OMP already uses TypeSafe as a judgment backend (/login typesafe, TYPESAFE_API_KEY, providers.judgmentProvider, auto-thinking, unexpected-stop, git AI staging, eval judge()).

It does not yet name which installed skill to read before a turn. With a few dozen SKILL.md files the model still guesses from truncated one-liners. TypeSafe's published cookbook is exactly this problem: Skill suggestion.

The example in #12364 duplicates fetch, walks three hardcoded skill dirs, and parses ~/.omp/.env itself. Core already has TypeSafeJudge, loadSkills() / session skills, and /login typesafe.

Proposal

  • Pure suggestSkill(judge, { prompt, skills }) next to the cookbook call 1: one choice + three gate nouls, gate 0.30, no none_of_these
  • Session hook on plain user turns: TypeSafeJudge directly (not resolveJudgeno tiny/smol fallback), 2.5s abort, 1 effective attempt, fail-open
  • Setting skills.suggestion: auto | typesafe | off (default auto = on only when TypeSafe is authenticated)
  • /jev status / auto / typesafe / off
  • Inject <skill_relevance> via the existing per-turn system-prompt override (same path as before_agent_start). Skip if an extension already wrote that tag
  • Hidden skills stay out of the Choice roster

Out of scope

  • Cookbook call 2 (rerank top 3 with SKILL.md excerpts) until the roster hits the 255-choice cap or names collide
  • GodsBoy-style tournament
  • Changing TypeSafeJudge retries for other features
  • Bundling Jev as /model

Live check (this machine, 39 skills, jev-1.13.0)

p50 ~330ms, p95 ~372ms, 0/6 over 2.5s. Chat stays on the session model.