simple-agents-wasm 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/index.d.ts +26 -2
- package/index.js +59 -1158
- package/package.json +1 -1
- package/pkg/simple_agents_wasm.d.ts +0 -3
- package/pkg/simple_agents_wasm.js +4 -13
- package/pkg/simple_agents_wasm_bg.wasm +0 -0
- package/pkg/simple_agents_wasm_bg.wasm.d.ts +0 -1
- package/runtime/rust-runtime.js +21 -3
- package/rust/Cargo.toml +1 -1
- package/rust/src/lib.rs +111 -54
package/package.json
CHANGED
|
@@ -24,15 +24,12 @@ export class WasmClient {
|
|
|
24
24
|
|
|
25
25
|
export function supportsRustWasm(): boolean;
|
|
26
26
|
|
|
27
|
-
export function toJsArray(value: any): Array<any>;
|
|
28
|
-
|
|
29
27
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
30
28
|
|
|
31
29
|
export interface InitOutput {
|
|
32
30
|
readonly memory: WebAssembly.Memory;
|
|
33
31
|
readonly __wbg_wasmclient_free: (a: number, b: number) => void;
|
|
34
32
|
readonly supportsRustWasm: () => number;
|
|
35
|
-
readonly toJsArray: (a: any) => any;
|
|
36
33
|
readonly wasmclient_complete: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
37
34
|
readonly wasmclient_new: (a: number, b: number, c: any) => [number, number, number];
|
|
38
35
|
readonly wasmclient_runWorkflowYaml: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
@@ -108,15 +108,6 @@ export function supportsRustWasm() {
|
|
|
108
108
|
return ret !== 0;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
/**
|
|
112
|
-
* @param {any} value
|
|
113
|
-
* @returns {Array<any>}
|
|
114
|
-
*/
|
|
115
|
-
export function toJsArray(value) {
|
|
116
|
-
const ret = wasm.toJsArray(value);
|
|
117
|
-
return ret;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
111
|
function __wbg_get_imports() {
|
|
121
112
|
const import0 = {
|
|
122
113
|
__proto__: null,
|
|
@@ -357,13 +348,13 @@ function __wbg_get_imports() {
|
|
|
357
348
|
const ret = arg0.next();
|
|
358
349
|
return ret;
|
|
359
350
|
}, arguments); },
|
|
351
|
+
__wbg_parse_545d11396395fbbd: function() { return handleError(function (arg0, arg1) {
|
|
352
|
+
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
|
353
|
+
return ret;
|
|
354
|
+
}, arguments); },
|
|
360
355
|
__wbg_prototypesetcall_3e05eb9545565046: function(arg0, arg1, arg2) {
|
|
361
356
|
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
|
|
362
357
|
},
|
|
363
|
-
__wbg_push_6bdbc990be5ac37b: function(arg0, arg1) {
|
|
364
|
-
const ret = arg0.push(arg1);
|
|
365
|
-
return ret;
|
|
366
|
-
},
|
|
367
358
|
__wbg_queueMicrotask_abaf92f0bd4e80a4: function(arg0) {
|
|
368
359
|
const ret = arg0.queueMicrotask;
|
|
369
360
|
return ret;
|
|
Binary file
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
export const memory: WebAssembly.Memory;
|
|
4
4
|
export const __wbg_wasmclient_free: (a: number, b: number) => void;
|
|
5
5
|
export const supportsRustWasm: () => number;
|
|
6
|
-
export const toJsArray: (a: any) => any;
|
|
7
6
|
export const wasmclient_complete: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
8
7
|
export const wasmclient_new: (a: number, b: number, c: any) => [number, number, number];
|
|
9
8
|
export const wasmclient_runWorkflowYaml: (a: number, b: number, c: number, d: any) => [number, number, number];
|
package/runtime/rust-runtime.js
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
let rustModulePromise;
|
|
2
2
|
|
|
3
|
+
function isNodeRuntime() {
|
|
4
|
+
return typeof process !== "undefined" && Boolean(process.versions?.node);
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
export async function loadRustModule() {
|
|
4
8
|
if (!rustModulePromise) {
|
|
5
9
|
rustModulePromise = (async () => {
|
|
6
10
|
try {
|
|
7
11
|
const moduleValue = await import("../pkg/simple_agents_wasm.js");
|
|
8
12
|
const wasmUrl = new URL("../pkg/simple_agents_wasm_bg.wasm", import.meta.url);
|
|
9
|
-
|
|
13
|
+
let initArg;
|
|
14
|
+
if (isNodeRuntime()) {
|
|
15
|
+
const [{ readFile }, { fileURLToPath }] = await Promise.all([
|
|
16
|
+
import("node:fs/promises"),
|
|
17
|
+
import("node:url")
|
|
18
|
+
]);
|
|
19
|
+
initArg = { module_or_path: await readFile(fileURLToPath(wasmUrl)) };
|
|
20
|
+
} else {
|
|
21
|
+
initArg = { module_or_path: wasmUrl };
|
|
22
|
+
}
|
|
23
|
+
await moduleValue.default(initArg);
|
|
10
24
|
return moduleValue;
|
|
11
25
|
} catch (error) {
|
|
12
|
-
|
|
13
|
-
|
|
26
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
27
|
+
throw new Error(
|
|
28
|
+
`[simple-agents-wasm] Failed to load Rust WASM backend. ` +
|
|
29
|
+
`Build artifacts are required (run "npm run build" in bindings/wasm/simple-agents-wasm). ` +
|
|
30
|
+
`Original error: ${reason}`
|
|
31
|
+
);
|
|
14
32
|
}
|
|
15
33
|
})();
|
|
16
34
|
}
|
package/rust/Cargo.toml
CHANGED
package/rust/src/lib.rs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
use js_sys::{Array, Function, Object, Promise, Reflect};
|
|
2
2
|
use serde::{Deserialize, Serialize};
|
|
3
3
|
use serde_json::{json, Map as JsonMap, Value as JsonValue};
|
|
4
|
+
use std::cell::RefCell;
|
|
4
5
|
use std::collections::HashMap;
|
|
5
6
|
use wasm_bindgen::prelude::*;
|
|
6
7
|
use wasm_bindgen::JsCast;
|
|
@@ -271,6 +272,27 @@ struct WorkflowRunOptions {
|
|
|
271
272
|
trace: Option<JsonValue>,
|
|
272
273
|
#[serde(skip)]
|
|
273
274
|
functions_js: Option<JsValue>,
|
|
275
|
+
/// Injected by JS as `__fetchImpl` so HTTP calls use the same fetch as tests (no global race).
|
|
276
|
+
#[serde(skip)]
|
|
277
|
+
fetch_js: Option<JsValue>,
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
struct FetchOverrideGuard<'a> {
|
|
281
|
+
cell: &'a RefCell<Option<JsValue>>,
|
|
282
|
+
previous: Option<JsValue>,
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
impl<'a> FetchOverrideGuard<'a> {
|
|
286
|
+
fn new(cell: &'a RefCell<Option<JsValue>>, value: Option<JsValue>) -> Self {
|
|
287
|
+
let previous = cell.replace(value);
|
|
288
|
+
Self { cell, previous }
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
impl Drop for FetchOverrideGuard<'_> {
|
|
293
|
+
fn drop(&mut self) {
|
|
294
|
+
self.cell.replace(self.previous.take());
|
|
295
|
+
}
|
|
274
296
|
}
|
|
275
297
|
|
|
276
298
|
fn js_error(message: impl Into<String>) -> JsValue {
|
|
@@ -289,6 +311,14 @@ fn config_error(message: impl Into<String>) -> JsValue {
|
|
|
289
311
|
.into()
|
|
290
312
|
}
|
|
291
313
|
|
|
314
|
+
/// Plain objects for JS `Function.call` / stream callbacks. `serde_wasm_bindgen::to_value`
|
|
315
|
+
/// can yield empty externref objects in Node for callback arguments; `JSON.parse` matches browser behavior.
|
|
316
|
+
fn json_value_to_js_plain(value: &JsonValue) -> Result<JsValue, JsValue> {
|
|
317
|
+
let s =
|
|
318
|
+
serde_json::to_string(value).map_err(|_| js_error("failed to serialize value for JS"))?;
|
|
319
|
+
js_sys::JSON::parse(&s).map_err(|_| js_error("failed to parse JSON for JS"))
|
|
320
|
+
}
|
|
321
|
+
|
|
292
322
|
fn now_millis() -> f64 {
|
|
293
323
|
let global = js_sys::global();
|
|
294
324
|
let performance = Reflect::get(&global, &JsValue::from_str("performance")).ok();
|
|
@@ -463,13 +493,23 @@ fn call_method2_sync(
|
|
|
463
493
|
}
|
|
464
494
|
|
|
465
495
|
async fn js_fetch(
|
|
496
|
+
fetch_override: Option<JsValue>,
|
|
466
497
|
url: &str,
|
|
467
498
|
body: &JsonValue,
|
|
468
499
|
headers: &HashMap<String, String>,
|
|
469
500
|
) -> Result<JsValue, JsValue> {
|
|
470
501
|
let global = js_sys::global();
|
|
471
|
-
let fetch_value =
|
|
472
|
-
.
|
|
502
|
+
let fetch_value = if let Some(f) = fetch_override {
|
|
503
|
+
if f.is_function() {
|
|
504
|
+
f
|
|
505
|
+
} else {
|
|
506
|
+
Reflect::get(&global, &JsValue::from_str("fetch"))
|
|
507
|
+
.map_err(|_| js_error("global fetch is unavailable"))?
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
Reflect::get(&global, &JsValue::from_str("fetch"))
|
|
511
|
+
.map_err(|_| js_error("global fetch is unavailable"))?
|
|
512
|
+
};
|
|
473
513
|
let fetch_fn = fetch_value
|
|
474
514
|
.dyn_into::<Function>()
|
|
475
515
|
.map_err(|_| js_error("global fetch is not callable"))?;
|
|
@@ -985,6 +1025,7 @@ pub struct WasmClient {
|
|
|
985
1025
|
base_url: String,
|
|
986
1026
|
api_key: String,
|
|
987
1027
|
headers: HashMap<String, String>,
|
|
1028
|
+
fetch_override: RefCell<Option<JsValue>>,
|
|
988
1029
|
}
|
|
989
1030
|
|
|
990
1031
|
#[wasm_bindgen]
|
|
@@ -1013,6 +1054,7 @@ impl WasmClient {
|
|
|
1013
1054
|
base_url: normalize_base_url(&base),
|
|
1014
1055
|
api_key: parsed.api_key,
|
|
1015
1056
|
headers: parsed.headers.unwrap_or_default(),
|
|
1057
|
+
fetch_override: RefCell::new(None),
|
|
1016
1058
|
})
|
|
1017
1059
|
}
|
|
1018
1060
|
|
|
@@ -1066,7 +1108,9 @@ impl WasmClient {
|
|
|
1066
1108
|
.or_insert_with(|| "https://simpleagents.dev".to_string());
|
|
1067
1109
|
}
|
|
1068
1110
|
|
|
1111
|
+
let fetch_override = self.fetch_override.borrow().clone();
|
|
1069
1112
|
let response = js_fetch(
|
|
1113
|
+
fetch_override,
|
|
1070
1114
|
&format!("{}/chat/completions", self.base_url),
|
|
1071
1115
|
&body,
|
|
1072
1116
|
&headers,
|
|
@@ -1235,7 +1279,9 @@ impl WasmClient {
|
|
|
1235
1279
|
.or_insert_with(|| "https://simpleagents.dev".to_string());
|
|
1236
1280
|
}
|
|
1237
1281
|
|
|
1282
|
+
let fetch_override = self.fetch_override.borrow().clone();
|
|
1238
1283
|
let response = js_fetch(
|
|
1284
|
+
fetch_override,
|
|
1239
1285
|
&format!("{}/chat/completions", self.base_url),
|
|
1240
1286
|
&body,
|
|
1241
1287
|
&headers,
|
|
@@ -1260,8 +1306,7 @@ impl WasmClient {
|
|
|
1260
1306
|
"eventType": "error",
|
|
1261
1307
|
"error": { "message": message }
|
|
1262
1308
|
});
|
|
1263
|
-
let event_js =
|
|
1264
|
-
.map_err(|_| js_error("failed to serialize stream error event"))?;
|
|
1309
|
+
let event_js = json_value_to_js_plain(&err_event)?;
|
|
1265
1310
|
on_event
|
|
1266
1311
|
.call1(&JsValue::NULL, &event_js)
|
|
1267
1312
|
.map_err(|_| js_error("failed to call stream callback"))?;
|
|
@@ -1337,8 +1382,7 @@ impl WasmClient {
|
|
|
1337
1382
|
"raw": data,
|
|
1338
1383
|
}
|
|
1339
1384
|
});
|
|
1340
|
-
let event_js =
|
|
1341
|
-
.map_err(|_| js_error("failed to serialize stream delta event"))?;
|
|
1385
|
+
let event_js = json_value_to_js_plain(&delta_event)?;
|
|
1342
1386
|
on_event
|
|
1343
1387
|
.call1(&JsValue::NULL, &event_js)
|
|
1344
1388
|
.map_err(|_| js_error("failed to call stream callback"))?;
|
|
@@ -1348,8 +1392,7 @@ impl WasmClient {
|
|
|
1348
1392
|
.await?;
|
|
1349
1393
|
|
|
1350
1394
|
let done_event = json!({ "eventType": "done" });
|
|
1351
|
-
let done_js =
|
|
1352
|
-
.map_err(|_| js_error("failed to serialize stream done event"))?;
|
|
1395
|
+
let done_js = json_value_to_js_plain(&done_event)?;
|
|
1353
1396
|
on_event
|
|
1354
1397
|
.call1(&JsValue::NULL, &done_js)
|
|
1355
1398
|
.map_err(|_| js_error("failed to call stream callback"))?;
|
|
@@ -1396,14 +1439,25 @@ impl WasmClient {
|
|
|
1396
1439
|
telemetry: None,
|
|
1397
1440
|
trace: None,
|
|
1398
1441
|
functions_js: None,
|
|
1442
|
+
fetch_js: None,
|
|
1399
1443
|
};
|
|
1400
1444
|
if let Some(options_js) = workflow_options {
|
|
1401
1445
|
options = serde_wasm_bindgen::from_value(options_js.clone())
|
|
1402
1446
|
.map_err(|_| config_error("invalid workflowOptions object"))?;
|
|
1403
1447
|
let functions_value = Reflect::get(&options_js, &JsValue::from_str("functions")).ok();
|
|
1404
|
-
options.functions_js = functions_value
|
|
1448
|
+
options.functions_js = functions_value.and_then(|v| {
|
|
1449
|
+
if v.is_undefined() || v.is_null() {
|
|
1450
|
+
None
|
|
1451
|
+
} else {
|
|
1452
|
+
Some(v)
|
|
1453
|
+
}
|
|
1454
|
+
});
|
|
1455
|
+
let fetch_js = Reflect::get(&options_js, &JsValue::from_str("__fetchImpl")).ok();
|
|
1456
|
+
options.fetch_js = fetch_js;
|
|
1405
1457
|
}
|
|
1406
1458
|
|
|
1459
|
+
let _fetch_guard = FetchOverrideGuard::new(&self.fetch_override, options.fetch_js.clone());
|
|
1460
|
+
|
|
1407
1461
|
if raw_doc.get("entry_node").is_some() && raw_doc.get("nodes").is_some() {
|
|
1408
1462
|
let graph_doc: GraphWorkflowDoc = serde_json::from_value(raw_doc.clone())
|
|
1409
1463
|
.map_err(|error| config_error(format!("invalid graph workflow YAML: {error}")))?;
|
|
@@ -1519,8 +1573,10 @@ impl WasmClient {
|
|
|
1519
1573
|
tool_calls: None,
|
|
1520
1574
|
});
|
|
1521
1575
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1576
|
+
json_value_to_js_plain(
|
|
1577
|
+
&serde_json::to_value(&history)
|
|
1578
|
+
.map_err(|_| js_error("failed to serialize graph llm messages"))?,
|
|
1579
|
+
)?
|
|
1524
1580
|
} else {
|
|
1525
1581
|
JsValue::from_str(&prompt)
|
|
1526
1582
|
};
|
|
@@ -1530,11 +1586,7 @@ impl WasmClient {
|
|
|
1530
1586
|
.complete(
|
|
1531
1587
|
model,
|
|
1532
1588
|
prompt_js,
|
|
1533
|
-
Some(
|
|
1534
|
-
serde_wasm_bindgen::to_value(&opts).map_err(|_| {
|
|
1535
|
-
js_error("failed to serialize completion options")
|
|
1536
|
-
})?,
|
|
1537
|
-
),
|
|
1589
|
+
Some(json_value_to_js_plain(&opts)?),
|
|
1538
1590
|
)
|
|
1539
1591
|
.await?;
|
|
1540
1592
|
let completion: JsonValue = serde_wasm_bindgen::from_value(completion_js)
|
|
@@ -1630,17 +1682,23 @@ impl WasmClient {
|
|
|
1630
1682
|
.unwrap_or_else(|| handler.clone());
|
|
1631
1683
|
let functions_js = options.functions_js.clone().ok_or_else(|| {
|
|
1632
1684
|
config_error(format!(
|
|
1633
|
-
"custom_worker node '{}' requires workflowOptions.functions",
|
|
1634
|
-
node.id
|
|
1685
|
+
"custom_worker node '{}' requires workflowOptions.functions['{}']",
|
|
1686
|
+
node.id, lookup_key
|
|
1635
1687
|
))
|
|
1636
1688
|
})?;
|
|
1637
1689
|
let function_value = Reflect::get(&functions_js, &JsValue::from_str(&lookup_key))
|
|
1638
1690
|
.map_err(|_| {
|
|
1639
1691
|
config_error(format!(
|
|
1640
|
-
"
|
|
1641
|
-
lookup_key
|
|
1692
|
+
"custom_worker node '{}' requires workflowOptions.functions['{}']",
|
|
1693
|
+
node.id, lookup_key
|
|
1642
1694
|
))
|
|
1643
1695
|
})?;
|
|
1696
|
+
if function_value.is_undefined() || function_value.is_null() {
|
|
1697
|
+
return Err(config_error(format!(
|
|
1698
|
+
"custom_worker node '{}' requires workflowOptions.functions['{}']",
|
|
1699
|
+
node.id, lookup_key
|
|
1700
|
+
)));
|
|
1701
|
+
}
|
|
1644
1702
|
let function = function_value.dyn_into::<Function>().map_err(|_| {
|
|
1645
1703
|
config_error(format!(
|
|
1646
1704
|
"custom_worker node '{}' requires workflowOptions.functions['{}']",
|
|
@@ -1660,10 +1718,8 @@ impl WasmClient {
|
|
|
1660
1718
|
.unwrap_or(JsonValue::Null),
|
|
1661
1719
|
"nodeId": node.id.clone()
|
|
1662
1720
|
});
|
|
1663
|
-
let args_js =
|
|
1664
|
-
|
|
1665
|
-
let context_js = serde_wasm_bindgen::to_value(&graph_context)
|
|
1666
|
-
.map_err(|_| js_error("failed to serialize graph context"))?;
|
|
1721
|
+
let args_js = json_value_to_js_plain(&worker_args)?;
|
|
1722
|
+
let context_js = json_value_to_js_plain(&graph_context)?;
|
|
1667
1723
|
let worker_call_output = function
|
|
1668
1724
|
.call2(&JsValue::NULL, &args_js, &context_js)
|
|
1669
1725
|
.map_err(|_| {
|
|
@@ -1814,8 +1870,9 @@ impl WasmClient {
|
|
|
1814
1870
|
trace_id: None,
|
|
1815
1871
|
metadata: Some(json!({"nerdstats": nerdstats})),
|
|
1816
1872
|
};
|
|
1817
|
-
|
|
1818
|
-
.map_err(|_| js_error("failed to serialize workflow result"))
|
|
1873
|
+
let jv = serde_json::to_value(&result)
|
|
1874
|
+
.map_err(|_| js_error("failed to serialize workflow result"))?;
|
|
1875
|
+
return json_value_to_js_plain(&jv);
|
|
1819
1876
|
}
|
|
1820
1877
|
|
|
1821
1878
|
let doc: WorkflowDoc = serde_json::from_value(raw_doc)
|
|
@@ -1885,11 +1942,7 @@ impl WasmClient {
|
|
|
1885
1942
|
.complete(
|
|
1886
1943
|
model,
|
|
1887
1944
|
JsValue::from_str(&prompt),
|
|
1888
|
-
Some(
|
|
1889
|
-
serde_wasm_bindgen::to_value(&opts).map_err(|_| {
|
|
1890
|
-
js_error("failed to serialize completion options")
|
|
1891
|
-
})?,
|
|
1892
|
-
),
|
|
1945
|
+
Some(json_value_to_js_plain(&opts)?),
|
|
1893
1946
|
)
|
|
1894
1947
|
.await?;
|
|
1895
1948
|
let completion: JsonValue = serde_wasm_bindgen::from_value(completion_js)
|
|
@@ -1956,11 +2009,8 @@ impl WasmClient {
|
|
|
1956
2009
|
.unwrap_or_else(|| JsonValue::Object(JsonMap::new())),
|
|
1957
2010
|
&context,
|
|
1958
2011
|
);
|
|
1959
|
-
let args_js =
|
|
1960
|
-
|
|
1961
|
-
let context_js =
|
|
1962
|
-
serde_wasm_bindgen::to_value(&JsonValue::Object(context.clone()))
|
|
1963
|
-
.map_err(|_| js_error("failed to serialize workflow context"))?;
|
|
2012
|
+
let args_js = json_value_to_js_plain(&args_value)?;
|
|
2013
|
+
let context_js = json_value_to_js_plain(&JsonValue::Object(context.clone()))?;
|
|
1964
2014
|
let call_output = function
|
|
1965
2015
|
.call2(&JsValue::NULL, &args_js, &context_js)
|
|
1966
2016
|
.map_err(|_| {
|
|
@@ -2017,18 +2067,32 @@ impl WasmClient {
|
|
|
2017
2067
|
pointer += 1;
|
|
2018
2068
|
}
|
|
2019
2069
|
|
|
2070
|
+
let trace: Vec<String> = events
|
|
2071
|
+
.iter()
|
|
2072
|
+
.filter(|e| e.status == "completed")
|
|
2073
|
+
.map(|e| e.step_id.clone())
|
|
2074
|
+
.collect();
|
|
2075
|
+
let terminal_node = trace.last().cloned();
|
|
2076
|
+
|
|
2077
|
+
let context_value = JsonValue::Object(context);
|
|
2078
|
+
let outputs_value = context_value
|
|
2079
|
+
.as_object()
|
|
2080
|
+
.cloned()
|
|
2081
|
+
.map(JsonValue::Object)
|
|
2082
|
+
.unwrap_or_else(|| JsonValue::Object(JsonMap::new()));
|
|
2083
|
+
|
|
2020
2084
|
let result = WorkflowRunResult {
|
|
2021
2085
|
status: "ok".to_string(),
|
|
2022
|
-
context:
|
|
2023
|
-
output,
|
|
2086
|
+
context: context_value.clone(),
|
|
2087
|
+
output: output.clone(),
|
|
2024
2088
|
events,
|
|
2025
|
-
workflow_id:
|
|
2089
|
+
workflow_id: Some("wasm_workflow".to_string()),
|
|
2026
2090
|
entry_node: None,
|
|
2027
2091
|
email_text: None,
|
|
2028
|
-
trace:
|
|
2029
|
-
outputs:
|
|
2030
|
-
terminal_node
|
|
2031
|
-
terminal_output:
|
|
2092
|
+
trace: Some(trace),
|
|
2093
|
+
outputs: Some(outputs_value),
|
|
2094
|
+
terminal_node,
|
|
2095
|
+
terminal_output: output,
|
|
2032
2096
|
step_timings: None,
|
|
2033
2097
|
total_elapsed_ms: None,
|
|
2034
2098
|
ttft_ms: None,
|
|
@@ -2040,8 +2104,9 @@ impl WasmClient {
|
|
|
2040
2104
|
trace_id: None,
|
|
2041
2105
|
metadata: None,
|
|
2042
2106
|
};
|
|
2043
|
-
|
|
2044
|
-
.map_err(|_| js_error("failed to serialize workflow result"))
|
|
2107
|
+
let jv = serde_json::to_value(&result)
|
|
2108
|
+
.map_err(|_| js_error("failed to serialize workflow result"))?;
|
|
2109
|
+
json_value_to_js_plain(&jv)
|
|
2045
2110
|
}
|
|
2046
2111
|
|
|
2047
2112
|
#[wasm_bindgen(js_name = runWorkflowYaml)]
|
|
@@ -2080,8 +2145,7 @@ impl WasmClient {
|
|
|
2080
2145
|
serde_json::json!([])
|
|
2081
2146
|
};
|
|
2082
2147
|
|
|
2083
|
-
let input_js =
|
|
2084
|
-
.map_err(|_| js_error("failed to serialize messages input"))?;
|
|
2148
|
+
let input_js = json_value_to_js_plain(&serde_json::json!({ "messages": messages_value }))?;
|
|
2085
2149
|
|
|
2086
2150
|
self.run_workflow_yaml_string(yaml_text, input_js, options).await
|
|
2087
2151
|
}
|
|
@@ -2091,10 +2155,3 @@ impl WasmClient {
|
|
|
2091
2155
|
pub fn supports_rust_wasm() -> bool {
|
|
2092
2156
|
true
|
|
2093
2157
|
}
|
|
2094
|
-
|
|
2095
|
-
#[wasm_bindgen(js_name = toJsArray)]
|
|
2096
|
-
pub fn to_js_array(value: JsValue) -> Array {
|
|
2097
|
-
let arr = Array::new();
|
|
2098
|
-
arr.push(&value);
|
|
2099
|
-
arr
|
|
2100
|
-
}
|