nyxia commited on
Commit
0907f54
·
verified ·
1 Parent(s): 8f0fb02

API endpoint /decide

Browse files
Files changed (1) hide show
  1. app.py +37 -0
app.py CHANGED
@@ -155,6 +155,40 @@ def decide(state, n, *fields):
155
  return run(state, qs)
156
 
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  def load_example(i):
159
  _, state, qs = EX[i]
160
  ups = [state, len(qs), None]
@@ -201,6 +235,9 @@ with gr.Blocks(title="Blink v0.3 — one forward pass, one calibrated decision")
201
  temp = gr.Slider(0.5, 3.0, value=T_CALIBRATED, step=0.05, label="Temperature · 1.3 is calibrated")
202
  gr.HTML(NOTE)
203
  gr.HTML(HOW)
 
 
 
204
 
205
  go.click(decide, [state, nq, *fields], res).then(lambda r, t: readout(r, t, True), [res, temp], out)
206
  temp.change(lambda r, t: readout(r, t, False), [res, temp], out, show_progress="hidden")
 
155
  return run(state, qs)
156
 
157
 
158
+ def decide_api(state: str, questions: list):
159
+ """Score typed decisions about one state with Blink v0.3.
160
+
161
+ Args:
162
+ state: the situation — plain text, or a JSON object/array as a string.
163
+ questions: up to 4 items {"type": "choice"|"noul"|"score", "question": str, "options": [str]}.
164
+ choice: "key" or "key: description" per option; score: levels from lowest to highest;
165
+ noul (yes/no): options optional ("false: ...", "true: ...").
166
+
167
+ Returns:
168
+ {"answers": [{type, question, keys, probabilities, best, logprobs, ms}], "temperature": 1.3, "total_ms": int}
169
+ """
170
+ if not isinstance(questions, list) or not 1 <= len(questions) <= MAXQ:
171
+ raise gr.Error(f"questions must be a list of 1 to {MAXQ} items")
172
+ qs = []
173
+ for q in questions:
174
+ kind = q.get("type")
175
+ if kind not in ("choice", "noul", "score"):
176
+ raise gr.Error("type must be choice, noul or score")
177
+ try:
178
+ build(kind, list(q.get("options") or []))
179
+ except ValueError as e:
180
+ raise gr.Error(f"{q.get('question', '')[:60]}: {e}")
181
+ qs.append((kind, str(q.get("question", "")).strip(), list(q.get("options") or [])))
182
+ res = run(state, qs)
183
+ for a in res["answers"]:
184
+ p = soft(a["logprobs"], T_CALIBRATED)
185
+ a["probabilities"] = dict(zip(a["keys"], [round(v, 4) for v in p]))
186
+ a["best"] = a["keys"][max(range(len(p)), key=p.__getitem__)]
187
+ a.pop("prompt", None)
188
+ res["temperature"] = T_CALIBRATED
189
+ return res
190
+
191
+
192
  def load_example(i):
193
  _, state, qs = EX[i]
194
  ups = [state, len(qs), None]
 
235
  temp = gr.Slider(0.5, 3.0, value=T_CALIBRATED, step=0.05, label="Temperature · 1.3 is calibrated")
236
  gr.HTML(NOTE)
237
  gr.HTML(HOW)
238
+ with gr.Row(visible=False): # API-only endpoint: POST /decide (state, questions) -> JSON
239
+ api_state, api_qs, api_out = gr.Textbox(), gr.JSON(), gr.JSON()
240
+ gr.Button().click(decide_api, [api_state, api_qs], api_out, api_name="decide")
241
 
242
  go.click(decide, [state, nq, *fields], res).then(lambda r, t: readout(r, t, True), [res, temp], out)
243
  temp.change(lambda r, t: readout(r, t, False), [res, temp], out, show_progress="hidden")