返回 CodeWhale
mod.rs
根目录 / crates / tui / src / rlm / mod.rs
1 //! Recursive Language Model presentation and persistent Python context.
2 //!
3 //! The serving Engine captures one call-local route, policy, service and
4 //! cancellation receipt. `llm_query` and `rlm_query` submit bounded invocations
5 //! to the same `Engine::run_turn`; this module owns no provider/code loop.
6 //!
7 //! Long input stays in `_context` (`_ctx` / `content` compatibility aliases).
8 //! Core's session keeps initial metadata plus every code/result round until
9 //! FINAL, the strict partial-response refusal or the bounded deadline/cap.
10 //! Python kernels retain variables and pipes, never their borrowed dispatcher
11 //! or caller. The persistent `rlm` action surface is caller-session scoped;
12 //! `share_session=true` explicitly refuses. No HTTP sidecar is created.
13
14 use codewhale_models::Usage;
15
16 pub mod bridge;
17 pub mod prompt;
18 pub mod session;
19 pub mod turn;
20
21 pub(crate) use bridge::RlmBridge;
22 pub use prompt::rlm_system_prompt;
23 pub use turn::{RlmTermination, RlmTurnResult};
24
25 fn add_usage_with_prompt_cache(total: &mut Usage, delta: &Usage) {
26 total.input_tokens = total.input_tokens.saturating_add(delta.input_tokens);
27 total.output_tokens = total.output_tokens.saturating_add(delta.output_tokens);
28 total.prompt_cache_hit_tokens =
29 add_optional_usage(total.prompt_cache_hit_tokens, delta.prompt_cache_hit_tokens);
30 total.prompt_cache_miss_tokens = add_optional_usage(
31 total.prompt_cache_miss_tokens,
32 delta.prompt_cache_miss_tokens,
33 );
34 total.prompt_cache_write_tokens = add_optional_usage(
35 total.prompt_cache_write_tokens,
36 delta.prompt_cache_write_tokens,
37 );
38 total.reasoning_tokens = add_optional_usage(total.reasoning_tokens, delta.reasoning_tokens);
39 total.reasoning_replay_tokens =
40 add_optional_usage(total.reasoning_replay_tokens, delta.reasoning_replay_tokens);
41 if let Some(delta_server) = delta.server_tool_use.as_ref() {
42 let total_server = total.server_tool_use.get_or_insert_default();
43 total_server.code_execution_requests = add_optional_usage(
44 total_server.code_execution_requests,
45 delta_server.code_execution_requests,
46 );
47 total_server.tool_search_requests = add_optional_usage(
48 total_server.tool_search_requests,
49 delta_server.tool_search_requests,
50 );
51 }
52 }
53
54 fn add_optional_usage(total: Option<u32>, delta: Option<u32>) -> Option<u32> {
55 match (total, delta) {
56 (Some(total), Some(delta)) => Some(total.saturating_add(delta)),
57 (None, Some(delta)) => Some(delta),
58 (Some(total), None) => Some(total),
59 (None, None) => None,
60 }
61 }
62
63 #[cfg(test)]
64 mod tests {
65 use super::*;
66
67 #[test]
68 fn add_usage_with_prompt_cache_preserves_cache_counts() {
69 let mut total = Usage {
70 input_tokens: 100,
71 output_tokens: 10,
72 prompt_cache_hit_tokens: Some(80),
73 prompt_cache_miss_tokens: Some(20),
74 ..Usage::default()
75 };
76 let delta = Usage {
77 input_tokens: 50,
78 output_tokens: 5,
79 prompt_cache_hit_tokens: Some(30),
80 prompt_cache_miss_tokens: Some(20),
81 reasoning_tokens: Some(4),
82 reasoning_replay_tokens: Some(3),
83 server_tool_use: Some(codewhale_models::ServerToolUsage {
84 code_execution_requests: Some(2),
85 tool_search_requests: Some(1),
86 }),
87 ..Usage::default()
88 };
89
90 add_usage_with_prompt_cache(&mut total, &delta);
91
92 assert_eq!(total.input_tokens, 150);
93 assert_eq!(total.output_tokens, 15);
94 assert_eq!(total.prompt_cache_hit_tokens, Some(110));
95 assert_eq!(total.prompt_cache_miss_tokens, Some(40));
96 assert_eq!(total.reasoning_tokens, Some(4));
97 assert_eq!(total.reasoning_replay_tokens, Some(3));
98 assert_eq!(
99 total.server_tool_use,
100 Some(codewhale_models::ServerToolUsage {
101 code_execution_requests: Some(2),
102 tool_search_requests: Some(1),
103 })
104 );
105 }
106 }
107
107 lines RUST