@rodrigocoliveira/agno-client 1.0.1 → 1.0.2

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/dist/index.d.mts CHANGED
@@ -67,6 +67,25 @@ declare class AgnoClient extends EventEmitter {
67
67
  headers?: Record<string, string>;
68
68
  params?: Record<string, string>;
69
69
  }): Promise<void>;
70
+ /**
71
+ * Determine if a RunEvent is a team-level event (prefixed with "Team")
72
+ */
73
+ private isTeamEvent;
74
+ /**
75
+ * Determine if an event should update the user-facing message based on mode.
76
+ *
77
+ * In team mode: only Team* events should update the user-facing message.
78
+ * In agent mode: only Run* (non-Team) events should update the user-facing message.
79
+ *
80
+ * Certain events are always processed regardless of mode:
81
+ * - CustomEvent, RunPaused, RunContinued (control flow events)
82
+ */
83
+ private shouldProcessForUserMessage;
84
+ /**
85
+ * Emit member-specific events for internal team member activity.
86
+ * Only emits when emitMemberEvents config option is true.
87
+ */
88
+ private emitMemberEvent;
70
89
  /**
71
90
  * Handle streaming chunk
72
91
  */
package/dist/index.d.ts CHANGED
@@ -67,6 +67,25 @@ declare class AgnoClient extends EventEmitter {
67
67
  headers?: Record<string, string>;
68
68
  params?: Record<string, string>;
69
69
  }): Promise<void>;
70
+ /**
71
+ * Determine if a RunEvent is a team-level event (prefixed with "Team")
72
+ */
73
+ private isTeamEvent;
74
+ /**
75
+ * Determine if an event should update the user-facing message based on mode.
76
+ *
77
+ * In team mode: only Team* events should update the user-facing message.
78
+ * In agent mode: only Run* (non-Team) events should update the user-facing message.
79
+ *
80
+ * Certain events are always processed regardless of mode:
81
+ * - CustomEvent, RunPaused, RunContinued (control flow events)
82
+ */
83
+ private shouldProcessForUserMessage;
84
+ /**
85
+ * Emit member-specific events for internal team member activity.
86
+ * Only emits when emitMemberEvents config option is true.
87
+ */
88
+ private emitMemberEvent;
70
89
  /**
71
90
  * Handle streaming chunk
72
91
  */
package/dist/index.js CHANGED
@@ -272,6 +272,30 @@ var ConfigManager = class {
272
272
  setOnTokenExpired(callback) {
273
273
  this.config.onTokenExpired = callback;
274
274
  }
275
+ /**
276
+ * Get whether to emit member:* events for internal team activity
277
+ */
278
+ getEmitMemberEvents() {
279
+ return this.config.emitMemberEvents ?? false;
280
+ }
281
+ /**
282
+ * Set whether to emit member:* events
283
+ */
284
+ setEmitMemberEvents(emit) {
285
+ this.updateField("emitMemberEvents", emit);
286
+ }
287
+ /**
288
+ * Get whether to request member events from backend
289
+ */
290
+ getStreamMemberEvents() {
291
+ return this.config.streamMemberEvents ?? false;
292
+ }
293
+ /**
294
+ * Set whether to request member events from backend
295
+ */
296
+ setStreamMemberEvents(stream) {
297
+ this.updateField("streamMemberEvents", stream);
298
+ }
275
299
  /**
276
300
  * Get current entity ID (agent or team based on mode)
277
301
  */
@@ -590,10 +614,13 @@ var SessionManager = class {
590
614
  }
591
615
  }
592
616
  /**
593
- * Convert session runs array to chat messages
617
+ * Convert session runs array to chat messages.
618
+ * Filters out child runs (those with parent_run_id) to prevent
619
+ * internal team member communications from appearing as user messages.
594
620
  */
595
621
  convertSessionToMessages(runs) {
596
- const messages = this.convertRunsToMessages(runs);
622
+ const rootRuns = runs.filter((run) => !run.parent_run_id);
623
+ const messages = this.convertRunsToMessages(rootRuns);
597
624
  return messages;
598
625
  }
