simple-agents-wasm 0.3.3 → 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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-agents-wasm",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Browser-compatible SimpleAgents client for OpenAI-compatible providers",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -418,7 +418,7 @@ function __wbg_get_imports() {
418
418
  return ret;
419
419
  },
420
420
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
421
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 151, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
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`.
422
422
  const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h9f53f643b01d7c8e);
423
423
  return ret;
424
424
  },
Binary file
package/rust/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "simple-agents-wasm-rust"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2021"
5
5
  license = "MIT OR Apache-2.0"
6
6
 
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
- content: String,
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
- content: String,
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,