hchevva commited on
Commit
7adad6c
·
verified ·
1 Parent(s): d8031b4

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -20
app.py CHANGED
@@ -43,9 +43,19 @@ def _counts_str(counts):
43
 
44
 
45
  def _write_tmp(filename: str, content: str) -> str:
46
- p = pathlib.Path(tempfile.gettempdir()) / filename
47
- p.write_text(content, encoding="utf-8")
48
- return str(p)
 
 
 
 
 
 
 
 
 
 
49
 
50
 
51
  def _circuit_hash(history):
@@ -114,27 +124,41 @@ def measure_collapse(qc, shots):
114
  return last_counts, f"✅ Collapsed to |{res}⟩ and sampled shots."
115
 
116
 
117
- def explain_llm(qc, n_qubits, shots, last_hash):
118
  # circuit-change gating
119
  curr_hash = _circuit_hash(qc.history)
120
  if curr_hash == last_hash:
121
- return "ℹ️ Circuit unchanged. Explanation reused.", last_hash, ""
 
 
 
122
 
123
  # cost guard
124
  EST_TOKENS = 900
125
  if not allow_request(EST_TOKENS):
126
- return "🚫 Explanation disabled (daily token limit reached).", last_hash, ""
 
 
 
 
127
 
128
  state_ket = qc.ket_notation(max_terms=6)
129
  probs_top = _probs_top(qc, int(n_qubits), k=6)
130
 
131
- explanation = explain_with_gpt4o(
132
- n_qubits=int(n_qubits),
133
- history=qc.history,
134
- state_ket=state_ket,
135
- probs_top=probs_top,
136
- shots=int(shots),
137
- )
 
 
 
 
 
 
 
138
 
139
  return explanation, curr_hash, explanation
140
 
@@ -148,6 +172,13 @@ def _refresh_choices(n):
148
  )
149
 
150
 
 
 
 
 
 
 
 
151
  # ---------- Styling ----------
