@assistant-ui/react-langchain 0.0.31 → 0.0.33

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.
Files changed (60) hide show
  1. package/dist/attachSubagentTranscripts.d.ts +19 -12
  2. package/dist/attachSubagentTranscripts.d.ts.map +1 -1
  3. package/dist/attachSubagentTranscripts.js +8 -4
  4. package/dist/attachSubagentTranscripts.js.map +1 -1
  5. package/dist/convertMessages.d.ts +8 -11
  6. package/dist/convertMessages.d.ts.map +1 -1
  7. package/dist/convertMessages.js +53 -15
  8. package/dist/convertMessages.js.map +1 -1
  9. package/dist/converter.d.ts +137 -138
  10. package/dist/converter.d.ts.map +1 -1
  11. package/dist/converter.js +2 -1
  12. package/dist/converter.js.map +1 -1
  13. package/dist/findForkCheckpointInHistory.d.ts +17 -19
  14. package/dist/findForkCheckpointInHistory.d.ts.map +1 -1
  15. package/dist/hooks.d.ts +19 -22
  16. package/dist/hooks.d.ts.map +1 -1
  17. package/dist/index.d.ts +7 -8
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/resolveForkCheckpoint.d.ts +5 -7
  20. package/dist/resolveForkCheckpoint.d.ts.map +1 -1
  21. package/dist/runtimeExtras.d.ts +2 -5
  22. package/dist/runtimeExtras.d.ts.map +1 -1
  23. package/dist/sdkIdentity.d.ts +2 -5
  24. package/dist/sdkIdentity.d.ts.map +1 -1
  25. package/dist/sdkIdentity.js +1 -1
  26. package/dist/streamingTiming.d.ts +4 -7
  27. package/dist/streamingTiming.d.ts.map +1 -1
  28. package/dist/subagentMessagesProjection.d.ts +17 -0
  29. package/dist/subagentMessagesProjection.d.ts.map +1 -0
  30. package/dist/subagentMessagesProjection.js +40 -0
  31. package/dist/subagentMessagesProjection.js.map +1 -0
  32. package/dist/types.d.ts +106 -109
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/uiMessages.d.ts +37 -10
  35. package/dist/uiMessages.d.ts.map +1 -1
  36. package/dist/uiMessages.js +55 -5
  37. package/dist/uiMessages.js.map +1 -1
  38. package/dist/useStreamRuntime.d.ts +9 -12
  39. package/dist/useStreamRuntime.d.ts.map +1 -1
  40. package/dist/useStreamRuntime.js +102 -28
  41. package/dist/useStreamRuntime.js.map +1 -1
  42. package/dist/useSubagentTranscripts.d.ts +5 -8
  43. package/dist/useSubagentTranscripts.d.ts.map +1 -1
  44. package/dist/useSubagentTranscripts.js +129 -34
  45. package/dist/useSubagentTranscripts.js.map +1 -1
  46. package/package.json +16 -11
  47. package/src/attachSubagentTranscripts.test.ts +13 -5
  48. package/src/attachSubagentTranscripts.ts +26 -7
  49. package/src/convertMessages.test.ts +69 -0
  50. package/src/convertMessages.ts +46 -8
  51. package/src/converter.ts +6 -0
  52. package/src/subagentMessagesProjection.test.ts +175 -0
  53. package/src/subagentMessagesProjection.ts +50 -0
  54. package/src/uiMessages.test.ts +149 -0
  55. package/src/uiMessages.ts +79 -4
  56. package/src/useStreamRuntime.test.tsx +212 -0
  57. package/src/useStreamRuntime.ts +202 -50
  58. package/src/useStreamRuntime.voice.test.tsx +712 -0
  59. package/src/useSubagentTranscripts.test.tsx +795 -52
  60. package/src/useSubagentTranscripts.ts +269 -50
@@ -1,16 +1,23 @@
1
- import { ThreadMessage } from "@assistant-ui/core";
2
- //#region src/attachSubagentTranscripts.d.ts
3
- type AttachedTranscript = readonly [string, readonly ThreadMessage[]];
1
+ import { type ThreadMessage, type ToolCallTiming } from "@assistant-ui/core";
2
+ export type SubagentTranscript = {
3
+ readonly messages: readonly ThreadMessage[];
4
+ /**
5
+ * Only present when the client watched the task run: the discovery
6
+ * timestamps are stamped when the task call is first seen, so a thread
7
+ * seeded from a checkpoint would report a duration of zero.
8
+ */
9
+ readonly timing?: ToolCallTiming;
10
+ };
11
+ type AttachedTranscript = readonly [string, SubagentTranscript];
4
12
  type AttachedMessage = {
5
- transcripts: readonly AttachedTranscript[];
6
- attached: ThreadMessage;
13
+ transcripts: readonly AttachedTranscript[];
14
+ attached: ThreadMessage;
7
15
  };