599
626
  /**
@@ -605,10 +632,67 @@ var SessionManager = class {
605
632
  for (const run of runs) {
606
633
  const timestamp = run.created_at ? new Date(run.created_at).getTime() / 1e3 : Math.floor(Date.now() / 1e3);
607
634
  if (run.run_input) {
635
+ const userImages = [];
636
+ const userAudio = [];
637
+ const userFiles = [];
638
+ if (run.input_media && typeof run.input_media === "object") {
639
+ const media = run.input_media;
640
+ if (Array.isArray(media.images)) {
641
+ for (const img of media.images) {
642
+ const imgObj = img;
643
+ let url = imgObj.url;
644
+ if (!url && imgObj.content) {
645
+ const mimeType = imgObj.mime_type || `image/${imgObj.format || "png"}`;
646
+ url = `data:${mimeType};base64,${imgObj.content}`;
647
+ }
648
+ if (url) {
649
+ userImages.push({
650
+ url,
651
+ revised_prompt: imgObj.original_name || "Uploaded image"
652
+ });
653
+ }
654
+ }
655
+ }
656
+ if (Array.isArray(media.audio)) {
657
+ for (const aud of media.audio) {
658
+ const audObj = aud;
659
+ let url = audObj.url;
660
+ if (!url && audObj.content) {
661
+ const mimeType = audObj.mime_type || `audio/${audObj.format || "wav"}`;
662
+ url = `data:${mimeType};base64,${audObj.content}`;
663
+ }
664
+ if (url) {
665
+ userAudio.push({
666
+ url,
667
+ mime_type: audObj.mime_type || void 0
668
+ });
669
+ }
670
+ }
671
+ }
672
+ if (Array.isArray(media.files)) {
673
+ for (const file of media.files) {
674
+ const fileObj = file;
675
+ let url = fileObj.url;
676
+ if (!url && fileObj.content) {
677
+ const mimeType = fileObj.mime_type || fileObj.content_type || "application/octet-stream";
678
+ url = `data:${mimeType};base64,${fileObj.content}`;
679
+ }
680
+ userFiles.push({
681
+ name: fileObj.original_name || fileObj.name || "file",
682
+ type: fileObj.content_type || fileObj.mime_type || "",
683
+ url,
684
+ size: fileObj.size || void 0
685
+ });
686
+ }
687
+ }
688
+ }
608
689
  messages.push({
609
690
  role: "user",
610
691
  content: run.run_input,
611
- created_at: timestamp
692
+ created_at: timestamp,
693
+ ...userImages.length > 0 ? { images: userImages } : {},
694
+ ...userAudio.length > 0 ? { audio: userAudio } : {},
695
+ ...userFiles.length > 0 ? { files: userFiles } : {}
612
696
  });
613
697
  }
614
698
  const toolCalls = [];
@@ -1879,10 +1963,38 @@ var AgnoClient = class extends import_eventemitter3.default {
1879
1963
  this.messageStore.removeLastMessages(2);
1880
1964
  }
1881
1965
  }
1966
+ const userImages = [];
1967
+ const userAudio = [];
1968
+ const userFiles = [];
1969
+ if (message instanceof FormData) {
1970
+ const entries = message.getAll("files");
1971
+ for (const entry of entries) {
1972
+ if (typeof entry !== "string") {
1973
+ const file = entry;
1974
+ const url = URL.createObjectURL(file);
1975
+ const mimeType = file.type || "";
1976
+ if (mimeType.startsWith("image/")) {
1977
+ userImages.push({ url, revised_prompt: file.name || "Uploaded image" });
1978
+ } else if (mimeType.startsWith("audio/")) {
1979
+ userAudio.push({ url, mime_type: mimeType });
1980
+ } else {
1981
+ userFiles.push({
1982
+ name: file.name || "file",
1983
+ type: mimeType,
1984
+ url,
1985
+ size: file.size
1986
+ });
1987
+ }
1988
+ }
1989
+ }
1990
+ }
1882
1991
  this.messageStore.addMessage({
1883
1992
  role: "user",
1884
1993
  content: formData.get("message"),
1885
- created_at: Math.floor(Date.now() / 1e3)
1994
+ created_at: Math.floor(Date.now() / 1e3),
1995
+ ...userImages.length > 0 ? { images: userImages } : {},
1996
+ ...userAudio.length > 0 ? { audio: userAudio } : {},
1997
+ ...userFiles.length > 0 ? { files: userFiles } : {}
1886
1998
  });
1887
1999
  this.messageStore.addMessage({
1888
2000
  role: "agent",
@@ -1900,6 +2012,10 @@ var AgnoClient = class extends import_eventemitter3.default {
1900
2012
  if (userId) {
1901
2013
  formData.append("user_id", userId);
1902
2014
  }
2015
+ if (this.configManager.getMode() === "team") {
2016
+ const streamMembers = this.configManager.getStreamMemberEvents();
2017
+ formData.append("stream_member_events", String(streamMembers));
2018
+ }
1903
2019
  await this.executeStream({
1904
2020
  apiUrl: runUrl,
1905
2021
  requestBody: formData,
@@ -1933,13 +2049,56 @@ var AgnoClient = class extends import_eventemitter3.default {
1933
2049
  }
1934
2050
  });
1935
2051
  }
2052
+ /**
2053
+ * Determine if a RunEvent is a team-level event (prefixed with "Team")
2054
+ */
2055
+ isTeamEvent(event) {
2056
+ return event.toString().startsWith("Team");
2057
+ }
2058
+ /**
2059
+ * Determine if an event should update the user-facing message based on mode.
2060
+ *
2061
+ * In team mode: only Team* events should update the user-facing message.
2062
+ * In agent mode: only Run* (non-Team) events should update the user-facing message.
2063
+ *
2064
+ * Certain events are always processed regardless of mode:
2065
+ * - CustomEvent, RunPaused, RunContinued (control flow events)
2066
+ */
2067
+ shouldProcessForUserMessage(event) {
2068
+ if (event === import_agno_types2.RunEvent.CustomEvent || event === import_agno_types2.RunEvent.RunPaused || event === import_agno_types2.RunEvent.RunContinued) {
2069
+ return true;
2070
+ }
2071
+ const mode = this.configManager.getMode();
2072
+ const isTeam = this.isTeamEvent(event);
2073
+ if (mode === "team") {
2074
+ return isTeam;
2075
+ }
2076
+ return !isTeam;
2077
+ }
2078
+ /**
2079
+ * Emit member-specific events for internal team member activity.
2080
+ * Only emits when emitMemberEvents config option is true.
2081
+ */
2082
+ emitMemberEvent(event, chunk) {
2083
+ if (!this.configManager.getEmitMemberEvents()) return;
2084
+ this.emit("member:event", chunk);
2085
+ if (event === import_agno_types2.RunEvent.RunStarted) {
2086
+ this.emit("member:started", chunk);
2087
+ } else if (event === import_agno_types2.RunEvent.RunContent) {
2088
+ this.emit("member:content", chunk);
2089
+ } else if (event === import_agno_types2.RunEvent.RunCompleted) {
2090
+ this.emit("member:completed", chunk);
2091
+ } else if (event === import_agno_types2.RunEvent.RunError) {
2092
+ this.emit("member:error", chunk);
2093
+ }
2094
+ }
1936
2095
  /**
1937
2096
  * Handle streaming chunk
1938
2097
  */
