diff --git a/engine/baml-schema-wasm/src/runtime_wasm/mod.rs b/engine/baml-schema-wasm/src/runtime_wasm/mod.rs index 7d615c2dc..b37d5d6e3 100644 --- a/engine/baml-schema-wasm/src/runtime_wasm/mod.rs +++ b/engine/baml-schema-wasm/src/runtime_wasm/mod.rs @@ -55,6 +55,8 @@ pub fn on_wasm_init() { const LOG_LEVEL: log::Level = log::Level::Warn; } }; + // This line is required if we want to see normal log::info! messages in JS console logs. + wasm_logger::init(wasm_logger::Config::new(LOG_LEVEL)); match console_log::init_with_level(LOG_LEVEL) { Ok(_) => web_sys::console::log_1( &format!("Initialized BAML runtime logging as log::{}", LOG_LEVEL).into(), @@ -140,6 +142,7 @@ impl WasmDiagnosticError { } #[wasm_bindgen(getter_with_clone, inspectable)] +#[derive(Debug)] pub struct WasmError { #[wasm_bindgen(readonly)] pub r#type: String, @@ -282,7 +285,7 @@ pub struct WasmRuntime { } #[wasm_bindgen(getter_with_clone, inspectable)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct WasmFunction { #[wasm_bindgen(readonly)] pub name: String, @@ -297,7 +300,7 @@ pub struct WasmFunction { } #[wasm_bindgen(getter_with_clone, inspectable)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct WasmSpan { #[wasm_bindgen(readonly)] pub file_path: String, @@ -312,7 +315,7 @@ pub struct WasmSpan { } #[wasm_bindgen(getter_with_clone, inspectable)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct WasmGeneratorConfig { #[wasm_bindgen(readonly)] pub output_type: String, @@ -348,7 +351,7 @@ impl Default for WasmSpan { } #[wasm_bindgen(getter_with_clone, inspectable)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct WasmParentFunction { #[wasm_bindgen(readonly)] pub start: usize, @@ -359,7 +362,7 @@ pub struct WasmParentFunction { } #[wasm_bindgen(getter_with_clone, inspectable)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct WasmTestCase { #[wasm_bindgen(readonly)] pub name: String, @@ -374,7 +377,7 @@ pub struct WasmTestCase { } #[wasm_bindgen(getter_with_clone, inspectable)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct WasmParam { #[wasm_bindgen(readonly)] pub name: String, @@ -783,7 +786,9 @@ fn get_dummy_value( Some(format!("({},)", dummy)) } baml_runtime::FieldType::Optional(_) => None, - baml_runtime::FieldType::Constrained{ base, .. } => get_dummy_value(indent, allow_multiline, t) + baml_runtime::FieldType::Constrained { base, .. } => { + get_dummy_value(indent, allow_multiline, base) + } } } diff --git a/engine/baml-schema-wasm/tests/test_file_manager.rs b/engine/baml-schema-wasm/tests/test_file_manager.rs index ec3f8089a..489a93431 100644 --- a/engine/baml-schema-wasm/tests/test_file_manager.rs +++ b/engine/baml-schema-wasm/tests/test_file_manager.rs @@ -1,3 +1,5 @@ +// Run from the baml-schema-wasm folder with: +// wasm-pack test --node #[cfg(test)] mod tests { use std::collections::HashMap; @@ -17,13 +19,7 @@ mod tests { /// Sample BAML content for testing. fn sample_baml_content() -> String { r##" - generator lang_python { - language python - project_root "../" - test_command "poetry run pytest" - install_command "poetry add baml@latest" - package_version_command "poetry show baml" - } + class Email { subject string @@ -139,4 +135,41 @@ mod tests { assert!(diagnostics.errors().is_empty()); } + + #[wasm_bindgen_test] + fn test_diagnostics_no_errors_2() { + wasm_logger::init(wasm_logger::Config::new(log::Level::Info)); + let sample_baml_content = r##" +function PredictAgeBare(inp: string @assert(big_enough, {{this|length > 1}}) ) -> int { + client "openai/gpt-4o" + prompt #" + Using your understanding of the historical popularity + of names, predict the age of a person with the name + {{ inp }} in years. Also predict their genus and + species. It's Homo sapiens (with exactly that spelling). + + {{ctx.output_format}} + "# +} + + "##; + let mut files = HashMap::new(); + files.insert("error.baml".to_string(), sample_baml_content.to_string()); + let files_js = to_value(&files).unwrap(); + let project = WasmProject::new("baml_src", files_js) + .map_err(JsValue::from) + .unwrap(); + + let env_vars = [("OPENAI_API_KEY", "12345")] + .iter() + .cloned() + .collect::>(); + let env_vars_js = to_value(&env_vars).unwrap(); + + let current_runtime = project.runtime(env_vars_js).map_err(JsValue::from).unwrap(); + let diagnostics = project.diagnostics(¤t_runtime); + current_runtime.list_functions(); + + assert!(diagnostics.errors().is_empty()); + } } diff --git a/typescript/vscode-ext/packages/language-server/src/lib/baml_project_manager.ts b/typescript/vscode-ext/packages/language-server/src/lib/baml_project_manager.ts index 5cb5a17b3..e8adaf2f6 100644 --- a/typescript/vscode-ext/packages/language-server/src/lib/baml_project_manager.ts +++ b/typescript/vscode-ext/packages/language-server/src/lib/baml_project_manager.ts @@ -167,7 +167,7 @@ class Project { .map(([path, content]) => [URI.file(path).toString(), content]), ) const diagnostics = this.wasmProject.diagnostics(this.current_runtime) - this.onSuccess(this.wasmProject.diagnostics(this.current_runtime), fileMap) + this.onSuccess(diagnostics, fileMap) } } @@ -622,7 +622,11 @@ class BamlProjectManager { await this.wrapAsync(async () => { for (const project of this.projects.values()) { project.requestDiagnostics() - this.notifier({ type: 'runtime_updated', root_path: project.rootPath(), files: project.files() }) + if (project.runtime()) { + this.notifier({ type: 'runtime_updated', root_path: project.rootPath(), files: project.files() }) + } else { + console.log('undefined runtime') + } } }) } diff --git a/typescript/vscode-ext/packages/language-server/src/server.ts b/typescript/vscode-ext/packages/language-server/src/server.ts index c4673a328..185e7f0fe 100644 --- a/typescript/vscode-ext/packages/language-server/src/server.ts +++ b/typescript/vscode-ext/packages/language-server/src/server.ts @@ -80,7 +80,9 @@ export function startServer(options?: LSOptions): void { switch (params.type) { case 'runtime_updated': // console.log(`runtime_updated today! ${Object.keys(params.files).length}: ${Object.entries(params.files).length}`) - connection.sendRequest('runtime_updated', params) + connection.sendRequest('runtime_updated', params).catch((e) => { + console.error('Error sending runtime_updated: ' + e) + }) break case 'diagnostic': params.errors.forEach(([uri, diagnostics]) => {