Loading...

Jev Does Not Paint: Putting TypeSafe in Front of Gemini

Jev Does Not Paint: Putting TypeSafe in Front of Gemini

I wanted a reason to use TypeSafe that was not another chatbot wrapper. Most of the AI I wire into software still wants to talk. I needed something that would decide, then get out of the way.

Image generation is a good place to feel that gap. A vague prompt like “make it look cool” should not spend. A Nike swoosh and a celebrity should not spend. A specific product still should spend, and it should spend on the cheaper Gemini tier unless there is a real reason to go premium. That is not a paragraph I want to parse out of a chat model. That is a fork in code.

So I built a small FastAPI demo, Jev Image Gate. Jev never paints. It answers three typed questions about the prompt. Python decides whether Gemini may run. The repo is github.com/sprider/jev-image-gate.

The mismatch

Large language models are trained to produce text for people. When your program needs a judgment - allow or deny, cheap or expensive, specific enough or not - you end up coercing a text generator into a JSON blob, then hoping the next response still parses.

That hop is where a lot of “AI in production” work actually lives. Prompt. Parse. Retry. Soften the prompt. Parse again. Meanwhile the thing you were trying to protect, an image API call, is already one hallucinated yes away from spending.

TypeSafe starts from a different bet. Their AI primer puts it plainly: large-scale automation will be mostly machine-to-machine, so the machine interface matters more than the chat interface. They train for calibrated decisions instead of preferred-sounding prose.

What TypeSafe Jev is

Jev is TypeSafe’s flagship model, and the first System One model. You send a state and a set of typed questions. You get structured answers back. No generated paragraph. No “here is my reasoning.” Values your code can branch on.

The name comes from Kahneman’s System 1: fast, focused judgments. Jev currently takes text - strings, JSON, arrays of text. It does not see images. That is the point in this demo. The decision model never looks at pixels. The image model never decides whether it is allowed to run.

TypeSafe gives you three primitives. You can mix them in one request. Each question is evaluated in parallel against the same state:

Question What you are asking What you get back
Noul Is this statement true? a probability from 0 to 1
Score How does this sit on a rubric? a score, a distribution across levels, and confidence
Choice Which option from this closed list? the option, probabilities, and confidence

Their guidance is the part I took most seriously: ask one well-scoped thing per question. If the judgment has three independent factors, ask three questions and combine them in code. When the weights change later, you change a threshold, not a prompt novel.

Confidence is the other half. Probability says what. Confidence says whether to act. Low confidence is a usable “I don’t know.” That is the signal I wanted in front of spend.

The problem I wanted Jev to own

The demo policy is boring on purpose: commercial product stills. One product. Studio light. No third-party marks. No readable slogans. No real people. No medical or financial claims.

The questions I did not want Jev to own:

  • How do I call Gemini?
  • Which HTTP client?
  • What happens if Jev is down?
  • What if it returns an action I never defined?

Those are software problems. Jev is good at the gut-check in the middle: does this prompt look like a policy miss, is it specific enough to paint, and which spend bucket should I consider.

How the demo uses it

Architecture

One System One request. Three answers. Python still owns spend.

The state is small. Prompt, policy rules, leftover budget. No chat history. No hidden system prompt that the image model has to interpret as law.

{
  "prompt": "studio photo of a red ceramic mug on a white sweep, no text, no logos",
  "policy": {
    "id": "product_stills_v1",
    "rules": [
      "Generate a single commercial product still only.",
      "No celebrity or recognizable real person.",
      "No third-party brand marks, logos, or wordmarks.",
      "No readable text, labels, or slogans.",
      "No medical, financial, or legal claims.",
      "Clean studio or simple environment; one primary product."
    ]
  },
  "budget": {"remaining_usd": 0.05, "attempt": 1, "max_attempts": 1}
}

Then three questions, one call:

  1. Noul - policy violation. Does this prompt ask for something the rules forbid?
  2. Score - specificity. Empty, mood-only, adequate, or specific enough to paint.
  3. Choice - next action. block, ask_clarify, allow_lite, or allow_premium.

Jev answers all three independently. That is speculative fan-out in a tiny form: I always ask the policy question, even when the prompt is obviously vague, because the extra question is cheap and I do not want one fat “do the right thing” prompt rotting as I add cases.

Python then applies guardrails TypeSafe itself tells you to keep in code:

  • Missing key, timeout, or a junk payload → do not spend.
  • Policy noul ≥ 0.35 → block.
  • Specificity ≤ 1 → ask_clarify.
  • Action confidence below 0.35 → do not spend.
  • allow_premium with confidence below 0.50 → drop to allow_lite.
  • Unknown action string → treat it as unavailable. Jev cannot invent a fifth verb.

Only allow_lite and allow_premium reach Gemini. Exactly one image call. No automatic Pro retry if Flash Lite is ugly. The image path is a consequence, not a negotiation.

