diff --git a/src/app_controller.py b/src/app_controller.py index 39d3376..dc5cc8c 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -1458,9 +1458,22 @@ class AppController: if kind == "response" and "usage" in payload: u = payload["usage"] - for k in ["input_tokens", "output_tokens", "cache_read_input_tokens", "cache_creation_input_tokens", "total_tokens"]: - if k in u: - self.session_usage[k] += u.get(k, 0) or 0 + inp = u.get("input_tokens", u.get("prompt_tokens", 0)) + out = u.get("output_tokens", u.get("completion_tokens", 0)) + cache_read = u.get("cache_read_input_tokens", 0) + cache_create = u.get("cache_creation_input_tokens", 0) + total = u.get("total_tokens", 0) + + # Store normalized usage back in payload for history rendering + u["input_tokens"] = inp + u["output_tokens"] = out + u["cache_read_input_tokens"] = cache_read + + self.session_usage["input_tokens"] += inp + self.session_usage["output_tokens"] += out + self.session_usage["cache_read_input_tokens"] += cache_read + self.session_usage["cache_creation_input_tokens"] += cache_create + self.session_usage["total_tokens"] += total input_t = u.get("input_tokens", 0) output_t = u.get("output_tokens", 0) model = payload.get("model", "unknown") diff --git a/src/gui_2.py b/src/gui_2.py index 97c636b..b649b3c 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -326,22 +326,31 @@ class App: if is_nerv: imgui.pop_style_color() # ---------------------------------------------------------------- gui - def _render_thinking_trace(self, segments: list[dict], entry_index: int) -> None: + def _render_thinking_trace(self, segments: list[dict], entry_index: int, is_standalone: bool = False) -> None: if not segments: return imgui.push_style_color(imgui.Col_.child_bg, vec4(40, 35, 25, 180)) imgui.push_style_color(imgui.Col_.text, vec4(200, 200, 150)) imgui.indent() - header_label = f"Monologue ({len(segments)} traces)###thinking_header_{entry_index}" - if imgui.collapsing_header(header_label): - imgui.begin_child(f"thinking_content_{entry_index}", imgui.ImVec2(0, 80), True) + show_content = True + if not is_standalone: + header_label = f"Monologue ({len(segments)} traces)###thinking_header_{entry_index}" + show_content = imgui.collapsing_header(header_label) + + if show_content: + h = 150 if is_standalone else 100 + imgui.begin_child(f"thinking_content_{entry_index}", imgui.ImVec2(0, h), True) for idx, seg in enumerate(segments): content = seg.get("content", "") marker = seg.get("marker", "thinking") imgui.push_id(f"think_{entry_index}_{idx}") imgui.text_colored(vec4(180, 150, 80), f"[{marker}]") - imgui.same_line() - imgui.text_colored(vec4(200, 200, 150), content) + if self.ui_word_wrap: + imgui.push_text_wrap_pos(imgui.get_content_region_avail().x) + imgui.text_colored(vec4(200, 200, 150), content) + imgui.pop_text_wrap_pos() + else: + imgui.text_colored(vec4(200, 200, 150), content) imgui.pop_id() imgui.separator() imgui.end_child() @@ -2280,11 +2289,16 @@ def hello(): imgui.same_line() preview = entry["content"].replace("\\n", " ")[:60] if len(entry["content"]) > 60: preview += "..." + if not preview.strip() and entry.get("thinking_segments"): + preview = entry["thinking_segments"][0]["content"].replace("\\n", " ")[:60] + if len(entry["thinking_segments"][0]["content"]) > 60: preview += "..." imgui.text_colored(vec4(160, 160, 150), preview) if not collapsed: thinking_segments = entry.get("thinking_segments", []) + has_content = bool(entry.get("content", "").strip()) + is_standalone = bool(thinking_segments) and not has_content if thinking_segments: - self._render_thinking_trace(thinking_segments, i) + self._render_thinking_trace(thinking_segments, i, is_standalone=is_standalone) if read_mode: content = entry["content"] if content.strip(): @@ -2943,7 +2957,7 @@ def hello(): text_content = payload.get("text", "") segments, parsed_response = thinking_parser.parse_thinking_trace(text_content) if segments: - self._render_thinking_trace([{"content": s.content, "marker": s.marker} for s in segments], i) + self._render_thinking_trace([{"content": s.content, "marker": s.marker} for s in segments], i, is_standalone=not bool(parsed_response.strip())) if parsed_response: self._render_heavy_text("text", parsed_response, idx_str)