brainwires_wasm/lib.rs
1#![deny(missing_docs)]
2//! # Brainwires WASM
3//!
4//! WASM bindings for the Brainwires Agent Framework.
5//!
6//! This crate provides a JavaScript-friendly API for the WASM-compatible subset of the
7//! Brainwires framework, enabling browser-based AI agent applications. All public functions
8//! are exposed via `wasm-bindgen` and can be called directly from JavaScript/TypeScript.
9//!
10//! ## Features
11//!
12//! - **Core types** (messages, tools, tasks) — always available
13//! - **MDAP types and configuration** — always available
14//! - **Code interpreters** — enabled with the `interpreters` feature
15//! - **Tool orchestrator** — enabled with the `orchestrator` feature; provides a Rhai-based
16//! script engine that can invoke JavaScript tool callbacks from WASM
17//!
18//! ## JS Usage
19//!
20//! ```js
21//! import init, { version, validate_message, serialize_history } from 'brainwires-wasm';
22//!
23//! await init();
24//! console.log(version()); // e.g. "0.4.1"
25//! ```
26
27use wasm_bindgen::prelude::*;
28
29/// Re-export of the [`brainwires_core`] crate for Rust consumers who depend on this
30/// WASM crate and need access to core types (`Message`, `Tool`, `Task`, etc.).
31pub use brainwires_core;
32
33/// Re-export of the MDAP module from [`brainwires_agents`] for Rust consumers
34/// who need MDAP (Multi-Dimensional Adaptive Planning) types and configuration.
35pub use brainwires_agents::mdap;
36
37/// Re-export of the [`brainwires_code_interpreters`] crate (requires the `interpreters` feature).
38///
39/// Provides sandboxed code execution capabilities for languages like JavaScript and Python
40/// within the WASM environment.
41#[cfg(feature = "interpreters")]
42pub use brainwires_code_interpreters;
43
44/// WASM orchestrator module providing JavaScript-compatible bindings for the tool orchestrator.
45///
46/// This module is only available when the `orchestrator` feature is enabled. It exposes
47/// [`WasmOrchestrator`](wasm_orchestrator::WasmOrchestrator) and
48/// [`ExecutionLimits`](wasm_orchestrator::ExecutionLimits) for running Rhai scripts
49/// that can call registered JavaScript tool functions.
50#[cfg(feature = "orchestrator")]
51pub mod wasm_orchestrator;
52
53/// Convenience re-exports of the orchestrator types at crate root level.
54///
55/// - [`WasmExecutionLimits`] — Alias for [`wasm_orchestrator::ExecutionLimits`]
56/// - [`WasmOrchestrator`] — The main orchestrator entry point
57#[cfg(feature = "orchestrator")]
58pub use wasm_orchestrator::{ExecutionLimits as WasmExecutionLimits, WasmOrchestrator};
59
60// ── WASM Bindings ────────────────────────────────────────────────────────
61
62/// Returns the crate version string (e.g. `"0.4.1"`).
63///
64/// This is the version of the `brainwires-wasm` package as declared in `Cargo.toml`.
65///
66/// # JS Example
67///
68/// ```js
69/// const v = version();
70/// console.log(`Brainwires WASM v${v}`);
71/// ```
72#[wasm_bindgen]
73pub fn version() -> String {
74 env!("CARGO_PKG_VERSION").to_string()
75}
76
77/// Validates and normalizes a JSON-encoded message.
78///
79/// Parses the input JSON string into a [`brainwires_core::Message`] struct and
80/// re-serializes it back to JSON. This ensures the message conforms to the expected
81/// schema and strips any unknown fields.
82///
83/// # Parameters
84///
85/// - `json` — A JSON string representing a single message object.
86///
87/// # Returns
88///
89/// The normalized JSON string on success, or an error string describing the
90/// validation failure.
91///
92/// # JS Example
93///
94/// ```js
95/// try {
96/// const normalized = validate_message('{"role":"user","content":"Hello"}');
97/// console.log(normalized);
98/// } catch (e) {
99/// console.error("Invalid message:", e);
100/// }
101/// ```
102#[wasm_bindgen]
103pub fn validate_message(json: &str) -> Result<String, String> {
104 let msg: brainwires_core::Message =
105 serde_json::from_str(json).map_err(|e| format!("Invalid message JSON: {e}"))?;
106 serde_json::to_string(&msg).map_err(|e| format!("Serialization error: {e}"))
107}
108
109/// Validates and normalizes a JSON-encoded tool definition.
110///
111/// Parses the input JSON string into a [`brainwires_core::Tool`] struct and
112/// re-serializes it back to JSON. Use this to verify that a tool definition
113/// is well-formed before registering it.
114///
115/// # Parameters
116///
117/// - `json` — A JSON string representing a tool definition object.
118///
119/// # Returns
120///
121/// The normalized JSON string on success, or an error string describing the
122/// validation failure.
123///
124/// # JS Example
125///
126/// ```js
127/// const toolJson = JSON.stringify({
128/// name: "calculator",
129/// description: "Performs arithmetic",
130/// input_schema: { type: "object", properties: { expr: { type: "string" } } }
131/// });
132/// const normalized = validate_tool(toolJson);
133/// ```
134#[wasm_bindgen]
135pub fn validate_tool(json: &str) -> Result<String, String> {
136 let tool: brainwires_core::Tool =
137 serde_json::from_str(json).map_err(|e| format!("Invalid tool JSON: {e}"))?;
138 serde_json::to_string(&tool).map_err(|e| format!("Serialization error: {e}"))
139}
140
141/// Serializes a conversation history to the stateless protocol format.
142///
143/// Takes a JSON array of [`brainwires_core::Message`] objects and converts them
144/// into the stateless history format used by AI provider APIs. This is useful
145/// when you need to send a full conversation context in a single API request.
146///
147/// # Parameters
148///
149/// - `messages_json` — A JSON string containing an array of message objects.
150///
151/// # Returns
152///
153/// A JSON string in the stateless history format on success, or an error string
154/// if the input is malformed.
155///
156/// # JS Example
157///
158/// ```js
159/// const messages = JSON.stringify([
160/// { role: "user", content: "What is 2+2?" },
161/// { role: "assistant", content: "4" }
162/// ]);
163/// const history = serialize_history(messages);
164/// // Use `history` in an API request body
165/// ```
166#[wasm_bindgen]
167pub fn serialize_history(messages_json: &str) -> Result<String, String> {
168 let messages: Vec<brainwires_core::Message> =
169 serde_json::from_str(messages_json).map_err(|e| format!("Invalid messages JSON: {e}"))?;
170 let history = brainwires_core::serialize_messages_to_stateless_history(&messages);
171 serde_json::to_string(&history).map_err(|e| format!("Serialization error: {e}"))
172}