Browser/WASM Binding (Preview)
This document defines the current browser-compatible binding surface for simple-agents-wasm and how it maps to simple-agents-node.
Current status
- Package path:
bindings/wasm/simple-agents-wasm - Maturity: preview (WS1/WS2 rollout stage)
- Runtime target: modern browsers and fetch-capable JS runtimes
- Runtime engine: Rust
wasm-bindgencore (bindings/wasm/simple-agents-wasm/rust) with JS fallback for non-wasm environments
Contract goals
- Keep method naming and result shapes aligned with
simple-agents-node. - Preserve message and completion type semantics where possible.
- Keep browser-incompatible APIs explicit (fail fast with actionable errors).
Supported APIs
new Client(provider, config)whereproviderisopenaioropenroutercomplete(model, promptOrMessages, options?)stream(model, promptOrMessages, onChunk, options?)streamEvents(model, promptOrMessages, onEvent, options?)runWorkflowYamlString(yamlText, workflowInput, workflowOptions?)run(request)/runAsync(request)/streamWorkflow(request, onEvent?)(typed, messages-first workflow facade)createWorkflowStreamPrinter({ splitThinking? })fromsimple-agents-wasm/workflow_stream_printerfor a default streamingonEventimplementation (Node usesprocess.stdout.writewhen available; browsers fall back toconsole.log)
Deliberate differences vs Node binding
- Browser config is explicit object-based; env-driven provider config is not used.
healed_jsonandschemamodes are not yet implemented.- Path-based workflow methods are not supported in browser runtime.
- Usage metadata in streams may be unavailable (
usageAvailable: false) depending on provider stream payloads.
Browser-safe workflow direction
WASM/browser flow support is string/object based:
- Implemented:
runWorkflowYamlString(yamlText, workflowInput, workflowOptions?)- Supports step DSL (
steps) and graph YAML (entry_node+nodes+edges) forllm_call,switch, andcustom_workernode types. custom_workerrequires exact handler lookup inworkflowOptions.functions:- without
handler_file:workflowOptions.functions[handler] - with
handler_file:workflowOptions.functions["<handler_file>#<handler>"]
- without
- Each handler is called as
(args, graphContext)(sync or async/Promise). The first argument includes resolvedpayload,handler,nodeId, and related metadata; the second is the live graph context (input, nodes, globals). Payload interpolation andnodes.*.outputtemplate rules match YAML_WORKFLOW_SYSTEM.md. This differs from Python’s kwargs-onlycontext/payloadcall shape, but the data is the same.
- Supports step DSL (
- Not supported in browser:
runWorkflowYaml(workflowPath, ...)
Workflow result contract is strict: runWorkflowYamlString expects outputs containing workflow_id and outputs, and throws if the backend response shape is incompatible.
Unified workflow request shape for browser runtime:
workflow_yaml: string(inline YAML text; browser runtime does not support local filesystem path loading)messages: MessageInput[](required)- optional
context,media,input,execution,workflow_options
workflow_options.telemetry and workflow_options.trace use explicit TypeScript interfaces in index.d.ts (WorkflowTelemetryConfig, WorkflowTraceConfig, etc., snake_case field names to match the Rust runner). input may include optional workflow-specific fields (some older examples used a scalar like email_text); prefer messages as the primary chat payload and keep extra keys only when templates reference input.*.
Note: completion APIs already use stream(...), so workflow streaming is exposed as streamWorkflow(...) to avoid method-name collision on the shared Client surface.
Security and deployment notes
- BYOK credentials are provided at runtime and must not be persisted by default.
- Browser mode still depends on provider CORS behavior.
- Use server fallback only when CORS/provider constraints require it.
Local development workflow
- Install package deps:
cd bindings/wasm/simple-agents-wasm && npm install - Build wasm + JS package:
make build-wasm - Run wasm binding tests:
make test-wasm - Run repository contract/parity checks:
make test-binding-contractsandmake test-binding-layers
Rust + JavaScript quality gates
- Rust formatting:
cargo fmt --manifest-path bindings/wasm/simple-agents-wasm/rust/Cargo.toml -- --check - Rust linting:
cargo clippy --manifest-path bindings/wasm/simple-agents-wasm/rust/Cargo.toml --all-targets - JS tests (Node runtime fallback + parity):
cd bindings/wasm/simple-agents-wasm && npm test
Type-checking and editor support
- Public TS surface is maintained in
bindings/wasm/simple-agents-wasm/index.d.ts. - Keep
index.d.tsaligned with runtime behavior for both Rust-backed and JS fallback execution. - Use TypeScript-aware editors (
tsserver) to validate consumer-facing types and callback signatures when updating APIs.