1// Command fakejev is a stand-in for the TypeSafe JEV service, for demo2// recordings: it answers every question about a value by looking for3// complaint words in the value, so a demo never needs a real key and4// always records the same answers. Point 012 at it with5//6// TYPESAFE_API_KEY=demo TYPESAFE_BASE_URL=http://127.0.0.1:8799 ./bin/0127package main89import (10 "encoding/json"11 "flag"12 "io"13 "log"14 "net/http"15 "slices"16 "strings"17 "time"18)1920// negative words mark a value as a complaint.21var negative = []string{"crushed", "broken", "late", "wrong", "refund", "never", "missing"}2223func main() {24 addr := flag.String("addr", "127.0.0.1:8799", "listen address")25 delay := flag.Duration("delay", 600*time.Millisecond, "time to answer, so Loading… shows")26 flag.Parse()27 http.HandleFunc("/v1/systemone", func(w http.ResponseWriter, r *http.Request) {28 body, _ := io.ReadAll(r.Body)29 time.Sleep(*delay)30 answer, err := answerFor(body)31 if err != nil {32 http.Error(w, err.Error(), http.StatusBadRequest)33 return34 }35 json.NewEncoder(w).Encode(map[string]any{36 "model": "jev-demo", "answers": map[string]any{"answer": answer},37 "usage": map[string]int{"input_tokens": 1, "output_tokens": 1},38 })39 })40 log.Printf("fake JEV service on http://%s", *addr)41 log.Fatal(http.ListenAndServe(*addr, nil))42}4344// answerFor answers the request's question: yes-or-no, a choice of45// labels, or a score on levels.46func answerFor(body []byte) (map[string]any, error) {47 var req struct {48 State json.RawMessage `json:"state"`49 Questions map[string]struct {50 Type string `json:"type"`51 Criteria json.RawMessage `json:"criteria"`52 } `json:"questions"`53 }54 if err := json.Unmarshal(body, &req); err != nil {55 return nil, err56 }57 text := strings.ToLower(string(req.State))58 bad := slices.ContainsFunc(negative, func(w string) bool { return strings.Contains(text, w) })59 q := req.Questions["answer"]60 switch q.Type {61 case "noul":62 p := 0.0763 if bad {64 p = 0.9465 }66 return map[string]any{"type": "noul", "noul": p}, nil67 case "choice":68 var labels map[string]any69 json.Unmarshal(q.Criteria, &labels)70 keys := make([]string, 0, len(labels))71 for l := range labels {72 keys = append(keys, l)73 }74 slices.Sort(keys)75 pick := keys[len(keys)-1]76 if bad {77 pick = keys[0]78 }79 probs := map[string]float64{}80 for _, l := range keys {81 probs[l] = 0.1 / float64(max(len(keys)-1, 1))82 }83 probs[pick] = 0.984 return map[string]any{"type": "choice", "choice": pick, "confidence": 0.9, "probabilities": probs}, nil85 }86 score, probs := 0.2, map[string]float64{"0": 0.8, "1": 0.15, "2": 0.05}87 if bad {88 score, probs = 1.8, map[string]float64{"0": 0.05, "1": 0.15, "2": 0.8}89 }90 return map[string]any{"type": "score", "score": score, "confidence": 0.8,91 "legend": map[string]any{"0": "low", "1": "mid", "2": "high"}, "probabilities": probs}, nil92}