152
  CSS = """
153
  #title h1 { font-size: 42px !important; margin-bottom: 6px; }
@@ -298,9 +329,9 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
298
  )
299
 
300
  n_qubits.change(
301
- fn=_refresh_choices,
302
  inputs=[n_qubits],
303
- outputs=[target, control, cnot_target],
304
  ).then(
305
  fn=update_views,
306
  inputs=[qc_state, last_counts_state, n_qubits],
@@ -390,7 +421,7 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
390
 
391
  explain_btn.click(
392
  fn=explain_llm,
393
- inputs=[qc_state, n_qubits, shots, last_explained_hash],
394
  outputs=[llm_out, last_explained_hash, explanation_md],
395
  )
396
 
@@ -409,13 +440,18 @@ with gr.Blocks(theme=theme, css=CSS, title="Quread.ai — State Vector Studio")
409
  return _write_tmp("explanation.md", md_text)
410
 
411
  def dl_explain_pdf(md_text):
412
- path = pathlib.Path(tempfile.gettempdir()) / "explanation.pdf"
413
- md_to_pdf(md_text, str(path))
414
- return str(path)
 
 
 
 
 
415
 
416
  dl_md.click(fn=dl_explain_md, inputs=[explanation_md], outputs=[dl_md])
417
  dl_pdf.click(fn=dl_explain_pdf, inputs=[explanation_md], outputs=[dl_pdf])
418
 
419
 
420
  if __name__ == "__main__":
421
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
43
 
44
 
45
  def _write_tmp(filename: str, content: str) -> str:
46
+ base = pathlib.Path(filename).name
47
+ stem = pathlib.Path(base).stem or "quread"
48
+ suffix = pathlib.Path(base).suffix or ".txt"
49
+ with tempfile.NamedTemporaryFile(
50
+ mode="w",
51
+ encoding="utf-8",
52
+ prefix=f"{stem}_",
53
+ suffix=suffix,
54
+ dir=tempfile.gettempdir(),
55
+ delete=False,
56
+ ) as f:
57
+ f.write(content)
58
+ return f.name
59
 
60
 
61
  def _circuit_hash(history):
 
124
  return last_counts, f"✅ Collapsed to |{res}⟩ and sampled shots."
125
 
126
 
127
+ def explain_llm(qc, n_qubits, shots, last_hash, previous_explanation):
128
  # circuit-change gating
129
  curr_hash = _circuit_hash(qc.history)
130
  if curr_hash == last_hash:
131
+ if previous_explanation:
132
+ shown = f"ℹ️ Circuit unchanged. Reusing previous explanation.\n\n{previous_explanation}"
133
+ return shown, last_hash, previous_explanation
134
+ return "ℹ️ Circuit unchanged. No previous explanation available.", last_hash, previous_explanation
135
 
136
  # cost guard
137
  EST_TOKENS = 900
138
  if not allow_request(EST_TOKENS):
139
+ if previous_explanation:
140
+ shown = "🚫 Explanation disabled (daily token limit reached). Showing previous explanation.\n\n"
141
+ shown += previous_explanation
142
+ return shown, last_hash, previous_explanation
143
+ return "🚫 Explanation disabled (daily token limit reached).", last_hash, previous_explanation
144
 
145
  state_ket = qc.ket_notation(max_terms=6)
146
  probs_top = _probs_top(qc, int(n_qubits), k=6)
147
 
148
+ try:
149
+ explanation = explain_with_gpt4o(
150
+ n_qubits=int(n_qubits),
151
+ history=qc.history,
152
+ state_ket=state_ket,
153
+ probs_top=probs_top,
154
+ shots=int(shots),
155
+ )
156
+ except Exception as exc:
157
+ safe_msg = f"❌ Explanation request failed: {exc}"
158
+ if previous_explanation:
159
+ shown = f"{safe_msg}\n\nShowing previous explanation:\n\n{previous_explanation}"
160
+ return shown, last_hash, previous_explanation
161
+ return safe_msg, last_hash, previous_explanation
162
 
163
  return explanation, curr_hash, explanation
164
 
 
172
  )
173
 
174
 
175
+ def _on_qubit_count_change(n):
176
+ qc, last_counts, selected_gate = _new_sim(n)
177
+ t, c, ct = _refresh_choices(n)
178
+ msg = f"✅ Reinitialized simulator with {int(n)} qubits."
179
+ return qc, last_counts, selected_gate, t, c, ct, msg
180
+
181
+
182
  # ---------- Styling ----------
183
  CSS = """
184
  #title h1 { font-size: 42px !important; margin-bottom: 6px; }
 
329
  )
330
 
331
  n_qubits.change(
332
+ fn=_on_qubit_count_change,
333
  inputs=[n_qubits],
334
+ outputs=[qc_state, last_counts_state, selected_gate_state, target, control, cnot_target, status],
335
  ).then(
336
  fn=update_views,
337
  inputs=[qc_state, last_counts_state, n_qubits],
 
421
 
422
  explain_btn.click(
423
  fn=explain_llm,
424
+ inputs=[qc_state, n_qubits, shots, last_explained_hash, explanation_md],
425
  outputs=[llm_out, last_explained_hash, explanation_md],
426
  )
427
 
 
440
  return _write_tmp("explanation.md", md_text)
441
 
442
  def dl_explain_pdf(md_text):
443
+ fd, path = tempfile.mkstemp(
444
+ prefix="explanation_",
445
+ suffix=".pdf",
446
+ dir=tempfile.gettempdir(),
447
+ )
448
+ os.close(fd)
449
+ md_to_pdf(md_text, path)
450
+ return path
451
 
452
  dl_md.click(fn=dl_explain_md, inputs=[explanation_md], outputs=[dl_md])
453
  dl_pdf.click(fn=dl_explain_pdf, inputs=[explanation_md], outputs=[dl_pdf])
454
 
455
 
456
  if __name__ == "__main__":
457
+ demo.launch(server_name="0.0.0.0", server_port=7860)