MCPcopy Create free account
hub / github.com/AI45Lab/Code / call_decision

Method call_decision

sdk/node/src/lib.rs:5142–5183  ·  view source on GitHub ↗
(
        &self,
        tsfn: &napi::threadsafe_function::ThreadsafeFunction<
            serde_json::Value,
            napi::threadsafe_function::ErrorStrategy::Fatal,
        >,
        args: serd

Source from the content-addressed store, hash-verified

5140
5141impl NodeBudgetGuard {
5142 fn call_decision(
5143 &self,
5144 tsfn: &napi::threadsafe_function::ThreadsafeFunction<
5145 serde_json::Value,
5146 napi::threadsafe_function::ErrorStrategy::Fatal,
5147 >,
5148 args: serde_json::Value,
5149 ) -> a3s_code_core::budget::BudgetDecision {
5150 let (tx, rx) = std::sync::mpsc::sync_channel::<a3s_code_core::budget::BudgetDecision>(1);
5151 tsfn.call_with_return_value(
5152 args,
5153 napi::threadsafe_function::ThreadsafeFunctionCallMode::NonBlocking,
5154 move |ret: napi::JsUnknown| {
5155 // FAIL-CLOSED: if the JS return value can't even be read as
5156 // a napi value, deny rather than allow. A budget guard is a
5157 // cost/quota control — silently permitting on a broken
5158 // response is the dangerous direction. (Explicit responses
5159 // like null / {decision:'allow'} are still parsed leniently
5160 // as Allow inside parse_js_budget_decision.)
5161 let decision = parse_js_budget_decision(ret).unwrap_or_else(|_| {
5162 a3s_code_core::budget::BudgetDecision::Deny {
5163 resource: "budget_guard_error".to_string(),
5164 reason: "budget guard return value could not be read".to_string(),
5165 }
5166 });
5167 let _ = tx.send(decision);
5168 Ok(())
5169 },
5170 );
5171 // FAIL-CLOSED on timeout: a hung or throwing guard (under Fatal
5172 // strategy a JS throw means the return closure never fires, so the
5173 // channel stays empty and we hit this timeout) must DENY, not
5174 // Allow. Previously this defaulted to Allow — meaning a slow/buggy
5175 // guard silently disabled budget enforcement (a fail-open hole).
5176 tokio::task::block_in_place(|| {
5177 rx.recv_timeout(std::time::Duration::from_millis(self.timeout_ms))
5178 .unwrap_or_else(|_| a3s_code_core::budget::BudgetDecision::Deny {
5179 resource: "budget_guard_timeout".to_string(),
5180 reason: format!("budget guard did not respond within {}ms", self.timeout_ms),
5181 })
5182 })
5183 }
5184}
5185
5186#[async_trait::async_trait]

Callers 2

check_before_llmMethod · 0.80
check_before_toolMethod · 0.80

Calls 2

parse_js_budget_decisionFunction · 0.85
sendMethod · 0.45

Tested by

no test coverage detected