8
- type AttachMemo = {
9
- messages: WeakMap<ThreadMessage, AttachedMessage>;
10
- results: WeakMap<readonly ThreadMessage[], readonly ThreadMessage[]>;
16
+ export type AttachMemo = {
17
+ messages: WeakMap<ThreadMessage, AttachedMessage>;
18
+ results: WeakMap<readonly ThreadMessage[], readonly ThreadMessage[]>;
11
19
  };
12
- declare const createAttachMemo: () => AttachMemo;
13
- declare const attachSubagentTranscripts: (messages: readonly ThreadMessage[], transcripts: ReadonlyMap<string, readonly ThreadMessage[]>, memo: AttachMemo) => readonly ThreadMessage[];
14
- //#endregion
15
- export { AttachMemo, attachSubagentTranscripts, createAttachMemo };
20
+ export declare const createAttachMemo: () => AttachMemo;
21
+ export declare const attachSubagentTranscripts: (messages: readonly ThreadMessage[], transcripts: ReadonlyMap<string, SubagentTranscript>, memo: AttachMemo) => readonly ThreadMessage[];
22
+ export {};
16
23
  //# sourceMappingURL=attachSubagentTranscripts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachSubagentTranscripts.d.ts","names":[],"sources":["../src/attachSubagentTranscripts.ts"],"mappings":";;KAMK,gDAAgD;KAEhD;EACH,sBAAsB;EACtB,UAAU;;KAGA;EACV,UAAU,QAAQ,eAAe;EACjC,SAAS,iBAAiB,0BAA0B;;cAGzC,wBAAuB;cAevB,4BACX,mBAAmB,iBACnB,aAAa,6BAA6B,kBAC1C,MAAM,wBACI"}
1
+ {"version":3,"file":"attachSubagentTranscripts.d.ts","sourceRoot":"","sources":["../src/attachSubagentTranscripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;CAClC,CAAC;AAEF,KAAK,kBAAkB,GAAG,SAAS,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAEhE,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC3C,QAAQ,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;IAClD,OAAO,EAAE,OAAO,CAAC,SAAS,aAAa,EAAE,EAAE,SAAS,aAAa,EAAE,CAAC,CAAC;CACtE,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,UAGlC,CAAC;AAYH,eAAO,MAAM,yBAAyB,GACpC,UAAU,SAAS,aAAa,EAAE,EAClC,aAAa,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACpD,MAAM,UAAU,KACf,SAAS,aAAa,EA0CxB,CAAC"}
@@ -15,10 +15,14 @@ const attachSubagentTranscripts = (messages, transcripts, memo) => {
15
15
  if (cached && sameTranscripts(cached.transcripts, attachedTranscripts)) return cached.attached;
16
16
  const attached = {
17
17
  ...message,
18
- content: message.content.map((part) => part.type === "tool-call" && transcripts.has(part.toolCallId) ? {
19
- ...part,
20
- messages: transcripts.get(part.toolCallId)
21
- } : part)
18
+ content: message.content.map((part) => {
19
+ const transcript = part.type === "tool-call" ? transcripts.get(part.toolCallId) : void 0;
20
+ return transcript ? {
21
+ ...part,
22
+ messages: transcript.messages,
23
+ ...transcript.timing && { timing: transcript.timing }
24
+ } : part;
25
+ })
22
26
  };
23
27
  memo.messages.set(message, {
24
28
  transcripts: attachedTranscripts,
@@ -1 +1 @@
1
- {"version":3,"file":"attachSubagentTranscripts.js","names":[],"sources":["../src/attachSubagentTranscripts.ts"],"sourcesContent":["import {\n bindExternalStoreMessage,\n getExternalStoreMessages,\n type ThreadMessage,\n} from \"@assistant-ui/core\";\n\ntype AttachedTranscript = readonly [string, readonly ThreadMessage[]];\n\ntype AttachedMessage = {\n transcripts: readonly AttachedTranscript[];\n attached: ThreadMessage;\n};\n\nexport type AttachMemo = {\n messages: WeakMap<ThreadMessage, AttachedMessage>;\n results: WeakMap<readonly ThreadMessage[], readonly ThreadMessage[]>;\n};\n\nexport const createAttachMemo = (): AttachMemo => ({\n messages: new WeakMap(),\n results: new WeakMap(),\n});\n\nconst sameTranscripts = (\n a: readonly AttachedTranscript[],\n b: readonly AttachedTranscript[],\n) =>\n a.length === b.length &&\n a.every(\n ([toolCallId, transcript], index) =>\n toolCallId === b[index]![0] && transcript === b[index]![1],\n );\n\nexport const attachSubagentTranscripts = (\n messages: readonly ThreadMessage[],\n transcripts: ReadonlyMap<string, readonly ThreadMessage[]>,\n memo: AttachMemo,\n): readonly ThreadMessage[] => {\n let attachedAny = false;\n const next = messages.map((message) => {\n const attachedTranscripts = message.content.flatMap((part) =>\n part.type === \"tool-call\" && transcripts.has(part.toolCallId)\n ? [[part.toolCallId, transcripts.get(part.toolCallId)!] as const]\n : [],\n );\n if (attachedTranscripts.length === 0) return message;\n attachedAny = true;\n\n const cached = memo.messages.get(message);\n if (cached && sameTranscripts(cached.transcripts, attachedTranscripts))\n return cached.attached;\n\n const attached = {\n ...message,\n content: message.content.map((part) =>\n part.type === \"tool-call\" && transcripts.has(part.toolCallId)\n ? { ...part, messages: transcripts.get(part.toolCallId)! }\n : part,\n ),\n } as ThreadMessage;\n memo.messages.set(message, { transcripts: attachedTranscripts, attached });\n return attached;\n });\n\n if (!attachedAny) return messages;\n const previous = memo.results.get(messages);\n if (previous && previous.every((message, index) => message === next[index]))\n return previous;\n bindExternalStoreMessage(next, getExternalStoreMessages({ messages }));\n memo.results.set(messages, next);\n return next;\n};\n"],"mappings":";;AAkBA,MAAa,0BAAsC;CACjD,0BAAU,IAAI,QAAQ;CACtB,yBAAS,IAAI,QAAQ;AACvB;AAEA,MAAM,mBACJ,GACA,MAEA,EAAE,WAAW,EAAE,UACf,EAAE,OACC,CAAC,YAAY,aAAa,UACzB,eAAe,EAAE,MAAM,CAAE,MAAM,eAAe,EAAE,MAAM,CAAE,EAC5D;AAEF,MAAa,6BACX,UACA,aACA,SAC6B;CAC7B,IAAI,cAAc;CAClB,MAAM,OAAO,SAAS,KAAK,YAAY;EACrC,MAAM,sBAAsB,QAAQ,QAAQ,SAAS,SACnD,KAAK,SAAS,eAAe,YAAY,IAAI,KAAK,UAAU,IACxD,CAAC,CAAC,KAAK,YAAY,YAAY,IAAI,KAAK,UAAU,CAAE,CAAU,IAC9D,CAAC,CACP;EACA,IAAI,oBAAoB,WAAW,GAAG,OAAO;EAC7C,cAAc;EAEd,MAAM,SAAS,KAAK,SAAS,IAAI,OAAO;EACxC,IAAI,UAAU,gBAAgB,OAAO,aAAa,mBAAmB,GACnE,OAAO,OAAO;EAEhB,MAAM,WAAW;GACf,GAAG;GACH,SAAS,QAAQ,QAAQ,KAAK,SAC5B,KAAK,SAAS,eAAe,YAAY,IAAI,KAAK,UAAU,IACxD;IAAE,GAAG;IAAM,UAAU,YAAY,IAAI,KAAK,UAAU;GAAG,IACvD,IACN;EACF;EACA,KAAK,SAAS,IAAI,SAAS;GAAE,aAAa;GAAqB;EAAS,CAAC;EACzE,OAAO;CACT,CAAC;CAED,IAAI,CAAC,aAAa,OAAO;CACzB,MAAM,WAAW,KAAK,QAAQ,IAAI,QAAQ;CAC1C,IAAI,YAAY,SAAS,OAAO,SAAS,UAAU,YAAY,KAAK,MAAM,GACxE,OAAO;CACT,yBAAyB,MAAM,yBAAyB,EAAE,SAAS,CAAC,CAAC;CACrE,KAAK,QAAQ,IAAI,UAAU,IAAI;CAC/B,OAAO;AACT"}
1
+ {"version":3,"file":"attachSubagentTranscripts.js","names":[],"sources":["../src/attachSubagentTranscripts.ts"],"sourcesContent":["import {\n bindExternalStoreMessage,\n getExternalStoreMessages,\n type ThreadMessage,\n type ToolCallTiming,\n} from \"@assistant-ui/core\";\n\nexport type SubagentTranscript = {\n readonly messages: readonly ThreadMessage[];\n /**\n * Only present when the client watched the task run: the discovery\n * timestamps are stamped when the task call is first seen, so a thread\n * seeded from a checkpoint would report a duration of zero.\n */\n readonly timing?: ToolCallTiming;\n};\n\ntype AttachedTranscript = readonly [string, SubagentTranscript];\n\ntype AttachedMessage = {\n transcripts: readonly AttachedTranscript[];\n attached: ThreadMessage;\n};\n\nexport type AttachMemo = {\n messages: WeakMap<ThreadMessage, AttachedMessage>;\n results: WeakMap<readonly ThreadMessage[], readonly ThreadMessage[]>;\n};\n\nexport const createAttachMemo = (): AttachMemo => ({\n messages: new WeakMap(),\n results: new WeakMap(),\n});\n\nconst sameTranscripts = (\n a: readonly AttachedTranscript[],\n b: readonly AttachedTranscript[],\n) =>\n a.length === b.length &&\n a.every(\n ([toolCallId, transcript], index) =>\n toolCallId === b[index]![0] && transcript === b[index]![1],\n );\n\nexport const attachSubagentTranscripts = (\n messages: readonly ThreadMessage[],\n transcripts: ReadonlyMap<string, SubagentTranscript>,\n memo: AttachMemo,\n): readonly ThreadMessage[] => {\n let attachedAny = false;\n const next = messages.map((message) => {\n const attachedTranscripts = message.content.flatMap((part) =>\n part.type === \"tool-call\" && transcripts.has(part.toolCallId)\n ? [[part.toolCallId, transcripts.get(part.toolCallId)!] as const]\n : [],\n );\n if (attachedTranscripts.length === 0) return message;\n attachedAny = true;\n\n const cached = memo.messages.get(message);\n if (cached && sameTranscripts(cached.transcripts, attachedTranscripts))\n return cached.attached;\n\n const attached = {\n ...message,\n content: message.content.map((part) => {\n const transcript =\n part.type === \"tool-call\"\n ? transcripts.get(part.toolCallId)\n : undefined;\n return transcript\n ? {\n ...part,\n messages: transcript.messages,\n ...(transcript.timing && { timing: transcript.timing }),\n }\n : part;\n }),\n } as ThreadMessage;\n memo.messages.set(message, { transcripts: attachedTranscripts, attached });\n return attached;\n });\n\n if (!attachedAny) return messages;\n const previous = memo.results.get(messages);\n if (previous && previous.every((message, index) => message === next[index]))\n return previous;\n bindExternalStoreMessage(next, getExternalStoreMessages({ messages }));\n memo.results.set(messages, next);\n return next;\n};\n"],"mappings":";;AA6BA,MAAa,0BAAsC;CACjD,0BAAU,IAAI,QAAQ;CACtB,yBAAS,IAAI,QAAQ;AACvB;AAEA,MAAM,mBACJ,GACA,MAEA,EAAE,WAAW,EAAE,UACf,EAAE,OACC,CAAC,YAAY,aAAa,UACzB,eAAe,EAAE,MAAM,CAAE,MAAM,eAAe,EAAE,MAAM,CAAE,EAC5D;AAEF,MAAa,6BACX,UACA,aACA,SAC6B;CAC7B,IAAI,cAAc;CAClB,MAAM,OAAO,SAAS,KAAK,YAAY;EACrC,MAAM,sBAAsB,QAAQ,QAAQ,SAAS,SACnD,KAAK,SAAS,eAAe,YAAY,IAAI,KAAK,UAAU,IACxD,CAAC,CAAC,KAAK,YAAY,YAAY,IAAI,KAAK,UAAU,CAAE,CAAU,IAC9D,CAAC,CACP;EACA,IAAI,oBAAoB,WAAW,GAAG,OAAO;EAC7C,cAAc;EAEd,MAAM,SAAS,KAAK,SAAS,IAAI,OAAO;EACxC,IAAI,UAAU,gBAAgB,OAAO,aAAa,mBAAmB,GACnE,OAAO,OAAO;EAEhB,MAAM,WAAW;GACf,GAAG;GACH,SAAS,QAAQ,QAAQ,KAAK,SAAS;IACrC,MAAM,aACJ,KAAK,SAAS,cACV,YAAY,IAAI,KAAK,UAAU,IAC/B,KAAA;IACN,OAAO,aACH;KACE,GAAG;KACH,UAAU,WAAW;KACrB,GAAI,WAAW,UAAU,EAAE,QAAQ,WAAW,OAAO;IACvD,IACA;GACN,CAAC;EACH;EACA,KAAK,SAAS,IAAI,SAAS;GAAE,aAAa;GAAqB;EAAS,CAAC;EACzE,OAAO;CACT,CAAC;CAED,IAAI,CAAC,aAAa,OAAO;CACzB,MAAM,WAAW,KAAK,QAAQ,IAAI,QAAQ;CAC1C,IAAI,YAAY,SAAS,OAAO,SAAS,UAAU,YAAY,KAAK,MAAM,GACxE,OAAO;CACT,yBAAyB,MAAM,yBAAyB,EAAE,SAAS,CAAC,CAAC;CACrE,KAAK,QAAQ,IAAI,UAAU,IAAI;CAC/B,OAAO;AACT"}
@@ -1,14 +1,11 @@
1
- import { getMessageContent } from "./converter.js";
2
- import { LangChainBaseMessage, UIMessage } from "./types.js";
3
- import { MessageTiming } from "@assistant-ui/core";
4
- import { useExternalMessageConverter } from "@assistant-ui/core/react";
5
- //#region src/convertMessages.d.ts
1
+ import type { MessageTiming } from "@assistant-ui/core";
2
+ import type { useExternalMessageConverter } from "@assistant-ui/core/react";
3
+ import type { LangChainBaseMessage, UIMessage } from "./types.js";
6
4
  type LangChainMessageConverterMetadata = useExternalMessageConverter.Metadata & {
7
- uiMessagesByParent?: Map<string, UIMessage[]>;
8
- messageTiming?: Record<string, MessageTiming>;
5
+ uiMessagesByParent?: Map<string, UIMessage[]>;
6
+ messageTiming?: Record<string, MessageTiming>;
9
7
  };
10
- declare const getMessageType: (message: LangChainBaseMessage) => string;
11
- declare const convertLangChainBaseMessage: (message: LangChainBaseMessage, metadata?: LangChainMessageConverterMetadata) => useExternalMessageConverter.Message;
12
- //#endregion
13
- export { convertLangChainBaseMessage, getMessageContent, getMessageType };
8
+ export declare const getMessageType: (message: LangChainBaseMessage) => string;
9
+ export declare const convertLangChainBaseMessage: (message: LangChainBaseMessage, metadata?: LangChainMessageConverterMetadata) => useExternalMessageConverter.Message;
10
+ export { getMessageContent } from "./converter.js";
14
11
  //# sourceMappingURL=convertMessages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessages.d.ts","names":[],"sources":["../src/convertMessages.ts"],"mappings":";;;;;KAiBK,oCACH,4BAA4B;EAC1B,qBAAqB,YAAY;EACjC,gBAAgB,eAAe;;cAetB,iBAAkB,SAAS;cAuC3B,8BACX,SAAS,sBACT,WAAU,sCACT,4BAA4B"}
1
+ {"version":3,"file":"convertMessages.d.ts","sourceRoot":"","sources":["../src/convertMessages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAS5E,OAAO,KAAK,EACV,oBAAoB,EAEpB,SAAS,EACV,mBAAgB;AAEjB,KAAK,iCAAiC,GACpC,2BAA2B,CAAC,QAAQ,GAAG;IACrC,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC/C,CAAC;AAcJ,eAAO,MAAM,cAAc,GAAI,SAAS,oBAAoB,KAAG,MAQ9D,CAAC;AA4DF,eAAO,MAAM,2BAA2B,GACtC,SAAS,oBAAoB,EAC7B,WAAU,iCAAsC,KAC/C,2BAA2B,CAAC,OAoG9B,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,uBAAoB"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { convertLangChainContentBlock, getCustomMetadata, getMessageContent, uiMessageToDataPart, withAudioTranscript } from "./converter.js";
2
+ import { convertLangChainContentBlock, getCustomMetadata, getMessageContent, getMessageModality, uiMessageToDataPart, withAudioTranscript } from "./converter.js";
3
3
  //#region src/convertMessages.ts
4
4
  const warnedMalformedMessages = /* @__PURE__ */ new Set();
5
5
  const warnOnceInDevelopment = (message) => {
@@ -20,6 +20,33 @@ const contentBlocks = (content) => {
20
20
  warnOnceInDevelopment(`Ignoring message content that is neither a string nor an array: ${typeof content}`);
21
21
  return [];
22
22
  };
23
+ const normalizeToolCallArgs = (args) => {
24
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return {};
25
+ try {
26
+ const prototype = Object.getPrototypeOf(args);
27
+ return prototype === Object.prototype || prototype === null ? args : {};
28
+ } catch {
29
+ return {};
30
+ }
31
+ };
32
+ const toolCallArgs = (value) => {
33
+ const args = normalizeToolCallArgs(value);
34
+ try {
35
+ const argsText = JSON.stringify(args);
36
+ return typeof argsText === "string" ? {
37
+ args,
38
+ argsText
39
+ } : {
40
+ args: {},
41
+ argsText: "{}"
42
+ };
43
+ } catch {
44
+ return {
45
+ args: {},
46
+ argsText: "{}"
47
+ };
48
+ }
49
+ };
23
50
  const contentToParts = (content) => {
24
51
  if (typeof content === "string") return [{
25
52
  type: "text",
@@ -42,23 +69,33 @@ const convertLangChainBaseMessage = (message, metadata = {}) => {
42
69
  }],
43
70
  metadata: { custom: getCustomMetadata(message.additional_kwargs) }
44
71
  };
45
- case "human": return {
46
- role: "user",
47
- id: message.id,
48
- content: contentToParts(message.content),
49
- metadata: { custom: getCustomMetadata(message.additional_kwargs) }
50
- };
72
+ case "human": {
73
+ const modality = getMessageModality(message.additional_kwargs);
74
+ return {
75
+ role: "user",
76
+ id: message.id,
77
+ content: contentToParts(message.content),
78
+ metadata: {
79
+ custom: getCustomMetadata(message.additional_kwargs),
80
+ ...modality && { modality }
81
+ }
82
+ };
83
+ }
51
84
  case "ai": {
52
- const toolCallParts = message.tool_calls?.map((tc) => ({
53
- type: "tool-call",
54
- toolCallId: tc.id,
55
- toolName: tc.name,
56
- args: tc.args,
57
- argsText: JSON.stringify(tc.args)
58
- })) ?? [];
85
+ const toolCallParts = message.tool_calls?.map((tc) => {
86
+ const { args, argsText } = toolCallArgs(tc.args);
87
+ return {
88
+ type: "tool-call",
89
+ toolCallId: tc.id,
90
+ toolName: tc.name,
91
+ args,
92
+ argsText
93
+ };
94
+ }) ?? [];
59
95
  const assistantStatus = typeof message.status === "object" ? message.status : void 0;
60
96
  const uiDataParts = (message.id ? metadata.uiMessagesByParent?.get(message.id)?.map(uiMessageToDataPart) : void 0) ?? [];
61
97
  const timing = metadata.messageTiming?.[message.id ?? ""];
98
+ const modality = getMessageModality(message.additional_kwargs);
62
99
  return {
63
100
  role: "assistant",
64
101
  id: message.id,
@@ -69,7 +106,8 @@ const convertLangChainBaseMessage = (message, metadata = {}) => {
69
106
  ],
70
107
  metadata: {
71
108
  custom: getCustomMetadata(message.additional_kwargs),
72
- ...timing && { timing }
109
+ ...timing && { timing },
110
+ ...modality && { modality }
73
111
  },
74
112
  ...assistantStatus && { status: assistantStatus }
75
113
  };
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessages.js","names":[],"sources":["../src/convertMessages.ts"],"sourcesContent":["\"use client\";\n\nimport type { MessageTiming } from \"@assistant-ui/core\";\nimport type { useExternalMessageConverter } from \"@assistant-ui/core/react\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport {\n convertLangChainContentBlock,\n getCustomMetadata,\n uiMessageToDataPart,\n withAudioTranscript,\n} from \"./converter\";\nimport type {\n LangChainBaseMessage,\n LangChainContentBlock,\n UIMessage,\n} from \"./types\";\n\ntype LangChainMessageConverterMetadata =\n useExternalMessageConverter.Metadata & {\n uiMessagesByParent?: Map<string, UIMessage[]>;\n messageTiming?: Record<string, MessageTiming>;\n };\n\nconst warnedMalformedMessages = new Set<string>();\nconst warnOnceInDevelopment = (message: string) => {\n if (\n typeof process === \"undefined\" ||\n process?.env?.NODE_ENV !== \"development\"\n )\n return;\n if (warnedMalformedMessages.has(message)) return;\n warnedMalformedMessages.add(message);\n console.warn(message);\n};\n\nexport const getMessageType = (message: LangChainBaseMessage): string => {\n if (typeof message._getType === \"function\") return message._getType();\n if (\"type\" in message)\n return (message as Record<string, unknown>).type as string;\n warnOnceInDevelopment(\n \"Cannot determine message type; rendering the message as system text\",\n );\n return \"unknown\";\n};\n\nconst contentBlocks = (content: unknown): readonly LangChainContentBlock[] => {\n if (content == null) return [];\n if (Array.isArray(content))\n return content.filter(\n (block) => typeof block === \"object\" && block !== null,\n );\n warnOnceInDevelopment(\n `Ignoring message content that is neither a string nor an array: ${typeof content}`,\n );\n return [];\n};\n\nconst contentToParts = (content: unknown) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n\n return contentBlocks(content)\n .map(convertLangChainContentBlock)\n .filter((part) => part !== null && part !== undefined);\n};\n\nconst getStringContent = (content: unknown): string => {\n if (typeof content === \"string\") return content;\n return contentBlocks(content)\n .filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\");\n};\n\nexport const convertLangChainBaseMessage = (\n message: LangChainBaseMessage,\n metadata: LangChainMessageConverterMetadata = {},\n): useExternalMessageConverter.Message => {\n const type = getMessageType(message);\n\n switch (type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: getStringContent(message.content) }],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"human\":\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"ai\": {\n const toolCallParts =\n message.tool_calls?.map((tc) => ({\n type: \"tool-call\" as const,\n toolCallId: tc.id,\n toolName: tc.name,\n args: tc.args as ReadonlyJSONObject,\n argsText: JSON.stringify(tc.args),\n })) ?? [];\n\n const assistantStatus =\n typeof message.status === \"object\" ? message.status : undefined;\n\n const uiDataParts =\n (message.id\n ? metadata.uiMessagesByParent\n ?.get(message.id)\n ?.map(uiMessageToDataPart)\n : undefined) ?? [];\n\n const timing = metadata.messageTiming?.[message.id ?? \"\"];\n\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...withAudioTranscript(\n contentToParts(message.content),\n message.additional_kwargs,\n ),\n ...toolCallParts,\n ...uiDataParts,\n ],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n ...(timing && { timing }),\n },\n ...(assistantStatus && { status: assistantStatus }),\n };\n }\n\n case \"tool\":\n return {\n role: \"tool\",\n // `joinExternalMessages` only checks the name against the tool call\n // when it is non-null, so an empty name manufactures a mismatch.\n toolName: message.name || undefined,\n toolCallId: message.tool_call_id ?? \"\",\n result: message.content,\n artifact: message.artifact,\n isError: message.status === \"error\",\n };\n\n default:\n return {\n role: \"system\",\n id: message.id,\n content: [\n {\n type: \"text\",\n text:\n typeof message.content === \"string\"\n ? message.content\n : (JSON.stringify(message.content) ?? \"\"),\n },\n ],\n };\n }\n};\n\nexport { getMessageContent } from \"./converter\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"convertMessages.js","names":[],"sources":["../src/convertMessages.ts"],"sourcesContent":["\"use client\";\n\nimport type { MessageTiming } from \"@assistant-ui/core\";\nimport type { useExternalMessageConverter } from \"@assistant-ui/core/react\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport {\n convertLangChainContentBlock,\n getCustomMetadata,\n getMessageModality,\n uiMessageToDataPart,\n withAudioTranscript,\n} from \"./converter\";\nimport type {\n LangChainBaseMessage,\n LangChainContentBlock,\n UIMessage,\n} from \"./types\";\n\ntype LangChainMessageConverterMetadata =\n useExternalMessageConverter.Metadata & {\n uiMessagesByParent?: Map<string, UIMessage[]>;\n messageTiming?: Record<string, MessageTiming>;\n };\n\nconst warnedMalformedMessages = new Set<string>();\nconst warnOnceInDevelopment = (message: string) => {\n if (\n typeof process === \"undefined\" ||\n process?.env?.NODE_ENV !== \"development\"\n )\n return;\n if (warnedMalformedMessages.has(message)) return;\n warnedMalformedMessages.add(message);\n console.warn(message);\n};\n\nexport const getMessageType = (message: LangChainBaseMessage): string => {\n if (typeof message._getType === \"function\") return message._getType();\n if (\"type\" in message)\n return (message as Record<string, unknown>).type as string;\n warnOnceInDevelopment(\n \"Cannot determine message type; rendering the message as system text\",\n );\n return \"unknown\";\n};\n\nconst contentBlocks = (content: unknown): readonly LangChainContentBlock[] => {\n if (content == null) return [];\n if (Array.isArray(content))\n return content.filter(\n (block) => typeof block === \"object\" && block !== null,\n );\n warnOnceInDevelopment(\n `Ignoring message content that is neither a string nor an array: ${typeof content}`,\n );\n return [];\n};\n\nconst normalizeToolCallArgs = (args: unknown): ReadonlyJSONObject => {\n if (typeof args !== \"object\" || args === null || Array.isArray(args)) {\n return {};\n }\n\n try {\n const prototype = Object.getPrototypeOf(args);\n return prototype === Object.prototype || prototype === null\n ? (args as ReadonlyJSONObject)\n : {};\n } catch {\n return {};\n }\n};\n\nconst toolCallArgs = (\n value: unknown,\n): { args: ReadonlyJSONObject; argsText: string } => {\n const args = normalizeToolCallArgs(value);\n try {\n const argsText = JSON.stringify(args);\n return typeof argsText === \"string\"\n ? { args, argsText }\n : { args: {}, argsText: \"{}\" };\n } catch {\n return { args: {}, argsText: \"{}\" };\n }\n};\n\nconst contentToParts = (content: unknown) => {\n if (typeof content === \"string\")\n return [{ type: \"text\" as const, text: content }];\n\n return contentBlocks(content)\n .map(convertLangChainContentBlock)\n .filter((part) => part !== null && part !== undefined);\n};\n\nconst getStringContent = (content: unknown): string => {\n if (typeof content === \"string\") return content;\n return contentBlocks(content)\n .filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\");\n};\n\nexport const convertLangChainBaseMessage = (\n message: LangChainBaseMessage,\n metadata: LangChainMessageConverterMetadata = {},\n): useExternalMessageConverter.Message => {\n const type = getMessageType(message);\n\n switch (type) {\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n content: [{ type: \"text\", text: getStringContent(message.content) }],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n },\n };\n\n case \"human\": {\n const modality = getMessageModality(message.additional_kwargs);\n return {\n role: \"user\",\n id: message.id,\n content: contentToParts(message.content),\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n ...(modality && { modality }),\n },\n };\n }\n\n case \"ai\": {\n const toolCallParts =\n message.tool_calls?.map((tc) => {\n const { args, argsText } = toolCallArgs(tc.args);\n return {\n type: \"tool-call\" as const,\n toolCallId: tc.id,\n toolName: tc.name,\n args,\n argsText,\n };\n }) ?? [];\n\n const assistantStatus =\n typeof message.status === \"object\" ? message.status : undefined;\n\n const uiDataParts =\n (message.id\n ? metadata.uiMessagesByParent\n ?.get(message.id)\n ?.map(uiMessageToDataPart)\n : undefined) ?? [];\n\n const timing = metadata.messageTiming?.[message.id ?? \"\"];\n const modality = getMessageModality(message.additional_kwargs);\n\n return {\n role: \"assistant\",\n id: message.id,\n content: [\n ...withAudioTranscript(\n contentToParts(message.content),\n message.additional_kwargs,\n ),\n ...toolCallParts,\n ...uiDataParts,\n ],\n metadata: {\n custom: getCustomMetadata(message.additional_kwargs),\n ...(timing && { timing }),\n ...(modality && { modality }),\n },\n ...(assistantStatus && { status: assistantStatus }),\n };\n }\n\n case \"tool\":\n return {\n role: \"tool\",\n // `joinExternalMessages` only checks the name against the tool call\n // when it is non-null, so an empty name manufactures a mismatch.\n toolName: message.name || undefined,\n toolCallId: message.tool_call_id ?? \"\",\n result: message.content,\n artifact: message.artifact,\n isError: message.status === \"error\",\n };\n\n default:\n return {\n role: \"system\",\n id: message.id,\n content: [\n {\n type: \"text\",\n text:\n typeof message.content === \"string\"\n ? message.content\n : (JSON.stringify(message.content) ?? \"\"),\n },\n ],\n };\n }\n};\n\nexport { getMessageContent } from \"./converter\";\n"],"mappings":"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"}
@@ -1,180 +1,179 @@
1
- import { AppendMessage, DataMessagePart, ThreadAssistantMessage, ThreadUserMessage } from "@assistant-ui/core";
2
- import { StreamingTimingAccessors } from "@assistant-ui/core/react";
3
- //#region src/converter.d.ts
1
+ import type { AppendMessage, DataMessagePart, MessageModality, ThreadAssistantMessage, ThreadUserMessage } from "@assistant-ui/core";
2
+ import type { StreamingTimingAccessors } from "@assistant-ui/core/react";
4
3
  /** Known content block types from @langchain/core messages. */
5
- type LangChainContentBlock = {
6
- type: "text";
7
- text: string;
4
+ export type LangChainContentBlock = {
5
+ type: "text";
6
+ text: string;
8
7
  } | {
9
- type: "text_delta";
10
- text: string;
8
+ type: "text_delta";
9
+ text: string;
11
10
  } | {
12
- type: "image_url";
13
- image_url: string | {
14
- url?: string;
15
- };
11
+ type: "image_url";
12
+ image_url: string | {
13
+ url?: string;
14
+ };
16
15
  } | {
17
- type: "thinking";
18
- thinking: string;
16
+ type: "thinking";
17
+ thinking: string;
19
18
  } | {
20
- type: "reasoning";
21
- summary?: Array<{
22
- type: "summary_text";
23
- text?: string;
24
- }>;
25
- reasoning?: string;
19
+ type: "reasoning";
20
+ summary?: Array<{
21
+ type: "summary_text";
22
+ text?: string;
23
+ }>;
24
+ reasoning?: string;
26
25
  } | {
27
- type: "file";
28
- data: string;
29
- mime_type: string;
30
- source_type?: "base64";
31
- metadata?: {
32
- filename?: string;
33
- };
26
+ type: "file";
27
+ data: string;
28
+ mime_type: string;
29
+ source_type?: "base64";
30
+ metadata?: {
31
+ filename?: string;
32
+ };
34
33
  } | {
35
- type: "file";
36
- url: string;
37
- mime_type?: string;
38
- source_type: "url";
39
- metadata?: {
40
- filename?: string;
41
- };
34
+ type: "file";
35
+ url: string;
36
+ mime_type?: string;
37
+ source_type: "url";
38
+ metadata?: {
39
+ filename?: string;
40
+ };
42
41
  } | {
43
- type: "file";
44
- id: string;
45
- mime_type?: string;
46
- source_type: "id";
47
- metadata?: {
48
- filename?: string;
49
- };
42
+ type: "file";
43
+ id: string;
44
+ mime_type?: string;
45
+ source_type: "id";
46
+ metadata?: {
47
+ filename?: string;
48
+ };
50
49
  } | {
51
- type: "audio";
52
- data: string;
53
- mime_type: string;
54
- source_type: "base64";
50
+ type: "audio";
51
+ data: string;
52
+ mime_type: string;
53
+ source_type: "base64";
55
54
  } | {
56
- type: "tool_use" | "input_json_delta";
55
+ type: "tool_use" | "input_json_delta";
57
56
  };
58
57
  type ConvertedContentPart = ThreadUserMessage["content"][number] | ThreadAssistantMessage["content"][number];
59
- declare const convertLangChainContentBlock: (part: LangChainContentBlock) => ConvertedContentPart | null | undefined;
58
+ export declare const convertLangChainContentBlock: (part: LangChainContentBlock) => ConvertedContentPart | null | undefined;
60
59
  /**
61
60
  * Audio output arrives outside the content array: providers leave `content`
62
61
  * empty and put the spoken text in `additional_kwargs.audio.transcript`. The
63
62
  * audio bytes stay behind because no provider reports their media type, and a
64
63
  * streamed response carries raw PCM rather than a playable file.
65
64
  */
66
- declare const withAudioTranscript: <T extends {
67
- type: string;
68
- text?: unknown;
65
+ export declare const withAudioTranscript: <T extends {
66
+ type: string;
67
+ text?: unknown;
69
68
  }>(parts: readonly T[], additionalKwargs: Record<string, unknown> | undefined) => readonly (T | {
70
- type: "text";
71
- text: string;
69
+ type: "text";
70
+ text: string;
72
71
  })[];
73
- declare const getCustomMetadata: (additionalKwargs: Record<string, unknown> | undefined) => Record<string, unknown>;
74
- declare const uiMessageToDataPart: <TUIMessage extends {
75
- name: string;
76
- props: Record<string, unknown>;
72
+ export declare const getCustomMetadata: (additionalKwargs: Record<string, unknown> | undefined) => Record<string, unknown>;
73
+ export declare const getMessageModality: (additionalKwargs: Record<string, unknown> | undefined) => MessageModality | undefined;
74
+ export declare const uiMessageToDataPart: <TUIMessage extends {
75
+ name: string;
76
+ props: Record<string, unknown>;
77
77
  }>(ui: TUIMessage) => DataMessagePart;
78
- declare const getMessageContent: (msg: AppendMessage) => string | ({
79
- type: "text";
80
- text: string;
81
- image_url?: never;
82
- id?: never;
83
- mime_type?: never;
84
- filename?: never;
85
- metadata?: never;
86
- source_type?: never;
87
- url?: never;
88
- data?: never;
78
+ export declare const getMessageContent: (msg: AppendMessage) => string | ({
79
+ type: "text";
80
+ text: string;
81
+ image_url?: never;
82
+ id?: never;
83
+ mime_type?: never;
84
+ filename?: never;
85
+ metadata?: never;
86
+ source_type?: never;
87
+ url?: never;
88
+ data?: never;
89
89
  } | {
90
- type: "image_url";
91
- image_url: {
92
- url: string;
93
- };
94
- text?: never;
95
- id?: never;
96
- mime_type?: never;
97
- filename?: never;
98
- metadata?: never;
99
- source_type?: never;
100
- url?: never;
101
- data?: never;
90
+ type: "image_url";
91
+ image_url: {
92
+ url: string;
93
+ };
94
+ text?: never;
95
+ id?: never;
96
+ mime_type?: never;
97
+ filename?: never;
98
+ metadata?: never;
99
+ source_type?: never;
100
+ url?: never;
101
+ data?: never;
102
102
  } | {
103
- type: "file";
104
- id: string;
105
- mime_type: string;
106
- filename: string;
107
- metadata: {
103
+ type: "file";
104
+ id: string;
105
+ mime_type: string;
108
106
  filename: string;
109
- };
110
- source_type: "id";
111
- text?: never;
112
- image_url?: never;
113
- url?: never;
114
- data?: never;
107
+ metadata: {
108
+ filename: string;
109
+ };
110
+ source_type: "id";
111
+ text?: never;
112
+ image_url?: never;
113
+ url?: never;
114
+ data?: never;
115
115
  } | {
116
- type: "file";
117
- url: string;
118
- mime_type: string;
119
- filename: string;
120
- metadata: {
116
+ type: "file";
117
+ url: string;
118
+ mime_type: string;
121
119
  filename: string;
122
- };
123
- source_type: "url";
124
- text?: never;
125
- image_url?: never;
126
- id?: never;
127
- data?: never;
120
+ metadata: {
121
+ filename: string;
122
+ };
123
+ source_type: "url";
124
+ text?: never;
125
+ image_url?: never;
126
+ id?: never;
127
+ data?: never;
128
128
  } | {
129
- type: "file";
130
- data: string;
131
- mime_type: string;
132
- filename: string;
133
- metadata: {
129
+ type: "file";
130
+ data: string;
131
+ mime_type: string;
134
132
  filename: string;
135
- };
136
- source_type: "base64";
137
- text?: never;
138
- image_url?: never;
139
- id?: never;
140
- url?: never;
133
+ metadata: {
134
+ filename: string;
135
+ };
136
+ source_type: "base64";
137
+ text?: never;
138
+ image_url?: never;
139
+ id?: never;
140
+ url?: never;
141
141
  } | {
142
- type: "audio";
143
- data: string;
144
- mime_type: string;
145
- source_type: "base64";
146
- text?: never;
147
- image_url?: never;
148
- id?: never;
149
- filename?: never;
150
- metadata?: never;
151
- url?: never;
142
+ type: "audio";
143
+ data: string;
144
+ mime_type: string;
145
+ source_type: "base64";
146
+ text?: never;
147
+ image_url?: never;
148
+ id?: never;
149
+ filename?: never;
150
+ metadata?: never;
151
+ url?: never;
152
152
  })[];
153
- declare const createLangChainStreamingTimingAccessors: <TMessage extends {
154
- id?: string | undefined;
155
- content?: unknown;
156
- tool_calls?: readonly unknown[] | undefined;
153
+ export declare const createLangChainStreamingTimingAccessors: <TMessage extends {
154
+ id?: string | undefined;
155
+ content?: unknown;
156
+ tool_calls?: readonly unknown[] | undefined;
157
157
  }>(getType: (message: TMessage) => string) => StreamingTimingAccessors<TMessage>;
158
158
  /**
159
159
  * Resolve the assistant message a `UIMessage` belongs to: the parent id comes
160
160
  * from `metadata.message_id` (Python SDK) or `metadata.id` (JS SDK).
161
161
  */
162
- declare const getUIMessageParentId: (ui: {
163
- metadata?: {
164
- message_id?: string;
165
- id?: string;
166
- } | undefined;
162
+ export declare const getUIMessageParentId: (ui: {
163
+ metadata?: {
164
+ message_id?: string;
165
+ id?: string;
166
+ } | undefined;
167
167
  }) => string | undefined;
168
168
  /**
169
169
  * Group the graph's accumulated `UIMessage`s by the assistant message they
170
170
  * belong to. Non-array state and entries without a parent link are dropped.
171
171
  */
172
- declare const groupUIMessagesByParent: <T extends {
173
- metadata?: {
174
- message_id?: string;
175
- id?: string;
176
- } | undefined;
172
+ export declare const groupUIMessagesByParent: <T extends {
173
+ metadata?: {
174
+ message_id?: string;
175
+ id?: string;
176
+ } | undefined;
177
177
  }>(value: unknown) => Map<string, T[]>;
178
- //#endregion
179
- export { LangChainContentBlock, convertLangChainContentBlock, createLangChainStreamingTimingAccessors, getCustomMetadata, getMessageContent, getUIMessageParentId, groupUIMessagesByParent, uiMessageToDataPart, withAudioTranscript };
178
+ export {};
180
179
  //# sourceMappingURL=converter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"converter.d.ts","names":[],"sources":["../src/converter.ts"],"mappings":";;;;KAaY;EACN;EAAc;;EACd;EAAoB;;EACpB;EAAmB;IAAsB;;;EACzC;EAAkB;;EAElB;EACA,UAAU;IAAQ;IAAsB;;EACxC;;EAGA;EACA;EACA;EACA;EACA;IAAa;;;EAGb;EACA;EACA;EACA;EACA;IAAa;;;EAGb;EACA;EACA;EACA;EACA;IAAa;;;EAGb;EACA;EACA;EACA;;EAEA;;KAED,uBACD,uCACA;cAES,+BACX,MAAM,0BACL;;;;;;;cAqEU,sBAAuB;EAAY;EAAc;GAC5D,gBAAgB,KAChB,kBAAkB,kDACP;EAAM;EAAc;;cAapB,oBACX,kBAAkB,wCACjB;cAGU,sBACX;EAAqB;EAAc,OAAO;GAE1C,IAAI,eACH;cAoBU,oBAAqB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuG1B,0CACX;EACE;EACA;EACA;GAGF,UAAU,SAAS,wBAClB,yBAAyB;;;;;cA+Df,uBAAwB;EACnC;IAAa;IAAqB;;;;;;;cAOvB,0BACX;EACE;IAAa;IAAqB;;GAGpC,mBACC,YAAY"}
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../src/converter.ts"],"names":[],"mappings":"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"}
package/dist/converter.js CHANGED
@@ -65,6 +65,7 @@ const withAudioTranscript = (parts, additionalKwargs) => {
65
65
  }];
66
66
  };
67
67
  const getCustomMetadata = (additionalKwargs) => additionalKwargs?.metadata ?? {};
68
+ const getMessageModality = (additionalKwargs) => additionalKwargs?.modality === "voice" ? "voice" : void 0;
68
69
  const uiMessageToDataPart = (ui) => ({
69
70
  type: "data",
70
71
  name: ui.name,
@@ -216,6 +217,6 @@ const groupUIMessagesByParent = (value) => {
216
217
  return map;
217
218
  };
218
219
  //#endregion
219
- export { convertLangChainContentBlock, createLangChainStreamingTimingAccessors, getCustomMetadata, getMessageContent, getUIMessageParentId, groupUIMessagesByParent, uiMessageToDataPart, withAudioTranscript };
220
+ export { convertLangChainContentBlock, createLangChainStreamingTimingAccessors, getCustomMetadata, getMessageContent, getMessageModality, getUIMessageParentId, groupUIMessagesByParent, uiMessageToDataPart, withAudioTranscript };
220
221
 
221
222
  //# sourceMappingURL=converter.js.map