Follow-up TypeSafe Jev use cases after core skill suggestion
Tracking issue. Do not implement independently while #12372 / #12373 is in flight. This is the leftover surface from the TypeSafe cookbook and public Jev usage, not a rewrite of call 1.
Depends on: #12372 (core), #12363 (example). Related-but-different from #9429 (skill_search / allowlist — not TypeSafe).
Already shipped or in review
| Path | Status |
|---|---|
TypeSafe as judgment backend (auto-thinking, unexpected-stop, git AI staging, eval judge()) |
In core today |
Cookbook call 1: one choice over the roster + three gate nouls, gate 0.30, inject <skill_relevance>, fail-open 2.5s, no tiny/smol fallback |
#12373 |
Copy-paste examples/extensions/typesafe-jev.ts |
#12364 |
/jev status / auto / typesafe / off |
#12373 |
Jev as /model |
Never. Max output tokens is 0. |
Call 1 is the published recipe for an omp-sized roster (~40 skills, Choice cap 255). Live check on this machine: p50 ~330ms, p95 ~372ms, 0/6 over 2.5s, jev-1.13.0.
Follow-ups (priority order)
1. Cookbook call 2 — rerank the top 3 with SKILL.md excerpts
Official recipe: Skill suggestion, Step 4.
After call 1 names a shortlist, a second POST /v1/systemone:
which=Choiceover the top 3, criteria = longer description + ~700 chars of eachSKILL.mdfits::{name}= onenoulper candidate (“does this skill actually do the thing asked?”)- Drop the shortlist if the best fits noul is
< 0.30(FITS_THRESHOLD) - Still fail-open; still not a chat model
When to turn it on (not by default):
- Roster grows past ~100, or hits the 255-choice cap
- Two visible skills have colliding names/descriptions (lookalikes)
- Call 1 injects but the chat model then ignores / misreads the skill
mizchi/jev-playground reproduced this cookbook shape (no none_of_these on call 1; inject as advice). Hermes injects the same <skill_relevance> line into the user message to keep the prompt-cache prefix byte-stable; OMP should stay on the per-turn system prompt override (same as pirate.ts / #12373).
Budget: a second ~300ms round trip. Keep the 2.5s wall for the pair, or skip call 2 when call 1 already has high gate + high p. pi-fabric does not auto-retry — a late inject is worse than none.
2. Tournament / chunking past the Choice cap
GodsBoy/jev-agent-skill-router runs a tournament for huge catalogs (~1.3s). Overkill for 40 skills. Worth it only if:
loadSkills()returns more than 255 visible (non-hide) skills, or- call 1 has to drop names because of
MAX_CHOICES
Shape: chunk the roster, run call 1 per chunk in parallel (cookbook notes extra questions barely change latency; extra requests do), then call 2 on the winners. Still TypeSafe-only — do not fall back to tiny/smol to “finish” a tournament.
3. Optional autoload instead of a hint
#12373 appends a <skill_relevance> line and trusts the chat model to Read the skill. Subagents already have autoloadSkills / sendCustomMessage (same mechanic as /skill:<name>).
A later flag, e.g. skills.suggestion.autoload: off | hint | load:
hint(default, current behavior)load= actually inject the skill body the way/skill:does, only when gate andpare both high (stricter than 0.30 — maybe 0.6+) so a wrong pick does not burn context
Do not autoload on a gate miss or a colliding shortlist; fall back to hint or quiet.
4. Collision / lookalike detector on small rosters
Even at 40 skills, systematic-debugging vs recurring-operational-root-cause style pairs confuse call 1. Trigger call 2 (or stay quiet) when the top-2 choice probabilities are within ~0.1 of each other, regardless of roster size. Cheap; no tournament.
5. Observability (not a new backend)
/jev status already prints last name / gate / ms once #12373 lands. Follow-ups if people cannot tell whether Jev ran:
- Session ledger usage with
purpose: "skill-suggestion"(parity with auto-thinking’sonUsage) - One debug log line is already there; do not add a chat-visible banner on every turn (quiet on
heyis a feature)
6. Explicitly never
| Idea | Why not |
|---|---|
/model jev |
Max output tokens 0; it only answers typed questions |
resolveJudge / tiny/smol fallback on this path |
A wrong skill name is worse than none. Other judgment features may fall back; this must not. pi-fabric: no auto-retry |
Raising TypeSafeJudge’s 3× / 10s retry for skill suggestion |
Auto-thinking can wait 4s. Skill inject has a 2.5s abort on purpose |
Replacing #9429 skill_search with Jev |
Different product: deterministic search vs calibrated suggestion |
| Shipping GodsBoy as the default | 1.3s on every turn for ~40 skills |
Public usage this is based on
- TypeSafe cookbook: two-stage, gate 0.30, fits 0.30, inject in the system prompt, extra questions in the same POST are cheap
elizaOS/eliza, Verceltypesafe-ai, LangChainlangchain_typesafe: nativePOST /v1/systemone,jev-latest, not a chat modelmonotykamary/pi-fabric: same endpoint, no automatic retryy0usaf/pi-jev: Pi extension, fail-open, several questions in one ~300ms callGodsBoy/jev-agent-skill-router: tournament for huge catalogsmizchi/jev-playground: cookbook reproduction
Suggested split
- Keep #12373 as call 1 only.
- A later PR can add
suggestSkillRerank(...)next tosuggestSkill, gated byskills.suggestion.rerank: off | auto(auto= call 2 when roster > 100 or top-2 probabilities are tied). - Tournament is a third PR, only after someone actually hits 255 visible skills.
Source: can1357/oh-my-pi