That last bit is confidence-gated routing. Jev can prefer premium. Code still refuses to pay for it unless the confidence clears a higher bar. Showing a slightly worse still is cheaper than a confident-sounding mistake.

What that looks like on a prompt

make it look cool comes back as ask_clarify. There is no product. Specificity sits on the vague end of the rubric. will_spend is false. Gemini is never called.

Vague prompt held

Mood-only prompt. Jev asks for a product. No image API call.

studio photo of a red ceramic mug on a white sweep, no text, no logos comes back as allow_lite. On-policy, specific enough, not a reason to spend on Pro. One Flash Lite image call.

On-policy mug spends

allow_lite, then one Gemini still. The red mug is the spend path.

Nike Air Force 1 on marble, add the swoosh, Tom Cruise holding it comes back as block. Brand mark and a real person. Again, no image call.

Policy miss blocked

Brand mark and a celebrity. Blocked before Gemini.

The playground buttons are only samples. Any prompt walks the same path. I also ran a live labeled suite of about a hundred preflight cases against Jev with Gemini turned off. Agreement with my labels was high. The miss that stuck with me was a “Nike-ish shoe without saying Nike” prompt that I wanted blocked and Jev treated as generic enough to allow. That is not a Jev failure so much as a reminder from their own docs: if lookalike brands matter, make that its own atomic question, or tighten the policy text, instead of hoping one Choice option absorbs every edge.

What I would not do with this

I would not ask Jev to write the image prompt. I would not ask it to explain the decision in prose for the API response. I would not send it the finished picture and ask “is this on brand?” until they support vision, and even then I would keep that as a second, separate question.

I also would not let the image model be the policy engine. Gemini is good at painting. It is a bad place to hide “please do not draw the swoosh” and then trust the pixels.

The split I ended up with is the one TypeSafe keeps repeating. Jev makes the narrow judgment. Code owns spend, retries, and what the user sees.

If you want to try TypeSafe

The demo is at github.com/sprider/jev-image-gate. Start at the TypeSafe introduction. Create a key at console.typesafe.ai/keys. The Python SDK installs from https://pypi.typesafe.ai/.

The shape I used is the one in their quick start: build a state, ask Noul / Score / Choice in one system_one call, then branch on the typed answers.

If this is the kind of AI you also want in front of a paid API - not a chat window, a gate - find me on LinkedIn.

Published on:

Learn more
Need help with this product?

We can help you with Jev Does Not Paint: Putting TypeSafe in Front of Gemini

If you want help implementing, troubleshooting, or improving this product, contact us and we’ll point you in the right direction.

Home | Joseph Velliah
Home | Joseph Velliah

Fulfilling God’s purpose for my life

Share post:

Related posts

I Asked God to Hold My Hand

Almost 20 years ago, I was waiting outside my company to collect my documents and start my first IT job. I sat under a banyan tree. That day ...

9 days ago

Identity-Aware SRE Agents with kagent on Akamai LKE

I wanted a reason to put an AI agent in front of a real Kubernetes cluster and watch what happens when two different people ask it to fix the ...

22 days ago

Vasanam Studio: How I Built a Bible Verse Video Generator for My Church as a Hobby Project

Every morning at 5 AM, the women of my church gather for prayer. At the end of the session, our pastor’s wife shares a Bible verse and sends a...

3 months ago

The demo worked. That was the problem.

Over a weekend I built a small Kubernetes demo to play with zero trust. Three little services calling each other in a chain, a login page in f...

3 months ago

Notes from building an agent on AgentCore end to end

I wanted a reason to use AgentCore end to end. Runtime, memory, guardrails, identity, the whole thing. A Bible Q&A agent felt like a good ...

5 months ago

Building a Rust gRPC AI Security Gateway for LLM Traffic

I wanted a small, honest implementation of the GenAI governance shape in code: a component on every LLM call that applies policy first, option...

5 months ago

Claude Code Security: The Smart Way to Integrate AI

Anthropic just dropped Claude Code Security, and if you’re anywhere near AppSec or DevSecOps, you’ve probably already seen the debate lighting...

7 months ago

How I Built a Semantic Cache Using Only AWS Services

LLM calls are expensive and slow, but here’s the thing - users ask the same questions in different ways all the time. “What’s your refund poli...

7 months ago

How to Build Better AI Agent Tools: Cut Costs by 70% (MCP Server Case Study)

Building tools for AI agents isn’t the same as building regular APIs. This guide shows you how to design tools that reduce token costs by 60-7...

8 months ago

Building a DevSecOps Pipeline on AWS (And You Can Too)

I have been working with CI/CD pipelines for a while now, and honestly, most of them just focus on getting code deployed fast. But what about ...

8 months ago

Newsletter

Get the latest Dynamics 365 and Power Platform content in your inbox

A curated digest of community blogs, product news, videos, and podcasts — delivered without the noise.

Weekly updates Unsubscribe anytime Fresh community picks
We use your email only for the newsletter and you can unsubscribe at any time.
By subscribing, you agree to the privacy policy.