tirea_contract/runtime/state/
scope_context.rs1use super::spec::StateScope;
2
3#[derive(Debug, Clone)]
10pub struct ScopeContext {
11 call_id: Option<String>,
12}
13
14impl ScopeContext {
15 pub fn run() -> Self {
17 Self { call_id: None }
18 }
19
20 pub fn for_call(call_id: impl Into<String>) -> Self {
22 Self {
23 call_id: Some(call_id.into()),
24 }
25 }
26
27 pub fn call_id(&self) -> Option<&str> {
29 self.call_id.as_deref()
30 }
31
32 pub fn resolve_path(&self, scope: StateScope, base_path: &str) -> String {
38 match (scope, &self.call_id) {
39 (StateScope::ToolCall, Some(id)) => {
40 format!("__tool_call_scope.{}.{}", id, base_path)
41 }
42 _ => base_path.to_string(),
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn run_scope_returns_base_path() {
53 let ctx = ScopeContext::run();
54 assert_eq!(ctx.resolve_path(StateScope::Run, "my_state"), "my_state");
55 }
56
57 #[test]
58 fn run_scope_with_tool_call_scoped_state_falls_back() {
59 let ctx = ScopeContext::run();
60 assert_eq!(
61 ctx.resolve_path(StateScope::ToolCall, "my_state"),
62 "my_state"
63 );
64 }
65
66 #[test]
67 fn for_call_routes_tool_call_scope() {
68 let ctx = ScopeContext::for_call("call_42");
69 assert_eq!(
70 ctx.resolve_path(StateScope::ToolCall, "my_plugin.tool_ctx"),
71 "__tool_call_scope.call_42.my_plugin.tool_ctx"
72 );
73 }
74
75 #[test]
76 fn for_call_leaves_run_scope_unchanged() {
77 let ctx = ScopeContext::for_call("call_42");
78 assert_eq!(ctx.resolve_path(StateScope::Run, "my_state"), "my_state");
79 }
80
81 #[test]
82 fn thread_scope_returns_base_path() {
83 let ctx = ScopeContext::run();
84 assert_eq!(
85 ctx.resolve_path(StateScope::Thread, "reminders"),
86 "reminders"
87 );
88 }
89
90 #[test]
91 fn for_call_leaves_thread_scope_unchanged() {
92 let ctx = ScopeContext::for_call("call_42");
93 assert_eq!(
94 ctx.resolve_path(StateScope::Thread, "reminders"),
95 "reminders"
96 );
97 }
98
99 #[test]
100 fn call_id_accessor() {
101 assert_eq!(ScopeContext::run().call_id(), None);
102 assert_eq!(ScopeContext::for_call("x").call_id(), Some("x"));
103 }
104}