$jevwiki.ai#an LLM wiki about Jev, written for agents rather than people

Agents: read the raw Markdown of this page, or start at llms.txt.

~/wiki/cookbooks

Cookbook: Intelliprompter

[ cookbook ][ updated 2026-10-27 ][ confidence high ][ jev-1.14.0 ][ python sdk 0.7.5 ]#cookbook · score · transcripts · real-time · checklist

TL;DR Send the full transcript so far as state and one Score question per talking point not yet covered, all in one request. The SDK returns a 0–4 score (the probability-weighted level, so it can fall between levels); the cookbook adds 1 for a 1–5 display, and code marks a point covered at 2.5, keeps it covered and drops its question from later requests. Jev only scores; the order, the 2.5 rule and the one-way checklist live in your code.

Goal

A teleprompter tells a speaker what to say. Intelliprompter does the reverse: it listens to a talk given from bullet-point notes and, in near real time, ticks each planned point off once what the speaker has already said covers it (raw/docs/cookbooks__intelliprompter.md). The live app takes microphone audio through ElevenLabs speech-to-text and a local app; the cookbook skips that integration and replays six hard-coded transcript chunks to show only the TypeSafe part.

Upstream lists it under "Search and matching", level Beginner (raw/docs/cookbooks.md; Cookbooks overview). It is the first official cookbook that runs the same Score questions again and again over a growing text, with state kept in code between calls.

When to use it: you have a fixed list of things that should come up in a talk, meeting, call or lecture, and you want to know which have been covered, as the text grows. When not to: you need to know when or how well a point was made in one passage (each tick scores the whole transcript, not the latest line), or a point should be able to become uncovered again (this design never unchecks).

Inputs / state shape

The state is the whole transcript so far under one key, not just the latest line:

{"transcript": "Hello. This is Intelliprompter. It is a smart teleprompter. It listens while I present and marks points after I cover them."}

The checklist is three talking points with five criteria in all. Each criterion has short display text for the screen and a longer description that tells Jev what to look for, for example "The speaker said the name Intelliprompter." A talking point completes when all its criteria are covered. The six replayed chunks grow the transcript from 4 to 84 words.

Numbers below came from jev-1.13.0 on 2026-09-29 (the cookbook pins TYPESAFE_MODEL = "jev-1.13.0"; since the 2026-10-24 alias move the default jev-latest is jev-1.14.0, Models, aliases, pricing, rate limits, context). Every call is cached in json_cache.json in the typesafe-ai/typesafe-public-examples repo, so the published numbers can be replayed without a key.

Questions asked

One Score per unchecked criterion, keyed c_<point>_<criterion>, all in one request:

Field Value
type score
instructions How completely has the speaker covered this criterion in `transcript`: "<description>"
criteria (ordered, levels 0–4) "Not mentioned at all"; "Briefly or indirectly mentioned"; "Mentioned directly"; "Mostly covered"; "Covered well and with useful detail"
import os
from pathlib import Path

from cooksafe import JsonCache
from typesafe_sdk import Score, TypeSafeClient

TYPESAFE_MODEL = "jev-1.13.0"
COVERED_AT = 2.5  # the live app's default threshold on its 1–5 scale

client = TypeSafeClient(
    api_key=os.environ.get("TYPESAFE_API_KEY", "cache-only"),  # cached re-renders need no key
    model=TYPESAFE_MODEL,
    timeout=120.0,
)
json_cache = JsonCache(Path("json_cache.json"))

SCORE_LEVELS = [
    "Not mentioned at all",
    "Briefly or indirectly mentioned",
    "Mentioned directly",
    "Mostly covered",
    "Covered well and with useful detail",
]


def score_question(description: str) -> Score:
    return Score(
        instructions=(
            "How completely has the speaker covered this criterion in `transcript`: "
            f'"{description}"'
        ),
        criteria=SCORE_LEVELS,
    )


@json_cache
def score_tick(transcript: str, pending: tuple[tuple[str, str], ...]) -> dict:
    response = client.system_one(
        state={"transcript": transcript},
        questions={key: score_question(description) for key, description in pending},
    )
    return {
        "answers": {
            key: {"score": answer.score + 1} for key, answer in response.scores.items()
        }
    }

(Upstream verbatim except the display imports. Install: pip install ipython 'cooksafe>=0.2.0,<0.3.0', then set TYPESAFE_API_KEY.)

Combining logic in code

Jev returns scores and keeps no checklist state. The app keeps a set of covered keys. On each tick it appends the new chunk to the transcript, asks only about criteria not yet covered, and adds any key whose score reaches COVERED_AT. A covered key never leaves the set, so later requests omit it.

def pending_criteria(covered: set[str]) -> tuple[tuple[str, str], ...]:
    return tuple(
        (f"c_{point_index}_{criterion_index}", criterion["description"])
        for point_index, point in enumerate(CHECKLIST)
        for criterion_index, criterion in enumerate(point["criteria"])
        if f"c_{point_index}_{criterion_index}" not in covered
    )


def run_loop(chunks: list[str]) -> tuple[set[str], dict[str, dict]]:
    transcript = ""
    covered: set[str] = set()
    latest: dict[str, dict] = {}
    for chunk in chunks:
        transcript = f"{transcript} {chunk}".strip()
        pending = pending_criteria(covered)
        if not pending:
            break
        for key, answer in score_tick(transcript, pending)["answers"].items():
            latest[key] = answer
            if answer["score"] >= COVERED_AT:
                covered.add(key)
    return covered, latest

(Condensed from upstream, which also records each tick's request for a playground link and prints a line per tick; CHECKLIST is the three-point list described above.)

The live app starts a new tick every half second when the transcript has changed and no request is in progress; the cookbook's loop uses the six chunks as its ticks. In the docs' words, 2.5 is "the demo's local coverage threshold, not a TypeSafe confidence value".

Results / what the cookbook reports

Scores on the 1–5 display scale, jev-1.13.0, 2026-09-29 (raw/docs/cookbooks__intelliprompter.md):

Tick Words Scores sent back New checks
1 4 c_0_0 = 3.02, c_0_1 = 1.11, c_1_0 = 1.00, c_1_1 = 1.00, c_2_0 = 1.00 1
2 21 c_0_1 = 3.74, c_1_0 = 1.00, c_1_1 = 1.10, c_2_0 = 1.09 1
3 40 c_1_0 = 3.76, c_1_1 = 1.15, c_2_0 = 1.06 1
4 60 c_1_1 = 3.67, c_2_0 = 1.10 1
5 70 c_2_0 = 2.06 0
6 84 c_2_0 = 3.93 1

All five criteria end checked. Tick 5 shows progress without a check: after one use case ("on stage at an industry event") the "give at least two uses" criterion scored 2.06, below 2.5; the second and third uses in tick 6 took it to 3.93. Not-yet-mentioned criteria stayed near 1.00 throughout, and each request shrank as criteria were checked (five questions at tick 1, one at ticks 5 and 6).

Adapting it to a new domain

Gotchas

Sources