1939
2098
  handleChunk(chunk, currentSessionId, messageContent) {
1940
2099
  const event = chunk.event;
1941
2100
  if (event === import_agno_types2.RunEvent.RunStarted || event === import_agno_types2.RunEvent.TeamRunStarted || event === import_agno_types2.RunEvent.ReasoningStarted || event === import_agno_types2.RunEvent.TeamReasoningStarted) {
1942
- if (chunk.run_id) {
2101
+ if (this.shouldProcessForUserMessage(event) && chunk.run_id) {
1943
2102
  this.currentRunId = chunk.run_id;
1944
2103
  this.state.currentRunId = chunk.run_id;
1945
2104
  this.emit("state:change", this.getState());
@@ -1976,6 +2135,10 @@ var AgnoClient = class extends import_eventemitter3.default {
1976
2135
  this.emit("state:change", this.getState());
1977
2136
  return;
1978
2137
  }
2138
+ if (!this.shouldProcessForUserMessage(event)) {
2139
+ this.emitMemberEvent(event, chunk);
2140
+ return;
2141
+ }
1979
2142
  if (event === import_agno_types2.RunEvent.RunError || event === import_agno_types2.RunEvent.TeamRunError) {
1980
2143
  const errorContent = chunk.content || "Error during run";
1981
2144
  this.state.errorMessage = errorContent;
@@ -2274,6 +2437,7 @@ var AgnoClient = class extends import_eventemitter3.default {
2274
2437
  this.emit("state:change", this.getState());
2275
2438
  try {
2276
2439
  const existingUIComponents = /* @__PURE__ */ new Map();
2440
+ const existingUserAttachments = [];
2277
2441
  for (const message of this.messageStore.getMessages()) {
2278
2442
  if (message.tool_calls) {
2279
2443
  for (const toolCall of message.tool_calls) {
@@ -2282,6 +2446,13 @@ var AgnoClient = class extends import_eventemitter3.default {
2282
2446
  }
2283
2447
  }
2284
2448
  }
2449
+ if (message.role === "user") {
2450
+ existingUserAttachments.push({
2451
+ images: message.images,
2452
+ audio: message.audio,
2453
+ files: message.files
2454
+ });
2455
+ }
2285
2456
  }
2286
2457
  const config = this.configManager.getConfig();
2287
2458
  const entityType = this.configManager.getMode();
@@ -2314,6 +2485,24 @@ var AgnoClient = class extends import_eventemitter3.default {
2314
2485
  }
2315
2486
  }
2316
2487
  }
2488
+ if (existingUserAttachments.length > 0) {
2489
+ let userIdx = 0;
2490
+ for (const message of messages) {
2491
+ if (message.role === "user" && userIdx < existingUserAttachments.length) {
2492
+ const saved = existingUserAttachments[userIdx];
2493
+ if (!message.images?.length && saved.images?.length) {
2494
+ message.images = saved.images;
2495
+ }
2496
+ if (!message.audio?.length && saved.audio?.length) {
2497
+ message.audio = saved.audio;
2498
+ }
2499
+ if (!message.files?.length && saved.files?.length) {
2500
+ message.files = saved.files;
2501
+ }
2502
+ userIdx++;
2503
+ }
2504
+ }
2505
+ }
2317
2506
  this.messageStore.setMessages(messages);
2318
2507
  Logger.debug("[AgnoClient] Session refreshed:", `${messages.length} messages`);
2319
2508
  this.emit("message:refreshed", messages);
package/dist/index.mjs CHANGED
@@ -234,6 +234,30 @@ var ConfigManager = class {
234
234
  setOnTokenExpired(callback) {
235
235
  this.config.onTokenExpired = callback;
236
236
  }
237
+ /**
238
+ * Get whether to emit member:* events for internal team activity
239
+ */
240
+ getEmitMemberEvents() {
241
+ return this.config.emitMemberEvents ?? false;
242
+ }
243
+ /**
244
+ * Set whether to emit member:* events
245
+ */
246
+ setEmitMemberEvents(emit) {
247
+ this.updateField("emitMemberEvents", emit);
248
+ }
249
+ /**
250
+ * Get whether to request member events from backend
251
+ */
252
+ getStreamMemberEvents() {
253
+ return this.config.streamMemberEvents ?? false;
254
+ }
255
+ /**
256
+ * Set whether to request member events from backend
257
+ */
258
+ setStreamMemberEvents(stream) {
259
+ this.updateField("streamMemberEvents", stream);
260
+ }
237
261
  /**
238
262
  * Get current entity ID (agent or team based on mode)
239
263
  */
@@ -552,10 +576,13 @@ var SessionManager = class {
552
576
  }
553
577
  }
554
578
  /**
555
- * Convert session runs array to chat messages
579
+ * Convert session runs array to chat messages.
580
+ * Filters out child runs (those with parent_run_id) to prevent
581
+ * internal team member communications from appearing as user messages.
556
582
  */
557
583
  convertSessionToMessages(runs) {
558
- const messages = this.convertRunsToMessages(runs);
584
+ const rootRuns = runs.filter((run) => !run.parent_run_id);
585
+ const messages = this.convertRunsToMessages(rootRuns);
559
586
  return messages;
560
587
  }
561
588
  /**
@@ -567,10 +594,67 @@ var SessionManager = class {
567
594
  for (const run of runs) {
568
595
  const timestamp = run.created_at ? new Date(run.created_at).getTime() / 1e3 : Math.floor(Date.now() / 1e3);
569
596
  if (run.run_input) {
597
+ const userImages = [];
598
+ const userAudio = [];
599
+ const userFiles = [];
600
+ if (run.input_media && typeof run.input_media === "object") {
601
+ const media = run.input_media;
602
+ if (Array.isArray(media.images)) {
603
+ for (const img of media.images) {
604
+ const imgObj = img;
605
+ let url = imgObj.url;
606
+ if (!url && imgObj.content) {
607
+ const mimeType = imgObj.mime_type || `image/${imgObj.format || "png"}`;
608
+ url = `data:${mimeType};base64,${imgObj.content}`;
609
+ }
610
+ if (url) {
611
+ userImages.push({
612
+ url,
613
+ revised_prompt: imgObj.original_name || "Uploaded image"
614
+ });
615
+ }
616
+ }
617
+ }
618
+ if (Array.isArray(media.audio)) {
619
+ for (const aud of media.audio) {
620
+ const audObj = aud;
621
+ let url = audObj.url;
622
+ if (!url && audObj.content) {
623
+ const mimeType = audObj.mime_type || `audio/${audObj.format || "wav"}`;
624
+ url = `data:${mimeType};base64,${audObj.content}`;
625
+ }
626
+ if (url) {
627
+ userAudio.push({
628
+ url,
629
+ mime_type: audObj.mime_type || void 0
630
+ });
631
+ }
632
+ }
633
+ }
634
+ if (Array.isArray(media.files)) {
635
+ for (const file of media.files) {
636
+ const fileObj = file;
637
+ let url = fileObj.url;
638
+ if (!url && fileObj.content) {
639
+ const mimeType = fileObj.mime_type || fileObj.content_type || "application/octet-stream";
640
+ url = `data:${mimeType};base64,${fileObj.content}`;
641
+ }
642
+ userFiles.push({
643
+ name: fileObj.original_name || fileObj.name || "file",
644
+ type: fileObj.content_type || fileObj.mime_type || "",
645
+ url,
646
+ size: fileObj.size || void 0
647
+ });
648
+ }
649
+ }
650
+ }
570
651
  messages.push({
571
652
  role: "user",
572
653
  content: run.run_input,
573
- created_at: timestamp
654
+ created_at: timestamp,
655
+ ...userImages.length > 0 ? { images: userImages } : {},
656
+ ...userAudio.length > 0 ? { audio: userAudio } : {},
657
+ ...userFiles.length > 0 ? { files: userFiles } : {}
574
658
  });
575
659
  }
576
660
  const toolCalls = [];
@@ -1841,10 +1925,38 @@ var AgnoClient = class extends EventEmitter {
1841
1925
  this.messageStore.removeLastMessages(2);
1842
1926
  }
1843
1927
  }
1928
+ const userImages = [];
1929
+ const userAudio = [];
1930
+ const userFiles = [];
1931
+ if (message instanceof FormData) {
1932
+ const entries = message.getAll("files");
1933
+ for (const entry of entries) {
1934
+ if (typeof entry !== "string") {
1935
+ const file = entry;
1936
+ const url = URL.createObjectURL(file);
1937
+ const mimeType = file.type || "";
1938
+ if (mimeType.startsWith("image/")) {
1939
+ userImages.push({ url, revised_prompt: file.name || "Uploaded image" });
1940
+ } else if (mimeType.startsWith("audio/")) {
1941
+ userAudio.push({ url, mime_type: mimeType });
1942
+ } else {
1943
+ userFiles.push({
1944
+ name: file.name || "file",
1945
+ type: mimeType,
1946
+ url,
1947
+ size: file.size
1948
+ });
1949
+ }
1950
+ }
1951
+ }
1952
+ }
1844
1953
  this.messageStore.addMessage({
1845
1954
  role: "user",
1846
1955
  content: formData.get("message"),
1847
- created_at: Math.floor(Date.now() / 1e3)
1956
+ created_at: Math.floor(Date.now() / 1e3),
1957
+ ...userImages.length > 0 ? { images: userImages } : {},
1958
+ ...userAudio.length > 0 ? { audio: userAudio } : {},
1959
+ ...userFiles.length > 0 ? { files: userFiles } : {}
1848
1960
  });
1849
1961
  this.messageStore.addMessage({
1850
1962
  role: "agent",
@@ -1862,6 +1974,10 @@ var AgnoClient = class extends EventEmitter {
1862
1974
  if (userId) {
1863
1975
  formData.append("user_id", userId);
1864
1976
  }
1977
+ if (this.configManager.getMode() === "team") {
1978
+ const streamMembers = this.configManager.getStreamMemberEvents();
1979
+ formData.append("stream_member_events", String(streamMembers));
1980
+ }
1865
1981
  await this.executeStream({
1866
1982
  apiUrl: runUrl,
1867
1983
  requestBody: formData,
@@ -1895,13 +2011,56 @@ var AgnoClient = class extends EventEmitter {
1895
2011
  }
1896
2012
  });
1897
2013
  }
2014
+ /**
2015
+ * Determine if a RunEvent is a team-level event (prefixed with "Team")
2016
+ */
2017
+ isTeamEvent(event) {
2018
+ return event.toString().startsWith("Team");
2019
+ }
2020
+ /**
2021
+ * Determine if an event should update the user-facing message based on mode.
2022
+ *
2023
+ * In team mode: only Team* events should update the user-facing message.
2024
+ * In agent mode: only Run* (non-Team) events should update the user-facing message.
2025
+ *
2026
+ * Certain events are always processed regardless of mode:
2027
+ * - CustomEvent, RunPaused, RunContinued (control flow events)
2028
+ */
2029
+ shouldProcessForUserMessage(event) {
2030
+ if (event === RunEvent.CustomEvent || event === RunEvent.RunPaused || event === RunEvent.RunContinued) {
2031
+ return true;
2032
+ }
2033
+ const mode = this.configManager.getMode();
2034
+ const isTeam = this.isTeamEvent(event);
2035
+ if (mode === "team") {
2036
+ return isTeam;
2037
+ }
2038
+ return !isTeam;
2039
+ }
2040
+ /**
2041
+ * Emit member-specific events for internal team member activity.
2042
+ * Only emits when emitMemberEvents config option is true.
2043
+ */
2044
+ emitMemberEvent(event, chunk) {
2045
+ if (!this.configManager.getEmitMemberEvents()) return;
2046
+ this.emit("member:event", chunk);
2047
+ if (event === RunEvent.RunStarted) {
2048
+ this.emit("member:started", chunk);
2049
+ } else if (event === RunEvent.RunContent) {
2050
+ this.emit("member:content", chunk);
2051
+ } else if (event === RunEvent.RunCompleted) {
2052
+ this.emit("member:completed", chunk);
2053
+ } else if (event === RunEvent.RunError) {
2054
+ this.emit("member:error", chunk);
2055
+ }
2056
+ }
1898
2057
  /**
1899
2058
  * Handle streaming chunk
1900
2059
  */
1901
2060
  handleChunk(chunk, currentSessionId, messageContent) {
1902
2061
  const event = chunk.event;
1903
2062
  if (event === RunEvent.RunStarted || event === RunEvent.TeamRunStarted || event === RunEvent.ReasoningStarted || event === RunEvent.TeamReasoningStarted) {
1904
- if (chunk.run_id) {
2063
+ if (this.shouldProcessForUserMessage(event) && chunk.run_id) {
1905
2064
  this.currentRunId = chunk.run_id;
1906
2065
  this.state.currentRunId = chunk.run_id;
1907
2066
  this.emit("state:change", this.getState());
@@ -1938,6 +2097,10 @@ var AgnoClient = class extends EventEmitter {
1938
2097
  this.emit("state:change", this.getState());
1939
2098
  return;
1940
2099
  }
2100
+ if (!this.shouldProcessForUserMessage(event)) {
2101
+ this.emitMemberEvent(event, chunk);
2102
+ return;
2103
+ }
1941
2104
  if (event === RunEvent.RunError || event === RunEvent.TeamRunError) {
1942
2105
  const errorContent = chunk.content || "Error during run";
1943
2106
  this.state.errorMessage = errorContent;
@@ -2236,6 +2399,7 @@ var AgnoClient = class extends EventEmitter {
2236
2399
  this.emit("state:change", this.getState());
2237
2400
  try {
2238
2401
  const existingUIComponents = /* @__PURE__ */ new Map();
2402
+ const existingUserAttachments = [];
2239
2403
  for (const message of this.messageStore.getMessages()) {
2240
2404
  if (message.tool_calls) {
2241
2405
  for (const toolCall of message.tool_calls) {
@@ -2244,6 +2408,13 @@ var AgnoClient = class extends EventEmitter {
2244
2408
  }
2245
2409
  }
2246
2410
  }
2411
+ if (message.role === "user") {
2412
+ existingUserAttachments.push({
2413
+ images: message.images,
2414
+ audio: message.audio,
2415
+ files: message.files
2416
+ });
2417
+ }
2247
2418
  }
2248
2419
  const config = this.configManager.getConfig();
2249
2420
  const entityType = this.configManager.getMode();
@@ -2276,6 +2447,24 @@ var AgnoClient = class extends EventEmitter {
2276
2447
  }
2277
2448
  }
2278
2449
  }
2450
+ if (existingUserAttachments.length > 0) {
2451
+ let userIdx = 0;
2452
+ for (const message of messages) {
2453
+ if (message.role === "user" && userIdx < existingUserAttachments.length) {
2454
+ const saved = existingUserAttachments[userIdx];
2455
+ if (!message.images?.length && saved.images?.length) {
2456
+ message.images = saved.images;
2457
+ }
2458
+ if (!message.audio?.length && saved.audio?.length) {
2459
+ message.audio = saved.audio;
2460
+ }
2461
+ if (!message.files?.length && saved.files?.length) {
2462
+ message.files = saved.files;
2463
+ }
2464
+ userIdx++;
2465
+ }
2466
+ }
2467
+ }
2279
2468
  this.messageStore.setMessages(messages);
2280
2469
  Logger.debug("[AgnoClient] Session refreshed:", `${messages.length} messages`);
2281
2470
  this.emit("message:refreshed", messages);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rodrigocoliveira/agno-client",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Core client library for Agno agents with streaming support and HITL frontend tool execution",
5
5
  "author": "rodrigocoliveira",
6
6
  "license": "MIT",
@@ -23,9 +23,9 @@
23
23
  "types": "./dist/index.d.ts",
24
24
  "exports": {
25
25
  ".": {
26
+ "types": "./dist/index.d.ts",
26
27
  "import": "./dist/index.mjs",
27
- "require": "./dist/index.js",
28
- "types": "./dist/index.d.ts"
28
+ "require": "./dist/index.js"
29
29
  }
30
30
  },
31
31
  "files": [
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "eventemitter3": "^5.0.1",
37
- "@rodrigocoliveira/agno-types": "1.0.1"
37
+ "@rodrigocoliveira/agno-types": "1.0.2"
38
38
  },
39
39
  "devDependencies": {
40
40
  "tsup": "^8.0.1",