@@ -25,6 +25,7 @@ use crate::tools::write_to_file::WriteToFileTool;
2525use crate :: Config ;
2626use anyhow:: Result ;
2727use futures:: StreamExt ;
28+ use itertools:: Itertools ;
2829use mcp_core:: types:: ProtocolVersion ;
2930use rig:: agent:: AgentBuilder ;
3031use rig:: completion:: CompletionError ;
@@ -93,8 +94,8 @@ impl Display for AgentError {
9394 }
9495}
9596
96- fn count_tokens ( system_prompt : & str ) -> u32 {
97- system_prompt . len ( ) as u32 / 4
97+ fn count_tokens ( text : & str ) -> u32 {
98+ text . len ( ) as u32 / 4
9899}
99100
100101impl Agent {
@@ -246,7 +247,8 @@ impl Agent {
246247 async fn configure_agent < M > (
247248 mut agent_builder : AgentBuilder < M > ,
248249 context : BuildAgentContext < ' _ > ,
249- ) -> Result < AgentBuilder < M > >
250+ tools_tokens : & mut u32 ,
251+ ) -> Result < rig:: agent:: Agent < M > >
250252 where
251253 M : CompletionModel ,
252254 {
@@ -256,10 +258,24 @@ impl Agent {
256258 let mcp_config = context. config . mcp . as_ref ( ) ;
257259 agent_builder = Self :: add_static_tools ( agent_builder, context) ;
258260 agent_builder = Self :: add_mcp_tools ( agent_builder, mcp_config) . await ?;
259- Ok ( agent_builder)
261+ let agent = agent_builder. build ( ) ;
262+ * tools_tokens = count_tokens (
263+ & agent
264+ . tools
265+ . documents ( )
266+ . await
267+ . unwrap ( )
268+ . iter ( )
269+ . map ( |d| & d. text )
270+ . join ( "\n " ) ,
271+ ) ;
272+ Ok ( agent)
260273 }
261274
262- async fn build_agent ( context : BuildAgentContext < ' _ > ) -> Result < Box < dyn HulyAgent > > {
275+ async fn build_agent (
276+ context : BuildAgentContext < ' _ > ,
277+ tools_tokens : & mut u32 ,
278+ ) -> Result < Box < dyn HulyAgent > > {
263279 match context. config . provider {
264280 ProviderKind :: OpenAI => {
265281 let agent_builder = rig:: providers:: openai:: Client :: new (
@@ -271,7 +287,7 @@ impl Agent {
271287 )
272288 . agent ( & context. config . model ) ;
273289 Ok ( Box :: new (
274- Self :: configure_agent ( agent_builder, context) . await ?. build ( ) ,
290+ Self :: configure_agent ( agent_builder, context, tools_tokens ) . await ?,
275291 ) )
276292 }
277293 ProviderKind :: Anthropic => {
@@ -286,7 +302,7 @@ impl Agent {
286302 . agent ( & context. config . model )
287303 . max_tokens ( 20000 ) ;
288304 Ok ( Box :: new (
289- Self :: configure_agent ( agent_builder, context) . await ?. build ( ) ,
305+ Self :: configure_agent ( agent_builder, context, tools_tokens ) . await ?,
290306 ) )
291307 }
292308 ProviderKind :: OpenRouter => {
@@ -299,7 +315,7 @@ impl Agent {
299315 )
300316 . agent ( & context. config . model ) ;
301317 Ok ( Box :: new (
302- Self :: configure_agent ( agent_builder, context) . await ?. build ( ) ,
318+ Self :: configure_agent ( agent_builder, context, tools_tokens ) . await ?,
303319 ) )
304320 }
305321 ProviderKind :: LMStudio => {
@@ -313,7 +329,7 @@ impl Agent {
313329 )
314330 . agent ( & context. config . model ) ;
315331 Ok ( Box :: new (
316- Self :: configure_agent ( agent_builder, context) . await ?. build ( ) ,
332+ Self :: configure_agent ( agent_builder, context, tools_tokens ) . await ?,
317333 ) )
318334 }
319335 }
@@ -332,6 +348,16 @@ impl Agent {
332348 self . sender
333349 . send ( AgentOutputEvent :: AddMessage ( message. clone ( ) ) )
334350 . unwrap ( ) ;
351+ if let Message :: User { .. } = & message {
352+ // clear previous messages from env details
353+ self . messages . iter_mut ( ) . for_each ( |m| {
354+ if let Message :: User { content, .. } = m {
355+ if content. len ( ) > 1 {
356+ * content = OneOrMany :: one ( content. first ( ) ) ;
357+ }
358+ }
359+ } ) ;
360+ }
335361 self . messages . push ( message) ;
336362 }
337363
@@ -477,7 +503,7 @@ impl Agent {
477503 } else {
478504 add_env_message (
479505 & mut result_message,
480- None ,
506+ self . memory_index . as_ref ( ) ,
481507 & self . config . workspace ,
482508 self . process_registry . clone ( ) ,
483509 )
@@ -565,17 +591,23 @@ impl Agent {
565591 let system_prompt =
566592 prepare_system_prompt ( & self . config . workspace , & self . config . user_instructions ) . await ;
567593 let system_prompt_token_count = count_tokens ( & system_prompt) ;
594+ let mut tools_tokens = 0 ;
568595 self . agent = Some (
569- Self :: build_agent ( BuildAgentContext {
570- config : & self . config ,
571- system_prompt,
572- memory : self . memory . clone ( ) ,
573- process_registry : self . process_registry . clone ( ) ,
574- sender : self . sender . clone ( ) ,
575- } )
596+ Self :: build_agent (
597+ BuildAgentContext {
598+ config : & self . config ,
599+ system_prompt,
600+ memory : self . memory . clone ( ) ,
601+ process_registry : self . process_registry . clone ( ) ,
602+ sender : self . sender . clone ( ) ,
603+ } ,
604+ & mut tools_tokens,
605+ )
576606 . await
577607 . unwrap ( ) ,
578608 ) ;
609+ // This is workaround to calculate tokens from system prompt and tools for providers like LMStudio
610+ let system_prompt_token_count = system_prompt_token_count + tools_tokens / 2 ;
579611 // restore state from messages
580612 self . set_state ( if self . messages . is_empty ( ) {
581613 AgentState :: WaitingUserPrompt
0 commit comments