refactor: streamline token counting and message shaping logic

This commit is contained in:
asepharyana
2026-07-17 10:29:52 +07:00
parent 0dfde96f81
commit 5aad7e1eb1
3 changed files with 81 additions and 45 deletions
@@ -2,6 +2,8 @@
//! `apply_action` in the root module. Each handler mutates `AppStateRest`
//! in place.
use crate::app::runtime::context::tokens::count_tokens;
use crate::app::runtime::context::window;
use crate::app::state::rest::{AppStateRest, ChatMessageDisplay};
use crate::app::state::runtime::TurnEvent;
use crate::app::state::types::{Overlay, Toast, ToastKind};
@@ -205,24 +207,15 @@ pub(super) fn handle_abort_turn(state: &mut AppStateRest) {
}
pub(super) fn handle_compact(state: &mut AppStateRest) {
let max_wire_tokens = state
.app_config
.model_roles
.values()
.find(|role| {
role.provider == state.settings.provider && role.model == state.settings.model
})
.and_then(|role| role.context_window)
.unwrap_or(state.app_config.default_context_window) as usize;
let max_wire_tokens = window::resolve(&state.app_config, &state.settings);
if let Some(ref mut rt) = state.session_runtime {
let total_chars: usize = rt
let token_estimate: usize = rt
.messages
.iter()
.filter_map(|m| m.content.as_deref())
.map(str::len)
.map(count_tokens)
.sum();
let token_estimate = total_chars / 3;
rt.messages =
crate::app::runtime::context::shaping::shape_messages(
&rt.messages,
@@ -230,6 +223,7 @@ pub(super) fn handle_compact(state: &mut AppStateRest) {
max_wire_tokens,
true,
None,
None,
);
state.push_toast(Toast::new(
ToastKind::Success,
@@ -13,6 +13,7 @@ use sha2::Digest;
use zesdex_cms::domain::repository::EditLogRepository;
use crate::app::guard::Verdict;
use crate::app::runtime::context::tokens::count_tokens;
use crate::app::state::runtime::TurnEvent;
use zesdex_cms::domain::repository::MemoryRepository;
use crate::dto::chat::message::ChatMessage;
@@ -326,12 +327,11 @@ pub(super) fn run_agent_turn(
let mut todo_retry_count = 0usize;
loop {
let total_chars: usize = msgs
let token_estimate: usize = msgs
.iter()
.filter_map(|m| m.content.as_deref())
.map(str::len)
.map(count_tokens)
.sum();
let token_estimate = total_chars / 4;
let max_wire_tokens = tc.context_window;
// Skip message compaction if abort was requested — the non-streaming
@@ -352,6 +352,7 @@ pub(super) fn run_agent_turn(
max_wire_tokens,
false,
Some(&tc.client),
Some(&tc.abort_flag),
);
// Dispatch the compacted messages to the main thread so the local session history
@@ -488,12 +489,12 @@ pub(super) fn run_agent_turn(
let (mut tok_in, mut tok_out) = final_usage.unwrap_or((0, 0));
if tok_in == 0 {
let total_chars: usize = wire_msgs
let total_tokens: usize = wire_msgs
.iter()
.filter_map(|m| m.content.as_deref())
.map(str::len)
.map(count_tokens)
.sum();
tok_in = (total_chars / 4).max(1) as u64;
tok_in = total_tokens.max(1) as u64;
}
if tok_out == 0 {
let response_chars = response.content.as_deref().map_or(0, str::len);