1name = "lmjtfy" 2main = "build/index.js" 3compatibility_date = "2026-09-01" 4# The site is https://lmjtfy.fun, bare (the owner's domain, on Cloudflare, 5# 2026-10-03). It began at https://lmjtfy.deizel.workers.dev, which stays on, 6# and www.lmjtfy.fun is attached, only so the Worker can send their 7# visitors, link previews and clones on with a permanent redirect (`moved` in 8# src/lib.rs). No per-version preview addresses beside them. 9workers_dev = true 10preview_urls = false 11routes = [ 12 { pattern = "lmjtfy.fun", custom_domain = true }, 13 { pattern = "www.lmjtfy.fun", custom_domain = true }, 14] 15 16[build] 17command = "worker-build --release" 18 19[vars] 20# A pinned model: jev-protocol refuses aliases, because the answers behind an 21# alias change without a change here. 22JEV_MODEL = "jev-1.13.0" 23# The LLM that writes Jev's questions: the cheapest candidate that passed 24# every case of tools/eval (2026-10-02: 14/14, about 16 neurons a call; the 25# one cheaper model, granite-4.0-h-micro, passed 11). Rerun the eval before 26# changing it. 27LLM_MODEL = "@cf/qwen/qwen3-30b-a3b-fp8" 28# The most all visitors together may spend on Jev in a UTC day, in dollars. 29# The LLM's own budget is not set here: it is Workers AI's free allocation 30# (llm::FREE_NEURONS_PER_DAY). A dollar is about 25,000 requests at 31# $0.00004 each (the owner, 2026-10-02: "they will never hit it anyway"). 32JEV_DOLLARS_PER_DAY = "1" 33 34# Workers AI. There is no local emulation: `wrangler dev` calls the real 35# models on the real account, so it needs the account's token 36# (`lmjtfy-wrangler`, from the devshell). 37[ai] 38binding = "AI" 39 40# The day's budgets, shared by every visitor (src/meter.rs). 41[[durable_objects.bindings]] 42name = "BUDGET" 43class_name = "Budget" 44 45# Every request that was answered, and what people asked (src/archive.rs). 46# It also makes the calls, so the same request is never sent twice. 47[[durable_objects.bindings]] 48name = "ARCHIVE" 49class_name = "Archive" 50 51[[migrations]] 52tag = "v1" 53new_sqlite_classes = ["Budget"] 54 55[[migrations]] 56tag = "v2" 57new_sqlite_classes = ["Archive"] 58 59# The key is a secret, not a var. Declaring it makes `wrangler dev` read it 60# from the process environment (op-env-run puts it there) and makes 61# `wrangler deploy` refuse if the deployed Worker lacks it. 62[secrets] 63required = [ 64 "LMJTFY_TYPESAFE_API_KEY", 65 # For the account's real Workers AI usage (src/meter.rs): a token that can 66 # read analytics and nothing else, and the account it reads. A dev server 67 # without them counts only itself, and says so on the page. 68 "CLOUDFLARE_ANALYTICS_TOKEN", 69 "CLOUDFLARE_ACCOUNT_ID", 70 # For `git clone <site>/lmjtfy.git` (src/clone.rs): a GitHub fine-grained 71 # token with Contents: read on deizel/lmjtfy and deizel/jevcrates and no 72 # other permission. A dev server without it answers clones with 503. 73 "LMJTFY_GITHUB_TOKEN", 74] 75 76# Cloudflare's own record of what the Worker did (the owner, 2026-10-02): 77# every invocation logged, with what it logged, and every request traced 78# (fetches, Durable Object calls, the handler). Kept in the account's 79# dashboard: logs 3 days (Workers Free: 200,000 events a day), traces 7 days. 80# Traces count towards Cloudflare Observability billing from 2026-12-01; 81# lower `head_sampling_rate` before then if they would. 82[observability] 83enabled = true 84 85[observability.logs] 86enabled = true 87invocation_logs = true 88head_sampling_rate = 1 89 90[observability.traces] 91enabled = true 92head_sampling_rate = 1