1#![forbid(unsafe_code)]
11
12use std::cell::RefCell;
13use std::time::Duration;
14use wasm_bindgen::prelude::*;
15use wasm_bindgen_futures::JsFuture;
16
17pub use web_time::Instant;
19
20pub use wasm_bindgen_futures::spawn_local;
22
23pub use console_error_panic_hook::set_once as set_panic_hook;
25
26#[derive(Debug, Clone)]
31pub struct WasmLlmConfig {
32 pub api_key: String,
33 pub base_url: String,
34 pub model: String,
35}
36
37impl Default for WasmLlmConfig {
38 fn default() -> Self {
39 Self {
40 api_key: String::new(),
41 base_url: "https://api.openai.com/v1".to_string(),
42 model: "gpt-4o-mini".to_string(),
43 }
44 }
45}
46
47thread_local! {
48 static WASM_LLM_CONFIG: RefCell<WasmLlmConfig> = RefCell::new(WasmLlmConfig::default());
49}
50
51#[wasm_bindgen]
60pub fn sage_configure(base_url: &str, model: &str, api_key: &str) {
61 WASM_LLM_CONFIG.with(|c| {
62 *c.borrow_mut() = WasmLlmConfig {
63 api_key: api_key.to_string(),
64 base_url: base_url.to_string(),
65 model: model.to_string(),
66 };
67 });
68}
69
70pub fn get_llm_config() -> WasmLlmConfig {
72 WASM_LLM_CONFIG.with(|c| c.borrow().clone())
73}
74
75pub async fn sleep(duration: Duration) {
77 let ms = duration.as_millis() as i32;
78 let promise = js_sys::Promise::new(&mut |resolve, _| {
79 let global = js_sys::global();
81 let _ = js_sys::Reflect::apply(
82 &js_sys::Function::from(js_sys::Reflect::get(&global, &"setTimeout".into()).unwrap()),
83 &global,
84 &js_sys::Array::of2(&resolve, &JsValue::from(ms)),
85 );
86 });
87 let _ = JsFuture::from(promise).await;
88}
89
90pub fn console_log(msg: &str) {
92 web_sys::console::log_1(&msg.into());
93}
94
95pub fn console_warn(msg: &str) {
97 web_sys::console::warn_1(&msg.into());
98}
99
100pub fn console_error(msg: &str) {
102 web_sys::console::error_1(&msg.into());
103}