feat(gui): Implement per-response token metrics and AI discussion compression
- Display token metrics (input/output/cache) per response in Discussion Hub. - Add total Discussion Token usage in the panel header. - Implement 'Compress' feature to intelligently summarize and replace exhausted discussion histories using an AI subagent.
This commit is contained in:
+36
-11
@@ -3416,17 +3416,29 @@ def render_discussion_entry(app: App, entry: dict, index: int) -> None:
|
||||
imgui.same_line()
|
||||
if imgui.button("[Edit]" if read_mode else "[Read]"): entry["read_mode"] = not read_mode
|
||||
ts_str = entry.get("ts", "")
|
||||
if ts_str:
|
||||
imgui.same_line(); imgui.text_colored(vec4(120, 120, 100), str(ts_str)); e_dt = project_manager.parse_ts(ts_str)
|
||||
if e_dt:
|
||||
e_unix, next_unix = e_dt.timestamp(), float('inf')
|
||||
if index + 1 < len(app.disc_entries):
|
||||
n_ts = app.disc_entries[index+1].get("ts", ""); n_dt = project_manager.parse_ts(n_ts)
|
||||
if n_dt: next_unix = n_dt.timestamp()
|
||||
injected = [f for f in app.files if hasattr(f, 'injected_at') and f.injected_at and e_unix <= f.injected_at < next_unix]
|
||||
if injected:
|
||||
imgui.same_line(); imgui.text_colored(vec4(100, 255, 100), f"[{len(injected)}+]")
|
||||
if imgui.is_item_hovered(): imgui.set_tooltip("Files injected at this point:\n" + "\n".join([f.path for f in injected]))
|
||||
usage = entry.get("usage", {})
|
||||
if ts_str or usage:
|
||||
imgui.same_line()
|
||||
if ts_str:
|
||||
imgui.text_colored(vec4(120, 120, 100), str(ts_str))
|
||||
e_dt = project_manager.parse_ts(ts_str)
|
||||
if e_dt:
|
||||
e_unix, next_unix = e_dt.timestamp(), float('inf')
|
||||
if index + 1 < len(app.disc_entries):
|
||||
n_ts = app.disc_entries[index+1].get("ts", ""); n_dt = project_manager.parse_ts(n_ts)
|
||||
if n_dt: next_unix = n_dt.timestamp()
|
||||
injected = [f for f in app.files if hasattr(f, 'injected_at') and f.injected_at and e_unix <= f.injected_at < next_unix]
|
||||
if injected:
|
||||
imgui.same_line(); imgui.text_colored(vec4(100, 255, 100), f"[{len(injected)}+]")
|
||||
if imgui.is_item_hovered(): imgui.set_tooltip("Files injected at this point:\n" + "\n".join([f.path for f in injected]))
|
||||
if usage:
|
||||
inp = usage.get("input_tokens", 0)
|
||||
out = usage.get("output_tokens", 0)
|
||||
cache = usage.get("cache_read_input_tokens", 0)
|
||||
usage_str = f" in:{inp} out:{out}"
|
||||
if cache: usage_str += f" cache:{cache}"
|
||||
imgui.same_line()
|
||||
imgui.text_colored(vec4(100, 150, 180), usage_str)
|
||||
if collapsed:
|
||||
imgui.same_line()
|
||||
if imgui.button("Ins"): app.disc_entries.insert(index, {"role": "User", "content": "", "collapsed": True, "ts": project_manager.now_ts()})
|
||||
@@ -3794,6 +3806,8 @@ def render_discussion_entry_controls(app: App) -> None:
|
||||
if imgui.button("Clear All"): app.disc_entries.clear()
|
||||
imgui.same_line()
|
||||
if imgui.button("Save"): app._flush_to_project(); app._flush_to_config(); models.save_config(app.config); app.ai_status = "discussion saved"
|
||||
imgui.same_line()
|
||||
if imgui.button("Compress"): app.controller._handle_compress_discussion()
|
||||
_, app.ui_auto_add_history = imgui.checkbox("Auto-add message & response to history", app.ui_auto_add_history)
|
||||
imgui.text("Keep Pairs:"); imgui.same_line(); imgui.set_next_item_width(80)
|
||||
ch, app.ui_disc_truncate_pairs = imgui.input_int("##trunc_pairs", app.ui_disc_truncate_pairs, 1)
|
||||
@@ -3806,6 +3820,17 @@ def render_discussion_entry_controls(app: App) -> None:
|
||||
def render_discussion_metadata(app: App) -> None:
|
||||
disc_data = app.project.get("discussion", {}).get("discussions", {}).get(app.active_discussion, {})
|
||||
git_commit, last_updated = disc_data.get("git_commit", ""), disc_data.get("last_updated", "")
|
||||
|
||||
total_in, total_out, total_cache = 0, 0, 0
|
||||
for entry in app.disc_entries:
|
||||
if "usage" in entry:
|
||||
total_in += entry["usage"].get("input_tokens", 0)
|
||||
total_out += entry["usage"].get("output_tokens", 0)
|
||||
total_cache += entry["usage"].get("cache_read_input_tokens", 0)
|
||||
if total_in > 0 or total_out > 0:
|
||||
imgui.text_colored(vec4(100, 150, 180), f"Discussion Tokens: {total_in} In | {total_out} Out | {total_cache} Cache")
|
||||
imgui.separator()
|
||||
|
||||
imgui.text_colored(C_LBL, "commit:"); imgui.same_line()
|
||||
render_selectable_label(app, 'git_commit_val', git_commit[:12] if git_commit else '(none)', width=100, color=(C_IN if git_commit else C_LBL))
|
||||
imgui.same_line()
|
||||
|
||||
Reference in New Issue
Block a user