chuckfinca Claude Opus 4.6 (1M context) commited on
Commit
20e30aa
·
1 Parent(s): 195413e

Extract shared post-processing into _process_completed_trace

Browse files

Citation processing, trace upload, stats formatting, and trace
rendering consolidated into one function used by both chat()
and stream_question(). Eliminates ~20 lines of duplication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +48 -44
app.py CHANGED
@@ -209,7 +209,39 @@ def format_stats(trace) -> str:
209
 
210
 
211
  # ---------------------------------------------------------------------------
212
- # Chat
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  # ---------------------------------------------------------------------------
214
 
215
 
@@ -280,36 +312,22 @@ def chat(message: str, scratch_path: str, session_cost: float):
280
  yield f"Error: {exc}", "", scratch_path, session_cost
281
  return
282
 
283
- trace = agent_run.trace
284
- trace.wall_time_s = round(time.monotonic() - start, 2)
285
- raw_answer = trace.answer or accumulated_answer or "(no answer)"
286
- clean_answer, sources = process_citations(raw_answer, WORKSPACE_DIR)
287
 
288
- if sources:
 
289
  source_lines = "\n".join(
290
  f"{superscript(s['id'])} {s['doc']}: \"{s['quote']}\""
291
- for s in sources
292
  )
293
- clean_answer += f"\n\n---\n{source_lines}"
294
 
295
- stats = format_stats(trace)
296
- result = {
297
- "question": message,
298
- "source": SOURCE,
299
- "passed": True,
300
- "assertions": {},
301
- "trace": asdict(trace),
302
- "citations": sources,
303
- }
304
- upload_trace(result)
305
- trace_html = render_trace(result, max_chars=2000)
306
-
307
- remaining = _daily_questions_remaining()
308
- remaining_msg = f"\n\n---\n*{stats}*\n\n*{remaining} question{'s' if remaining != 1 else ''} remaining today*"
309
 
310
  yield (
311
- f"{clean_answer}{remaining_msg}",
312
- trace_html,
313
  scratch_path,
314
  session_cost,
315
  )
@@ -661,29 +679,15 @@ def stream_question(question: str) -> Generator[str, None, None]:
661
  yield json.dumps({"type": "error", "error": "An error occurred during processing."})
662
  return
663
 
664
- trace = agent_run.trace
665
- trace.wall_time_s = round(time.monotonic() - start, 2)
666
-
667
- clean_answer, sources = process_citations(trace.answer or "", WORKSPACE_DIR)
668
-
669
- result = {
670
- "question": question,
671
- "source": SOURCE,
672
- "passed": True,
673
- "assertions": {},
674
- "trace": asdict(trace),
675
- "citations": sources,
676
- }
677
- upload_trace(result)
678
- trace_html = render_trace(result, max_chars=2000)
679
 
680
  yield json.dumps({
681
  "type": "done",
682
- "answer": clean_answer,
683
- "sources": sources,
684
- "stats": format_stats(trace),
685
- "trace_html": trace_html,
686
- "remaining": _daily_questions_remaining(),
687
  })
688
 
689
 
 
209
 
210
 
211
  # ---------------------------------------------------------------------------
212
+ # Post-processing (shared between chat and stream_question)
213
+ # ---------------------------------------------------------------------------
214
+
215
+
216
+ def _process_completed_trace(question: str, trace, start_time: float) -> dict:
217
+ """Process a completed agent trace: citations, upload, render.
218
+
219
+ Returns a dict with answer, sources, stats, trace_html, and remaining.
220
+ """
221
+ trace.wall_time_s = round(time.monotonic() - start_time, 2)
222
+ clean_answer, sources = process_citations(trace.answer or "", WORKSPACE_DIR)
223
+
224
+ result = {
225
+ "question": question,
226
+ "source": SOURCE,
227
+ "passed": True,
228
+ "assertions": {},
229
+ "trace": asdict(trace),
230
+ "citations": sources,
231
+ }
232
+ upload_trace(result)
233
+
234
+ return {
235
+ "answer": clean_answer,
236
+ "sources": sources,
237
+ "stats": format_stats(trace),
238
+ "trace_html": render_trace(result, max_chars=2000),
239
+ "remaining": _daily_questions_remaining(),
240
+ }
241
+
242
+
243
+ # ---------------------------------------------------------------------------
244
+ # Chat (Gradio chatbot interface)
245
  # ---------------------------------------------------------------------------
246
 
247
 
 
312
  yield f"Error: {exc}", "", scratch_path, session_cost
313
  return
314
 
315
+ processed = _process_completed_trace(message, agent_run.trace, start)
 
 
 
316
 
317
+ answer = processed["answer"]
318
+ if processed["sources"]:
319
  source_lines = "\n".join(
320
  f"{superscript(s['id'])} {s['doc']}: \"{s['quote']}\""
321
+ for s in processed["sources"]
322
  )
323
+ answer += f"\n\n---\n{source_lines}"
324
 
325
+ remaining = processed["remaining"]
326
+ answer += f"\n\n---\n*{processed['stats']}*\n\n*{remaining} question{'s' if remaining != 1 else ''} remaining today*"
 
 
 
 
 
 
 
 
 
 
 
 
327
 
328
  yield (
329
+ answer,
330
+ processed["trace_html"],
331
  scratch_path,
332
  session_cost,
333
  )
 
679
  yield json.dumps({"type": "error", "error": "An error occurred during processing."})
680
  return
681
 
682
+ processed = _process_completed_trace(question, agent_run.trace, start)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
683
 
684
  yield json.dumps({
685
  "type": "done",
686
+ "answer": processed["answer"],
687
+ "sources": processed["sources"],
688
+ "stats": processed["stats"],
689
+ "trace_html": processed["trace_html"],
690
+ "remaining": processed["remaining"],
691
  })
692
 
693