simple-agents-wasm 0.3.2 → 0.3.4
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/index.d.ts +15 -1
- package/package.json +1 -1
- package/pkg/simple_agents_wasm.d.ts +12 -0
- package/pkg/simple_agents_wasm.js +25 -1
- package/pkg/simple_agents_wasm_bg.wasm +0 -0
- package/pkg/simple_agents_wasm_bg.wasm.d.ts +1 -0
- package/rust/Cargo.toml +1 -1
- package/rust/src/lib.rs +90 -5
package/index.d.ts
CHANGED
|
@@ -7,9 +7,23 @@ export interface CompleteOptions {
|
|
|
7
7
|
schema?: unknown;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Simplified multimodal segment (normalized to OpenAI wire format before send).
|
|
12
|
+
* You may also pass native OpenAI parts (e.g. `{ type: "image_url", image_url: { url } }`).
|
|
13
|
+
*/
|
|
14
|
+
export interface ContentPartInput {
|
|
15
|
+
type: "text" | "image" | "audio" | "video";
|
|
16
|
+
text?: string;
|
|
17
|
+
/** Base64 payload without data: prefix */
|
|
18
|
+
data?: string;
|
|
19
|
+
/** MIME type, e.g. image/png (also accepts camelCase `mediaType`) */
|
|
20
|
+
media_type?: string;
|
|
21
|
+
mediaType?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
export interface MessageInput {
|
|
11
25
|
role: "system" | "user" | "assistant" | "tool";
|
|
12
|
-
content: string;
|
|
26
|
+
content: string | ContentPartInput[];
|
|
13
27
|
name?: string;
|
|
14
28
|
toolCallId?: string;
|
|
15
29
|
toolCalls?: Array<JsToolCall>;
|
package/package.json
CHANGED
|
@@ -8,6 +8,17 @@ export class WasmClient {
|
|
|
8
8
|
constructor(provider: string, config: any);
|
|
9
9
|
runWorkflowYaml(workflow_path: string, _workflow_input: any): any;
|
|
10
10
|
runWorkflowYamlString(yaml_text: string, workflow_input: any, workflow_options?: any | null): Promise<any>;
|
|
11
|
+
/**
|
|
12
|
+
* Run a YAML workflow from a YAML text string (new unified API alias).
|
|
13
|
+
*
|
|
14
|
+
* This is an alias for `runWorkflowYamlString` using the new naming convention.
|
|
15
|
+
* WASM cannot use file paths; pass the YAML document text directly.
|
|
16
|
+
*
|
|
17
|
+
* ```js
|
|
18
|
+
* const result = await client.runYamlString(yamlText, messages);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
runYamlString(yaml_text: string, messages: any, options?: any | null): Promise<any>;
|
|
11
22
|
streamEvents(model: string, prompt_or_messages: any, on_event: Function, options?: any | null): Promise<any>;
|
|
12
23
|
}
|
|
13
24
|
|
|
@@ -26,6 +37,7 @@ export interface InitOutput {
|
|
|
26
37
|
readonly wasmclient_new: (a: number, b: number, c: any) => [number, number, number];
|
|
27
38
|
readonly wasmclient_runWorkflowYaml: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
28
39
|
readonly wasmclient_runWorkflowYamlString: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
40
|
+
readonly wasmclient_runYamlString: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
29
41
|
readonly wasmclient_streamEvents: (a: number, b: number, c: number, d: any, e: any, f: number) => any;
|
|
30
42
|
readonly wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e: (a: number, b: number, c: any) => [number, number];
|
|
31
43
|
readonly wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b: (a: number, b: number, c: any, d: any) => void;
|
|
@@ -64,6 +64,26 @@ export class WasmClient {
|
|
|
64
64
|
const ret = wasm.wasmclient_runWorkflowYamlString(this.__wbg_ptr, ptr0, len0, workflow_input, isLikeNone(workflow_options) ? 0 : addToExternrefTable0(workflow_options));
|
|
65
65
|
return ret;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Run a YAML workflow from a YAML text string (new unified API alias).
|
|
69
|
+
*
|
|
70
|
+
* This is an alias for `runWorkflowYamlString` using the new naming convention.
|
|
71
|
+
* WASM cannot use file paths; pass the YAML document text directly.
|
|
72
|
+
*
|
|
73
|
+
* ```js
|
|
74
|
+
* const result = await client.runYamlString(yamlText, messages);
|
|
75
|
+
* ```
|
|
76
|
+
* @param {string} yaml_text
|
|
77
|
+
* @param {any} messages
|
|
78
|
+
* @param {any | null} [options]
|
|
79
|
+
* @returns {Promise<any>}
|
|
80
|
+
*/
|
|
81
|
+
runYamlString(yaml_text, messages, options) {
|
|
82
|
+
const ptr0 = passStringToWasm0(yaml_text, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
83
|
+
const len0 = WASM_VECTOR_LEN;
|
|
84
|
+
const ret = wasm.wasmclient_runYamlString(this.__wbg_ptr, ptr0, len0, messages, isLikeNone(options) ? 0 : addToExternrefTable0(options));
|
|
85
|
+
return ret;
|
|
86
|
+
}
|
|
67
87
|
/**
|
|
68
88
|
* @param {string} model
|
|
69
89
|
* @param {any} prompt_or_messages
|
|
@@ -267,6 +287,10 @@ function __wbg_get_imports() {
|
|
|
267
287
|
const ret = result;
|
|
268
288
|
return ret;
|
|
269
289
|
},
|
|
290
|
+
__wbg_isArray_4daec0bfe3d60230: function(arg0) {
|
|
291
|
+
const ret = Array.isArray(arg0);
|
|
292
|
+
return ret;
|
|
293
|
+
},
|
|
270
294
|
__wbg_isArray_db61795ad004c139: function(arg0) {
|
|
271
295
|
const ret = Array.isArray(arg0);
|
|
272
296
|
return ret;
|
|
@@ -394,7 +418,7 @@ function __wbg_get_imports() {
|
|
|
394
418
|
return ret;
|
|
395
419
|
},
|
|
396
420
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
397
|
-
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx:
|
|
421
|
+
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 152, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
398
422
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e);
|
|
399
423
|
return ret;
|
|
400
424
|
},
|
|
Binary file
|
|
@@ -8,6 +8,7 @@ export const wasmclient_complete: (a: number, b: number, c: number, d: any, e: n
|
|
|
8
8
|
export const wasmclient_new: (a: number, b: number, c: any) => [number, number, number];
|
|
9
9
|
export const wasmclient_runWorkflowYaml: (a: number, b: number, c: number, d: any) => [number, number, number];
|
|
10
10
|
export const wasmclient_runWorkflowYamlString: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
11
|
+
export const wasmclient_runYamlString: (a: number, b: number, c: number, d: any, e: number) => any;
|
|
11
12
|
export const wasmclient_streamEvents: (a: number, b: number, c: number, d: any, e: any, f: number) => any;
|
|
12
13
|
export const wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e: (a: number, b: number, c: any) => [number, number];
|
|
13
14
|
export const wasm_bindgen__convert__closures_____invoke__h05acb8c479b21d4b: (a: number, b: number, c: any, d: any) => void;
|
package/rust/Cargo.toml
CHANGED
package/rust/src/lib.rs
CHANGED
|
@@ -18,7 +18,8 @@ struct ClientConfig {
|
|
|
18
18
|
#[serde(rename_all = "camelCase")]
|
|
19
19
|
struct MessageInput {
|
|
20
20
|
role: String,
|
|
21
|
-
|
|
21
|
+
/// Plain string or multimodal parts array (OpenAI-compatible JSON).
|
|
22
|
+
content: JsonValue,
|
|
22
23
|
name: Option<String>,
|
|
23
24
|
#[serde(alias = "tool_call_id")]
|
|
24
25
|
tool_call_id: Option<String>,
|
|
@@ -44,7 +45,8 @@ struct JsToolCallFunction {
|
|
|
44
45
|
#[derive(Serialize, Clone)]
|
|
45
46
|
struct OpenAiMessageInput {
|
|
46
47
|
role: String,
|
|
47
|
-
|
|
48
|
+
/// Plain string or multimodal parts array.
|
|
49
|
+
content: JsonValue,
|
|
48
50
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
49
51
|
name: Option<String>,
|
|
50
52
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
@@ -310,7 +312,7 @@ fn to_messages(prompt_or_messages: JsValue) -> Result<Vec<MessageInput>, JsValue
|
|
|
310
312
|
}
|
|
311
313
|
return Ok(vec![MessageInput {
|
|
312
314
|
role: "user".to_string(),
|
|
313
|
-
content: trimmed.to_string(),
|
|
315
|
+
content: JsonValue::String(trimmed.to_string()),
|
|
314
316
|
name: None,
|
|
315
317
|
tool_call_id: None,
|
|
316
318
|
tool_calls: None,
|
|
@@ -325,12 +327,64 @@ fn to_messages(prompt_or_messages: JsValue) -> Result<Vec<MessageInput>, JsValue
|
|
|
325
327
|
Ok(messages)
|
|
326
328
|
}
|
|
327
329
|
|
|
330
|
+
/// Reads `media_type` or `mediaType` from a JSON object (JS often uses camelCase).
|
|
331
|
+
fn media_type_field(obj: &JsonMap<String, JsonValue>) -> Option<&str> {
|
|
332
|
+
obj.get("media_type")
|
|
333
|
+
.or_else(|| obj.get("mediaType"))
|
|
334
|
+
.and_then(|v| v.as_str())
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/// Converts simplified multimodal parts (`type`: image|audio|video + data) to OpenAI chat
|
|
338
|
+
/// wire format. Passes through strings, native OpenAI parts, and unknown objects unchanged.
|
|
339
|
+
fn normalize_message_content(content: JsonValue) -> JsonValue {
|
|
340
|
+
match content {
|
|
341
|
+
JsonValue::Array(parts) => JsonValue::Array(
|
|
342
|
+
parts.into_iter().map(normalize_content_part).collect(),
|
|
343
|
+
),
|
|
344
|
+
other => other,
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
fn normalize_content_part(part: JsonValue) -> JsonValue {
|
|
349
|
+
let Some(obj) = part.as_object() else {
|
|
350
|
+
return part;
|
|
351
|
+
};
|
|
352
|
+
let ty = obj.get("type").and_then(|v| v.as_str());
|
|
353
|
+
match ty {
|
|
354
|
+
Some("image") => {
|
|
355
|
+
let mt = media_type_field(obj).unwrap_or("");
|
|
356
|
+
let data = obj.get("data").and_then(|v| v.as_str()).unwrap_or("");
|
|
357
|
+
json!({
|
|
358
|
+
"type": "image_url",
|
|
359
|
+
"image_url": { "url": format!("data:{mt};base64,{data}") }
|
|
360
|
+
})
|
|
361
|
+
}
|
|
362
|
+
Some("audio") => {
|
|
363
|
+
let mt = media_type_field(obj).unwrap_or("");
|
|
364
|
+
let data = obj.get("data").and_then(|v| v.as_str()).unwrap_or("");
|
|
365
|
+
json!({
|
|
366
|
+
"type": "input_audio",
|
|
367
|
+
"input_audio": { "media_type": mt, "data": data }
|
|
368
|
+
})
|
|
369
|
+
}
|
|
370
|
+
Some("video") => {
|
|
371
|
+
let mt = media_type_field(obj).unwrap_or("");
|
|
372
|
+
let data = obj.get("data").and_then(|v| v.as_str()).unwrap_or("");
|
|
373
|
+
json!({
|
|
374
|
+
"type": "video",
|
|
375
|
+
"video": { "media_type": mt, "data": data }
|
|
376
|
+
})
|
|
377
|
+
}
|
|
378
|
+
_ => part,
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
328
382
|
fn to_openai_messages(messages: Vec<MessageInput>) -> Vec<OpenAiMessageInput> {
|
|
329
383
|
messages
|
|
330
384
|
.into_iter()
|
|
331
385
|
.map(|message| OpenAiMessageInput {
|
|
332
386
|
role: message.role,
|
|
333
|
-
content: message.content,
|
|
387
|
+
content: normalize_message_content(message.content),
|
|
334
388
|
name: message.name,
|
|
335
389
|
tool_call_id: message.tool_call_id,
|
|
336
390
|
tool_calls: message.tool_calls.map(|tool_calls| {
|
|
@@ -1459,7 +1513,7 @@ impl WasmClient {
|
|
|
1459
1513
|
if llm.append_prompt_as_user.unwrap_or(true) {
|
|
1460
1514
|
history.push(MessageInput {
|
|
1461
1515
|
role: "user".to_string(),
|
|
1462
|
-
content: prompt,
|
|
1516
|
+
content: JsonValue::String(prompt),
|
|
1463
1517
|
name: None,
|
|
1464
1518
|
tool_call_id: None,
|
|
1465
1519
|
tool_calls: None,
|
|
@@ -2000,6 +2054,37 @@ impl WasmClient {
|
|
|
2000
2054
|
"workflow file paths are not supported in browser runtime: {workflow_path}"
|
|
2001
2055
|
)))
|
|
2002
2056
|
}
|
|
2057
|
+
|
|
2058
|
+
/// Run a YAML workflow from a YAML text string (new unified API alias).
|
|
2059
|
+
///
|
|
2060
|
+
/// This is an alias for `runWorkflowYamlString` using the new naming convention.
|
|
2061
|
+
/// WASM cannot use file paths; pass the YAML document text directly.
|
|
2062
|
+
///
|
|
2063
|
+
/// ```js
|
|
2064
|
+
/// const result = await client.runYamlString(yamlText, messages);
|
|
2065
|
+
/// ```
|
|
2066
|
+
#[wasm_bindgen(js_name = runYamlString)]
|
|
2067
|
+
pub async fn run_yaml_string(
|
|
2068
|
+
&self,
|
|
2069
|
+
yaml_text: String,
|
|
2070
|
+
messages: JsValue,
|
|
2071
|
+
options: Option<JsValue>,
|
|
2072
|
+
) -> Result<JsValue, JsValue> {
|
|
2073
|
+
// Build workflow input envelope from the messages arg
|
|
2074
|
+
let messages_value: serde_json::Value = if messages.is_array() || messages.is_object() {
|
|
2075
|
+
serde_wasm_bindgen::from_value(messages)
|
|
2076
|
+
.unwrap_or(serde_json::json!([]))
|
|
2077
|
+
} else if let Some(prompt) = messages.as_string() {
|
|
2078
|
+
serde_json::json!([{"role": "user", "content": prompt}])
|
|
2079
|
+
} else {
|
|
2080
|
+
serde_json::json!([])
|
|
2081
|
+
};
|
|
2082
|
+
|
|
2083
|
+
let input_js = serde_wasm_bindgen::to_value(&serde_json::json!({ "messages": messages_value }))
|
|
2084
|
+
.map_err(|_| js_error("failed to serialize messages input"))?;
|
|
2085
|
+
|
|
2086
|
+
self.run_workflow_yaml_string(yaml_text, input_js, options).await
|
|
2087
|
+
}
|
|
2003
2088
|
}
|
|
2004
2089
|
|
|
2005
2090
|
#[wasm_bindgen(js_name = supportsRustWasm)]
|