| 8725 | } |
| 8726 | |
| 8727 | static void live_tool_state_free(live_tool_state *st) { |
| 8728 | if (!st) return; |
| 8729 | live_tool_state_clear_locked(st); |
| 8730 | free(st->call_ids.v); |
| 8731 | memset(st, 0, sizeof(*st)); |
| 8732 | } |
| 8733 | |
| 8734 | static void visible_live_clear_locked(visible_live_state *st) { |
| 8735 | if (!st) return; |
| 8736 | free(st->visible_text); |
| 8737 | st->visible_text = NULL; |
| 8738 | st->visible_len = 0; |
| 8739 | st->live_tokens = 0; |
| 8740 | st->valid = false; |
| 8741 | } |
| 8742 | |
| 8743 | static void visible_live_free(visible_live_state *st) { |
| 8744 | if (!st) return; |
| 8745 | visible_live_clear_locked(st); |
| 8746 | memset(st, 0, sizeof(*st)); |
| 8747 | } |
| 8748 | |
| 8749 | static void thinking_live_clear(server *s, server_slot *slot) { |
| 8750 | if (!s || !slot) return; |
| 8751 | pthread_mutex_lock(&s->tool_mu); |
| 8752 | visible_live_clear_locked(&slot->thinking_live); |
| 8753 | pthread_mutex_unlock(&s->tool_mu); |
| 8754 | } |
| 8755 | |
| 8756 | static void thinking_live_remember(server *s, server_slot *slot, |
| 8757 | const char *visible_text) { |
| 8758 | if (!s || !slot || !visible_text || !visible_text[0]) return; |
| 8759 | pthread_mutex_lock(&s->tool_mu); |
| 8760 | visible_live_clear_locked(&slot->thinking_live); |
| 8761 | slot->thinking_live.visible_text = xstrdup(visible_text); |
| 8762 | slot->thinking_live.visible_len = strlen(visible_text); |
| 8763 | slot->thinking_live.live_tokens = ds4_session_pos(slot->session); |
| 8764 | slot->thinking_live.valid = true; |
| 8765 | pthread_mutex_unlock(&s->tool_mu); |
| 8766 | } |
| 8767 | |
| 8768 | static void responses_live_remember(server *s, server_slot *slot, |
| 8769 | const char *visible_text, |
no test coverage detected