Define AI decisions in Protobuf. Generate type-safe clients for Go, TypeScript, and Python.
Instead of writing loose text prompts and parsing untyped JSON, protoc-gen-jev turns your Protocol Buffer schemas into strongly typed clients for Jev—a fast, non-autoregressive cognitive AI model designed for parallel, structured evaluation.
┌─────────────────────────────────┐ buf generate ┌───────────────────────────────────┐
│ Protobuf Schema │ ────────────────────────> │ Type-Safe Client SDKs │
│ Questions · Rubrics · Thresholds│ protoc-gen-jev │ Go · TypeScript · Python │
└─────────────────────────────────┘ └───────────────────────────────────┘
Experimental: Schema options and generated APIs are under active development. Pin the generator and runtime dependencies to the same release.
Your Protobuf response fields map directly to Jev's decision primitives:
| Decision | Protobuf Type | Jev Evaluation Semantics |
|---|---|---|
| Yes / No (Noul) | bool |
Binary classification with calibrated probability and configurable threshold. |
| Rubric / Rating (Score) | Numeric (int32, int64, float) |
Rating along an ordered rubric scale, linearly interpolated into domain numbers with rounding. |
| Categorical (Choice) | enum, string, routing oneof |
Discrete selection among predefined choices or enum values. |
| Execution Metadata | jev.v1.Response, jev.v1.Meta |
Automatically populated with model name, token usage, confidence scores, and probability distributions. |
Add the dependency to your buf.yaml:
version: v2
modules:
- path: proto
deps:
- buf.build/bufbuild-experimental/protoc-gen-jevAnnotate your response message in proto/triage/v1/triage.proto:
edition = "2024";
option features.field_presence = IMPLICIT;
package triage.v1;
option go_package = "example.com/myapp/gen/jev/triage/v1;triagev1";
import "jev/v1/options.proto";
message TriageRequest {
string description = 1;
}
message TriageResponse {
// Yes/No decision with an 85% confidence threshold
bool page = 1 [
features.field_presence = EXPLICIT,
(jev.v1.field).instructions = "Does this incident require immediate paging?",
(jev.v1.field).noul = { threshold: 0.85 }
];
// Rubric decision evaluated on a 1-5 scale
int32 urgency = 2 [
(jev.v1.field).instructions = "How urgently does this incident need attention?",
(jev.v1.field).score = {
levels: [
{ value: 1, description: "Minor; can wait for routine maintenance" },
{ value: 3, description: "Degraded service; a workaround exists" },
{ value: 5, description: "Active outage; immediate intervention required" }
]
}
];
}
service TriageService {
rpc Triage(TriageRequest) returns (TriageResponse);
}Configure buf.gen.yaml:
version: v2
clean: true
inputs:
- directory: proto
plugins:
- remote: buf.build/protocolbuffers/go:v1.36.12
out: gen
opt: [paths=source_relative]
- local: protoc-gen-jev
out: gen
opt: [targets=go, paths=source_relative]Generate the client:
buf dep update && buf generateGo
client := triagev1.NewJevTriageService(jev.NewClient(os.Getenv("TYPESAFE_API_KEY")))
decision, err := client.Triage(ctx, &triagev1.TriageRequest{
Description: "Database connection pool exhausted; requests failing with 500",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Page: %v, Urgency: %d\n", decision.GetPage(), decision.GetUrgency())TypeScript
import { create } from "@bufbuild/protobuf";
import { JevTriageService } from "./gen/triage/v1/triage_jev.js";
import { TriageRequestSchema } from "./gen/triage/v1/triage_pb.js";
const client = new JevTriageService();
const decision = await client.triage(
create(TriageRequestSchema, {
description: "Database connection pool exhausted; requests failing with 500",
})
);
console.log(`Page: ${decision.page}, Urgency: ${decision.urgency}`);Python
from jev.triage.v1.triage_pb import TriageRequest
from jev.triage.v1.triage_jev import JevTriageService
client = JevTriageService()
decision = client.triage(
TriageRequest(description="Database connection pool exhausted; requests failing with 500")
)
print(f"Page: {decision.page}, Urgency: {decision.urgency}")| Language | Generator Flag | Runtime Dependencies | Complete Working Example |
|---|---|---|---|
| Go | targets=go |
google.golang.org/protobuf, pkg/jev |
examples/go/ |
| TypeScript | targets=ts |
@bufbuild/protobuf (v2), @typesafe-ai/sdk |
examples/typescript/ |
| Python | targets=python |
protobuf-py (v0.5+), typesafe-sdk |
examples/python/ |
| JSON | targets=json |
None (emits language-agnostic .jev.json spec) |
examples/json/ |
Generate multiple targets simultaneously: opt: [targets=go,targets=ts].
Generated clients communicate over the standard Jev /v1/systemone wire protocol and can run against any compatible decision engine:
- Jev (TypeSafe Cloud API): Hosted high-throughput decision model (
https://api.typesafe.ai), configured viaTYPESAFE_API_KEY. - Laya (Local Open Engine): Open-weights local evaluation server (
http://127.0.0.1:8000) viajust start-layaandjust run-examples-laya. - Clef (Cloudflare Decision Models): Compatible with Cloudflare's non-autoregressive decision model architecture. Test locally via
just start-clefandjust run-examples-clef.
See the Development Guide for full details on running examples and configuring endpoints.
- Pre-compiled Binary: Download from GitHub Releases and place on
PATH. - Go Install:
go install github.com/bufbuild/protoc-gen-jev@latest - Mise:
mise use github:bufbuild/protoc-gen-jev@latest
- Schema & Client Reference: Field annotations (
instructions,score,noul,choice,skip), routing oneofs, detailed decision types (jev.v1.Noul,Score,Choice), metadata inspection (jev.v1.Response), and error handling. - Development Guide: Local build instructions, unit and cross-language tests, the local Laya server, and golden file workflows.
MIT licensed; see LICENSE.